diff options
Diffstat (limited to 'src')
181 files changed, 21001 insertions, 35359 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index d72aa07..ba07ac5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,17 +20,22 @@ HBLIBS = HBSOURCES = \ hb-atomic-private.hh \ hb-blob.cc \ + hb-buffer-deserialize-json.hh \ + hb-buffer-deserialize-text.hh \ hb-buffer-private.hh \ + hb-buffer-serialize.cc \ hb-buffer.cc \ hb-cache-private.hh \ hb-common.cc \ - hb-fallback-shape.cc \ + hb-face-private.hh \ + hb-face.cc \ hb-font-private.hh \ hb-font.cc \ hb-mutex-private.hh \ hb-object-private.hh \ hb-open-file-private.hh \ hb-open-type-private.hh \ + hb-ot-cmap-table.hh \ hb-ot-head-table.hh \ hb-ot-hhea-table.hh \ hb-ot-hmtx-table.hh \ @@ -47,7 +52,6 @@ HBSOURCES = \ hb-shaper-impl-private.hh \ hb-shaper-private.hh \ hb-shaper.cc \ - hb-tt-font.cc \ hb-unicode-private.hh \ hb-unicode.cc \ hb-utf-private.hh \ @@ -58,22 +62,28 @@ HBHEADERS = \ hb-blob.h \ hb-buffer.h \ hb-common.h \ + hb-deprecated.h \ + hb-face.h \ hb-font.h \ hb-set.h \ hb-shape.h \ hb-shape-plan.h \ hb-unicode.h \ + $(NULL) +HBNODISTHEADERS = \ hb-version.h \ $(NULL) if HAVE_OT HBSOURCES += \ + hb-ot-font.cc \ hb-ot-layout.cc \ hb-ot-layout-common-private.hh \ hb-ot-layout-gdef-table.hh \ hb-ot-layout-gpos-table.hh \ hb-ot-layout-gsubgpos-private.hh \ hb-ot-layout-gsub-table.hh \ + hb-ot-layout-jstf-table.hh \ hb-ot-layout-private.hh \ hb-ot-map.cc \ hb-ot-map-private.hh \ @@ -81,12 +91,20 @@ HBSOURCES += \ hb-ot-shape-complex-arabic.cc \ hb-ot-shape-complex-arabic-fallback.hh \ hb-ot-shape-complex-arabic-table.hh \ + hb-ot-shape-complex-arabic-win1256.hh \ hb-ot-shape-complex-default.cc \ + hb-ot-shape-complex-hangul.cc \ + hb-ot-shape-complex-hebrew.cc \ hb-ot-shape-complex-indic.cc \ hb-ot-shape-complex-indic-machine.hh \ hb-ot-shape-complex-indic-private.hh \ - hb-ot-shape-complex-indic-table.hh \ + hb-ot-shape-complex-indic-table.cc \ + hb-ot-shape-complex-myanmar.cc \ + hb-ot-shape-complex-myanmar-machine.hh \ + hb-ot-shape-complex-sea.cc \ + hb-ot-shape-complex-sea-machine.hh \ hb-ot-shape-complex-thai.cc \ + hb-ot-shape-complex-tibetan.cc \ hb-ot-shape-complex-private.hh \ hb-ot-shape-normalize-private.hh \ hb-ot-shape-normalize.cc \ @@ -96,11 +114,17 @@ HBSOURCES += \ $(NULL) HBHEADERS += \ hb-ot.h \ + hb-ot-font.h \ hb-ot-layout.h \ + hb-ot-shape.h \ hb-ot-tag.h \ $(NULL) endif +if HAVE_FALLBACK +HBSOURCES += hb-fallback-shape.cc +endif + if HAVE_PTHREAD HBCFLAGS += $(PTHREAD_CFLAGS) HBLIBS += $(PTHREAD_LIBS) @@ -113,28 +137,6 @@ HBSOURCES += hb-glib.cc HBHEADERS += hb-glib.h endif -if HAVE_GOBJECT -HBCFLAGS += $(GOBJECT_CFLAGS) -HBLIBS += $(GOBJECT_LIBS) -HBSOURCES += hb-gobject-structs.cc -nodist_HBSOURCES = hb-gobject-enums.cc -HBHEADERS += hb-gobject.h -BUILT_SOURCES += hb-gobject-enums.cc -EXTRA_DIST += hb-gobject-enums.cc.tmpl -DISTCLEANFILES += hb-gobject-enums.cc - -hb-gobject-enums.cc: hb-gobject-enums.cc.tmpl $(HBHEADERS) - $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > "$@.tmp" && \ - mv "$@.tmp" "$@" || ( $(RM) "@.tmp" && false ) -endif - -if HAVE_ICU -HBCFLAGS += $(ICU_CFLAGS) -HBLIBS += $(ICU_LIBS) -HBSOURCES += hb-icu.cc -HBHEADERS += hb-icu.h -endif - if HAVE_FREETYPE HBCFLAGS += $(FREETYPE_CFLAGS) HBLIBS += $(FREETYPE_LIBS) @@ -163,22 +165,6 @@ HBSOURCES += hb-coretext.cc HBHEADERS += hb-coretext.h endif -if HAVE_HB_OLD -SUBDIRS += hb-old -HBCFLAGS += -I$(srcdir)/hb-old -HBLIBS += hb-old/libhb-old.la -HBSOURCES += hb-old.cc -endif -DIST_SUBDIRS += hb-old - -if HAVE_ICU_LE -SUBDIRS += hb-icu-le -HBCFLAGS += -I$(srcdir)/hb-icu-le -HBLIBS += hb-icu-le/libhb-icu-le.la -HBSOURCES += hb-icu-le.cc -endif -DIST_SUBDIRS += hb-icu-le - if HAVE_UCDN SUBDIRS += hb-ucdn HBCFLAGS += -I$(srcdir)/hb-ucdn @@ -195,9 +181,6 @@ export_symbols = -export-symbols harfbuzz.def harfbuzz_def_dependency = harfbuzz.def libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS) else -if HAVE_ICU -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) @@ -205,19 +188,77 @@ else libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS) endif endif -endif -libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) -nodist_libharfbuzz_la_SOURCES = $(nodist_HBSOURCES) +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 = hb-version.h +nodist_pkginclude_HEADERS = $(HBNODISTHEADERS) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = harfbuzz.pc +EXTRA_DIST += harfbuzz.pc.in + +if HAVE_ICU +lib_LTLIBRARIES += libharfbuzz-icu.la +libharfbuzz_icu_la_SOURCES = hb-icu.cc +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.h +pkgconfig_DATA += harfbuzz-icu.pc +endif +EXTRA_DIST += harfbuzz-icu.pc.in + +if HAVE_GOBJECT +lib_LTLIBRARIES += libharfbuzz-gobject.la +libharfbuzz_gobject_la_SOURCES = hb-gobject-structs.cc +nodist_libharfbuzz_gobject_la_SOURCES = hb-gobject-enums.cc +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.h hb-gobject-structs.h +nodist_pkginclude_HEADERS += hb-gobject-enums.h +pkgconfig_DATA += harfbuzz-gobject.pc + +BUILT_SOURCES += \ + hb-gobject-enums.cc \ + hb-gobject-enums.h \ + $(NULL) +DISTCLEANFILES += \ + hb-gobject-enums.cc \ + hb-gobject-enums.h \ + $(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' > "$@.tmp" && \ + mv "$@.tmp" "$@" || ( $(RM) "@.tmp" && 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@%VERSION%@$(VERSION)@g' \ + "$<" \ + > "$@.tmp" && mv "$@.tmp" "$@" || ( $(RM) "$@.tmp"; false ) + +CLEANFILES += $(pkgconfig_DATA) + CLEANFILES += harfbuzz.def -harfbuzz.def: $(HBHEADERS) +harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) $(AM_V_GEN) (echo EXPORTS; \ (cat $^ || echo 'hb_ERROR ()' ) | \ $(EGREP) '^hb_.* \(' | \ @@ -232,30 +273,49 @@ GENERATORS = \ gen-arabic-table.py \ gen-indic-table.py \ $(NULL) - EXTRA_DIST += $(GENERATORS) unicode-tables: arabic-table indic-table indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.hh.tmp && \ - mv hb-ot-shape-complex-indic-table.hh.tmp $(srcdir)/hb-ot-shape-complex-indic-table.hh || \ - ($(RM) hb-ot-shape-complex-indic-table.hh.tmp; false) + $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc.tmp && \ + mv hb-ot-shape-complex-indic-table.cc.tmp $(srcdir)/hb-ot-shape-complex-indic-table.cc || \ + ($(RM) hb-ot-shape-complex-indic-table.cc.tmp; false) -arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt +arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh.tmp && \ mv hb-ot-shape-complex-arabic-table.hh.tmp $(srcdir)/hb-ot-shape-complex-arabic-table.hh || \ ($(RM) hb-ot-shape-complex-arabic-table.hh.tmp; false) +built-sources: $(BUILT_SOURCES) -.PHONY: unicode-tables arabic-table indic-table +.PHONY: unicode-tables arabic-table indic-table built-sources -EXTRA_DIST += hb-ot-shape-complex-indic-machine.rl -$(srcdir)/hb-ot-shape-complex-indic-machine.hh: hb-ot-shape-complex-indic-machine.rl - $(AM_V_GEN)$(top_srcdir)/missing --run ragel -e -F1 -o "$@.tmp" "$<" && \ +BUILT_SOURCES += \ + hb-buffer-deserialize-json.hh \ + hb-buffer-deserialize-text.hh \ + hb-ot-shape-complex-indic-machine.hh \ + hb-ot-shape-complex-myanmar-machine.hh \ + hb-ot-shape-complex-sea-machine.hh \ + $(NULL) +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-sea-machine.rl \ + $(NULL) +.rl.hh: + $(AM_V_GEN)$(RAGEL) -e -F1 -o "$@.tmp" "$<" && \ mv "$@.tmp" "$@" || ( $(RM) "$@.tmp" && false ) -noinst_PROGRAMS = main test test-would-substitute test-size-params +noinst_PROGRAMS = \ + main \ + test \ + test-buffer-serialize \ + test-size-params \ + test-would-substitute \ + $(NULL) bin_PROGRAMS = main_SOURCES = main.cc @@ -274,52 +334,70 @@ 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-exported-symbols.sh \ check-includes.sh \ - check-internal-symbols.sh \ + check-libstdc++.sh \ + check-static-inits.sh \ + check-symbols.sh \ $(NULL) -if HAVE_ICU -else -dist_check_SCRIPTS += check-libstdc++.sh -endif - -if HAVE_ICU_LE -else -dist_check_SCRIPTS += check-static-inits.sh -endif - TESTS = $(dist_check_SCRIPTS) TESTS_ENVIRONMENT = \ srcdir="$(srcdir)" \ MAKE="$(MAKE) $(AM_MAKEFLAGS)" \ HBSOURCES="$(HBSOURCES)" \ - HBHEADERS="$(HBHEADERS)" \ + HBHEADERS="$(HBHEADERS) $(HBNODISTHEADERS)" \ $(NULL) -#-include $(INTROSPECTION_MAKEFILE) -#INTROSPECTION_GIRS = hb-1.0.gir -#INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ -#INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) -# -#if HAVE_INTROSPECTION -# -#hb-1.0.gir: libharfbuzz.la -#hb_1_0_gir_INCLUDES = GObject-2.0 -#hb_1_0_gir_CFLAGS = $(INCLUDES) $(HBCFLAGS) -DHB_H -DHB_H_IN -DHB_OT_H -DHB_OT_H_IN -#hb_1_0_gir_LIBS = libharfbuzz.la -#hb_1_0_gir_FILES = $(HBHEADERS) -# -#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 +if HAVE_INTROSPECTION + +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = HarfBuzz-$(HB_VERSION_MAJOR).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 \ + $(NULL) +HarfBuzz_0_0_gir_LIBS = \ + libharfbuzz.la \ + libharfbuzz-gobject.la \ + $(NULL) +HarfBuzz_0_0_gir_FILES = \ + $(HBHEADERS) \ + $(HBNODISTHEADERS) \ + $(HBSOURCES) \ + hb-gobject-enums.cc \ + hb-gobject-enums.h \ + hb-gobject-structs.cc \ + hb-gobject-structs.h \ + $(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 diff --git a/src/Makefile.in b/src/Makefile.in index b52630a..703d994 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -19,7 +18,53 @@ + VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -39,12 +84,14 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_OT_TRUE@am__append_1 = \ +@HAVE_OT_TRUE@ hb-ot-font.cc \ @HAVE_OT_TRUE@ hb-ot-layout.cc \ @HAVE_OT_TRUE@ hb-ot-layout-common-private.hh \ @HAVE_OT_TRUE@ hb-ot-layout-gdef-table.hh \ @HAVE_OT_TRUE@ hb-ot-layout-gpos-table.hh \ @HAVE_OT_TRUE@ hb-ot-layout-gsubgpos-private.hh \ @HAVE_OT_TRUE@ hb-ot-layout-gsub-table.hh \ +@HAVE_OT_TRUE@ hb-ot-layout-jstf-table.hh \ @HAVE_OT_TRUE@ hb-ot-layout-private.hh \ @HAVE_OT_TRUE@ hb-ot-map.cc \ @HAVE_OT_TRUE@ hb-ot-map-private.hh \ @@ -52,12 +99,20 @@ host_triplet = @host@ @HAVE_OT_TRUE@ hb-ot-shape-complex-arabic.cc \ @HAVE_OT_TRUE@ hb-ot-shape-complex-arabic-fallback.hh \ @HAVE_OT_TRUE@ hb-ot-shape-complex-arabic-table.hh \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-arabic-win1256.hh \ @HAVE_OT_TRUE@ hb-ot-shape-complex-default.cc \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-hangul.cc \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-hebrew.cc \ @HAVE_OT_TRUE@ hb-ot-shape-complex-indic.cc \ @HAVE_OT_TRUE@ hb-ot-shape-complex-indic-machine.hh \ @HAVE_OT_TRUE@ hb-ot-shape-complex-indic-private.hh \ -@HAVE_OT_TRUE@ hb-ot-shape-complex-indic-table.hh \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-indic-table.cc \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-myanmar.cc \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-myanmar-machine.hh \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-sea.cc \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-sea-machine.hh \ @HAVE_OT_TRUE@ hb-ot-shape-complex-thai.cc \ +@HAVE_OT_TRUE@ hb-ot-shape-complex-tibetan.cc \ @HAVE_OT_TRUE@ hb-ot-shape-complex-private.hh \ @HAVE_OT_TRUE@ hb-ot-shape-normalize-private.hh \ @HAVE_OT_TRUE@ hb-ot-shape-normalize.cc \ @@ -68,71 +123,73 @@ host_triplet = @host@ @HAVE_OT_TRUE@am__append_2 = \ @HAVE_OT_TRUE@ hb-ot.h \ +@HAVE_OT_TRUE@ hb-ot-font.h \ @HAVE_OT_TRUE@ hb-ot-layout.h \ +@HAVE_OT_TRUE@ hb-ot-shape.h \ @HAVE_OT_TRUE@ hb-ot-tag.h \ @HAVE_OT_TRUE@ $(NULL) -@HAVE_PTHREAD_TRUE@am__append_3 = $(PTHREAD_CFLAGS) -@HAVE_PTHREAD_TRUE@am__append_4 = $(PTHREAD_LIBS) -@HAVE_GLIB_TRUE@am__append_5 = $(GLIB_CFLAGS) -@HAVE_GLIB_TRUE@am__append_6 = $(GLIB_LIBS) -@HAVE_GLIB_TRUE@am__append_7 = hb-glib.cc -@HAVE_GLIB_TRUE@am__append_8 = hb-glib.h -@HAVE_GOBJECT_TRUE@am__append_9 = $(GOBJECT_CFLAGS) -@HAVE_GOBJECT_TRUE@am__append_10 = $(GOBJECT_LIBS) -@HAVE_GOBJECT_TRUE@am__append_11 = hb-gobject-structs.cc -@HAVE_GOBJECT_TRUE@am__append_12 = hb-gobject.h -@HAVE_GOBJECT_TRUE@am__append_13 = hb-gobject-enums.cc -@HAVE_GOBJECT_TRUE@am__append_14 = hb-gobject-enums.cc.tmpl -@HAVE_GOBJECT_TRUE@am__append_15 = hb-gobject-enums.cc -@HAVE_ICU_TRUE@am__append_16 = $(ICU_CFLAGS) -@HAVE_ICU_TRUE@am__append_17 = $(ICU_LIBS) -@HAVE_ICU_TRUE@am__append_18 = hb-icu.cc -@HAVE_ICU_TRUE@am__append_19 = hb-icu.h -@HAVE_FREETYPE_TRUE@am__append_20 = $(FREETYPE_CFLAGS) -@HAVE_FREETYPE_TRUE@am__append_21 = $(FREETYPE_LIBS) -@HAVE_FREETYPE_TRUE@am__append_22 = hb-ft.cc -@HAVE_FREETYPE_TRUE@am__append_23 = hb-ft.h -@HAVE_GRAPHITE2_TRUE@am__append_24 = $(GRAPHITE2_CFLAGS) -@HAVE_GRAPHITE2_TRUE@am__append_25 = $(GRAPHITE2_LIBS) -@HAVE_GRAPHITE2_TRUE@am__append_26 = hb-graphite2.cc -@HAVE_GRAPHITE2_TRUE@am__append_27 = hb-graphite2.h -@HAVE_UNISCRIBE_TRUE@am__append_28 = $(UNISCRIBE_CFLAGS) -@HAVE_UNISCRIBE_TRUE@am__append_29 = $(UNISCRIBE_LIBS) -@HAVE_UNISCRIBE_TRUE@am__append_30 = hb-uniscribe.cc -@HAVE_UNISCRIBE_TRUE@am__append_31 = hb-uniscribe.h -@HAVE_CORETEXT_TRUE@am__append_32 = $(CORETEXT_CFLAGS) -@HAVE_CORETEXT_TRUE@am__append_33 = $(CORETEXT_LIBS) -@HAVE_CORETEXT_TRUE@am__append_34 = hb-coretext.cc -@HAVE_CORETEXT_TRUE@am__append_35 = hb-coretext.h -@HAVE_HB_OLD_TRUE@am__append_36 = hb-old -@HAVE_HB_OLD_TRUE@am__append_37 = -I$(srcdir)/hb-old -@HAVE_HB_OLD_TRUE@am__append_38 = hb-old/libhb-old.la -@HAVE_HB_OLD_TRUE@am__append_39 = hb-old.cc -@HAVE_ICU_LE_TRUE@am__append_40 = hb-icu-le -@HAVE_ICU_LE_TRUE@am__append_41 = -I$(srcdir)/hb-icu-le -@HAVE_ICU_LE_TRUE@am__append_42 = hb-icu-le/libhb-icu-le.la -@HAVE_ICU_LE_TRUE@am__append_43 = hb-icu-le.cc -@HAVE_UCDN_TRUE@am__append_44 = hb-ucdn -@HAVE_UCDN_TRUE@am__append_45 = -I$(srcdir)/hb-ucdn -@HAVE_UCDN_TRUE@am__append_46 = hb-ucdn/libhb-ucdn.la -@HAVE_UCDN_TRUE@am__append_47 = hb-ucdn.cc +@HAVE_FALLBACK_TRUE@am__append_3 = hb-fallback-shape.cc +@HAVE_PTHREAD_TRUE@am__append_4 = $(PTHREAD_CFLAGS) +@HAVE_PTHREAD_TRUE@am__append_5 = $(PTHREAD_LIBS) +@HAVE_GLIB_TRUE@am__append_6 = $(GLIB_CFLAGS) +@HAVE_GLIB_TRUE@am__append_7 = $(GLIB_LIBS) +@HAVE_GLIB_TRUE@am__append_8 = hb-glib.cc +@HAVE_GLIB_TRUE@am__append_9 = hb-glib.h +@HAVE_FREETYPE_TRUE@am__append_10 = $(FREETYPE_CFLAGS) +@HAVE_FREETYPE_TRUE@am__append_11 = $(FREETYPE_LIBS) +@HAVE_FREETYPE_TRUE@am__append_12 = hb-ft.cc +@HAVE_FREETYPE_TRUE@am__append_13 = hb-ft.h +@HAVE_GRAPHITE2_TRUE@am__append_14 = $(GRAPHITE2_CFLAGS) +@HAVE_GRAPHITE2_TRUE@am__append_15 = $(GRAPHITE2_LIBS) +@HAVE_GRAPHITE2_TRUE@am__append_16 = hb-graphite2.cc +@HAVE_GRAPHITE2_TRUE@am__append_17 = hb-graphite2.h +@HAVE_UNISCRIBE_TRUE@am__append_18 = $(UNISCRIBE_CFLAGS) +@HAVE_UNISCRIBE_TRUE@am__append_19 = $(UNISCRIBE_LIBS) +@HAVE_UNISCRIBE_TRUE@am__append_20 = hb-uniscribe.cc +@HAVE_UNISCRIBE_TRUE@am__append_21 = hb-uniscribe.h +@HAVE_CORETEXT_TRUE@am__append_22 = $(CORETEXT_CFLAGS) +@HAVE_CORETEXT_TRUE@am__append_23 = $(CORETEXT_LIBS) +@HAVE_CORETEXT_TRUE@am__append_24 = hb-coretext.cc +@HAVE_CORETEXT_TRUE@am__append_25 = hb-coretext.h +@HAVE_UCDN_TRUE@am__append_26 = hb-ucdn +@HAVE_UCDN_TRUE@am__append_27 = -I$(srcdir)/hb-ucdn +@HAVE_UCDN_TRUE@am__append_28 = hb-ucdn/libhb-ucdn.la +@HAVE_UCDN_TRUE@am__append_29 = hb-ucdn.cc +@HAVE_ICU_TRUE@am__append_30 = libharfbuzz-icu.la +@HAVE_ICU_TRUE@am__append_31 = hb-icu.h +@HAVE_ICU_TRUE@am__append_32 = harfbuzz-icu.pc +@HAVE_GOBJECT_TRUE@am__append_33 = libharfbuzz-gobject.la +@HAVE_GOBJECT_TRUE@am__append_34 = hb-gobject.h hb-gobject-structs.h +@HAVE_GOBJECT_TRUE@am__append_35 = hb-gobject-enums.h +@HAVE_GOBJECT_TRUE@am__append_36 = harfbuzz-gobject.pc +@HAVE_GOBJECT_TRUE@am__append_37 = \ +@HAVE_GOBJECT_TRUE@ hb-gobject-enums.cc \ +@HAVE_GOBJECT_TRUE@ hb-gobject-enums.h \ +@HAVE_GOBJECT_TRUE@ $(NULL) + +@HAVE_GOBJECT_TRUE@am__append_38 = \ +@HAVE_GOBJECT_TRUE@ hb-gobject-enums.cc \ +@HAVE_GOBJECT_TRUE@ hb-gobject-enums.h \ +@HAVE_GOBJECT_TRUE@ $(NULL) + noinst_PROGRAMS = main$(EXEEXT) test$(EXEEXT) \ - test-would-substitute$(EXEEXT) test-size-params$(EXEEXT) + test-buffer-serialize$(EXEEXT) test-size-params$(EXEEXT) \ + test-would-substitute$(EXEEXT) $(am__EXEEXT_1) bin_PROGRAMS = -@HAVE_ICU_FALSE@am__append_48 = check-libstdc++.sh -@HAVE_ICU_LE_FALSE@am__append_49 = check-static-inits.sh TESTS = $(am__EXEEXT_2) +@HAVE_INTROSPECTION_TRUE@am__append_39 = $(gir_DATA) $(typelib_DATA) subdir = src -DIST_COMMON = $(am__dist_check_SCRIPTS_DIST) \ - $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/hb-version.h.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/hb-version.h.in $(dist_check_SCRIPTS) \ + $(top_srcdir)/depcomp $(am__pkginclude_HEADERS_DIST) \ + $(top_srcdir)/test-driver ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -167,123 +224,170 @@ am__uninstall_files_from_dir = { \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)" + "$(DESTDIR)$(girdir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(pkgincludedir)" \ + "$(DESTDIR)$(pkgincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = +@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_DEPENDENCIES = \ +@HAVE_GOBJECT_TRUE@ $(am__DEPENDENCIES_1) libharfbuzz.la +am__libharfbuzz_gobject_la_SOURCES_DIST = hb-gobject-structs.cc +@HAVE_GOBJECT_TRUE@am_libharfbuzz_gobject_la_OBJECTS = libharfbuzz_gobject_la-hb-gobject-structs.lo +@HAVE_GOBJECT_TRUE@nodist_libharfbuzz_gobject_la_OBJECTS = \ +@HAVE_GOBJECT_TRUE@ libharfbuzz_gobject_la-hb-gobject-enums.lo +libharfbuzz_gobject_la_OBJECTS = $(am_libharfbuzz_gobject_la_OBJECTS) \ + $(nodist_libharfbuzz_gobject_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libharfbuzz_gobject_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(libharfbuzz_gobject_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@HAVE_GOBJECT_TRUE@am_libharfbuzz_gobject_la_rpath = -rpath $(libdir) +@HAVE_ICU_TRUE@libharfbuzz_icu_la_DEPENDENCIES = \ +@HAVE_ICU_TRUE@ $(am__DEPENDENCIES_1) libharfbuzz.la +am__libharfbuzz_icu_la_SOURCES_DIST = hb-icu.cc +@HAVE_ICU_TRUE@am_libharfbuzz_icu_la_OBJECTS = \ +@HAVE_ICU_TRUE@ libharfbuzz_icu_la-hb-icu.lo +libharfbuzz_icu_la_OBJECTS = $(am_libharfbuzz_icu_la_OBJECTS) +libharfbuzz_icu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(libharfbuzz_icu_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@HAVE_ICU_TRUE@am_libharfbuzz_icu_la_rpath = -rpath $(libdir) @HAVE_PTHREAD_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) @HAVE_GLIB_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) -@HAVE_GOBJECT_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) -@HAVE_ICU_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) -@HAVE_FREETYPE_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) -@HAVE_GRAPHITE2_TRUE@am__DEPENDENCIES_7 = $(am__DEPENDENCIES_1) -@HAVE_UNISCRIBE_TRUE@am__DEPENDENCIES_8 = $(am__DEPENDENCIES_1) -@HAVE_CORETEXT_TRUE@am__DEPENDENCIES_9 = $(am__DEPENDENCIES_1) -am__DEPENDENCIES_10 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \ +@HAVE_FREETYPE_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) +@HAVE_GRAPHITE2_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) +@HAVE_UNISCRIBE_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) +@HAVE_CORETEXT_TRUE@am__DEPENDENCIES_7 = $(am__DEPENDENCIES_1) +am__DEPENDENCIES_8 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) \ - $(am__DEPENDENCIES_6) $(am__DEPENDENCIES_7) \ - $(am__DEPENDENCIES_8) $(am__DEPENDENCIES_9) $(am__append_38) \ - $(am__append_42) $(am__append_46) -libharfbuzz_la_DEPENDENCIES = $(am__DEPENDENCIES_10) + $(am__DEPENDENCIES_6) $(am__DEPENDENCIES_7) $(am__append_28) +libharfbuzz_la_DEPENDENCIES = $(am__DEPENDENCIES_8) am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh hb-blob.cc \ - hb-buffer-private.hh hb-buffer.cc hb-cache-private.hh \ - hb-common.cc hb-fallback-shape.cc hb-font-private.hh \ - hb-font.cc hb-mutex-private.hh hb-object-private.hh \ - hb-open-file-private.hh hb-open-type-private.hh \ + hb-buffer-deserialize-json.hh hb-buffer-deserialize-text.hh \ + hb-buffer-private.hh hb-buffer-serialize.cc hb-buffer.cc \ + hb-cache-private.hh hb-common.cc hb-face-private.hh hb-face.cc \ + hb-font-private.hh hb-font.cc hb-mutex-private.hh \ + hb-object-private.hh hb-open-file-private.hh \ + hb-open-type-private.hh hb-ot-cmap-table.hh \ hb-ot-head-table.hh hb-ot-hhea-table.hh hb-ot-hmtx-table.hh \ hb-ot-maxp-table.hh hb-ot-name-table.hh hb-ot-tag.cc \ hb-private.hh hb-set-private.hh hb-set.cc hb-shape.cc \ hb-shape-plan-private.hh hb-shape-plan.cc hb-shaper-list.hh \ hb-shaper-impl-private.hh hb-shaper-private.hh hb-shaper.cc \ - hb-tt-font.cc hb-unicode-private.hh hb-unicode.cc \ - hb-utf-private.hh hb-warning.cc hb-ot-layout.cc \ + hb-unicode-private.hh hb-unicode.cc hb-utf-private.hh \ + hb-warning.cc hb-ot-font.cc hb-ot-layout.cc \ hb-ot-layout-common-private.hh hb-ot-layout-gdef-table.hh \ hb-ot-layout-gpos-table.hh hb-ot-layout-gsubgpos-private.hh \ - hb-ot-layout-gsub-table.hh hb-ot-layout-private.hh \ - hb-ot-map.cc hb-ot-map-private.hh hb-ot-shape.cc \ - hb-ot-shape-complex-arabic.cc \ + hb-ot-layout-gsub-table.hh hb-ot-layout-jstf-table.hh \ + hb-ot-layout-private.hh hb-ot-map.cc hb-ot-map-private.hh \ + hb-ot-shape.cc hb-ot-shape-complex-arabic.cc \ hb-ot-shape-complex-arabic-fallback.hh \ hb-ot-shape-complex-arabic-table.hh \ - hb-ot-shape-complex-default.cc hb-ot-shape-complex-indic.cc \ + hb-ot-shape-complex-arabic-win1256.hh \ + hb-ot-shape-complex-default.cc hb-ot-shape-complex-hangul.cc \ + hb-ot-shape-complex-hebrew.cc hb-ot-shape-complex-indic.cc \ hb-ot-shape-complex-indic-machine.hh \ hb-ot-shape-complex-indic-private.hh \ - hb-ot-shape-complex-indic-table.hh hb-ot-shape-complex-thai.cc \ + hb-ot-shape-complex-indic-table.cc \ + hb-ot-shape-complex-myanmar.cc \ + hb-ot-shape-complex-myanmar-machine.hh \ + hb-ot-shape-complex-sea.cc hb-ot-shape-complex-sea-machine.hh \ + hb-ot-shape-complex-thai.cc hb-ot-shape-complex-tibetan.cc \ hb-ot-shape-complex-private.hh \ hb-ot-shape-normalize-private.hh hb-ot-shape-normalize.cc \ hb-ot-shape-fallback-private.hh hb-ot-shape-fallback.cc \ - hb-ot-shape-private.hh hb-glib.cc hb-gobject-structs.cc \ - hb-icu.cc hb-ft.cc hb-graphite2.cc hb-uniscribe.cc \ - hb-coretext.cc hb-old.cc hb-icu-le.cc hb-ucdn.cc hb.h \ - hb-blob.h hb-buffer.h hb-common.h hb-font.h hb-set.h \ - hb-shape.h hb-shape-plan.h hb-unicode.h hb-version.h hb-ot.h \ - hb-ot-layout.h hb-ot-tag.h hb-glib.h hb-gobject.h hb-icu.h \ - hb-ft.h hb-graphite2.h hb-uniscribe.h hb-coretext.h + hb-ot-shape-private.hh hb-fallback-shape.cc hb-glib.cc \ + hb-ft.cc hb-graphite2.cc hb-uniscribe.cc hb-coretext.cc \ + hb-ucdn.cc hb.h hb-blob.h hb-buffer.h hb-common.h \ + hb-deprecated.h hb-face.h hb-font.h hb-set.h hb-shape.h \ + hb-shape-plan.h hb-unicode.h hb-ot.h hb-ot-font.h \ + hb-ot-layout.h hb-ot-shape.h hb-ot-tag.h hb-glib.h hb-ft.h \ + hb-graphite2.h hb-uniscribe.h hb-coretext.h hb-version.h am__objects_1 = -@HAVE_OT_TRUE@am__objects_2 = libharfbuzz_la-hb-ot-layout.lo \ +@HAVE_OT_TRUE@am__objects_2 = libharfbuzz_la-hb-ot-font.lo \ +@HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-layout.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-map.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-arabic.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-default.lo \ +@HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-hangul.lo \ +@HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-hebrew.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-indic.lo \ +@HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-indic-table.lo \ +@HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-myanmar.lo \ +@HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-sea.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-thai.lo \ +@HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-complex-tibetan.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-normalize.lo \ @HAVE_OT_TRUE@ libharfbuzz_la-hb-ot-shape-fallback.lo \ @HAVE_OT_TRUE@ $(am__objects_1) -@HAVE_GLIB_TRUE@am__objects_3 = libharfbuzz_la-hb-glib.lo -@HAVE_GOBJECT_TRUE@am__objects_4 = \ -@HAVE_GOBJECT_TRUE@ libharfbuzz_la-hb-gobject-structs.lo -@HAVE_ICU_TRUE@am__objects_5 = libharfbuzz_la-hb-icu.lo -@HAVE_FREETYPE_TRUE@am__objects_6 = libharfbuzz_la-hb-ft.lo -@HAVE_GRAPHITE2_TRUE@am__objects_7 = libharfbuzz_la-hb-graphite2.lo -@HAVE_UNISCRIBE_TRUE@am__objects_8 = libharfbuzz_la-hb-uniscribe.lo -@HAVE_CORETEXT_TRUE@am__objects_9 = libharfbuzz_la-hb-coretext.lo -@HAVE_HB_OLD_TRUE@am__objects_10 = libharfbuzz_la-hb-old.lo -@HAVE_ICU_LE_TRUE@am__objects_11 = libharfbuzz_la-hb-icu-le.lo -@HAVE_UCDN_TRUE@am__objects_12 = libharfbuzz_la-hb-ucdn.lo -am__objects_13 = libharfbuzz_la-hb-blob.lo libharfbuzz_la-hb-buffer.lo \ - libharfbuzz_la-hb-common.lo \ - libharfbuzz_la-hb-fallback-shape.lo libharfbuzz_la-hb-font.lo \ +@HAVE_FALLBACK_TRUE@am__objects_3 = \ +@HAVE_FALLBACK_TRUE@ libharfbuzz_la-hb-fallback-shape.lo +@HAVE_GLIB_TRUE@am__objects_4 = libharfbuzz_la-hb-glib.lo +@HAVE_FREETYPE_TRUE@am__objects_5 = libharfbuzz_la-hb-ft.lo +@HAVE_GRAPHITE2_TRUE@am__objects_6 = libharfbuzz_la-hb-graphite2.lo +@HAVE_UNISCRIBE_TRUE@am__objects_7 = libharfbuzz_la-hb-uniscribe.lo +@HAVE_CORETEXT_TRUE@am__objects_8 = libharfbuzz_la-hb-coretext.lo +@HAVE_UCDN_TRUE@am__objects_9 = libharfbuzz_la-hb-ucdn.lo +am__objects_10 = libharfbuzz_la-hb-blob.lo \ + libharfbuzz_la-hb-buffer-serialize.lo \ + libharfbuzz_la-hb-buffer.lo libharfbuzz_la-hb-common.lo \ + libharfbuzz_la-hb-face.lo libharfbuzz_la-hb-font.lo \ libharfbuzz_la-hb-ot-tag.lo libharfbuzz_la-hb-set.lo \ libharfbuzz_la-hb-shape.lo libharfbuzz_la-hb-shape-plan.lo \ - libharfbuzz_la-hb-shaper.lo libharfbuzz_la-hb-tt-font.lo \ - libharfbuzz_la-hb-unicode.lo libharfbuzz_la-hb-warning.lo \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) $(am__objects_6) \ - $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - $(am__objects_10) $(am__objects_11) $(am__objects_12) -@HAVE_OT_TRUE@am__objects_14 = $(am__objects_1) -am__objects_15 = $(am__objects_1) $(am__objects_14) $(am__objects_1) \ + libharfbuzz_la-hb-shaper.lo libharfbuzz_la-hb-unicode.lo \ + libharfbuzz_la-hb-warning.lo $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) $(am__objects_8) \ + $(am__objects_9) +@HAVE_OT_TRUE@am__objects_11 = $(am__objects_1) +am__objects_12 = $(am__objects_1) $(am__objects_11) $(am__objects_1) \ $(am__objects_1) $(am__objects_1) $(am__objects_1) \ - $(am__objects_1) $(am__objects_1) $(am__objects_1) -am_libharfbuzz_la_OBJECTS = $(am__objects_13) $(am__objects_15) -@HAVE_GOBJECT_TRUE@am__objects_16 = \ -@HAVE_GOBJECT_TRUE@ libharfbuzz_la-hb-gobject-enums.lo -nodist_libharfbuzz_la_OBJECTS = $(am__objects_16) -libharfbuzz_la_OBJECTS = $(am_libharfbuzz_la_OBJECTS) \ - $(nodist_libharfbuzz_la_OBJECTS) + $(am__objects_1) +am__objects_13 = $(am__objects_1) +am_libharfbuzz_la_OBJECTS = $(am__objects_10) $(am__objects_12) \ + $(am__objects_13) +libharfbuzz_la_OBJECTS = $(am_libharfbuzz_la_OBJECTS) +am__EXEEXT_1 = PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) am_main_OBJECTS = main-main.$(OBJEXT) main_OBJECTS = $(am_main_OBJECTS) -main_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_10) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent +main_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_8) am_test_OBJECTS = test-test.$(OBJEXT) test_OBJECTS = $(am_test_OBJECTS) -test_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_10) \ +test_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_8) \ $(am__DEPENDENCIES_1) +am_test_buffer_serialize_OBJECTS = \ + test_buffer_serialize-test-buffer-serialize.$(OBJEXT) +test_buffer_serialize_OBJECTS = $(am_test_buffer_serialize_OBJECTS) +test_buffer_serialize_DEPENDENCIES = libharfbuzz.la \ + $(am__DEPENDENCIES_8) am_test_size_params_OBJECTS = \ test_size_params-test-size-params.$(OBJEXT) test_size_params_OBJECTS = $(am_test_size_params_OBJECTS) -test_size_params_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_10) +test_size_params_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_8) am_test_would_substitute_OBJECTS = \ test_would_substitute-test-would-substitute.$(OBJEXT) test_would_substitute_OBJECTS = $(am_test_would_substitute_OBJECTS) test_would_substitute_DEPENDENCIES = libharfbuzz.la \ - $(am__DEPENDENCIES_10) $(am__DEPENDENCIES_1) -am__dist_check_SCRIPTS_DIST = check-c-linkage-decls.sh \ - check-header-guards.sh check-exported-symbols.sh \ - check-includes.sh check-internal-symbols.sh check-libstdc++.sh \ - check-static-inits.sh + $(am__DEPENDENCIES_8) $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -296,17 +400,16 @@ LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -315,50 +418,254 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libharfbuzz_la_SOURCES) $(nodist_libharfbuzz_la_SOURCES) \ - $(main_SOURCES) $(test_SOURCES) $(test_size_params_SOURCES) \ - $(test_would_substitute_SOURCES) -DIST_SOURCES = $(am__libharfbuzz_la_SOURCES_DIST) $(main_SOURCES) \ - $(test_SOURCES) $(test_size_params_SOURCES) \ +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libharfbuzz_gobject_la_SOURCES) \ + $(nodist_libharfbuzz_gobject_la_SOURCES) \ + $(libharfbuzz_icu_la_SOURCES) $(libharfbuzz_la_SOURCES) \ + $(main_SOURCES) $(test_SOURCES) \ + $(test_buffer_serialize_SOURCES) $(test_size_params_SOURCES) \ $(test_would_substitute_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +DIST_SOURCES = $(am__libharfbuzz_gobject_la_SOURCES_DIST) \ + $(am__libharfbuzz_icu_la_SOURCES_DIST) \ + $(am__libharfbuzz_la_SOURCES_DIST) $(main_SOURCES) \ + $(test_SOURCES) $(test_buffer_serialize_SOURCES) \ + $(test_size_params_SOURCES) $(test_would_substitute_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(gir_DATA) $(pkgconfig_DATA) $(typelib_DATA) am__pkginclude_HEADERS_DIST = hb.h hb-blob.h hb-buffer.h hb-common.h \ - hb-font.h hb-set.h hb-shape.h hb-shape-plan.h hb-unicode.h \ - hb-version.h hb-ot.h hb-ot-layout.h hb-ot-tag.h hb-glib.h \ - hb-gobject.h hb-icu.h hb-ft.h hb-graphite2.h hb-uniscribe.h \ - hb-coretext.h + hb-deprecated.h hb-face.h hb-font.h hb-set.h hb-shape.h \ + hb-shape-plan.h hb-unicode.h hb-ot.h hb-ot-font.h \ + hb-ot-layout.h hb-ot-shape.h hb-ot-tag.h hb-glib.h hb-ft.h \ + hb-graphite2.h hb-uniscribe.h hb-coretext.h hb-icu.h \ + hb-gobject.h hb-gobject-structs.h HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + check recheck distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__tty_colors = \ -red=; grn=; lgn=; blu=; std= -am__EXEEXT_1 = -am__EXEEXT_2 = check-c-linkage-decls.sh check-header-guards.sh \ - check-exported-symbols.sh check-includes.sh \ - check-internal-symbols.sh $(am__EXEEXT_1) $(am__append_48) \ - $(am__append_49) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +am__EXEEXT_2 = 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 $(am__EXEEXT_1) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -422,6 +729,7 @@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ FREETYPE_LIBS = @FREETYPE_LIBS@ +GIT = @GIT@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GLIB_MKENUMS = @GLIB_MKENUMS@ @@ -430,22 +738,34 @@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRAPHITE2_CFLAGS = @GRAPHITE2_CFLAGS@ GRAPHITE2_LIBS = @GRAPHITE2_LIBS@ GREP = @GREP@ -GTHREAD_CFLAGS = @GTHREAD_CFLAGS@ -GTHREAD_LIBS = @GTHREAD_LIBS@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@ HB_VERSION = @HB_VERSION@ HB_VERSION_MAJOR = @HB_VERSION_MAJOR@ HB_VERSION_MICRO = @HB_VERSION_MICRO@ HB_VERSION_MINOR = @HB_VERSION_MINOR@ +HTML_DIR = @HTML_DIR@ ICU_CFLAGS = @ICU_CFLAGS@ -ICU_LE_CFLAGS = @ICU_LE_CFLAGS@ -ICU_LE_LIBS = @ICU_LE_LIBS@ +ICU_CONFIG = @ICU_CONFIG@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ @@ -475,6 +795,7 @@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ +RAGEL = @RAGEL@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -538,66 +859,85 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ NULL = -SUBDIRS = $(am__append_36) $(am__append_40) $(am__append_44) -DIST_SUBDIRS = hb-old hb-icu-le hb-ucdn -BUILT_SOURCES = $(am__append_13) -EXTRA_DIST = $(am__append_14) $(GENERATORS) \ - hb-ot-shape-complex-indic-machine.rl -CLEANFILES = harfbuzz.def -DISTCLEANFILES = $(am__append_15) +SUBDIRS = $(am__append_26) +DIST_SUBDIRS = hb-ucdn +BUILT_SOURCES = $(am__append_37) hb-buffer-deserialize-json.hh \ + hb-buffer-deserialize-text.hh \ + hb-ot-shape-complex-indic-machine.hh \ + hb-ot-shape-complex-myanmar-machine.hh \ + hb-ot-shape-complex-sea-machine.hh $(NULL) +EXTRA_DIST = harfbuzz.pc.in harfbuzz-icu.pc.in harfbuzz-gobject.pc.in \ + hb-gobject-enums.cc.tmpl hb-gobject-enums.h.tmpl $(NULL) \ + $(GENERATORS) 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-sea-machine.rl $(NULL) +CLEANFILES = $(pkgconfig_DATA) harfbuzz.def $(am__append_39) +DISTCLEANFILES = $(am__append_38) MAINTAINERCLEANFILES = DISTCHECK_CONFIGURE_FLAGS = --enable-introspection # The following warning options are useful for debugging: -Wpadded #AM_CXXFLAGS = -lib_LTLIBRARIES = libharfbuzz.la -HBCFLAGS = $(am__append_3) $(am__append_5) $(am__append_9) \ - $(am__append_16) $(am__append_20) $(am__append_24) \ - $(am__append_28) $(am__append_32) $(am__append_37) \ - $(am__append_41) $(am__append_45) -HBLIBS = $(am__append_4) $(am__append_6) $(am__append_10) \ - $(am__append_17) $(am__append_21) $(am__append_25) \ - $(am__append_29) $(am__append_33) $(am__append_38) \ - $(am__append_42) $(am__append_46) -HBSOURCES = hb-atomic-private.hh hb-blob.cc hb-buffer-private.hh \ - hb-buffer.cc hb-cache-private.hh hb-common.cc \ - hb-fallback-shape.cc hb-font-private.hh hb-font.cc \ - hb-mutex-private.hh hb-object-private.hh \ - hb-open-file-private.hh hb-open-type-private.hh \ +lib_LTLIBRARIES = libharfbuzz.la $(am__append_30) $(am__append_33) +HBCFLAGS = $(am__append_4) $(am__append_6) $(am__append_10) \ + $(am__append_14) $(am__append_18) $(am__append_22) \ + $(am__append_27) +HBLIBS = $(am__append_5) $(am__append_7) $(am__append_11) \ + $(am__append_15) $(am__append_19) $(am__append_23) \ + $(am__append_28) +HBSOURCES = hb-atomic-private.hh hb-blob.cc \ + hb-buffer-deserialize-json.hh hb-buffer-deserialize-text.hh \ + hb-buffer-private.hh hb-buffer-serialize.cc hb-buffer.cc \ + hb-cache-private.hh hb-common.cc hb-face-private.hh hb-face.cc \ + hb-font-private.hh hb-font.cc hb-mutex-private.hh \ + hb-object-private.hh hb-open-file-private.hh \ + hb-open-type-private.hh hb-ot-cmap-table.hh \ hb-ot-head-table.hh hb-ot-hhea-table.hh hb-ot-hmtx-table.hh \ hb-ot-maxp-table.hh hb-ot-name-table.hh hb-ot-tag.cc \ hb-private.hh hb-set-private.hh hb-set.cc hb-shape.cc \ hb-shape-plan-private.hh hb-shape-plan.cc hb-shaper-list.hh \ hb-shaper-impl-private.hh hb-shaper-private.hh hb-shaper.cc \ - hb-tt-font.cc hb-unicode-private.hh hb-unicode.cc \ - hb-utf-private.hh hb-warning.cc $(NULL) $(am__append_1) \ - $(am__append_7) $(am__append_11) $(am__append_18) \ - $(am__append_22) $(am__append_26) $(am__append_30) \ - $(am__append_34) $(am__append_39) $(am__append_43) \ - $(am__append_47) -HBHEADERS = hb.h hb-blob.h hb-buffer.h hb-common.h hb-font.h hb-set.h \ - hb-shape.h hb-shape-plan.h hb-unicode.h hb-version.h $(NULL) \ - $(am__append_2) $(am__append_8) $(am__append_12) \ - $(am__append_19) $(am__append_23) $(am__append_27) \ - $(am__append_31) $(am__append_35) -@HAVE_GOBJECT_TRUE@nodist_HBSOURCES = hb-gobject-enums.cc + hb-unicode-private.hh hb-unicode.cc hb-utf-private.hh \ + hb-warning.cc $(NULL) $(am__append_1) $(am__append_3) \ + $(am__append_8) $(am__append_12) $(am__append_16) \ + $(am__append_20) $(am__append_24) $(am__append_29) +HBHEADERS = hb.h hb-blob.h hb-buffer.h hb-common.h hb-deprecated.h \ + hb-face.h hb-font.h hb-set.h hb-shape.h hb-shape-plan.h \ + hb-unicode.h $(NULL) $(am__append_2) $(am__append_9) \ + $(am__append_13) $(am__append_17) $(am__append_21) \ + $(am__append_25) +HBNODISTHEADERS = \ + hb-version.h \ + $(NULL) + # Put the library together @OS_WIN32_TRUE@export_symbols = -export-symbols harfbuzz.def @OS_WIN32_TRUE@harfbuzz_def_dependency = harfbuzz.def -@HAVE_GCC_FALSE@@HAVE_ICU_FALSE@@OS_WIN32_FALSE@libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS) +@HAVE_GCC_FALSE@@OS_WIN32_FALSE@libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS) # Use a C linker for GCC, not C++; Don't link to libstdc++ -@HAVE_GCC_TRUE@@HAVE_ICU_FALSE@@OS_WIN32_FALSE@libharfbuzz_la_LINK = $(LINK) $(libharfbuzz_la_LDFLAGS) -@HAVE_ICU_TRUE@@OS_WIN32_FALSE@libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS) +@HAVE_GCC_TRUE@@OS_WIN32_FALSE@libharfbuzz_la_LINK = $(LINK) $(libharfbuzz_la_LDFLAGS) @OS_WIN32_TRUE@libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS) -libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) -nodist_libharfbuzz_la_SOURCES = $(nodist_HBSOURCES) +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 = hb-version.h +pkginclude_HEADERS = $(HBHEADERS) $(am__append_31) $(am__append_34) +nodist_pkginclude_HEADERS = $(HBNODISTHEADERS) $(am__append_35) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = harfbuzz.pc $(am__append_32) $(am__append_36) +@HAVE_ICU_TRUE@libharfbuzz_icu_la_SOURCES = hb-icu.cc +@HAVE_ICU_TRUE@libharfbuzz_icu_la_CPPFLAGS = $(ICU_CFLAGS) +@HAVE_ICU_TRUE@libharfbuzz_icu_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined +@HAVE_ICU_TRUE@libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la +@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_SOURCES = hb-gobject-structs.cc +@HAVE_GOBJECT_TRUE@nodist_libharfbuzz_gobject_la_SOURCES = hb-gobject-enums.cc +@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_CPPFLAGS = $(GOBJECT_CFLAGS) +@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined +@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la GENERATORS = \ gen-arabic-table.py \ gen-indic-table.py \ @@ -615,22 +955,66 @@ 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) -dist_check_SCRIPTS = check-c-linkage-decls.sh check-header-guards.sh \ - check-exported-symbols.sh check-includes.sh \ - check-internal-symbols.sh $(NULL) $(am__append_48) \ - $(am__append_49) +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) + TESTS_ENVIRONMENT = \ srcdir="$(srcdir)" \ MAKE="$(MAKE) $(AM_MAKEFLAGS)" \ HBSOURCES="$(HBSOURCES)" \ - HBHEADERS="$(HBHEADERS)" \ + HBHEADERS="$(HBHEADERS) $(HBNODISTHEADERS)" \ $(NULL) +@HAVE_INTROSPECTION_TRUE@INTROSPECTION_GIRS = HarfBuzz-$(HB_VERSION_MAJOR).0.gir # What does the 0 mean anyway?! +@HAVE_INTROSPECTION_TRUE@INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ --warn-all +@HAVE_INTROSPECTION_TRUE@INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) +@HAVE_INTROSPECTION_TRUE@INTROSPECTION_SCANNER_ENV = CC="$(CC)" +@HAVE_INTROSPECTION_TRUE@HarfBuzz_0_0_gir_INCLUDES = GObject-2.0 +@HAVE_INTROSPECTION_TRUE@HarfBuzz_0_0_gir_CFLAGS = \ +@HAVE_INTROSPECTION_TRUE@ $(INCLUDES) \ +@HAVE_INTROSPECTION_TRUE@ $(HBCFLAGS) \ +@HAVE_INTROSPECTION_TRUE@ -DHB_H \ +@HAVE_INTROSPECTION_TRUE@ -DHB_H_IN \ +@HAVE_INTROSPECTION_TRUE@ -DHB_OT_H \ +@HAVE_INTROSPECTION_TRUE@ -DHB_OT_H_IN \ +@HAVE_INTROSPECTION_TRUE@ -DHB_GOBJECT_H \ +@HAVE_INTROSPECTION_TRUE@ -DHB_GOBJECT_H_IN \ +@HAVE_INTROSPECTION_TRUE@ $(NULL) + +@HAVE_INTROSPECTION_TRUE@HarfBuzz_0_0_gir_LIBS = \ +@HAVE_INTROSPECTION_TRUE@ libharfbuzz.la \ +@HAVE_INTROSPECTION_TRUE@ libharfbuzz-gobject.la \ +@HAVE_INTROSPECTION_TRUE@ $(NULL) + +@HAVE_INTROSPECTION_TRUE@HarfBuzz_0_0_gir_FILES = \ +@HAVE_INTROSPECTION_TRUE@ $(HBHEADERS) \ +@HAVE_INTROSPECTION_TRUE@ $(HBNODISTHEADERS) \ +@HAVE_INTROSPECTION_TRUE@ $(HBSOURCES) \ +@HAVE_INTROSPECTION_TRUE@ hb-gobject-enums.cc \ +@HAVE_INTROSPECTION_TRUE@ hb-gobject-enums.h \ +@HAVE_INTROSPECTION_TRUE@ hb-gobject-structs.cc \ +@HAVE_INTROSPECTION_TRUE@ hb-gobject-structs.h \ +@HAVE_INTROSPECTION_TRUE@ $(NULL) + +@HAVE_INTROSPECTION_TRUE@girdir = $(datadir)/gir-1.0 +@HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS) +@HAVE_INTROSPECTION_TRUE@typelibdir = $(libdir)/girepository-1.0 +@HAVE_INTROSPECTION_TRUE@typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: -.SUFFIXES: .cc .lo .o .obj +.SUFFIXES: .cc .hh .lo .log .o .obj .rl .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -663,9 +1047,9 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): hb-version.h: $(top_builddir)/config.status $(srcdir)/hb-version.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -673,6 +1057,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } @@ -688,24 +1074,38 @@ uninstall-libLTLIBRARIES: clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libharfbuzz-gobject.la: $(libharfbuzz_gobject_la_OBJECTS) $(libharfbuzz_gobject_la_DEPENDENCIES) $(EXTRA_libharfbuzz_gobject_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libharfbuzz_gobject_la_LINK) $(am_libharfbuzz_gobject_la_rpath) $(libharfbuzz_gobject_la_OBJECTS) $(libharfbuzz_gobject_la_LIBADD) $(LIBS) + +libharfbuzz-icu.la: $(libharfbuzz_icu_la_OBJECTS) $(libharfbuzz_icu_la_DEPENDENCIES) $(EXTRA_libharfbuzz_icu_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libharfbuzz_icu_la_LINK) $(am_libharfbuzz_icu_la_rpath) $(libharfbuzz_icu_la_OBJECTS) $(libharfbuzz_icu_la_LIBADD) $(LIBS) + libharfbuzz.la: $(libharfbuzz_la_OBJECTS) $(libharfbuzz_la_DEPENDENCIES) $(EXTRA_libharfbuzz_la_DEPENDENCIES) $(AM_V_GEN)$(libharfbuzz_la_LINK) -rpath $(libdir) $(libharfbuzz_la_OBJECTS) $(libharfbuzz_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -726,7 +1126,8 @@ uninstall-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files @@ -764,15 +1165,23 @@ clean-noinstPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list + main$(EXEEXT): $(main_OBJECTS) $(main_DEPENDENCIES) $(EXTRA_main_DEPENDENCIES) @rm -f main$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(main_OBJECTS) $(main_LDADD) $(LIBS) + test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) @rm -f test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +test-buffer-serialize$(EXEEXT): $(test_buffer_serialize_OBJECTS) $(test_buffer_serialize_DEPENDENCIES) $(EXTRA_test_buffer_serialize_DEPENDENCIES) + @rm -f test-buffer-serialize$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(test_buffer_serialize_OBJECTS) $(test_buffer_serialize_LDADD) $(LIBS) + test-size-params$(EXEEXT): $(test_size_params_OBJECTS) $(test_size_params_DEPENDENCIES) $(EXTRA_test_size_params_DEPENDENCIES) @rm -f test-size-params$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(test_size_params_OBJECTS) $(test_size_params_LDADD) $(LIBS) + test-would-substitute$(EXEEXT): $(test_would_substitute_OBJECTS) $(test_would_substitute_DEPENDENCIES) $(EXTRA_test_would_substitute_DEPENDENCIES) @rm -f test-would-substitute$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(test_would_substitute_OBJECTS) $(test_would_substitute_LDADD) $(LIBS) @@ -783,26 +1192,33 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-enums.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-structs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_icu_la-hb-icu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-blob.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-buffer-serialize.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-buffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-coretext.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-face.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-font.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ft.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-glib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-gobject-enums.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-gobject-structs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-graphite2.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-icu-le.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-icu.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-old.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-font.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-layout.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-arabic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-default.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hangul.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hebrew.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic-table.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-myanmar.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-sea.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-thai.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-tibetan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-fallback.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-normalize.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape.Plo@am__quote@ @@ -811,13 +1227,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shape-plan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shape.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shaper.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-tt-font.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-unicode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-uniscribe.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-warning.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_size_params-test-size-params.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_would_substitute-test-would-substitute.Po@am__quote@ @@ -842,6 +1258,27 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< +libharfbuzz_gobject_la-hb-gobject-structs.lo: hb-gobject-structs.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_gobject_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_gobject_la-hb-gobject-structs.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-structs.Tpo -c -o libharfbuzz_gobject_la-hb-gobject-structs.lo `test -f 'hb-gobject-structs.cc' || echo '$(srcdir)/'`hb-gobject-structs.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-structs.Tpo $(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-structs.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-gobject-structs.cc' object='libharfbuzz_gobject_la-hb-gobject-structs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_gobject_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_gobject_la-hb-gobject-structs.lo `test -f 'hb-gobject-structs.cc' || echo '$(srcdir)/'`hb-gobject-structs.cc + +libharfbuzz_gobject_la-hb-gobject-enums.lo: hb-gobject-enums.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_gobject_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_gobject_la-hb-gobject-enums.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-enums.Tpo -c -o libharfbuzz_gobject_la-hb-gobject-enums.lo `test -f 'hb-gobject-enums.cc' || echo '$(srcdir)/'`hb-gobject-enums.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-enums.Tpo $(DEPDIR)/libharfbuzz_gobject_la-hb-gobject-enums.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-gobject-enums.cc' object='libharfbuzz_gobject_la-hb-gobject-enums.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_gobject_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_gobject_la-hb-gobject-enums.lo `test -f 'hb-gobject-enums.cc' || echo '$(srcdir)/'`hb-gobject-enums.cc + +libharfbuzz_icu_la-hb-icu.lo: hb-icu.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_icu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_icu_la-hb-icu.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_icu_la-hb-icu.Tpo -c -o libharfbuzz_icu_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_icu_la-hb-icu.Tpo $(DEPDIR)/libharfbuzz_icu_la-hb-icu.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-icu.cc' object='libharfbuzz_icu_la-hb-icu.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_icu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_icu_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc + libharfbuzz_la-hb-blob.lo: hb-blob.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-blob.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-blob.Tpo -c -o libharfbuzz_la-hb-blob.lo `test -f 'hb-blob.cc' || echo '$(srcdir)/'`hb-blob.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-blob.Tpo $(DEPDIR)/libharfbuzz_la-hb-blob.Plo @@ -849,6 +1286,13 @@ libharfbuzz_la-hb-blob.lo: hb-blob.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-blob.lo `test -f 'hb-blob.cc' || echo '$(srcdir)/'`hb-blob.cc +libharfbuzz_la-hb-buffer-serialize.lo: hb-buffer-serialize.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-buffer-serialize.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-buffer-serialize.Tpo -c -o libharfbuzz_la-hb-buffer-serialize.lo `test -f 'hb-buffer-serialize.cc' || echo '$(srcdir)/'`hb-buffer-serialize.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-buffer-serialize.Tpo $(DEPDIR)/libharfbuzz_la-hb-buffer-serialize.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-buffer-serialize.cc' object='libharfbuzz_la-hb-buffer-serialize.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-buffer-serialize.lo `test -f 'hb-buffer-serialize.cc' || echo '$(srcdir)/'`hb-buffer-serialize.cc + libharfbuzz_la-hb-buffer.lo: hb-buffer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-buffer.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-buffer.Tpo -c -o libharfbuzz_la-hb-buffer.lo `test -f 'hb-buffer.cc' || echo '$(srcdir)/'`hb-buffer.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-buffer.Tpo $(DEPDIR)/libharfbuzz_la-hb-buffer.Plo @@ -863,12 +1307,12 @@ libharfbuzz_la-hb-common.lo: hb-common.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-common.lo `test -f 'hb-common.cc' || echo '$(srcdir)/'`hb-common.cc -libharfbuzz_la-hb-fallback-shape.lo: hb-fallback-shape.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-fallback-shape.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-fallback-shape.cc' object='libharfbuzz_la-hb-fallback-shape.lo' libtool=yes @AMDEPBACKSLASH@ +libharfbuzz_la-hb-face.lo: hb-face.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-face.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-face.Tpo -c -o libharfbuzz_la-hb-face.lo `test -f 'hb-face.cc' || echo '$(srcdir)/'`hb-face.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-face.Tpo $(DEPDIR)/libharfbuzz_la-hb-face.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-face.cc' object='libharfbuzz_la-hb-face.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-face.lo `test -f 'hb-face.cc' || echo '$(srcdir)/'`hb-face.cc libharfbuzz_la-hb-font.lo: hb-font.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-font.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-font.Tpo -c -o libharfbuzz_la-hb-font.lo `test -f 'hb-font.cc' || echo '$(srcdir)/'`hb-font.cc @@ -912,13 +1356,6 @@ libharfbuzz_la-hb-shaper.lo: hb-shaper.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-shaper.lo `test -f 'hb-shaper.cc' || echo '$(srcdir)/'`hb-shaper.cc -libharfbuzz_la-hb-tt-font.lo: hb-tt-font.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-tt-font.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-tt-font.Tpo -c -o libharfbuzz_la-hb-tt-font.lo `test -f 'hb-tt-font.cc' || echo '$(srcdir)/'`hb-tt-font.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-tt-font.Tpo $(DEPDIR)/libharfbuzz_la-hb-tt-font.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-tt-font.cc' object='libharfbuzz_la-hb-tt-font.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-tt-font.lo `test -f 'hb-tt-font.cc' || echo '$(srcdir)/'`hb-tt-font.cc - libharfbuzz_la-hb-unicode.lo: hb-unicode.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-unicode.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-unicode.Tpo -c -o libharfbuzz_la-hb-unicode.lo `test -f 'hb-unicode.cc' || echo '$(srcdir)/'`hb-unicode.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-unicode.Tpo $(DEPDIR)/libharfbuzz_la-hb-unicode.Plo @@ -933,6 +1370,13 @@ libharfbuzz_la-hb-warning.lo: hb-warning.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-warning.lo `test -f 'hb-warning.cc' || echo '$(srcdir)/'`hb-warning.cc +libharfbuzz_la-hb-ot-font.lo: hb-ot-font.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-font.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-font.Tpo -c -o libharfbuzz_la-hb-ot-font.lo `test -f 'hb-ot-font.cc' || echo '$(srcdir)/'`hb-ot-font.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-font.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-font.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-ot-font.cc' object='libharfbuzz_la-hb-ot-font.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-font.lo `test -f 'hb-ot-font.cc' || echo '$(srcdir)/'`hb-ot-font.cc + libharfbuzz_la-hb-ot-layout.lo: hb-ot-layout.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-layout.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-layout.Tpo -c -o libharfbuzz_la-hb-ot-layout.lo `test -f 'hb-ot-layout.cc' || echo '$(srcdir)/'`hb-ot-layout.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-layout.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-layout.Plo @@ -968,6 +1412,20 @@ libharfbuzz_la-hb-ot-shape-complex-default.lo: hb-ot-shape-complex-default.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-default.lo `test -f 'hb-ot-shape-complex-default.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-default.cc +libharfbuzz_la-hb-ot-shape-complex-hangul.lo: hb-ot-shape-complex-hangul.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-hangul.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hangul.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-hangul.lo `test -f 'hb-ot-shape-complex-hangul.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-hangul.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hangul.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hangul.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-ot-shape-complex-hangul.cc' object='libharfbuzz_la-hb-ot-shape-complex-hangul.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-hangul.lo `test -f 'hb-ot-shape-complex-hangul.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-hangul.cc + +libharfbuzz_la-hb-ot-shape-complex-hebrew.lo: hb-ot-shape-complex-hebrew.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-hebrew.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hebrew.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-hebrew.lo `test -f 'hb-ot-shape-complex-hebrew.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-hebrew.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hebrew.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-hebrew.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-ot-shape-complex-hebrew.cc' object='libharfbuzz_la-hb-ot-shape-complex-hebrew.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-hebrew.lo `test -f 'hb-ot-shape-complex-hebrew.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-hebrew.cc + libharfbuzz_la-hb-ot-shape-complex-indic.lo: hb-ot-shape-complex-indic.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-indic.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-indic.lo `test -f 'hb-ot-shape-complex-indic.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-indic.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic.Plo @@ -975,6 +1433,27 @@ libharfbuzz_la-hb-ot-shape-complex-indic.lo: hb-ot-shape-complex-indic.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-indic.lo `test -f 'hb-ot-shape-complex-indic.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-indic.cc +libharfbuzz_la-hb-ot-shape-complex-indic-table.lo: hb-ot-shape-complex-indic-table.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-indic-table.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic-table.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-indic-table.lo `test -f 'hb-ot-shape-complex-indic-table.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-indic-table.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic-table.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-indic-table.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-ot-shape-complex-indic-table.cc' object='libharfbuzz_la-hb-ot-shape-complex-indic-table.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-indic-table.lo `test -f 'hb-ot-shape-complex-indic-table.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-indic-table.cc + +libharfbuzz_la-hb-ot-shape-complex-myanmar.lo: hb-ot-shape-complex-myanmar.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-myanmar.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-myanmar.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-myanmar.lo `test -f 'hb-ot-shape-complex-myanmar.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-myanmar.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-myanmar.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-myanmar.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-ot-shape-complex-myanmar.cc' object='libharfbuzz_la-hb-ot-shape-complex-myanmar.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-myanmar.lo `test -f 'hb-ot-shape-complex-myanmar.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-myanmar.cc + +libharfbuzz_la-hb-ot-shape-complex-sea.lo: hb-ot-shape-complex-sea.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-sea.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-sea.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-sea.lo `test -f 'hb-ot-shape-complex-sea.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-sea.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-sea.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-sea.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-ot-shape-complex-sea.cc' object='libharfbuzz_la-hb-ot-shape-complex-sea.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-sea.lo `test -f 'hb-ot-shape-complex-sea.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-sea.cc + libharfbuzz_la-hb-ot-shape-complex-thai.lo: hb-ot-shape-complex-thai.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-thai.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-thai.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-thai.lo `test -f 'hb-ot-shape-complex-thai.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-thai.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-thai.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-thai.Plo @@ -982,6 +1461,13 @@ libharfbuzz_la-hb-ot-shape-complex-thai.lo: hb-ot-shape-complex-thai.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-thai.lo `test -f 'hb-ot-shape-complex-thai.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-thai.cc +libharfbuzz_la-hb-ot-shape-complex-tibetan.lo: hb-ot-shape-complex-tibetan.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-complex-tibetan.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-tibetan.Tpo -c -o libharfbuzz_la-hb-ot-shape-complex-tibetan.lo `test -f 'hb-ot-shape-complex-tibetan.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-tibetan.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-tibetan.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-tibetan.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-ot-shape-complex-tibetan.cc' object='libharfbuzz_la-hb-ot-shape-complex-tibetan.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-complex-tibetan.lo `test -f 'hb-ot-shape-complex-tibetan.cc' || echo '$(srcdir)/'`hb-ot-shape-complex-tibetan.cc + libharfbuzz_la-hb-ot-shape-normalize.lo: hb-ot-shape-normalize.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-shape-normalize.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-shape-normalize.Tpo -c -o libharfbuzz_la-hb-ot-shape-normalize.lo `test -f 'hb-ot-shape-normalize.cc' || echo '$(srcdir)/'`hb-ot-shape-normalize.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-shape-normalize.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-shape-normalize.Plo @@ -996,6 +1482,13 @@ libharfbuzz_la-hb-ot-shape-fallback.lo: hb-ot-shape-fallback.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-shape-fallback.lo `test -f 'hb-ot-shape-fallback.cc' || echo '$(srcdir)/'`hb-ot-shape-fallback.cc +libharfbuzz_la-hb-fallback-shape.lo: hb-fallback-shape.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-fallback-shape.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-fallback-shape.cc' object='libharfbuzz_la-hb-fallback-shape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc + libharfbuzz_la-hb-glib.lo: hb-glib.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-glib.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-glib.Tpo -c -o libharfbuzz_la-hb-glib.lo `test -f 'hb-glib.cc' || echo '$(srcdir)/'`hb-glib.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-glib.Tpo $(DEPDIR)/libharfbuzz_la-hb-glib.Plo @@ -1003,20 +1496,6 @@ libharfbuzz_la-hb-glib.lo: hb-glib.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-glib.lo `test -f 'hb-glib.cc' || echo '$(srcdir)/'`hb-glib.cc -libharfbuzz_la-hb-gobject-structs.lo: hb-gobject-structs.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-gobject-structs.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-gobject-structs.Tpo -c -o libharfbuzz_la-hb-gobject-structs.lo `test -f 'hb-gobject-structs.cc' || echo '$(srcdir)/'`hb-gobject-structs.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-gobject-structs.Tpo $(DEPDIR)/libharfbuzz_la-hb-gobject-structs.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-gobject-structs.cc' object='libharfbuzz_la-hb-gobject-structs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-gobject-structs.lo `test -f 'hb-gobject-structs.cc' || echo '$(srcdir)/'`hb-gobject-structs.cc - -libharfbuzz_la-hb-icu.lo: hb-icu.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-icu.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-icu.Tpo -c -o libharfbuzz_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-icu.Tpo $(DEPDIR)/libharfbuzz_la-hb-icu.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-icu.cc' object='libharfbuzz_la-hb-icu.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc - libharfbuzz_la-hb-ft.lo: hb-ft.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ft.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ft.Tpo -c -o libharfbuzz_la-hb-ft.lo `test -f 'hb-ft.cc' || echo '$(srcdir)/'`hb-ft.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ft.Tpo $(DEPDIR)/libharfbuzz_la-hb-ft.Plo @@ -1045,20 +1524,6 @@ libharfbuzz_la-hb-coretext.lo: hb-coretext.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-coretext.lo `test -f 'hb-coretext.cc' || echo '$(srcdir)/'`hb-coretext.cc -libharfbuzz_la-hb-old.lo: hb-old.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-old.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-old.Tpo -c -o libharfbuzz_la-hb-old.lo `test -f 'hb-old.cc' || echo '$(srcdir)/'`hb-old.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-old.Tpo $(DEPDIR)/libharfbuzz_la-hb-old.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-old.cc' object='libharfbuzz_la-hb-old.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-old.lo `test -f 'hb-old.cc' || echo '$(srcdir)/'`hb-old.cc - -libharfbuzz_la-hb-icu-le.lo: hb-icu-le.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-icu-le.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-icu-le.Tpo -c -o libharfbuzz_la-hb-icu-le.lo `test -f 'hb-icu-le.cc' || echo '$(srcdir)/'`hb-icu-le.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-icu-le.Tpo $(DEPDIR)/libharfbuzz_la-hb-icu-le.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-icu-le.cc' object='libharfbuzz_la-hb-icu-le.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-icu-le.lo `test -f 'hb-icu-le.cc' || echo '$(srcdir)/'`hb-icu-le.cc - libharfbuzz_la-hb-ucdn.lo: hb-ucdn.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ucdn.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ucdn.Tpo -c -o libharfbuzz_la-hb-ucdn.lo `test -f 'hb-ucdn.cc' || echo '$(srcdir)/'`hb-ucdn.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ucdn.Tpo $(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo @@ -1066,13 +1531,6 @@ libharfbuzz_la-hb-ucdn.lo: hb-ucdn.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ucdn.lo `test -f 'hb-ucdn.cc' || echo '$(srcdir)/'`hb-ucdn.cc -libharfbuzz_la-hb-gobject-enums.lo: hb-gobject-enums.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-gobject-enums.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-gobject-enums.Tpo -c -o libharfbuzz_la-hb-gobject-enums.lo `test -f 'hb-gobject-enums.cc' || echo '$(srcdir)/'`hb-gobject-enums.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-gobject-enums.Tpo $(DEPDIR)/libharfbuzz_la-hb-gobject-enums.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-gobject-enums.cc' object='libharfbuzz_la-hb-gobject-enums.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-gobject-enums.lo `test -f 'hb-gobject-enums.cc' || echo '$(srcdir)/'`hb-gobject-enums.cc - main-main.o: main.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(main_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT main-main.o -MD -MP -MF $(DEPDIR)/main-main.Tpo -c -o main-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/main-main.Tpo $(DEPDIR)/main-main.Po @@ -1101,6 +1559,20 @@ test-test.obj: test.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test-test.obj `if test -f 'test.cc'; then $(CYGPATH_W) 'test.cc'; else $(CYGPATH_W) '$(srcdir)/test.cc'; fi` +test_buffer_serialize-test-buffer-serialize.o: test-buffer-serialize.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_buffer_serialize_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_buffer_serialize-test-buffer-serialize.o -MD -MP -MF $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Tpo -c -o test_buffer_serialize-test-buffer-serialize.o `test -f 'test-buffer-serialize.cc' || echo '$(srcdir)/'`test-buffer-serialize.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Tpo $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='test-buffer-serialize.cc' object='test_buffer_serialize-test-buffer-serialize.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_buffer_serialize_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_buffer_serialize-test-buffer-serialize.o `test -f 'test-buffer-serialize.cc' || echo '$(srcdir)/'`test-buffer-serialize.cc + +test_buffer_serialize-test-buffer-serialize.obj: test-buffer-serialize.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_buffer_serialize_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_buffer_serialize-test-buffer-serialize.obj -MD -MP -MF $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Tpo -c -o test_buffer_serialize-test-buffer-serialize.obj `if test -f 'test-buffer-serialize.cc'; then $(CYGPATH_W) 'test-buffer-serialize.cc'; else $(CYGPATH_W) '$(srcdir)/test-buffer-serialize.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Tpo $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='test-buffer-serialize.cc' object='test_buffer_serialize-test-buffer-serialize.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_buffer_serialize_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_buffer_serialize-test-buffer-serialize.obj `if test -f 'test-buffer-serialize.cc'; then $(CYGPATH_W) 'test-buffer-serialize.cc'; else $(CYGPATH_W) '$(srcdir)/test-buffer-serialize.cc'; fi` + test_size_params-test-size-params.o: test-size-params.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_size_params-test-size-params.o -MD -MP -MF $(DEPDIR)/test_size_params-test-size-params.Tpo -c -o test_size_params-test-size-params.o `test -f 'test-size-params.cc' || echo '$(srcdir)/'`test-size-params.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_size_params-test-size-params.Tpo $(DEPDIR)/test_size_params-test-size-params.Po @@ -1134,10 +1606,76 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-girDATA: $(gir_DATA) + @$(NORMAL_INSTALL) + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(girdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(girdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(girdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(girdir)" || exit $$?; \ + done + +uninstall-girDATA: + @$(NORMAL_UNINSTALL) + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(girdir)'; $(am__uninstall_files_from_dir) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-typelibDATA: $(typelib_DATA) + @$(NORMAL_INSTALL) + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(typelibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(typelibdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(typelibdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(typelibdir)" || exit $$?; \ + done + +uninstall-typelibDATA: + @$(NORMAL_UNINSTALL) + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(typelibdir)'; $(am__uninstall_files_from_dir) install-nodist_pkgincludeHEADERS: $(nodist_pkginclude_HEADERS) @$(NORMAL_INSTALL) - test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" @list='$(nodist_pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -1154,8 +1692,11 @@ uninstall-nodist_pkgincludeHEADERS: dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) - test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -1172,22 +1713,25 @@ uninstall-pkgincludeHEADERS: dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -1202,57 +1746,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -1268,12 +1767,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -1285,15 +1779,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -1302,102 +1792,229 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ else \ - skipped="($$skip tests were not run)"; \ + color_start= color_end=; \ fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(dist_check_SCRIPTS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +check-c-linkage-decls.sh.log: check-c-linkage-decls.sh + @p='check-c-linkage-decls.sh'; \ + b='check-c-linkage-decls.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check-defs.sh.log: check-defs.sh + @p='check-defs.sh'; \ + b='check-defs.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check-header-guards.sh.log: check-header-guards.sh + @p='check-header-guards.sh'; \ + b='check-header-guards.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check-includes.sh.log: check-includes.sh + @p='check-includes.sh'; \ + b='check-includes.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check-libstdc++.sh.log: check-libstdc++.sh + @p='check-libstdc++.sh'; \ + b='check-libstdc++.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check-static-inits.sh.log: check-static-inits.sh + @p='check-static-inits.sh'; \ + b='check-static-inits.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check-symbols.sh.log: check-symbols.sh + @p='check-symbols.sh'; \ + b='check-symbols.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -1431,13 +2048,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -1462,12 +2076,12 @@ check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) install-binPROGRAMS: install-libLTLIBRARIES installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1491,6 +2105,9 @@ install-strip: "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) @@ -1528,8 +2145,9 @@ info: info-recursive info-am: -install-data-am: install-nodist_pkgincludeHEADERS \ - install-pkgincludeHEADERS +install-data-am: install-girDATA install-nodist_pkgincludeHEADERS \ + install-pkgconfigDATA install-pkgincludeHEADERS \ + install-typelibDATA install-dvi: install-dvi-recursive @@ -1575,38 +2193,53 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-nodist_pkgincludeHEADERS uninstall-pkgincludeHEADERS - -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ - check-am ctags-recursive install install-am install-strip \ - tags-recursive - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-TESTS check-am clean clean-binPROGRAMS \ - clean-generic clean-libLTLIBRARIES clean-libtool \ - clean-noinstPROGRAMS ctags ctags-recursive distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES install-man \ +uninstall-am: uninstall-binPROGRAMS uninstall-girDATA \ + uninstall-libLTLIBRARIES uninstall-nodist_pkgincludeHEADERS \ + uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS \ + uninstall-typelibDATA + +.MAKE: $(am__recursive_targets) all check check-am install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-TESTS check-am clean clean-binPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-girDATA \ + install-html install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man \ install-nodist_pkgincludeHEADERS install-pdf install-pdf-am \ - install-pkgincludeHEADERS install-ps install-ps-am \ - install-strip installcheck installcheck-am \ - installcheck-binPROGRAMS installdirs installdirs-am \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-nodist_pkgincludeHEADERS uninstall-pkgincludeHEADERS - - -@HAVE_GOBJECT_TRUE@hb-gobject-enums.cc: hb-gobject-enums.cc.tmpl $(HBHEADERS) -@HAVE_GOBJECT_TRUE@ $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > "$@.tmp" && \ + install-pkgconfigDATA install-pkgincludeHEADERS install-ps \ + install-ps-am install-strip install-typelibDATA installcheck \ + installcheck-am installcheck-binPROGRAMS installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ + uninstall uninstall-am uninstall-binPROGRAMS uninstall-girDATA \ + uninstall-libLTLIBRARIES uninstall-nodist_pkgincludeHEADERS \ + uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS \ + uninstall-typelibDATA + +@HAVE_GOBJECT_TRUE@hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS) +@HAVE_GOBJECT_TRUE@ $(AM_V_GEN) $(GLIB_MKENUMS) \ +@HAVE_GOBJECT_TRUE@ --identifier-prefix hb_ --symbol-prefix hb_gobject \ +@HAVE_GOBJECT_TRUE@ --template $^ | \ +@HAVE_GOBJECT_TRUE@ sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@.tmp" && \ @HAVE_GOBJECT_TRUE@ mv "$@.tmp" "$@" || ( $(RM) "@.tmp" && false ) -harfbuzz.def: $(HBHEADERS) + +%.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@%VERSION%@$(VERSION)@g' \ + "$<" \ + > "$@.tmp" && mv "$@.tmp" "$@" || ( $(RM) "$@.tmp"; false ) +harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) $(AM_V_GEN) (echo EXPORTS; \ (cat $^ || echo 'hb_ERROR ()' ) | \ $(EGREP) '^hb_.* \(' | \ @@ -1619,41 +2252,25 @@ harfbuzz.def: $(HBHEADERS) unicode-tables: arabic-table indic-table indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.hh.tmp && \ - mv hb-ot-shape-complex-indic-table.hh.tmp $(srcdir)/hb-ot-shape-complex-indic-table.hh || \ - ($(RM) hb-ot-shape-complex-indic-table.hh.tmp; false) + $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc.tmp && \ + mv hb-ot-shape-complex-indic-table.cc.tmp $(srcdir)/hb-ot-shape-complex-indic-table.cc || \ + ($(RM) hb-ot-shape-complex-indic-table.cc.tmp; false) -arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt +arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh.tmp && \ mv hb-ot-shape-complex-arabic-table.hh.tmp $(srcdir)/hb-ot-shape-complex-arabic-table.hh || \ ($(RM) hb-ot-shape-complex-arabic-table.hh.tmp; false) -.PHONY: unicode-tables arabic-table indic-table -$(srcdir)/hb-ot-shape-complex-indic-machine.hh: hb-ot-shape-complex-indic-machine.rl - $(AM_V_GEN)$(top_srcdir)/missing --run ragel -e -F1 -o "$@.tmp" "$<" && \ +built-sources: $(BUILT_SOURCES) + +.PHONY: unicode-tables arabic-table indic-table built-sources +.rl.hh: + $(AM_V_GEN)$(RAGEL) -e -F1 -o "$@.tmp" "$<" && \ mv "$@.tmp" "$@" || ( $(RM) "$@.tmp" && false ) -#-include $(INTROSPECTION_MAKEFILE) -#INTROSPECTION_GIRS = hb-1.0.gir -#INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ -#INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) -# -#if HAVE_INTROSPECTION -# -#hb-1.0.gir: libharfbuzz.la -#hb_1_0_gir_INCLUDES = GObject-2.0 -#hb_1_0_gir_CFLAGS = $(INCLUDES) $(HBCFLAGS) -DHB_H -DHB_H_IN -DHB_OT_H -DHB_OT_H_IN -#hb_1_0_gir_LIBS = libharfbuzz.la -#hb_1_0_gir_FILES = $(HBHEADERS) -# -#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 +@HAVE_INTROSPECTION_TRUE@-include $(INTROSPECTION_MAKEFILE) + +@HAVE_INTROSPECTION_TRUE@HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la -include $(top_srcdir)/git.mk diff --git a/src/check-c-linkage-decls.sh b/src/check-c-linkage-decls.sh index 44cdfa0..b10310f 100755 --- a/src/check-c-linkage-decls.sh +++ b/src/check-c-linkage-decls.sh @@ -6,8 +6,8 @@ export LC_ALL test -z "$srcdir" && srcdir=. stat=0 -test "x$HBHEADERS" = x && HBHEADERS=`find . -maxdepth 1 -name 'hb*.h'` -test "x$HBSOURCES" = x && HBSOURCES=`find . -maxdepth 1 -name 'hb*.h'` +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 diff --git a/src/check-exported-symbols.sh b/src/check-defs.sh index 6f0bf7f..357347f 100755 --- a/src/check-exported-symbols.sh +++ b/src/check-defs.sh @@ -10,7 +10,7 @@ stat=0 if which nm 2>/dev/null >/dev/null; then : else - echo "check-exported-symbols.sh: 'nm' not found; skipping test" + echo "check-defs.sh: 'nm' not found; skipping test" exit 77 fi @@ -20,20 +20,24 @@ 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__\>' | cut -d' ' -f3`" + if test -f "$so"; then + echo "Checking that $so has the same symbol list as $def" { echo EXPORTS - nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' T _fini\>\| T _init\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>' | cut -d' ' -f3 - stat=1 + 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-exported-symbols.sh: libharfbuzz shared library not found; skipping test" + echo "check-defs.sh: libharfbuzz shared library not found; skipping test" exit 77 fi diff --git a/src/check-header-guards.sh b/src/check-header-guards.sh index af9fa7f..9a3302c 100755 --- a/src/check-header-guards.sh +++ b/src/check-header-guards.sh @@ -6,8 +6,8 @@ export LC_ALL test -z "$srcdir" && srcdir=. stat=0 -test "x$HBHEADERS" = x && HBHEADERS=`find . -maxdepth 1 -name 'hb*.h'` -test "x$HBSOURCES" = x && HBSOURCES=`find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'` +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 diff --git a/src/check-includes.sh b/src/check-includes.sh index 79323a7..902f235 100755 --- a/src/check-includes.sh +++ b/src/check-includes.sh @@ -6,16 +6,14 @@ export LC_ALL test -z "$srcdir" && srcdir=. stat=0 -test "x$HBHEADERS" = x && HBHEADERS=`find . -maxdepth 1 -name 'hb*.h'` -test "x$HBSOURCES" = x && HBSOURCES=`find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'` - - -cd "$srcdir" +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"' | @@ -28,7 +26,8 @@ grep . >&2 && stat=1 echo 'Checking that source files #include "hb-*private.hh" first (or none)' for x in $HBSOURCES; do - grep '#.*\<include\>' "$x" /dev/null | head -n 1 + 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:' | @@ -36,7 +35,10 @@ grep . >&2 && stat=1 echo 'Checking that there is no #include <hb.*.h>' -grep '#.*\<include\>.*<.*hb' $HBHEADERS $HBSOURCES >&2 && stat=1 +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 diff --git a/src/check-internal-symbols.sh b/src/check-internal-symbols.sh deleted file mode 100755 index a8fdc53..0000000 --- a/src/check-internal-symbols.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/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-internal-symbols.sh: 'nm' not found; skipping test" - exit 77 -fi - -tested=false -for suffix in .so; do - so=`echo .libs/libharfbuzz$suffix` - if test -f "$so"; then - echo "Checking that we are not exposing internal symbols" - if nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' T _fini\>\| T _init\>\| T hb_\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>'; then - echo "Ouch, internal symbols exposed" - stat=1 - fi - tested=true - fi -done -if ! $tested; then - echo "check-internal-symbols.sh: libharfbuzz shared library not found; skipping test" - exit 77 -fi - -exit $stat diff --git a/src/check-static-inits.sh b/src/check-static-inits.sh index bb0a7ff..83d02c8 100755 --- a/src/check-static-inits.sh +++ b/src/check-static-inits.sh @@ -30,7 +30,7 @@ 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 '__c'; then + if objdump -t "$obj" | grep '__cxa_'; then echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff" stat=1 fi diff --git a/src/check-symbols.sh b/src/check-symbols.sh new file mode 100755 index 0000000..e000b01 --- /dev/null +++ b/src/check-symbols.sh @@ -0,0 +1,37 @@ +#!/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 so in `ls .libs/lib*.so .libs/lib*.dylib 2>/dev/null` ; do + + EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>' | cut -d' ' -f3`" + prefix=`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'` + + 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 diff --git a/src/gen-arabic-table.py b/src/gen-arabic-table.py index da5a4fc..308435f 100755 --- a/src/gen-arabic-table.py +++ b/src/gen-arabic-table.py @@ -3,34 +3,48 @@ import sys import os.path -if len (sys.argv) != 3: - print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt" +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 ()]] +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: -def print_joining_table(f): + j = line.find ('#') + if j >= 0: + line = line[:j] - print - print "static const uint8_t joining_table[] =" - print "{" + 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): - min_u = 0x110000 - max_u = 0 - num = 0 - last = -1 - block = '' + values = {} for line in f: if line[0] == '#': - if line.find (" characters"): - block = line[2:].strip () continue fields = [x.strip () for x in line.split (';')] @@ -38,43 +52,100 @@ def print_joining_table(f): continue u = int (fields[0], 16) - if u == 0x200C or u == 0x200D: - continue - if u < last: - raise Exception ("Input data character not sorted", u) - min_u = min (min_u, u) - max_u = max (max_u, u) - num += 1 - - if block: - print "\n /* %s */\n" % block - block = '' - - if last != -1: - last += 1 - while last < u: - print " JOINING_TYPE_X, /* %04X */" % last - last += 1 - else: - last = u if fields[3] in ["ALAPH", "DALATH RISH"]: value = "JOINING_GROUP_" + fields[3].replace(' ', '_') else: value = "JOINING_TYPE_" + fields[2] - print " %s, /* %s */" % (value, '; '.join(fields)) + 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 - 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 "#define JOINING_TABLE_FIRST 0x%04X" % min_u - print "#define JOINING_TABLE_LAST 0x%04X" % max_u + 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 - occupancy = num * 100 / (max_u - min_u + 1) - # Maintain at least 40% occupancy in the table */ - if occupancy < 40: - raise Exception ("Table too sparse, please investigate: ", occupancy) + 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): @@ -124,13 +195,13 @@ def print_shaping_table(f): 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%04X" % c for c in s) + 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%04X" % min_u - print "#define SHAPING_TABLE_LAST 0x%04X" % max_u + print "#define SHAPING_TABLE_FIRST 0x%04Xu" % min_u + print "#define SHAPING_TABLE_LAST 0x%04Xu" % max_u print ligas = {} @@ -160,9 +231,9 @@ def print_shaping_table(f): keys.sort () for first in keys: - print " { 0x%04X, {" % (first) + print " { 0x%04Xu, {" % (first) for liga in ligas[first]: - print " { 0x%04X, 0x%04X }, /* %s */" % (liga[0], liga[1], names[liga[1]]) + print " { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]) print " }}," print "};" @@ -174,7 +245,7 @@ print "/* == Start of generated table == */" print "/*" print " * The following table is generated by running:" print " *" -print " * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt" +print " * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt" print " *" print " * on files with these headers:" print " *" @@ -187,6 +258,7 @@ 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]) diff --git a/src/gen-indic-table.py b/src/gen-indic-table.py index 94aa2ab..4fb76f4 100755 --- a/src/gen-indic-table.py +++ b/src/gen-indic-table.py @@ -6,11 +6,12 @@ if len (sys.argv) != 4: print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.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 f in files] -blocks = {} data = [{} for f in files] values = [{} for f in files] for i, f in enumerate (files): @@ -35,10 +36,7 @@ for i, f in enumerate (files): for u in range (start, end + 1): data[i][u] = t - values[i][t] = values[i].get (t, 0) + 1 - - if i == 2: - blocks[t] = (start, end) + values[i][t] = values[i].get (t, 0) + end - start + 1 # Merge data into one dict: defaults = ('Other', 'Not_Applicable', 'No_Block') @@ -52,10 +50,15 @@ for i,d in enumerate (data): if not u in combined: combined[u] = list (defaults) combined[u][i] = v +combined = {k:v for k,v in combined.items() if v[2] not in BLACKLISTED_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 [0x00A0, 0x25CC]: @@ -75,13 +78,16 @@ for h in headers: print " * %s" % (l.strip()) print " */" print -print "#ifndef HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH" -print "#define HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH" +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', @@ -89,14 +95,14 @@ short = [{ },{ "Not_Applicable": 'x', }] -all_shorts = [[],[]] +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].append (s) + all_shorts[i][s] = v what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"] what_short = ["ISC", "IMC"] @@ -111,8 +117,8 @@ for i in range (2): 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, s) - all_shorts[i].append (s) + 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 (), \ @@ -125,11 +131,16 @@ print total = 0 used = 0 +last_block = None def print_block (block, start, end, data): - print - print - print " /* %s (%04X..%04X) */" % (block, start, end) + 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 @@ -139,14 +150,15 @@ def print_block (block, start, end, data): d = data.get (u, defaults) sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]]))) - global total, used total += end - start + 1 used += num + if block: + last_block = block uu = data.keys () uu.sort () -last = -1 +last = -100000 num = 0 offset = 0 starts = [] @@ -156,11 +168,16 @@ for u in uu: if u <= last: continue block = data[u][2] - (start, end) = blocks[block] + + 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 <= 33: - print_block ("FILLER", last+1, start-1, data) + if start - last <= 1+16*3: + print_block (None, last+1, start-1, data) last = start-1 else: if last >= 0: @@ -168,7 +185,7 @@ for u in uu: offset += ends[-1] - starts[-1] print print - print "#define indic_offset_0x%04x %d" % (start, offset) + print "#define indic_offset_0x%04xu %d" % (start, offset) starts.append (start) print_block (block, start, end, data) @@ -177,19 +194,30 @@ ends.append (last + 1) offset += ends[-1] - starts[-1] print print -print "#define indic_offset_total %d" % offset -print occupancy = used * 100. / total -print "}; /* Table occupancy: %d%% */" % occupancy +page_bits = 12 +print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) print -print "static INDIC_TABLE_ELEMENT_TYPE" -print "get_indic_categories (hb_codepoint_t u)" +print "INDIC_TABLE_ELEMENT_TYPE" +print "hb_indic_get_categories (hb_codepoint_t u)" print "{" -for (start,end) in zip (starts, ends): - offset = "indic_offset_0x%04x" % start - print " if (0x%04X <= u && u <= 0x%04X) return indic_table[u - 0x%04X + %s];" % (start, end, start, offset) -for u,d in singles.items (): - print " if (unlikely (u == 0x%04X)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]]) +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, 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 @@ -202,8 +230,6 @@ for i in range (2): print "#undef %s_%s" % \ (what_short[i], short[i][v]) print -print "#endif /* HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH */" -print print "/* == End of generated table == */" # Maintain at least 30% occupancy in the table */ diff --git a/src/harfbuzz-gobject.pc.in b/src/harfbuzz-gobject.pc.in new file mode 100644 index 0000000..7008360 --- /dev/null +++ b/src/harfbuzz-gobject.pc.in @@ -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 diff --git a/src/harfbuzz-icu.pc.in b/src/harfbuzz-icu.pc.in new file mode 100644 index 0000000..949869a --- /dev/null +++ b/src/harfbuzz-icu.pc.in @@ -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 diff --git a/src/harfbuzz.pc.in b/src/harfbuzz.pc.in new file mode 100644 index 0000000..7f27bbb --- /dev/null +++ b/src/harfbuzz.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: harfbuzz +Description: HarfBuzz text shaping library +Version: %VERSION% + +Libs: -L${libdir} -lharfbuzz +Cflags: -I${includedir}/harfbuzz diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh index b909bc8..e6738b7 100644 --- a/src/hb-atomic-private.hh +++ b/src/hb-atomic-private.hh @@ -42,27 +42,26 @@ #if 0 -#elif !defined(HB_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__) +#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) -#define WIN32_LEAN_AND_MEAN #include <windows.h> -/* mingw32 does not have MemoryBarrier. - * MemoryBarrier may be defined as a macro or a function. - * Just make a failsafe version for ourselves. */ -#ifdef MemoryBarrier -#define HBMemoryBarrier MemoryBarrier -#else -static inline void HBMemoryBarrier (void) { +/* 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_t; #define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) -#define hb_atomic_ptr_get(P) (HBMemoryBarrier (), (void *) *(P)) +#define hb_atomic_ptr_get(P) (_HBMemoryBarrier (), (void *) *(P)) #define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) @@ -82,7 +81,7 @@ typedef int32_t hb_atomic_int_t; #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) #define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) #else -#if __ppc64__ || __x86_64__ +#if __ppc64__ || __x86_64__ || __aarch64__ #define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) #else #define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 3ca50fb..b82b4b2 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -25,11 +25,12 @@ */ /* 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-blob.h" #include "hb-object-private.hh" #ifdef HAVE_SYS_MMAN_H @@ -76,6 +77,22 @@ _hb_blob_destroy_user_data (hb_blob_t *blob) } } +/** + * hb_blob_create: (Xconstructor) + * @data: (array length=length) (closure user_data) (destroy destroy) (scope notified) (transfer none): 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: 1.0 + **/ hb_blob_t * hb_blob_create (const char *data, unsigned int length, @@ -109,6 +126,26 @@ hb_blob_create (const char *data, 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: 1.0 + **/ hb_blob_t * hb_blob_create_sub_blob (hb_blob_t *parent, unsigned int offset, @@ -123,13 +160,24 @@ hb_blob_create_sub_blob (hb_blob_t *parent, blob = hb_blob_create (parent->data + offset, MIN (length, parent->length - offset), - parent->mode, + 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: 1.0 + **/ hb_blob_t * hb_blob_get_empty (void) { @@ -149,12 +197,36 @@ hb_blob_get_empty (void) 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: 1.0 + **/ 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: 1.0 + **/ void hb_blob_destroy (hb_blob_t *blob) { @@ -165,6 +237,18 @@ hb_blob_destroy (hb_blob_t *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: 1.0 + **/ hb_bool_t hb_blob_set_user_data (hb_blob_t *blob, hb_user_data_key_t *key, @@ -175,6 +259,17 @@ hb_blob_set_user_data (hb_blob_t *blob, 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: 1.0 + **/ void * hb_blob_get_user_data (hb_blob_t *blob, hb_user_data_key_t *key) @@ -183,6 +278,14 @@ hb_blob_get_user_data (hb_blob_t *blob, } +/** + * hb_blob_make_immutable: + * @blob: a blob. + * + * + * + * Since: 1.0 + **/ void hb_blob_make_immutable (hb_blob_t *blob) { @@ -192,6 +295,16 @@ hb_blob_make_immutable (hb_blob_t *blob) blob->immutable = true; } +/** + * hb_blob_is_immutable: + * @blob: a blob. + * + * + * + * Return value: TODO + * + * Since: 1.0 + **/ hb_bool_t hb_blob_is_immutable (hb_blob_t *blob) { @@ -199,12 +312,33 @@ hb_blob_is_immutable (hb_blob_t *blob) } +/** + * hb_blob_get_length: + * @blob: a blob. + * + * + * + * Return value: the length of blob data in bytes. + * + * Since: 1.0 + **/ 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: 1.0 + **/ const char * hb_blob_get_data (hb_blob_t *blob, unsigned int *length) { @@ -214,6 +348,22 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *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: 1.0 + **/ char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) { @@ -324,5 +474,3 @@ _try_writable (hb_blob_t *blob) return true; } - - diff --git a/src/hb-blob.h b/src/hb-blob.h index 1a93baa..b2419ab 100644 --- a/src/hb-blob.h +++ b/src/hb-blob.h @@ -36,6 +36,25 @@ 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, @@ -52,6 +71,12 @@ hb_blob_create (const char *data, 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_blob_t * hb_blob_create_sub_blob (hb_blob_t *parent, unsigned int offset, diff --git a/src/hb-buffer-deserialize-json.hh b/src/hb-buffer-deserialize-json.hh new file mode 100644 index 0000000..dead700 --- /dev/null +++ b/src/hb-buffer-deserialize-json.hh @@ -0,0 +1,643 @@ + +#line 1 "../../src/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.tmp" +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 "../../src/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; + hb_glyph_position_t pos; + +#line 466 "hb-buffer-deserialize-json.hh.tmp" + { + cs = deserialize_json_start; + } + +#line 471 "hb-buffer-deserialize-json.hh.tmp" + { + 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 "../../src/hb-buffer-deserialize-json.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} + break; + case 5: +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-json.rl" + { + tok = p; +} + break; + case 14: +#line 55 "../../src/hb-buffer-deserialize-json.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 15: +#line 62 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.codepoint)) return false; } + break; + case 8: +#line 63 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 10: +#line 64 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 12: +#line 65 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 3: +#line 66 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 6: +#line 67 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } + break; + case 16: +#line 62 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.codepoint)) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "../../src/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.tmp" + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } + +#line 125 "../../src/hb-buffer-deserialize-json.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/src/hb-buffer-deserialize-json.rl b/src/hb-buffer-deserialize-json.rl new file mode 100644 index 0000000..7351b2a --- /dev/null +++ b/src/hb-buffer-deserialize-json.rl @@ -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; + hb_glyph_position_t pos; + %%{ + write init; + write exec; + }%% + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/src/hb-buffer-deserialize-text.hh b/src/hb-buffer-deserialize-text.hh new file mode 100644 index 0000000..a38efe3 --- /dev/null +++ b/src/hb-buffer-deserialize-text.hh @@ -0,0 +1,571 @@ + +#line 1 "../../src/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.tmp" +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 "../../src/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; + hb_glyph_position_t pos; + +#line 343 "hb-buffer-deserialize-text.hh.tmp" + { + cs = deserialize_text_start; + } + +#line 348 "hb-buffer-deserialize-text.hh.tmp" + { + 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 "../../src/hb-buffer-deserialize-text.rl" + { + tok = p; +} + break; + case 5: +#line 55 "../../src/hb-buffer-deserialize-text.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 10: +#line 62 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 3: +#line 63 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 12: +#line 64 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 7: +#line 65 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 1: +#line 38 "../../src/hb-buffer-deserialize-text.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} +#line 51 "../../src/hb-buffer-deserialize-text.rl" + { + tok = p; +} + break; + case 4: +#line 55 "../../src/hb-buffer-deserialize-text.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "../../src/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.tmp" + } + +_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 "../../src/hb-buffer-deserialize-text.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "../../src/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 "../../src/hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "../../src/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.tmp" + } + } + + _out: {} + } + +#line 119 "../../src/hb-buffer-deserialize-text.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff --git a/src/hb-buffer-deserialize-text.rl b/src/hb-buffer-deserialize-text.rl new file mode 100644 index 0000000..8856580 --- /dev/null +++ b/src/hb-buffer-deserialize-text.rl @@ -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; + hb_glyph_position_t pos; + %%{ + write init; + write exec; + }%% + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 13cf4bb..069f925 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -31,7 +31,6 @@ #define HB_BUFFER_PRIVATE_HH #include "hb-private.hh" -#include "hb-buffer.h" #include "hb-object-private.hh" #include "hb-unicode-private.hh" @@ -49,14 +48,13 @@ struct hb_buffer_t { ASSERT_POD (); /* Information about how the text in the buffer should be treated */ - hb_unicode_funcs_t *unicode; /* Unicode functions */ - hb_segment_properties_t props; /* Script, language, direction */ hb_buffer_flags_t flags; /* BOT / EOT / etc. */ + hb_codepoint_t replacement; /* U+FFFD or something else. */ /* 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 */ @@ -80,6 +78,8 @@ struct hb_buffer_t { inline hb_glyph_info_t &prev (void) { return out_info[out_len - 1]; } inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; } + inline bool has_separate_output (void) const { return info != out_info; } + unsigned int serial; /* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */ @@ -101,6 +101,8 @@ struct hb_buffer_t { 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 allocate_var (unsigned int byte_i, unsigned int count, const char *owner); @@ -110,6 +112,7 @@ struct hb_buffer_t { 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); @@ -128,9 +131,10 @@ struct hb_buffer_t { 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 (hb_glyph_info_t &glyph_info); + 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 @@ -175,11 +179,16 @@ struct hb_buffer_t { HB_INTERNAL bool enlarge (unsigned int size); inline bool ensure (unsigned int size) - { return likely (size < allocated) ? true : enlarge (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); - HB_INTERNAL void *get_scratch_buffer (unsigned int *size); + 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; } }; diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc new file mode 100644 index 0000000..406d69d --- /dev/null +++ b/src/hb-buffer-serialize.cc @@ -0,0 +1,399 @@ +/* + * 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: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ +const char ** +hb_buffer_serialize_list_formats (void) +{ + return serialize_formats; +} + +/** + * hb_buffer_serialize_format_from_string: + * @str: + * @len: + * + * + * + * Return value: + * + * Since: 1.0 + **/ +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: + * + * + * + * Return value: + * + * Since: 1.0 + **/ +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 = 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); + } + + *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 = 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)); + } + + 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; +} + +/* Returns number of items, starting at start, that were serialized. */ +/** + * hb_buffer_serialize_glyphs: + * @buffer: a buffer. + * @start: + * @end: + * @buf: (array length=buf_size): + * @buf_size: + * @buf_consumed: (out): + * @font: + * @format: + * @flags: + * + * + * + * Return value: + * + * Since: 1.0 + **/ +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, /* May be NULL */ + hb_font_t *font, /* May be NULL */ + 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 (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: a buffer. + * @buf: (array length=buf_len): + * @buf_len: + * @end_ptr: (out): + * @font: + * @format: + * + * + * + * Return value: + * + * Since: 1.0 + **/ +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; + + } +} diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index c7860e9..74ae273 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -139,7 +139,20 @@ hb_buffer_t::make_room_for (unsigned int num_in, return true; } -void * +bool +hb_buffer_t::shift_forward (unsigned int count) +{ + assert (have_output); + if (unlikely (!ensure (len + count))) return false; + + memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0])); + len += count; + idx += count; + + return true; +} + +hb_buffer_t::scratch_buffer_t * hb_buffer_t::get_scratch_buffer (unsigned int *size) { have_output = false; @@ -148,8 +161,9 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size) out_len = 0; out_info = info; - *size = allocated * sizeof (pos[0]); - return pos; + assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0); + *size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t); + return (scratch_buffer_t *) (void *) pos; } @@ -164,6 +178,8 @@ hb_buffer_t::reset (void) hb_unicode_funcs_destroy (unicode); unicode = hb_unicode_funcs_get_default (); + flags = HB_BUFFER_FLAG_DEFAULT; + replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; clear (); } @@ -176,7 +192,6 @@ hb_buffer_t::clear (void) hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; props = default_props; - flags = HB_BUFFER_FLAGS_DEFAULT; content_type = HB_BUFFER_CONTENT_TYPE_INVALID; in_error = false; @@ -215,6 +230,17 @@ hb_buffer_t::add (hb_codepoint_t codepoint, } void +hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) +{ + if (unlikely (!ensure (len + 1))) return; + + info[len] = glyph_info; + + len++; +} + + +void hb_buffer_t::remove_output (void) { if (unlikely (hb_object_is_inert (this))) @@ -315,7 +341,7 @@ hb_buffer_t::output_glyph (hb_codepoint_t glyph_index) } void -hb_buffer_t::output_info (hb_glyph_info_t &glyph_info) +hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info) { if (unlikely (!make_room_for (0, 1))) return; @@ -334,6 +360,44 @@ hb_buffer_t::copy_glyph (void) out_len++; } +bool +hb_buffer_t::move_to (unsigned int i) +{ + if (!have_output) + { + assert (i <= len); + idx = i; + return true; + } + + assert (i <= out_len + (len - idx)); + + if (out_len < i) + { + unsigned int count = i - out_len; + if (unlikely (!make_room_for (count, count))) return false; + + memmove (out_info + out_len, info + idx, count * sizeof (out_info[0])); + idx += count; + out_len += count; + } + else if (out_len > i) + { + /* Tricky part: rewinding... */ + unsigned int count = out_len - i; + + if (unlikely (idx < count && !shift_forward (count + 32))) return false; + + assert (idx >= count); + + idx -= count; + out_len -= count; + memmove (info + idx, out_info + out_len, count * sizeof (out_info[0])); + } + + return true; +} + void hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index) { @@ -437,6 +501,10 @@ void hb_buffer_t::merge_clusters (unsigned int start, unsigned int end) { +#ifdef HB_NO_MERGE_CLUSTERS + return; +#endif + if (unlikely (end - start < 2)) return; @@ -465,6 +533,10 @@ void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { +#ifdef HB_NO_MERGE_CLUSTERS + return; +#endif + if (unlikely (end - start < 2)) return; @@ -538,7 +610,7 @@ void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const c { assert (byte_i < 8 && byte_i + count <= 8); - if (DEBUG (BUFFER)) + if (DEBUG_ENABLED (BUFFER)) dump_var_allocation (this); DEBUG_MSG (BUFFER, this, "Allocating var bytes %d..%d for %s", @@ -553,7 +625,7 @@ void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const c void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner) { - if (DEBUG (BUFFER)) + if (DEBUG_ENABLED (BUFFER)) dump_var_allocation (this); DEBUG_MSG (BUFFER, this, @@ -570,7 +642,7 @@ void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const void hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner) { - if (DEBUG (BUFFER)) + if (DEBUG_ENABLED (BUFFER)) dump_var_allocation (this); DEBUG_MSG (BUFFER, this, @@ -592,6 +664,15 @@ void hb_buffer_t::deallocate_var_all (void) /* Public API */ +/** + * hb_buffer_create: (Xconstructor) + * + * + * + * Return value: (transfer full) + * + * Since: 1.0 + **/ hb_buffer_t * hb_buffer_create (void) { @@ -605,6 +686,15 @@ hb_buffer_create (void) return buffer; } +/** + * hb_buffer_get_empty: + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_buffer_t * hb_buffer_get_empty (void) { @@ -612,10 +702,11 @@ hb_buffer_get_empty (void) HB_OBJECT_HEADER_STATIC, const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), - HB_SEGMENT_PROPERTIES_DEFAULT, - HB_BUFFER_FLAGS_DEFAULT, + HB_BUFFER_FLAG_DEFAULT, + HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, + HB_SEGMENT_PROPERTIES_DEFAULT, true, /* in_error */ true, /* have_output */ true /* have_positions */ @@ -626,12 +717,30 @@ hb_buffer_get_empty (void) return const_cast<hb_buffer_t *> (&_hb_buffer_nil); } +/** + * hb_buffer_reference: (skip) + * @buffer: a buffer. + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_buffer_t * hb_buffer_reference (hb_buffer_t *buffer) { return hb_object_reference (buffer); } +/** + * hb_buffer_destroy: (skip) + * @buffer: a buffer. + * + * + * + * Since: 1.0 + **/ void hb_buffer_destroy (hb_buffer_t *buffer) { @@ -645,6 +754,20 @@ hb_buffer_destroy (hb_buffer_t *buffer) free (buffer); } +/** + * hb_buffer_set_user_data: (skip) + * @buffer: a buffer. + * @key: + * @data: + * @destroy: + * @replace: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_buffer_set_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key, @@ -655,6 +778,17 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, return hb_object_set_user_data (buffer, key, data, destroy, replace); } +/** + * hb_buffer_get_user_data: (skip) + * @buffer: a buffer. + * @key: + * + * + * + * Return value: + * + * Since: 1.0 + **/ void * hb_buffer_get_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key) @@ -663,6 +797,15 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, } +/** + * hb_buffer_set_content_type: + * @buffer: a buffer. + * @content_type: + * + * + * + * Since: 1.0 + **/ void hb_buffer_set_content_type (hb_buffer_t *buffer, hb_buffer_content_type_t content_type) @@ -670,6 +813,16 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, buffer->content_type = content_type; } +/** + * hb_buffer_get_content_type: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_buffer_content_type_t hb_buffer_get_content_type (hb_buffer_t *buffer) { @@ -677,28 +830,56 @@ hb_buffer_get_content_type (hb_buffer_t *buffer) } +/** + * hb_buffer_set_unicode_funcs: + * @buffer: a buffer. + * @unicode_funcs: + * + * + * + * Since: 1.0 + **/ void hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, - hb_unicode_funcs_t *unicode) + hb_unicode_funcs_t *unicode_funcs) { if (unlikely (hb_object_is_inert (buffer))) return; - if (!unicode) - unicode = hb_unicode_funcs_get_default (); + if (!unicode_funcs) + unicode_funcs = hb_unicode_funcs_get_default (); - hb_unicode_funcs_reference (unicode); + hb_unicode_funcs_reference (unicode_funcs); hb_unicode_funcs_destroy (buffer->unicode); - buffer->unicode = unicode; + buffer->unicode = unicode_funcs; } +/** + * hb_buffer_get_unicode_funcs: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_unicode_funcs_t * hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) { return buffer->unicode; } +/** + * hb_buffer_set_direction: + * @buffer: a buffer. + * @direction: + * + * + * + * Since: 1.0 + **/ void hb_buffer_set_direction (hb_buffer_t *buffer, hb_direction_t direction) @@ -710,12 +891,31 @@ hb_buffer_set_direction (hb_buffer_t *buffer, buffer->props.direction = direction; } +/** + * hb_buffer_get_direction: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_direction_t hb_buffer_get_direction (hb_buffer_t *buffer) { return buffer->props.direction; } +/** + * hb_buffer_set_script: + * @buffer: a buffer. + * @script: + * + * + * + * Since: 1.0 + **/ void hb_buffer_set_script (hb_buffer_t *buffer, hb_script_t script) @@ -726,12 +926,31 @@ hb_buffer_set_script (hb_buffer_t *buffer, buffer->props.script = script; } +/** + * hb_buffer_get_script: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_script_t hb_buffer_get_script (hb_buffer_t *buffer) { return buffer->props.script; } +/** + * hb_buffer_set_language: + * @buffer: a buffer. + * @language: + * + * + * + * Since: 1.0 + **/ void hb_buffer_set_language (hb_buffer_t *buffer, hb_language_t language) @@ -742,12 +961,31 @@ hb_buffer_set_language (hb_buffer_t *buffer, buffer->props.language = language; } +/** + * hb_buffer_get_language: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_language_t hb_buffer_get_language (hb_buffer_t *buffer) { return buffer->props.language; } +/** + * hb_buffer_set_segment_properties: + * @buffer: a buffer. + * @props: + * + * + * + * Since: 1.0 + **/ void hb_buffer_set_segment_properties (hb_buffer_t *buffer, const hb_segment_properties_t *props) @@ -758,6 +996,15 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer, buffer->props = *props; } +/** + * hb_buffer_get_segment_properties: + * @buffer: a buffer. + * @props: + * + * + * + * Since: 1.0 + **/ void hb_buffer_get_segment_properties (hb_buffer_t *buffer, hb_segment_properties_t *props) @@ -766,6 +1013,15 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer, } +/** + * hb_buffer_set_flags: + * @buffer: a buffer. + * @flags: + * + * + * + * Since: 1.0 + **/ void hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_flags_t flags) @@ -776,6 +1032,16 @@ hb_buffer_set_flags (hb_buffer_t *buffer, buffer->flags = flags; } +/** + * hb_buffer_get_flags: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer) { @@ -783,30 +1049,113 @@ hb_buffer_get_flags (hb_buffer_t *buffer) } +/** + * hb_buffer_set_replacement_codepoint: + * @buffer: a buffer. + * @replacement: + * + * + * + * Since: 1.0 + **/ +void +hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, + hb_codepoint_t replacement) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->replacement = replacement; +} + +/** + * hb_buffer_get_replacement_codepoint: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ +hb_codepoint_t +hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) +{ + return buffer->replacement; +} + + +/** + * hb_buffer_reset: + * @buffer: a buffer. + * + * + * + * Since: 1.0 + **/ void hb_buffer_reset (hb_buffer_t *buffer) { buffer->reset (); } +/** + * hb_buffer_clear_contents: + * @buffer: a buffer. + * + * + * + * Since: 1.0 + **/ void hb_buffer_clear_contents (hb_buffer_t *buffer) { buffer->clear (); } +/** + * hb_buffer_pre_allocate: + * @buffer: a buffer. + * @size: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) { return buffer->ensure (size); } +/** + * hb_buffer_allocation_successful: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_buffer_allocation_successful (hb_buffer_t *buffer) { return !buffer->in_error; } +/** + * hb_buffer_add: + * @buffer: a buffer. + * @codepoint: + * @cluster: + * + * + * + * Since: 1.0 + **/ void hb_buffer_add (hb_buffer_t *buffer, hb_codepoint_t codepoint, @@ -816,6 +1165,17 @@ hb_buffer_add (hb_buffer_t *buffer, buffer->clear_context (1); } +/** + * hb_buffer_set_length: + * @buffer: a buffer. + * @length: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_buffer_set_length (hb_buffer_t *buffer, unsigned int length) @@ -836,19 +1196,43 @@ hb_buffer_set_length (hb_buffer_t *buffer, buffer->len = length; if (!length) + { + buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID; buffer->clear_context (0); + } buffer->clear_context (1); return true; } +/** + * hb_buffer_get_length: + * @buffer: a buffer. + * + * Returns the number of items in the buffer. + * + * Return value: buffer length. + * + * Since: 1.0 + **/ unsigned int hb_buffer_get_length (hb_buffer_t *buffer) { return buffer->len; } -/* Return value valid as long as buffer not modified */ +/** + * hb_buffer_get_glyph_infos: + * @buffer: a buffer. + * @length: (out): output array length. + * + * Returns buffer glyph information array. Returned pointer + * is valid as long as buffer contents are not modified. + * + * Return value: (transfer none) (array length=length): buffer glyph information array. + * + * Since: 1.0 + **/ hb_glyph_info_t * hb_buffer_get_glyph_infos (hb_buffer_t *buffer, unsigned int *length) @@ -859,7 +1243,18 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, return (hb_glyph_info_t *) buffer->info; } -/* Return value valid as long as buffer not modified */ +/** + * hb_buffer_get_glyph_positions: + * @buffer: a buffer. + * @length: (out): output length. + * + * Returns buffer glyph position array. Returned pointer + * is valid as long as buffer contents are not modified. + * + * Return value: (transfer none) (array length=length): buffer glyph position array. + * + * Since: 1.0 + **/ hb_glyph_position_t * hb_buffer_get_glyph_positions (hb_buffer_t *buffer, unsigned int *length) @@ -873,25 +1268,67 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, return (hb_glyph_position_t *) buffer->pos; } +/** + * hb_buffer_reverse: + * @buffer: a buffer. + * + * Reverses buffer contents. + * + * Since: 1.0 + **/ void hb_buffer_reverse (hb_buffer_t *buffer) { buffer->reverse (); } +/** + * hb_buffer_reverse_clusters: + * @buffer: a buffer. + * + * Reverses buffer clusters. That is, the buffer contents are + * reversed, then each cluster (consecutive items having the + * same cluster number) are reversed again. + * + * Since: 1.0 + **/ void hb_buffer_reverse_clusters (hb_buffer_t *buffer) { buffer->reverse_clusters (); } +/** + * hb_buffer_guess_segment_properties: + * @buffer: a buffer. + * + * Sets unset buffer segment properties based on buffer Unicode + * contents. If buffer is not empty, it must have content type + * %HB_BUFFER_CONTENT_TYPE_UNICODE. + * + * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it + * will be set to the Unicode script of the first character in + * the buffer that has a script other than %HB_SCRIPT_COMMON, + * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN. + * + * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID), + * it will be set to the natural horizontal direction of the + * buffer script as returned by hb_script_get_horizontal_direction(). + * + * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID), + * it will be set to the process's default language as returned by + * hb_language_get_default(). This may change in the future by + * taking buffer script into consideration when choosing a language. + * + * Since: 1.0 + **/ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer) { buffer->guess_segment_properties (); } -template <typename T> +template <bool validate, typename T> static inline void hb_buffer_add_utf (hb_buffer_t *buffer, const T *text, @@ -899,6 +1336,9 @@ hb_buffer_add_utf (hb_buffer_t *buffer, unsigned int item_offset, int item_length) { + typedef hb_utf_t<T, true> utf_t; + const hb_codepoint_t replacement = buffer->replacement; + assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); @@ -906,7 +1346,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer, return; if (text_length == -1) - text_length = hb_utf_strlen (text); + text_length = utf_t::strlen (text); if (item_length == -1) item_length = text_length - item_offset; @@ -929,7 +1369,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer, while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH) { hb_codepoint_t u; - prev = hb_utf_prev (prev, start, &u); + prev = utf_t::prev (prev, start, &u, replacement); buffer->context[0][buffer->context_len[0]++] = u; } } @@ -940,7 +1380,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer, { hb_codepoint_t u; const T *old_next = next; - next = hb_utf_next (next, end, &u); + next = utf_t::next (next, end, &u, replacement); buffer->add (u, old_next - (const T *) text); } @@ -950,13 +1390,25 @@ hb_buffer_add_utf (hb_buffer_t *buffer, while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH) { hb_codepoint_t u; - next = hb_utf_next (next, end, &u); + next = utf_t::next (next, end, &u, replacement); buffer->context[1][buffer->context_len[1]++] = u; } buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE; } +/** + * hb_buffer_add_utf8: + * @buffer: a buffer. + * @text: (array length=text_length): + * @text_length: + * @item_offset: + * @item_length: + * + * + * + * Since: 1.0 + **/ void hb_buffer_add_utf8 (hb_buffer_t *buffer, const char *text, @@ -964,19 +1416,43 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer, unsigned int item_offset, int item_length) { - hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, item_length); + hb_buffer_add_utf<true> (buffer, (const uint8_t *) text, text_length, item_offset, item_length); } +/** + * hb_buffer_add_utf16: + * @buffer: a buffer. + * @text: (array length=text_length): + * @text_length: + * @item_offset: + * @item_length: + * + * + * + * Since: 1.0 + **/ void hb_buffer_add_utf16 (hb_buffer_t *buffer, const uint16_t *text, int text_length, unsigned int item_offset, - int item_length) + int item_length) { - hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); + hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length); } +/** + * hb_buffer_add_utf32: + * @buffer: a buffer. + * @text: (array length=text_length): + * @text_length: + * @item_offset: + * @item_length: + * + * + * + * Since: 1.0 + **/ void hb_buffer_add_utf32 (hb_buffer_t *buffer, const uint32_t *text, @@ -984,7 +1460,29 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, unsigned int item_offset, int item_length) { - hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); + hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length); +} + +/** + * hb_buffer_add_codepoints: + * @buffer: a buffer. + * @text: (array length=text_length): + * @text_length: + * @item_offset: + * @item_length: + * + * + * + * Since: 1.0 + **/ +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_buffer_add_utf<false> (buffer, text, text_length, item_offset, item_length); } @@ -1043,6 +1541,14 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, } } +/** + * hb_buffer_normalize_glyphs: + * @buffer: a buffer. + * + * + * + * Since: 1.0 + **/ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) { @@ -1064,231 +1570,3 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer) } normalize_glyphs_cluster (buffer, start, end, backward); } - - -/* - * Serialize - */ - -static const char *serialize_formats[] = { - "text", - "json", - NULL -}; - -const char ** -hb_buffer_serialize_list_formats (void) -{ - return serialize_formats; -} - -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) & ~0x20202020); -} - -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 = 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 += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); - - if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { - p += 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); - } - - *p++ = '}'; - - if (buf_size > (p - b)) - { - unsigned int l = p - b; - 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 = hb_buffer_get_glyph_positions (buffer, NULL); - hb_direction_t direction = hb_buffer_get_direction (buffer); - - *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 += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); - - if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { - p += 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 += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset); - - *p++ = '+'; - if (HB_DIRECTION_IS_HORIZONTAL (direction) || pos[i].x_advance) - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance); - if (HB_DIRECTION_IS_VERTICAL (direction) || pos->y_advance) - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance); - } - - if (buf_size > (p - b)) - { - unsigned int l = p - b; - memcpy (buf, b, l); - buf += l; - buf_size -= l; - *buf_consumed += l; - *buf = '\0'; - } else - return i - start; - } - - return end - start; -} - -/* Returns number of items, starting at start, that were serialized. */ -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, /* May be NULL */ - hb_buffer_serialize_format_t format, - hb_buffer_serialize_flags_t flags) -{ - assert (start <= end && end <= buffer->len); - - *buf_consumed = 0; - - assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || - buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); - - 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; - - } -} - -hb_bool_t -hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - unsigned int *buf_consumed, - hb_font_t *font, /* May be NULL */ - hb_buffer_serialize_format_t format) -{ - return false; -} diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 5386e36..7b0c920 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -171,11 +171,11 @@ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer); -typedef enum { - HB_BUFFER_FLAGS_DEFAULT = 0x00000000, - HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */ - HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */ - HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004 +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; void @@ -186,12 +186,25 @@ hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer); + +#define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu + +/* Sets codepoint used to replace invalid UTF-8/16/32 entries. + * Default is 0xFFFDu. */ +void +hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, + hb_codepoint_t replacement); + +hb_codepoint_t +hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer); + + /* Resets the buffer. Afterwards it's as if it was just created, * except that it has a larger buffer allocated perhaps... */ void hb_buffer_reset (hb_buffer_t *buffer); -/* Like reset, but does NOT clear unicode_funcs. */ +/* Like reset, but does NOT clear unicode_funcs and replacement_codepoint. */ void hb_buffer_clear_contents (hb_buffer_t *buffer); @@ -240,6 +253,14 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, unsigned int item_offset, int item_length); +/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */ +void +hb_buffer_add_codepoints (hb_buffer_t *buffer, + const hb_codepoint_t *text, + int text_length, + unsigned int item_offset, + int item_length); + /* Clears any new items added at the end */ hb_bool_t @@ -274,11 +295,11 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer); * Serialize */ -typedef enum { - HB_BUFFER_SERIALIZE_FLAGS_DEFAULT = 0x00000000, - HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001, - HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002, - HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004 +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_flags_t; typedef enum { @@ -304,7 +325,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, unsigned int end, char *buf, unsigned int buf_size, - unsigned int *buf_consumed, + unsigned int *buf_consumed, /* May be NULL */ hb_font_t *font, /* May be NULL */ hb_buffer_serialize_format_t format, hb_buffer_serialize_flags_t flags); @@ -312,8 +333,8 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, const char *buf, - unsigned int buf_len, - unsigned int *buf_consumed, + 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); diff --git a/src/hb-common.cc b/src/hb-common.cc index 9422555..a6a5144 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -28,36 +28,72 @@ #include "hb-private.hh" -#include "hb-version.h" - #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): + * @len: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_tag_t -hb_tag_from_string (const char *s, int len) +hb_tag_from_string (const char *str, int len) { char tag[4]; unsigned int i; - if (!s || !len || !*s) + if (!str || !len || !*str) return HB_TAG_NONE; if (len < 0 || len > 4) len = 4; - for (i = 0; i < (unsigned) len && s[i]; i++) - tag[i] = s[i]; + 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: (array fixed-size=4): + * + * + * + * Since: 1.0 + **/ void hb_tag_to_string (hb_tag_t tag, char *buf) { @@ -77,6 +113,17 @@ const char direction_strings[][4] = { "btt" }; +/** + * hb_direction_from_string: + * @str: (array length=len): + * @len: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_direction_t hb_direction_from_string (const char *str, int len) { @@ -94,6 +141,16 @@ hb_direction_from_string (const char *str, int len) return HB_DIRECTION_INVALID; } +/** + * hb_direction_to_string: + * @direction: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ const char * hb_direction_to_string (hb_direction_t direction) { @@ -169,7 +226,7 @@ struct hb_language_item_t { return *this; } - void finish (void) { free (lang); } + void finish (void) { free ((void *) lang); } }; @@ -177,7 +234,8 @@ struct hb_language_item_t { static hb_language_item_t *langs; -static +#ifdef HB_USE_ATEXIT +static inline void free_langs (void) { while (langs) { @@ -187,6 +245,7 @@ void free_langs (void) langs = next; } } +#endif static hb_language_item_t * lang_find_or_insert (const char *key) @@ -210,7 +269,7 @@ retry: goto retry; } -#ifdef HAVE_ATEXIT +#ifdef HB_USE_ATEXIT if (!first_lang) atexit (free_langs); /* First person registers atexit() callback. */ #endif @@ -219,17 +278,32 @@ retry: } +/** + * hb_language_from_string: + * @str: (array length=len): + * @len: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_language_t hb_language_from_string (const char *str, int len) { + char strbuf[64]; + if (!str || !len || !*str) return HB_LANGUAGE_INVALID; - char strbuf[32]; - if (len >= 0) { + if (len >= 0) + { + /* NUL-terminate it. */ len = MIN (len, (int) sizeof (strbuf) - 1); - str = (char *) memcpy (strbuf, str, len); + memcpy (strbuf, str, len); strbuf[len] = '\0'; + str = strbuf; } hb_language_item_t *item = lang_find_or_insert (str); @@ -237,6 +311,16 @@ hb_language_from_string (const char *str, int len) return likely (item) ? item->lang : HB_LANGUAGE_INVALID; } +/** + * hb_language_to_string: + * @language: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ const char * hb_language_to_string (hb_language_t language) { @@ -244,6 +328,15 @@ hb_language_to_string (hb_language_t language) return language->s; } +/** + * hb_language_get_default: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_language_t hb_language_get_default (void) { @@ -261,6 +354,16 @@ hb_language_get_default (void) /* hb_script_t */ +/** + * hb_script_from_iso15924_tag: + * @tag: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag) { @@ -268,7 +371,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) return HB_SCRIPT_INVALID; /* Be lenient, adjust case (one capital letter followed by three small letters) */ - tag = (tag & 0xDFDFDFDF) | 0x00202020; + tag = (tag & 0xDFDFDFDFu) | 0x00202020u; switch (tag) { @@ -288,25 +391,56 @@ hb_script_from_iso15924_tag (hb_tag_t tag) } /* If it looks right, just use the tag as a script */ - if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060) + if (((uint32_t) tag & 0xE0E0E0E0u) == 0x40606060u) return (hb_script_t) tag; /* Otherwise, return unknown */ return HB_SCRIPT_UNKNOWN; } +/** + * hb_script_from_string: + * @s: (array length=len): + * @len: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_script_t hb_script_from_string (const char *s, int len) { return hb_script_from_iso15924_tag (hb_tag_from_string (s, len)); } +/** + * hb_script_to_iso15924_tag: + * @script: + * + * + * + * Return value: + * + * Since: 1.0 + **/ 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: 1.0 + **/ hb_direction_t hb_script_get_horizontal_direction (hb_script_t script) { @@ -350,6 +484,14 @@ hb_script_get_horizontal_direction (hb_script_t script) 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: + return HB_DIRECTION_RTL; } @@ -391,6 +533,16 @@ hb_user_data_array_t::get (hb_user_data_key_t *key) /* 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: 1.0 + **/ void hb_version (unsigned int *major, unsigned int *minor, @@ -401,18 +553,37 @@ hb_version (unsigned int *major, *micro = HB_VERSION_MICRO; } +/** + * hb_version_string: + * + * Returns library version as a string with three components. + * + * Return value: library version string. + * + * Since: 1.0 + **/ const char * hb_version_string (void) { return HB_VERSION_STRING; } +/** + * hb_version_atleast: + * @major: + * @minor: + * @micro: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t -hb_version_check (unsigned int major, - unsigned int minor, - unsigned int micro) +hb_version_atleast (unsigned int major, + unsigned int minor, + unsigned int micro) { - return HB_VERSION_CHECK (major, minor, micro); + return HB_VERSION_ATLEAST (major, minor, micro); } - - diff --git a/src/hb-common.h b/src/hb-common.h index cc221d3..b6ce3f7 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -90,10 +90,12 @@ typedef union _hb_var_int_t { typedef uint32_t hb_tag_t; -#define HB_TAG(a,b,c,d) ((hb_tag_t)((((uint8_t)(a))<<24)|(((uint8_t)(b))<<16)|(((uint8_t)(c))<<8)|((uint8_t)(d)))) +#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_tag_t @@ -121,17 +123,18 @@ hb_direction_from_string (const char *str, int len); 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_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4) -#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1)) /* Direction must be valid */ +#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1)) /* hb_language_t */ -typedef struct hb_language_impl_t *hb_language_t; +typedef const struct hb_language_impl_t *hb_language_t; /* len=-1 means str is NUL-terminated */ hb_language_t @@ -153,135 +156,159 @@ hb_language_get_default (void); /* Unicode Character Database property: Script (sc) */ typedef enum { - /* Unicode-1.1 additions */ - HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), - HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), - HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), - HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), - HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), - HB_SCRIPT_CANADIAN_ABORIGINAL = HB_TAG ('C','a','n','s'), - HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), - HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), - HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), - HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), - HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), - HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), - HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), - HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), - HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), - HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), - HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), - HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), - HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), - HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), - HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), - HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), - HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), - HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), - HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), - HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), - HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), - HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), - HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), - HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), - HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), - HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), - HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), - - /* Unicode-2.0 additions */ - HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), - - /* Unicode-3.0 additions */ - HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), - HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), - HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), - HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), - HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), - - /* Unicode-3.1 additions */ - HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), - HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), - HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), - - /* Unicode-3.2 additions */ - HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), - HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), - HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), - HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), - - /* Unicode-4.0 additions */ - HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), - HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), - HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), - HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), - HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), - HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), - HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), - HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), - - /* Unicode-4.1 additions */ - HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), - HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), - HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), - HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), - HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), - HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), - HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), - - /* Unicode-5.0 additions */ - HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), - HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), - HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), - HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), - HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), - HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), - - /* Unicode-5.1 additions */ - HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), - HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), - HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), - HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), - HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), - HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), - HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), - HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), - HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), - HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), - HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), - - /* Unicode-5.2 additions */ - HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), - HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), - HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), - HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), - HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), - HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), - HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), - HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), - HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), - HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), - HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), - HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), - HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), - HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), - HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), - - /* Unicode-6.0 additions */ - HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), - HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), - HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), - - /* Unicode-6.1 additions */ - HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), - HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), - HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), - HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), - HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), - HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), - HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), - - /* No script set */ - HB_SCRIPT_INVALID = HB_TAG_NONE + /*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'), + + /*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'), + + /* 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; @@ -290,7 +317,7 @@ typedef enum hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag); -/* suger for tag_from_string() then script_from_iso15924_tag */ +/* sugar for tag_from_string() then script_from_iso15924_tag */ /* len=-1 means s is NUL-terminated */ hb_script_t hb_script_from_string (const char *s, int len); diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 8f94795..9097cce 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -1,6 +1,6 @@ /* - * Copyright © 2012 Mozilla Foundation. - * Copyright © 2012 Google, Inc. + * Copyright © 2012,2013 Mozilla Foundation. + * Copyright © 2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -27,6 +27,7 @@ */ #define HB_SHAPER coretext +#define hb_coretext_shaper_face_data_t CGFont #include "hb-shaper-impl-private.hh" #include "hb-coretext.h" @@ -37,6 +38,38 @@ #endif +static void +release_table_data (void *user_data) +{ + CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data); + CFRelease(cf_data); +} + +static hb_blob_t * +reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +{ + CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data); + CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); + if (unlikely (!cf_data)) + return NULL; + + const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data)); + const size_t length = CFDataGetLength (cf_data); + if (!data || !length) + return NULL; + + return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, + reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)), + release_table_data); +} + +hb_face_t * +hb_coretext_face_create (CGFontRef cg_font) +{ + return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb_destroy_func_t) CGFontRelease); +} + + HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face) HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font) @@ -45,10 +78,6 @@ HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font) * shaper face data */ -struct hb_coretext_shaper_face_data_t { - CGFontRef cg_font; -}; - static void release_data (void *info, const void *data, size_t size) { @@ -61,24 +90,30 @@ release_data (void *info, const void *data, size_t size) hb_coretext_shaper_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { - hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t)); - if (unlikely (!data)) - return NULL; - - hb_blob_t *blob = hb_face_reference_blob (face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) - DEBUG_MSG (CORETEXT, face, "Face has empty blob"); + hb_coretext_shaper_face_data_t *data = NULL; - CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); - data->cg_font = CGFontCreateWithDataProvider (provider); - CGDataProviderRelease (provider); + if (face->destroy == (hb_destroy_func_t) CGFontRelease) + { + data = CGFontRetain ((CGFontRef) face->user_data); + } + else + { + hb_blob_t *blob = hb_face_reference_blob (face); + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (blob, &blob_length); + if (unlikely (!blob_length)) + DEBUG_MSG (CORETEXT, face, "Face has empty blob"); + + CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); + if (likely (provider)) + { + data = CGFontCreateWithDataProvider (provider); + CGDataProviderRelease (provider); + } + } - if (unlikely (!data->cg_font)) { + if (unlikely (!data)) { DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); - free (data); - return NULL; } return data; @@ -87,8 +122,7 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) void _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) { - CFRelease (data->cg_font); - free (data); + CFRelease (data); } CGFontRef @@ -96,7 +130,7 @@ hb_coretext_face_get_cg_font (hb_face_t *face) { if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL; hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - return face_data->cg_font; + return face_data; } @@ -120,7 +154,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) hb_face_t *face = font->face; hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - data->ct_font = CTFontCreateWithGraphicsFont (face_data->cg_font, font->y_scale, NULL, NULL); + data->ct_font = CTFontCreateWithGraphicsFont (face_data, font->y_scale, NULL, NULL); if (unlikely (!data->ct_font)) { DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); free (data); @@ -170,6 +204,222 @@ hb_coretext_font_get_ct_font (hb_font_t *font) * shaper */ +struct feature_record_t { + unsigned int feature; + unsigned int setting; +}; + +struct active_feature_t { + feature_record_t rec; + unsigned int order; + + static int cmp (const active_feature_t *a, const active_feature_t *b) { + return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 : + a->order < b->order ? -1 : a->order > b->order ? 1 : + a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 : + 0; + } + bool operator== (const active_feature_t *f) { + return cmp (this, f) == 0; + } +}; + +struct feature_event_t { + unsigned int index; + bool start; + active_feature_t feature; + + static int cmp (const feature_event_t *a, const feature_event_t *b) { + return a->index < b->index ? -1 : a->index > b->index ? 1 : + a->start < b->start ? -1 : a->start > b->start ? 1 : + active_feature_t::cmp (&a->feature, &b->feature); + } +}; + +struct range_record_t { + CTFontRef font; + unsigned int index_first; /* == start */ + unsigned int index_last; /* == end - 1 */ +}; + + +/* The following enum members are added in OS X 10.8. */ +#define kAltHalfWidthTextSelector 6 +#define kAltProportionalTextSelector 5 +#define kAlternateHorizKanaOffSelector 1 +#define kAlternateHorizKanaOnSelector 0 +#define kAlternateKanaType 34 +#define kAlternateVertKanaOffSelector 3 +#define kAlternateVertKanaOnSelector 2 +#define kCaseSensitiveLayoutOffSelector 1 +#define kCaseSensitiveLayoutOnSelector 0 +#define kCaseSensitiveLayoutType 33 +#define kCaseSensitiveSpacingOffSelector 3 +#define kCaseSensitiveSpacingOnSelector 2 +#define kContextualAlternatesOffSelector 1 +#define kContextualAlternatesOnSelector 0 +#define kContextualAlternatesType 36 +#define kContextualLigaturesOffSelector 19 +#define kContextualLigaturesOnSelector 18 +#define kContextualSwashAlternatesOffSelector 5 +#define kContextualSwashAlternatesOnSelector 4 +#define kDefaultLowerCaseSelector 0 +#define kDefaultUpperCaseSelector 0 +#define kHistoricalLigaturesOffSelector 21 +#define kHistoricalLigaturesOnSelector 20 +#define kHojoCharactersSelector 12 +#define kJIS2004CharactersSelector 11 +#define kLowerCasePetiteCapsSelector 2 +#define kLowerCaseSmallCapsSelector 1 +#define kLowerCaseType 37 +#define kMathematicalGreekOffSelector 11 +#define kMathematicalGreekOnSelector 10 +#define kNLCCharactersSelector 13 +#define kQuarterWidthTextSelector 4 +#define kScientificInferiorsSelector 4 +#define kStylisticAltEightOffSelector 17 +#define kStylisticAltEightOnSelector 16 +#define kStylisticAltEighteenOffSelector 37 +#define kStylisticAltEighteenOnSelector 36 +#define kStylisticAltElevenOffSelector 23 +#define kStylisticAltElevenOnSelector 22 +#define kStylisticAltFifteenOffSelector 31 +#define kStylisticAltFifteenOnSelector 30 +#define kStylisticAltFiveOffSelector 11 +#define kStylisticAltFiveOnSelector 10 +#define kStylisticAltFourOffSelector 9 +#define kStylisticAltFourOnSelector 8 +#define kStylisticAltFourteenOffSelector 29 +#define kStylisticAltFourteenOnSelector 28 +#define kStylisticAltNineOffSelector 19 +#define kStylisticAltNineOnSelector 18 +#define kStylisticAltNineteenOffSelector 39 +#define kStylisticAltNineteenOnSelector 38 +#define kStylisticAltOneOffSelector 3 +#define kStylisticAltOneOnSelector 2 +#define kStylisticAltSevenOffSelector 15 +#define kStylisticAltSevenOnSelector 14 +#define kStylisticAltSeventeenOffSelector 35 +#define kStylisticAltSeventeenOnSelector 34 +#define kStylisticAltSixOffSelector 13 +#define kStylisticAltSixOnSelector 12 +#define kStylisticAltSixteenOffSelector 33 +#define kStylisticAltSixteenOnSelector 32 +#define kStylisticAltTenOffSelector 21 +#define kStylisticAltTenOnSelector 20 +#define kStylisticAltThirteenOffSelector 27 +#define kStylisticAltThirteenOnSelector 26 +#define kStylisticAltThreeOffSelector 7 +#define kStylisticAltThreeOnSelector 6 +#define kStylisticAltTwelveOffSelector 25 +#define kStylisticAltTwelveOnSelector 24 +#define kStylisticAltTwentyOffSelector 41 +#define kStylisticAltTwentyOnSelector 40 +#define kStylisticAltTwoOffSelector 5 +#define kStylisticAltTwoOnSelector 4 +#define kStylisticAlternativesType 35 +#define kSwashAlternatesOffSelector 3 +#define kSwashAlternatesOnSelector 2 +#define kThirdWidthTextSelector 3 +#define kTraditionalNamesCharactersSelector 14 +#define kUpperCasePetiteCapsSelector 2 +#define kUpperCaseSmallCapsSelector 1 +#define kUpperCaseType 38 + +/* Table data courtesy of Apple. */ +struct feature_mapping_t { + FourCharCode otFeatureTag; + uint16_t aatFeatureType; + uint16_t selectorToEnable; + uint16_t selectorToDisable; +} feature_mappings[] = { + { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, + { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector }, + { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector }, + { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector }, + { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector }, + { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector }, + { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector }, + { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector }, + { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 }, + { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector }, + { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 }, + { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, + { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, + { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, }, + { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, + { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector }, + { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 }, + { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 }, + { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector }, + { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 }, + { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 }, + { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 }, + { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 }, + { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector }, + { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 }, + { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector }, + { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 }, + { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 }, + { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector }, + { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 }, + { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector }, + { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 }, + { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 }, + { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 }, + { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 }, + { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector }, + { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector }, + { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector }, + { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 }, + { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector }, + { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector }, + { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector }, + { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector }, + { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector }, + { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector }, + { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector }, + { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector }, + { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector }, + { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector }, + { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector }, + { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector }, + { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector }, + { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector }, + { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector }, + { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector }, + { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector }, + { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector }, + { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector }, + { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector }, + { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector }, + { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector }, + { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector }, + { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector }, + { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 }, + { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 }, + { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 }, + { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 }, + { 'unic', kLetterCaseType, 14, 15 }, + { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 }, + { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, + { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, + { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector }, + { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 }, + { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, + { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, +}; + +static int +_hb_feature_mapping_cmp (const void *key_, const void *entry_) +{ + unsigned int key = * (unsigned int *) key_; + const feature_mapping_t * entry = (const feature_mapping_t *) entry_; + return key < entry->otFeatureTag ? -1 : + key > entry->otFeatureTag ? 1 : + 0; +} + hb_bool_t _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_font_t *font, @@ -181,175 +431,725 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); -#define FAIL(...) \ - HB_STMT_START { \ - DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \ - return false; \ - } HB_STMT_END; + /* Attach marks to their bases, to match the 'ot' shaper. + * Adapted from hb-ot-shape:hb_form_clusters(). + * Note that this only makes us be closer to the 'ot' shaper, + * but by no means the same. For example, if there's + * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will + * continue pointing to B2 even though B2 was merged into B1's + * cluster... */ + { + hb_unicode_funcs_t *unicode = buffer->unicode; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 1; i < count; i++) + if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint))) + buffer->merge_clusters (i - 1, i + 1); + } + + hb_auto_array_t<feature_record_t> feature_records; + hb_auto_array_t<range_record_t> range_records; + + /* + * Set up features. + * (copied + modified from code from hb-uniscribe.cc) + */ + if (num_features) + { + /* Sort features by start/end events. */ + hb_auto_array_t<feature_event_t> feature_events; + for (unsigned int i = 0; i < num_features; i++) + { + const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag, + feature_mappings, + ARRAY_LENGTH (feature_mappings), + sizeof (feature_mappings[0]), + _hb_feature_mapping_cmp); + if (!mapping) + continue; + + active_feature_t feature; + feature.rec.feature = mapping->aatFeatureType; + feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable; + feature.order = i; + + feature_event_t *event; + + event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = features[i].start; + event->start = true; + event->feature = feature; + + event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = features[i].end; + event->start = false; + event->feature = feature; + } + feature_events.qsort (); + /* Add a strategic final event. */ + { + active_feature_t feature; + feature.rec.feature = HB_TAG_NONE; + feature.rec.setting = 0; + feature.order = num_features + 1; + + feature_event_t *event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = 0; /* This value does magic. */ + event->start = false; + event->feature = feature; + } + + /* Scan events and save features for each range. */ + hb_auto_array_t<active_feature_t> active_features; + unsigned int last_index = 0; + for (unsigned int i = 0; i < feature_events.len; i++) + { + feature_event_t *event = &feature_events[i]; + + if (event->index != last_index) + { + /* Save a snapshot of active features and the range. */ + range_record_t *range = range_records.push (); + if (unlikely (!range)) + goto fail_features; + + if (active_features.len) + { + CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + + /* TODO sort and resolve conflicting features? */ + /* active_features.qsort (); */ + for (unsigned int j = 0; j < active_features.len; j++) + { + CFStringRef keys[2] = { + kCTFontFeatureTypeIdentifierKey, + kCTFontFeatureSelectorIdentifierKey + }; + CFNumberRef values[2] = { + CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature), + CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting) + }; + CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault, + (const void **) keys, + (const void **) values, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease (values[0]); + CFRelease (values[1]); + + CFArrayAppendValue (features_array, dict); + CFRelease (dict); + + } + + CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, + (const void **) &kCTFontFeatureSettingsAttribute, + (const void **) &features_array, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease (features_array); + + CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); + CFRelease (attributes); + + range->font = CTFontCreateCopyWithAttributes (font_data->ct_font, 0.0, NULL, font_desc); + CFRelease (font_desc); + } + else + { + range->font = NULL; + } + + range->index_first = last_index; + range->index_last = event->index - 1; + + last_index = event->index; + } + + if (event->start) { + active_feature_t *feature = active_features.push (); + if (unlikely (!feature)) + goto fail_features; + *feature = event->feature; + } else { + active_feature_t *feature = active_features.find (&event->feature); + if (feature) + active_features.remove (feature - active_features.array); + } + } + + if (!range_records.len) /* No active feature found. */ + goto fail_features; + } + else + { + fail_features: + num_features = 0; + } unsigned int scratch_size; - char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); -#define utf16_index() var1.u32 +#define ALLOCATE_ARRAY(Type, name, len, on_no_room) \ + Type *name = (Type *) scratch; \ + { \ + unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ + if (unlikely (_consumed > scratch_size)) \ + { \ + on_no_room; \ + assert (0); \ + } \ + scratch += _consumed; \ + scratch_size -= _consumed; \ + } - UniChar *pchars = (UniChar *) scratch; + ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/); 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 < 0x10000)) + if (likely (c <= 0xFFFFu)) pchars[chars_len++] = c; - else if (unlikely (c >= 0x110000)) - pchars[chars_len++] = 0xFFFD; + else if (unlikely (c > 0x10FFFFu)) + pchars[chars_len++] = 0xFFFDu; else { - pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); - pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); + pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1)); } } -#undef utf16_index + ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/); + 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. */ + } + +#define FAIL(...) \ + HB_STMT_START { \ + DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \ + ret = false; \ + goto fail; \ + } HB_STMT_END; + + bool ret = true; + CFStringRef string_ref = NULL; + CTLineRef line = NULL; + + if (0) + { +resize_and_retry: + DEBUG_MSG (CORETEXT, buffer, "Buffer resize"); + /* string_ref uses the scratch-buffer for backing store, and line references + * string_ref (via attr_string). We must release those before resizing buffer. */ + assert (string_ref); + assert (line); + CFRelease (string_ref); + CFRelease (line); + string_ref = NULL; + line = NULL; + + /* Get previous start-of-scratch-area, that we use later for readjusting + * our existing scratch arrays. */ + unsigned int old_scratch_used; + hb_buffer_t::scratch_buffer_t *old_scratch; + old_scratch = buffer->get_scratch_buffer (&old_scratch_used); + old_scratch_used = scratch - old_scratch; + + if (unlikely (!buffer->ensure (buffer->allocated * 2))) + FAIL ("Buffer resize failed"); + + /* Adjust scratch, pchars, and log_cluster arrays. This is ugly, but really the + * cleanest way to do without completely restructuring the rest of this shaper. */ + scratch = buffer->get_scratch_buffer (&scratch_size); + pchars = reinterpret_cast<UniChar *> (((char *) scratch + ((char *) pchars - (char *) old_scratch))); + log_clusters = reinterpret_cast<unsigned int *> (((char *) scratch + ((char *) log_clusters - (char *) old_scratch))); + scratch += old_scratch_used; + scratch_size -= old_scratch_used; + } +retry: + { + string_ref = CFStringCreateWithCharactersNoCopy (NULL, + pchars, chars_len, + kCFAllocatorNull); + if (unlikely (!string_ref)) + FAIL ("CFStringCreateWithCharactersNoCopy failed"); + + /* Create an attributed string, populate it, and create a line from it, then release attributed string. */ + { + CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (kCFAllocatorDefault, + chars_len); + if (unlikely (!attr_string)) + FAIL ("CFAttributedStringCreateMutable failed"); + CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref); + if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) + { + CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), + kCTVerticalFormsAttributeName, kCFBooleanTrue); + } + + if (buffer->props.language) + { +/* What's the iOS equivalent of this check? + * The symbols was introduced in iOS 7.0. + * At any rate, our fallback is safe and works fine. */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 +# define kCTLanguageAttributeName CFSTR ("NSLanguage") +#endif + CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault, + hb_language_to_string (buffer->props.language), + kCFStringEncodingUTF8, + kCFAllocatorNull); + if (unlikely (!lang)) + FAIL ("CFStringCreateWithCStringNoCopy failed"); + CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), + kCTLanguageAttributeName, lang); + CFRelease (lang); + } + CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), + kCTFontAttributeName, font_data->ct_font); + + if (num_features) + { + unsigned int start = 0; + range_record_t *last_range = &range_records[0]; + for (unsigned int k = 0; k < chars_len; k++) + { + range_record_t *range = last_range; + while (log_clusters[k] < range->index_first) + range--; + while (log_clusters[k] > range->index_last) + range++; + if (range != last_range) + { + if (last_range->font) + CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, k - start), + kCTFontAttributeName, last_range->font); + + start = k; + } + + last_range = range; + } + if (start != chars_len && last_range->font) + CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, chars_len - start), + kCTFontAttributeName, last_range->font); + } - CFStringRef string_ref = CFStringCreateWithCharactersNoCopy (kCFAllocatorDefault, - pchars, chars_len, - kCFAllocatorNull); + int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; + CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level); + CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault, + (const void **) &kCTTypesetterOptionForcedEmbeddingLevel, + (const void **) &level_number, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (unlikely (!options)) + FAIL ("CFDictionaryCreate failed"); + + CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options); + CFRelease (options); + CFRelease (attr_string); + if (unlikely (!typesetter)) + FAIL ("CTTypesetterCreateWithAttributedStringAndOptions failed"); + + line = CTTypesetterCreateLine (typesetter, CFRangeMake(0, 0)); + CFRelease (typesetter); + if (unlikely (!line)) + FAIL ("CTTypesetterCreateLine failed"); + } - CFDictionaryRef attrs = CFDictionaryCreate (kCFAllocatorDefault, - (const void**) &kCTFontAttributeName, - (const void**) &font_data->ct_font, - 1, /* count of attributes */ - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + CFArrayRef glyph_runs = CTLineGetGlyphRuns (line); + unsigned int num_runs = CFArrayGetCount (glyph_runs); + DEBUG_MSG (CORETEXT, NULL, "Num runs: %d", num_runs); + + buffer->len = 0; + uint32_t status_and = ~0, status_or = 0; + + const CFRange range_all = CFRangeMake (0, 0); + + for (unsigned int i = 0; i < num_runs; i++) + { + CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i)); + CTRunStatus run_status = CTRunGetStatus (run); + status_or |= run_status; + status_and &= run_status; + DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status); + + /* CoreText does automatic font fallback (AKA "cascading") for characters + * not supported by the requested font, and provides no way to turn it off, + * so we must detect if the returned run uses a font other than the requested + * one and fill in the buffer with .notdef glyphs instead of random glyph + * indices from a different font. + */ + CFDictionaryRef attributes = CTRunGetAttributes (run); + CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName)); + if (!CFEqual (run_ct_font, font_data->ct_font)) + { + /* The run doesn't use our main font instance. We have to figure out + * whether font fallback happened, or this is just CoreText giving us + * another CTFont using the same underlying CGFont. CoreText seems + * to do that in a variety of situations, one of which being vertical + * text, but also perhaps for caching reasons. + * + * First, see if it uses any of our subfonts created to set font features... + * + * Next, compare the CGFont to the one we used to create our fonts. + * Even this doesn't work all the time. + * + * Finally, we compare PS names, which I don't think are unique... + * + * Looks like if we really want to be sure here we have to modify the + * font to change the name table, similar to what we do in the uniscribe + * backend. + * + * However, even that wouldn't work if we were passed in the CGFont to + * begin with. + * + * Webkit uses a slightly different approach: it installs LastResort + * as fallback chain, and then checks PS name of used font against + * LastResort. That one is safe for any font except for LastResort, + * as opposed to ours, which can fail if we are using any uninstalled + * font that has the same name as an installed font. + * + * See: http://github.com/behdad/harfbuzz/pull/36 + */ + bool matched = false; + for (unsigned int i = 0; i < range_records.len; i++) + if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font)) + { + matched = true; + break; + } + if (!matched) + { + CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0); + if (run_cg_font) + { + matched = CFEqual (run_cg_font, face_data); + CFRelease (run_cg_font); + } + } + if (!matched) + { + CFStringRef font_ps_name = CTFontCopyName (font_data->ct_font, kCTFontPostScriptNameKey); + CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey); + CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0); + CFRelease (run_ps_name); + CFRelease (font_ps_name); + if (result == kCFCompareEqualTo) + matched = true; + } + if (!matched) + { + CFRange range = CTRunGetStringRange (run); + DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld", + range.location, range.location + range.length); + if (!buffer->ensure_inplace (buffer->len + range.length)) + goto resize_and_retry; + hb_glyph_info_t *info = buffer->info + buffer->len; + + CGGlyph notdef = 0; + double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, ¬def, NULL, 1); + + unsigned int old_len = buffer->len; + for (CFIndex j = range.location; j < range.location + range.length; j++) + { + UniChar ch = CFStringGetCharacterAtIndex (string_ref, j); + if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j) + { + ch = CFStringGetCharacterAtIndex (string_ref, j - 1); + if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu)) + /* This is the second of a surrogate pair. Don't need .notdef + * for this one. */ + continue; + } + + info->codepoint = notdef; + info->cluster = log_clusters[j]; + + info->mask = advance; + info->var1.u32 = 0; + info->var2.u32 = 0; + + info++; + buffer->len++; + } + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + buffer->reverse_range (old_len, buffer->len); + continue; + } + } - /* TODO: support features */ + unsigned int num_glyphs = CTRunGetGlyphCount (run); + if (num_glyphs == 0) + continue; + + if (!buffer->ensure_inplace (buffer->len + num_glyphs)) + goto resize_and_retry; + + hb_glyph_info_t *run_info = buffer->info + buffer->len; + + /* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always + * succeed, and so copying data to our own buffer will be rare. Reports + * have it that this changed in OS X 10.10 Yosemite, and NULL is returned + * frequently. At any rate, we can test that codepath by setting USE_PTR + * to false. */ + +#define USE_PTR true + +#define SCRATCH_SAVE() \ + unsigned int scratch_size_saved = scratch_size; \ + hb_buffer_t::scratch_buffer_t *scratch_saved = scratch + +#define SCRATCH_RESTORE() \ + scratch_size = scratch_size_saved; \ + scratch = scratch_saved; + + { + SCRATCH_SAVE(); + const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL; + if (!glyphs) { + ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry); + CTRunGetGlyphs (run, range_all, glyph_buf); + glyphs = glyph_buf; + } + const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : NULL; + if (!string_indices) { + ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry); + CTRunGetStringIndices (run, range_all, index_buf); + string_indices = index_buf; + } + hb_glyph_info_t *info = run_info; + for (unsigned int j = 0; j < num_glyphs; j++) + { + info->codepoint = glyphs[j]; + info->cluster = log_clusters[string_indices[j]]; + info++; + } + SCRATCH_RESTORE(); + } + { + SCRATCH_SAVE(); + const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL; + if (!positions) { + ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry); + CTRunGetPositions (run, range_all, position_buf); + positions = position_buf; + } + double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL); + DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); + hb_glyph_info_t *info = run_info; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + { + for (unsigned int j = 0; j < num_glyphs; j++) + { + double advance = (j + 1 < num_glyphs ? positions[j + 1].x : positions[0].x + run_advance) - positions[j].x; + info->mask = advance; + info->var1.u32 = positions[0].x; /* Yes, zero. */ + info->var2.u32 = positions[j].y; + info++; + } + } + else + { + run_advance = -run_advance; + for (unsigned int j = 0; j < num_glyphs; j++) + { + double advance = (j + 1 < num_glyphs ? positions[j + 1].y : positions[0].y + run_advance) - positions[j].y; + info->mask = advance; + info->var1.u32 = positions[j].x; + info->var2.u32 = positions[0].y; /* Yes, zero. */ + info++; + } + } + SCRATCH_RESTORE(); + } +#undef SCRATCH_RESTORE +#undef SCRATCH_SAVE +#undef USE_PTR +#undef ALLOCATE_ARRAY - CFAttributedStringRef attr_string = CFAttributedStringCreate (kCFAllocatorDefault, string_ref, attrs); - CFRelease (string_ref); - CFRelease (attrs); + buffer->len += num_glyphs; + } - CTLineRef line = CTLineCreateWithAttributedString (attr_string); - CFRelease (attr_string); + /* Make sure all runs had the expected direction. */ + bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + assert (bool (status_and & kCTRunStatusRightToLeft) == backward); + assert (bool (status_or & kCTRunStatusRightToLeft) == backward); + + buffer->clear_positions (); + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + for (unsigned int i = 0; i < count; i++) + { + pos->x_advance = info->mask; + pos->x_offset = info->var1.u32; + pos->y_offset = info->var2.u32; + info++, pos++; + } + else + for (unsigned int i = 0; i < count; i++) + { + pos->y_advance = info->mask; + pos->x_offset = info->var1.u32; + pos->y_offset = info->var2.u32; + info++, pos++; + } - CFArrayRef glyph_runs = CTLineGetGlyphRuns (line); - unsigned int num_runs = CFArrayGetCount (glyph_runs); + /* Fix up clusters so that we never return out-of-order indices; + * if core text has reordered glyphs, we'll merge them to the + * beginning of the reordered cluster. CoreText is nice enough + * to tell us whenever it has produced nonmonotonic results... + * Note that we assume the input clusters were nonmonotonic to + * begin with. + * + * This does *not* mean we'll form the same clusters as Uniscribe + * or the native OT backend, only that the cluster indices will be + * monotonic in the output buffer. */ + if (count > 1 && (status_or & kCTRunStatusNonMonotonic)) + { + hb_glyph_info_t *info = buffer->info; + if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) + { + unsigned int cluster = info[count - 1].cluster; + for (unsigned int i = count - 1; i > 0; i--) + { + cluster = MIN (cluster, info[i - 1].cluster); + info[i - 1].cluster = cluster; + } + } + else + { + unsigned int cluster = info[0].cluster; + for (unsigned int i = 1; i < count; i++) + { + cluster = MIN (cluster, info[i].cluster); + info[i].cluster = cluster; + } + } + } + } - bool success = true; - buffer->len = 0; +#undef FAIL - const CFRange range_all = CFRangeMake (0, 0); +fail: + if (string_ref) + CFRelease (string_ref); + if (line) + CFRelease (line); - for (unsigned int i = 0; i < num_runs; i++) { - CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (glyph_runs, i); + for (unsigned int i = 0; i < range_records.len; i++) + if (range_records[i].font) + CFRelease (range_records[i].font); - unsigned int num_glyphs = CTRunGetGlyphCount (run); - if (num_glyphs == 0) - continue; + return ret; +} - buffer->ensure (buffer->len + num_glyphs); - /* Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds, - * and so copying data to our own buffer with CTRunGetGlyphs will be - * extremely rare. */ +/* + * AAT shaper + */ - unsigned int scratch_size; - char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); +HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face) +HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font) -#define ALLOCATE_ARRAY(Type, name, len) \ - Type *name = (Type *) scratch; \ - scratch += (len) * sizeof ((name)[0]); \ - scratch_size -= (len) * sizeof ((name)[0]); - - const CGGlyph* glyphs = CTRunGetGlyphsPtr (run); - if (!glyphs) { - ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs); - CTRunGetGlyphs (run, range_all, glyph_buf); - glyphs = glyph_buf; - } - const CGPoint* positions = CTRunGetPositionsPtr (run); - if (!positions) { - ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs); - CTRunGetPositions (run, range_all, position_buf); - positions = position_buf; - } +/* + * shaper face data + */ + +struct hb_coretext_aat_shaper_face_data_t {}; - const CFIndex* string_indices = CTRunGetStringIndicesPtr (run); - if (!string_indices) { - ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs); - CTRunGetStringIndices (run, range_all, index_buf); - string_indices = index_buf; +hb_coretext_aat_shaper_face_data_t * +_hb_coretext_aat_shaper_face_data_create (hb_face_t *face) +{ + hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT); + /* Umm, we just reference the table to check whether it exists. + * Maybe add better API for this? */ + if (!hb_blob_get_length (mort_blob)) + { + hb_blob_destroy (mort_blob); + mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX); + if (!hb_blob_get_length (mort_blob)) + { + hb_blob_destroy (mort_blob); + return NULL; } + } + hb_blob_destroy (mort_blob); -#undef ALLOCATE_ARRAY + return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL; +} + +void +_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED) +{ +} - double run_width = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL); - for (unsigned int j = 0; j < num_glyphs; j++) { - double advance = (j + 1 < num_glyphs ? positions[j + 1].x : positions[0].x + run_width) - positions[j].x; +/* + * shaper font data + */ - hb_glyph_info_t *info = &buffer->info[buffer->len]; - hb_glyph_position_t *pos = &buffer->pos[buffer->len]; +struct hb_coretext_aat_shaper_font_data_t {}; - info->codepoint = glyphs[j]; - info->cluster = string_indices[j]; +hb_coretext_aat_shaper_font_data_t * +_hb_coretext_aat_shaper_font_data_create (hb_font_t *font) +{ + return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL; +} - /* Currently, we do all x-positioning by setting the advance, we never use x-offset. */ - info->mask = advance; - info->var1.u32 = 0; - info->var2.u32 = positions[j].y; +void +_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED) +{ +} - buffer->len++; - } - } - buffer->clear_positions (); +/* + * shaper shape_plan data + */ - unsigned int count = buffer->len; - for (unsigned int i = 0; i < count; ++i) { - hb_glyph_info_t *info = &buffer->info[i]; - hb_glyph_position_t *pos = &buffer->pos[i]; +struct hb_coretext_aat_shaper_shape_plan_data_t {}; - /* TODO vertical */ - pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; - } +hb_coretext_aat_shaper_shape_plan_data_t * +_hb_coretext_aat_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) +{ + return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} - /* Fix up clusters so that we never return out-of-order indices; - * if core text has reordered glyphs, we'll merge them to the - * beginning of the reordered cluster. - * - * This does *not* mean we'll form the same clusters as Uniscribe - * or the native OT backend, only that the cluster indices will be - * monotonic in the output buffer. */ - if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) { - unsigned int prev_cluster = 0; - for (unsigned int i = 0; i < count; i++) { - unsigned int curr_cluster = buffer->info[i].cluster; - if (curr_cluster < prev_cluster) { - for (unsigned int j = i; j > 0; j--) { - if (buffer->info[j - 1].cluster > curr_cluster) - buffer->info[j - 1].cluster = curr_cluster; - else - break; - } - } - prev_cluster = curr_cluster; - } - } else { - unsigned int prev_cluster = (unsigned int)-1; - for (unsigned int i = 0; i < count; i++) { - unsigned int curr_cluster = buffer->info[i].cluster; - if (curr_cluster > prev_cluster) { - for (unsigned int j = i; j > 0; j--) { - if (buffer->info[j - 1].cluster < curr_cluster) - buffer->info[j - 1].cluster = curr_cluster; - else - break; - } - } - prev_cluster = curr_cluster; - } - } +void +_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper + */ - return true; +hb_bool_t +_hb_coretext_aat_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_coretext_shape (shape_plan, font, buffer, features, num_features); } diff --git a/src/hb-coretext.h b/src/hb-coretext.h index c4954fa..25267bc 100644 --- a/src/hb-coretext.h +++ b/src/hb-coretext.h @@ -29,11 +29,25 @@ #include "hb.h" -#include <ApplicationServices/ApplicationServices.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_face_t * +hb_coretext_face_create (CGFontRef cg_font); + + CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face); diff --git a/src/hb-old/harfbuzz-stream.h b/src/hb-deprecated.h index a155cc2..30ae4b1 100644 --- a/src/hb-old/harfbuzz-stream.h +++ b/src/hb-deprecated.h @@ -1,8 +1,7 @@ /* - * Copyright (C) 2005 David Turner - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * Copyright © 2013 Google, Inc. * - * This is part of HarfBuzz, an OpenType Layout engine library. + * 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 @@ -21,31 +20,32 @@ * 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 HARFBUZZ_STREAM_H -#define HARFBUZZ_STREAM_H +#ifndef HB_H_IN +#error "Include <hb.h> instead." +#endif -#include "harfbuzz-global.h" +#ifndef HB_DEPRECATED_H +#define HB_DEPRECATED_H -HB_BEGIN_HEADER +#include "hb-common.h" +#include "hb-unicode.h" +#include "hb-font.h" -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif +HB_BEGIN_DECLS -typedef struct HB_StreamRec_ -{ - HB_Byte* base; - HB_Byte* cursor; - HB_UInt size; - HB_UInt pos; -} HB_StreamRec; +#ifndef HB_DISABLE_DEPRECATED -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif +#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS -HB_END_HEADER +#define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT +#define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT #endif + +HB_END_DECLS + +#endif /* HB_DEPRECATED_H */ diff --git a/src/hb-face-private.hh b/src/hb-face-private.hh new file mode 100644 index 0000000..6520d3d --- /dev/null +++ b/src/hb-face-private.hh @@ -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 (!this || !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 */ diff --git a/src/hb-face.cc b/src/hb-face.cc new file mode 100644 index 0000000..9348af7 --- /dev/null +++ b/src/hb-face.cc @@ -0,0 +1,481 @@ +/* + * 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 "hb-cache-private.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: 1.0 + **/ +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 *) malloc (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: 1.0 + **/ +hb_face_t * +hb_face_create (hb_blob_t *blob, + unsigned int index) +{ + hb_face_t *face; + + if (unlikely (!blob || !hb_blob_get_length (blob))) + return hb_face_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: 1.0 + **/ +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: 1.0 + **/ +hb_face_t * +hb_face_reference (hb_face_t *face) +{ + return hb_object_reference (face); +} + +/** + * hb_face_destroy: (skip) + * @face: a face. + * + * + * + * Since: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +unsigned int +hb_face_get_index (hb_face_t *face) +{ + return face->index; +} + +/** + * hb_face_set_upem: + * @face: a face. + * @upem: + * + * + * + * Since: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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: 1.0 + **/ +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); +} + + diff --git a/src/hb-face.h b/src/hb-face.h new file mode 100644 index 0000000..f682c46 --- /dev/null +++ b/src/hb-face.h @@ -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_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_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 * +hb_face_get_empty (void); + +hb_face_t * +hb_face_reference (hb_face_t *face); + +void +hb_face_destroy (hb_face_t *face); + +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); + + +void * +hb_face_get_user_data (hb_face_t *face, + hb_user_data_key_t *key); + +void +hb_face_make_immutable (hb_face_t *face); + +hb_bool_t +hb_face_is_immutable (hb_face_t *face); + + +hb_blob_t * +hb_face_reference_table (hb_face_t *face, + hb_tag_t tag); + +hb_blob_t * +hb_face_reference_blob (hb_face_t *face); + +void +hb_face_set_index (hb_face_t *face, + unsigned int index); + +unsigned int +hb_face_get_index (hb_face_t *face); + +void +hb_face_set_upem (hb_face_t *face, + unsigned int upem); + +unsigned int +hb_face_get_upem (hb_face_t *face); + +void +hb_face_set_glyph_count (hb_face_t *face, + unsigned int glyph_count); + +unsigned int +hb_face_get_glyph_count (hb_face_t *face); + + +HB_END_DECLS + +#endif /* HB_FACE_H */ diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc index bdc8a80..9d061a9 100644 --- a/src/hb-fallback-shape.cc +++ b/src/hb-fallback-shape.cc @@ -95,34 +95,46 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED, 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; - font->get_glyph (' ', 0, &space); + bool has_space = font->get_glyph (' ', 0, &space); - buffer->guess_segment_properties (); 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 (buffer->unicode->is_default_ignorable (buffer->info[i].codepoint)) { - buffer->info[i].codepoint = space; - buffer->pos[i].x_advance = 0; - buffer->pos[i].y_advance = 0; + 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_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint); - font->get_glyph_advance_for_direction (buffer->info[i].codepoint, - buffer->props.direction, - &buffer->pos[i].x_advance, - &buffer->pos[i].y_advance); - font->subtract_glyph_origin_for_direction (buffer->info[i].codepoint, - buffer->props.direction, - &buffer->pos[i].x_offset, - &buffer->pos[i].y_offset); + font->get_glyph (info[i].codepoint, 0, &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 (buffer->props.direction)) + if (HB_DIRECTION_IS_BACKWARD (direction)) hb_buffer_reverse (buffer); return true; diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 48fbb0e..33bbf71 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh @@ -31,10 +31,9 @@ #include "hb-private.hh" -#include "hb-font.h" #include "hb-object-private.hh" +#include "hb-face-private.hh" #include "hb-shaper-private.hh" -#include "hb-shape-plan-private.hh" @@ -84,71 +83,6 @@ struct hb_font_funcs_t { }; -/* - * 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 (!this || !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 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; -}; - -#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 - /* * hb_font_t @@ -183,12 +117,12 @@ struct hb_font_t { /* 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 v * (int64_t) this->x_scale / this->parent->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 v * (int64_t) this->y_scale / this->parent->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) { @@ -210,6 +144,12 @@ struct hb_font_t { /* Public getters */ + inline hb_bool_t has_glyph (hb_codepoint_t unicode) + { + hb_codepoint_t glyph; + return get_glyph (unicode, 0, &glyph); + } + inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) { @@ -258,10 +198,10 @@ struct hb_font_t { klass->user_data.glyph_h_kerning); } - inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) + inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) { return klass->get.glyph_v_kerning (this, user_data, - left_glyph, right_glyph, + top_glyph, bottom_glyph, klass->user_data.glyph_v_kerning); } @@ -336,16 +276,21 @@ struct hb_font_t { hb_direction_t direction, hb_position_t *x, hb_position_t *y) { - if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { - hb_bool_t ret = get_glyph_h_origin (glyph, x, y); - if (!ret && (ret = get_glyph_v_origin (glyph, x, y))) { + if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) + { + 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; } - } else { - hb_bool_t ret = get_glyph_v_origin (glyph, x, y); - if (!ret && (ret = get_glyph_h_origin (glyph, x, y))) { + } + else + { + 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; @@ -421,7 +366,8 @@ struct hb_font_t { { if (get_glyph_name (glyph, s, size)) return; - snprintf (s, size, "gid%u", glyph); + if (size && snprintf (s, size, "gid%u", glyph) < 0) + *s = '\0'; } /* Parses gidDDD and uniUUUU strings automatically. */ @@ -456,7 +402,7 @@ struct hb_font_t { } private: - inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); } + inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); } }; #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS diff --git a/src/hb-font.cc b/src/hb-font.cc index b59fdeb..4364ca7 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -31,7 +31,6 @@ #include "hb-ot-layout-private.hh" #include "hb-font-private.hh" -#include "hb-blob.h" #include "hb-open-file-private.hh" #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" @@ -41,7 +40,6 @@ #include <string.h> - /* * hb_font_funcs_t */ @@ -231,6 +229,15 @@ static const hb_font_funcs_t _hb_font_funcs_nil = { }; +/** + * hb_font_funcs_create: (Xconstructor) + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_font_funcs_t * hb_font_funcs_create (void) { @@ -244,18 +251,45 @@ hb_font_funcs_create (void) return ffuncs; } +/** + * hb_font_funcs_get_empty: + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_font_funcs_t * hb_font_funcs_get_empty (void) { return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil); } +/** + * hb_font_funcs_reference: (skip) + * @ffuncs: font functions. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_font_funcs_t * hb_font_funcs_reference (hb_font_funcs_t *ffuncs) { return hb_object_reference (ffuncs); } +/** + * hb_font_funcs_destroy: (skip) + * @ffuncs: font functions. + * + * + * + * Since: 1.0 + **/ void hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) { @@ -269,6 +303,20 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) free (ffuncs); } +/** + * hb_font_funcs_set_user_data: (skip) + * @ffuncs: font functions. + * @key: + * @data: + * @destroy: + * @replace: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, hb_user_data_key_t *key, @@ -279,6 +327,17 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, return hb_object_set_user_data (ffuncs, key, data, destroy, replace); } +/** + * hb_font_funcs_get_user_data: (skip) + * @ffuncs: font functions. + * @key: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ void * hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, hb_user_data_key_t *key) @@ -287,15 +346,33 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, } +/** + * hb_font_funcs_make_immutable: + * @ffuncs: font functions. + * + * + * + * Since: 1.0 + **/ void hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) { - if (hb_object_is_inert (ffuncs)) + if (unlikely (hb_object_is_inert (ffuncs))) return; ffuncs->immutable = true; } +/** + * hb_font_funcs_is_immutable: + * @ffuncs: font functions. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) { @@ -337,6 +414,19 @@ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS /* Public getters */ +/** + * hb_font_get_glyph: + * @font: a font. + * @unicode: + * @variation_selector: + * @glyph: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph (hb_font_t *font, hb_codepoint_t unicode, hb_codepoint_t variation_selector, @@ -345,6 +435,17 @@ hb_font_get_glyph (hb_font_t *font, return font->get_glyph (unicode, variation_selector, glyph); } +/** + * hb_font_get_glyph_h_advance: + * @font: a font. + * @glyph: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_position_t hb_font_get_glyph_h_advance (hb_font_t *font, hb_codepoint_t glyph) @@ -352,6 +453,17 @@ hb_font_get_glyph_h_advance (hb_font_t *font, return font->get_glyph_h_advance (glyph); } +/** + * hb_font_get_glyph_v_advance: + * @font: a font. + * @glyph: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_position_t hb_font_get_glyph_v_advance (hb_font_t *font, hb_codepoint_t glyph) @@ -359,6 +471,19 @@ hb_font_get_glyph_v_advance (hb_font_t *font, return font->get_glyph_v_advance (glyph); } +/** + * hb_font_get_glyph_h_origin: + * @font: a font. + * @glyph: + * @x: (out): + * @y: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_h_origin (hb_font_t *font, hb_codepoint_t glyph, @@ -367,6 +492,19 @@ hb_font_get_glyph_h_origin (hb_font_t *font, return font->get_glyph_h_origin (glyph, x, y); } +/** + * hb_font_get_glyph_v_origin: + * @font: a font. + * @glyph: + * @x: (out): + * @y: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_v_origin (hb_font_t *font, hb_codepoint_t glyph, @@ -375,6 +513,18 @@ hb_font_get_glyph_v_origin (hb_font_t *font, return font->get_glyph_v_origin (glyph, x, y); } +/** + * hb_font_get_glyph_h_kerning: + * @font: a font. + * @left_glyph: + * @right_glyph: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) @@ -382,13 +532,37 @@ hb_font_get_glyph_h_kerning (hb_font_t *font, return font->get_glyph_h_kerning (left_glyph, right_glyph); } +/** + * hb_font_get_glyph_v_kerning: + * @font: a font. + * @top_glyph: + * @bottom_glyph: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_position_t hb_font_get_glyph_v_kerning (hb_font_t *font, - hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) + hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) { - return font->get_glyph_v_kerning (left_glyph, right_glyph); + return font->get_glyph_v_kerning (top_glyph, bottom_glyph); } +/** + * hb_font_get_glyph_extents: + * @font: a font. + * @glyph: + * @extents: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_extents (hb_font_t *font, hb_codepoint_t glyph, @@ -397,6 +571,20 @@ hb_font_get_glyph_extents (hb_font_t *font, return font->get_glyph_extents (glyph, extents); } +/** + * hb_font_get_glyph_contour_point: + * @font: a font. + * @glyph: + * @point_index: + * @x: (out): + * @y: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_contour_point (hb_font_t *font, hb_codepoint_t glyph, unsigned int point_index, @@ -405,6 +593,19 @@ hb_font_get_glyph_contour_point (hb_font_t *font, return font->get_glyph_contour_point (glyph, point_index, x, y); } +/** + * hb_font_get_glyph_name: + * @font: a font. + * @glyph: + * @name: (array length=size): + * @size: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_name (hb_font_t *font, hb_codepoint_t glyph, @@ -413,6 +614,19 @@ hb_font_get_glyph_name (hb_font_t *font, return font->get_glyph_name (glyph, name, size); } +/** + * hb_font_get_glyph_from_name: + * @font: a font. + * @name: (array length=len): + * @len: + * @glyph: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_from_name (hb_font_t *font, const char *name, int len, /* -1 means nul-terminated */ @@ -424,6 +638,18 @@ hb_font_get_glyph_from_name (hb_font_t *font, /* A bit higher-level, and with fallback */ +/** + * hb_font_get_glyph_advance_for_direction: + * @font: a font. + * @glyph: + * @direction: + * @x: (out): + * @y: (out): + * + * + * + * Since: 1.0 + **/ void hb_font_get_glyph_advance_for_direction (hb_font_t *font, hb_codepoint_t glyph, @@ -433,6 +659,18 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font, return font->get_glyph_advance_for_direction (glyph, direction, x, y); } +/** + * hb_font_get_glyph_origin_for_direction: + * @font: a font. + * @glyph: + * @direction: + * @x: (out): + * @y: (out): + * + * + * + * Since: 1.0 + **/ void hb_font_get_glyph_origin_for_direction (hb_font_t *font, hb_codepoint_t glyph, @@ -442,6 +680,18 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font, return font->get_glyph_origin_for_direction (glyph, direction, x, y); } +/** + * hb_font_add_glyph_origin_for_direction: + * @font: a font. + * @glyph: + * @direction: + * @x: (out): + * @y: (out): + * + * + * + * Since: 1.0 + **/ void hb_font_add_glyph_origin_for_direction (hb_font_t *font, hb_codepoint_t glyph, @@ -451,6 +701,18 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font, return font->add_glyph_origin_for_direction (glyph, direction, x, y); } +/** + * hb_font_subtract_glyph_origin_for_direction: + * @font: a font. + * @glyph: + * @direction: + * @x: (out): + * @y: (out): + * + * + * + * Since: 1.0 + **/ void hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, hb_codepoint_t glyph, @@ -460,6 +722,19 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); } +/** + * hb_font_get_glyph_kerning_for_direction: + * @font: a font. + * @first_glyph: + * @second_glyph: + * @direction: + * @x: (out): + * @y: (out): + * + * + * + * Since: 1.0 + **/ void hb_font_get_glyph_kerning_for_direction (hb_font_t *font, hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, @@ -469,6 +744,19 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); } +/** + * hb_font_get_glyph_extents_for_origin: + * @font: a font. + * @glyph: + * @direction: + * @extents: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_extents_for_origin (hb_font_t *font, hb_codepoint_t glyph, @@ -478,6 +766,21 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font, return font->get_glyph_extents_for_origin (glyph, direction, extents); } +/** + * hb_font_get_glyph_contour_point_for_origin: + * @font: a font. + * @glyph: + * @point_index: + * @direction: + * @x: (out): + * @y: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, hb_codepoint_t glyph, unsigned int point_index, @@ -488,6 +791,17 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, } /* Generates gidDDD if glyph has no name. */ +/** + * hb_font_glyph_to_string: + * @font: a font. + * @glyph: + * @s: (array length=size): + * @size: + * + * + * + * Since: 1.0 + **/ void hb_font_glyph_to_string (hb_font_t *font, hb_codepoint_t glyph, @@ -497,6 +811,19 @@ hb_font_glyph_to_string (hb_font_t *font, } /* Parses gidDDD and uniUUUU strings automatically. */ +/** + * hb_font_glyph_from_string: + * @font: a font. + * @s: (array length=len): + * @len: + * @glyph: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_glyph_from_string (hb_font_t *font, const char *s, int len, /* -1 means nul-terminated */ @@ -507,277 +834,19 @@ hb_font_glyph_from_string (hb_font_t *font, /* - * hb_face_t - */ - -static 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_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 *) malloc (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_t * -hb_face_create (hb_blob_t *blob, - unsigned int index) -{ - hb_face_t *face; - - if (unlikely (!blob || !hb_blob_get_length (blob))) - return hb_face_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_t * -hb_face_get_empty (void) -{ - return const_cast<hb_face_t *> (&_hb_face_nil); -} - - -hb_face_t * -hb_face_reference (hb_face_t *face) -{ - return hb_object_reference (face); -} - -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_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); -} - -void * -hb_face_get_user_data (hb_face_t *face, - hb_user_data_key_t *key) -{ - return hb_object_get_user_data (face, key); -} - -void -hb_face_make_immutable (hb_face_t *face) -{ - if (hb_object_is_inert (face)) - return; - - face->immutable = true; -} - -hb_bool_t -hb_face_is_immutable (hb_face_t *face) -{ - return face->immutable; -} - - -hb_blob_t * -hb_face_reference_table (hb_face_t *face, - hb_tag_t tag) -{ - return face->reference_table (tag); -} - -hb_blob_t * -hb_face_reference_blob (hb_face_t *face) -{ - return face->reference_table (HB_TAG_NONE); -} - -void -hb_face_set_index (hb_face_t *face, - unsigned int index) -{ - if (hb_object_is_inert (face)) - return; - - face->index = index; -} - -unsigned int -hb_face_get_index (hb_face_t *face) -{ - return face->index; -} - -void -hb_face_set_upem (hb_face_t *face, - unsigned int upem) -{ - if (hb_object_is_inert (face)) - return; - - face->upem = upem; -} - -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); -} - -void -hb_face_set_glyph_count (hb_face_t *face, - unsigned int glyph_count) -{ - if (hb_object_is_inert (face)) - return; - - face->num_glyphs = glyph_count; -} - -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); -} - - -/* * hb_font_t */ +/** + * hb_font_create: (Xconstructor) + * @face: a face. + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_font_t * hb_font_create (hb_face_t *face) { @@ -797,6 +866,16 @@ hb_font_create (hb_face_t *face) return font; } +/** + * hb_font_create_sub_font: + * @parent: parent font. + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_font_t * hb_font_create_sub_font (hb_font_t *parent) { @@ -819,6 +898,15 @@ hb_font_create_sub_font (hb_font_t *parent) return font; } +/** + * hb_font_get_empty: + * + * + * + * Return value: (transfer full) + * + * Since: 1.0 + **/ hb_font_t * hb_font_get_empty (void) { @@ -850,12 +938,30 @@ hb_font_get_empty (void) return const_cast<hb_font_t *> (&_hb_font_nil); } +/** + * hb_font_reference: (skip) + * @font: a font. + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_font_t * hb_font_reference (hb_font_t *font) { return hb_object_reference (font); } +/** + * hb_font_destroy: (skip) + * @font: a font. + * + * + * + * Since: 1.0 + **/ void hb_font_destroy (hb_font_t *font) { @@ -875,6 +981,20 @@ hb_font_destroy (hb_font_t *font) free (font); } +/** + * hb_font_set_user_data: (skip) + * @font: a font. + * @key: + * @data: + * @destroy: + * @replace: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_set_user_data (hb_font_t *font, hb_user_data_key_t *key, @@ -885,6 +1005,17 @@ hb_font_set_user_data (hb_font_t *font, return hb_object_set_user_data (font, key, data, destroy, replace); } +/** + * hb_font_get_user_data: (skip) + * @font: a font. + * @key: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ void * hb_font_get_user_data (hb_font_t *font, hb_user_data_key_t *key) @@ -892,27 +1023,65 @@ hb_font_get_user_data (hb_font_t *font, return hb_object_get_user_data (font, key); } +/** + * hb_font_make_immutable: + * @font: a font. + * + * + * + * Since: 1.0 + **/ void hb_font_make_immutable (hb_font_t *font) { - if (hb_object_is_inert (font)) + if (unlikely (hb_object_is_inert (font))) return; font->immutable = true; } +/** + * hb_font_is_immutable: + * @font: a font. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_font_is_immutable (hb_font_t *font) { return font->immutable; } +/** + * hb_font_get_parent: + * @font: a font. + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ hb_font_t * hb_font_get_parent (hb_font_t *font) { return font->parent; } +/** + * hb_font_get_face: + * @font: a font. + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ hb_face_t * hb_font_get_face (hb_font_t *font) { @@ -920,15 +1089,26 @@ hb_font_get_face (hb_font_t *font) } +/** + * hb_font_set_funcs: + * @font: a font. + * @klass: (closure font_data) (destroy destroy) (scope notified): + * @font_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_font_set_funcs (hb_font_t *font, hb_font_funcs_t *klass, - void *user_data, + void *font_data, hb_destroy_func_t destroy) { if (font->immutable) { if (destroy) - destroy (user_data); + destroy (font_data); return; } @@ -941,30 +1121,50 @@ hb_font_set_funcs (hb_font_t *font, hb_font_funcs_reference (klass); hb_font_funcs_destroy (font->klass); font->klass = klass; - font->user_data = user_data; + font->user_data = font_data; font->destroy = destroy; } +/** + * hb_font_set_funcs_data: + * @font: a font. + * @font_data: (destroy destroy) (scope notified): + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_font_set_funcs_data (hb_font_t *font, - void *user_data, + void *font_data, hb_destroy_func_t destroy) { /* Destroy user_data? */ if (font->immutable) { if (destroy) - destroy (user_data); + destroy (font_data); return; } if (font->destroy) font->destroy (font->user_data); - font->user_data = user_data; + font->user_data = font_data; font->destroy = destroy; } +/** + * hb_font_set_scale: + * @font: a font. + * @x_scale: + * @y_scale: + * + * + * + * Since: 1.0 + **/ void hb_font_set_scale (hb_font_t *font, int x_scale, @@ -977,6 +1177,16 @@ hb_font_set_scale (hb_font_t *font, font->y_scale = y_scale; } +/** + * hb_font_get_scale: + * @font: a font. + * @x_scale: (out): + * @y_scale: (out): + * + * + * + * Since: 1.0 + **/ void hb_font_get_scale (hb_font_t *font, int *x_scale, @@ -986,6 +1196,16 @@ hb_font_get_scale (hb_font_t *font, if (y_scale) *y_scale = font->y_scale; } +/** + * hb_font_set_ppem: + * @font: a font. + * @x_ppem: + * @y_ppem: + * + * + * + * Since: 1.0 + **/ void hb_font_set_ppem (hb_font_t *font, unsigned int x_ppem, @@ -998,6 +1218,16 @@ hb_font_set_ppem (hb_font_t *font, font->y_ppem = y_ppem; } +/** + * hb_font_get_ppem: + * @font: a font. + * @x_ppem: (out): + * @y_ppem: (out): + * + * + * + * Since: 1.0 + **/ void hb_font_get_ppem (hb_font_t *font, unsigned int *x_ppem, diff --git a/src/hb-font.h b/src/hb-font.h index 88d4895..7273db4 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -32,86 +32,13 @@ #define HB_FONT_H #include "hb-common.h" -#include "hb-blob.h" +#include "hb-face.h" HB_BEGIN_DECLS -typedef struct hb_face_t hb_face_t; typedef struct hb_font_t hb_font_t; -/* - * hb_face_t - */ - -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_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 * -hb_face_get_empty (void); - -hb_face_t * -hb_face_reference (hb_face_t *face); - -void -hb_face_destroy (hb_face_t *face); - -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); - - -void * -hb_face_get_user_data (hb_face_t *face, - hb_user_data_key_t *key); - -void -hb_face_make_immutable (hb_face_t *face); - -hb_bool_t -hb_face_is_immutable (hb_face_t *face); - - -hb_blob_t * -hb_face_reference_table (hb_face_t *face, - hb_tag_t tag); - -hb_blob_t * -hb_face_reference_blob (hb_face_t *face); - -void -hb_face_set_index (hb_face_t *face, - unsigned int index); - -unsigned int -hb_face_get_index (hb_face_t *face); - -void -hb_face_set_upem (hb_face_t *face, - unsigned int upem); - -unsigned int -hb_face_get_upem (hb_face_t *face); - -void -hb_face_set_glyph_count (hb_face_t *face, - unsigned int glyph_count); - -unsigned int -hb_face_get_glyph_count (hb_face_t *face); - /* * hb_font_funcs_t @@ -212,54 +139,180 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * /* func setters */ +/** + * hb_font_funcs_set_glyph_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_func_t glyph_func, + hb_font_get_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: 1.0 + **/ 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: 1.0 + **/ 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: 1.0 + **/ 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: 1.0 + **/ 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: 1.0 + **/ 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: 1.0 + **/ 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: 1.0 + **/ 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: 1.0 + **/ 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: 1.0 + **/ void hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_name_func_t glyph_func, + 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: 1.0 + **/ void hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_from_name_func_t glyph_func, + hb_font_get_glyph_from_name_func_t func, void *user_data, hb_destroy_func_t destroy); diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 6198185..16bf51f 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -53,14 +53,7 @@ * * - We don't handle / allow for emboldening / obliqueing. * - * - Rounding, etc? - * - * - In the future, we should add constructors to create fonts in font space. - * - * - I believe transforms are not correctly implemented. FreeType does not - * provide any API to get to the transform/delta set on the face. :( - * - * - Always use FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH? + * - In the future, we should add constructors to create fonts in font space? * * - FT_Load_Glyph() is exteremely costly. Do something about it? */ @@ -80,8 +73,7 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED, #ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX if (unlikely (variation_selector)) { *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); - if (*glyph) - return true; + return *glyph != 0; } #endif @@ -102,7 +94,7 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED, if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v))) return 0; - return v >> 10; + return (v + (1<<9)) >> 10; } static hb_position_t @@ -120,7 +112,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED, /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates * have a Y growing upward. Hence the extra negation. */ - return -v >> 10; + return (-v + (1<<9)) >> 10; } static hb_bool_t @@ -242,8 +234,8 @@ hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED, FT_Face ft_face = (FT_Face) font_data; hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size); - if (!ret || (size && !*name)) - snprintf (name, size, "gid%u", glyph); + if (ret && (size && !*name)) + ret = false; return ret; } @@ -268,6 +260,15 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED, *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; } @@ -318,7 +319,16 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) buffer, free); } - +/** + * hb_ft_face_create: + * @ft_face: (destroy destroy) (scope notified): + * @destroy: + * + * + * + * Return value: (transfer full): + * Since: 1.0 + **/ hb_face_t * hb_ft_face_create (FT_Face ft_face, hb_destroy_func_t destroy) @@ -354,6 +364,15 @@ 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: 1.0 + **/ hb_face_t * hb_ft_face_create_cached (FT_Face ft_face) { @@ -375,6 +394,16 @@ _do_nothing (void) } +/** + * hb_ft_font_create: + * @ft_face: (destroy destroy) (scope notified): + * @destroy: + * + * + * + * Return value: (transfer full): + * Since: 1.0 + **/ hb_font_t * hb_ft_font_create (FT_Face ft_face, hb_destroy_func_t destroy) @@ -389,8 +418,8 @@ hb_ft_font_create (FT_Face ft_face, _hb_ft_get_font_funcs (), ft_face, (hb_destroy_func_t) _do_nothing); hb_font_set_scale (font, - ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM) >> 16, - ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM) >> 16); + (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16), + (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16)); hb_font_set_ppem (font, ft_face->size->metrics.x_ppem, ft_face->size->metrics.y_ppem); @@ -403,7 +432,7 @@ hb_ft_font_create (FT_Face ft_face, static FT_Library ft_library; -static +static inline void free_ft_library (void) { FT_Done_FreeType (ft_library); @@ -426,7 +455,7 @@ retry: goto retry; } -#ifdef HAVE_ATEXIT +#ifdef HB_USE_ATEXIT atexit (free_ft_library); /* First person registers atexit() callback. */ #endif } diff --git a/src/hb-glib.cc b/src/hb-glib.cc index 676e660..af43cab 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -77,7 +77,7 @@ glib_script_to_script[] = HB_SCRIPT_THAANA, HB_SCRIPT_THAI, HB_SCRIPT_TIBETAN, - HB_SCRIPT_CANADIAN_ABORIGINAL, + HB_SCRIPT_CANADIAN_SYLLABICS, HB_SCRIPT_YI, HB_SCRIPT_TAGALOG, HB_SCRIPT_HANUNOO, @@ -340,7 +340,7 @@ hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED, 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); + 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 diff --git a/src/hb-gobject-enums.cc.tmpl b/src/hb-gobject-enums.cc.tmpl index 05abd89..ca458a3 100644 --- a/src/hb-gobject-enums.cc.tmpl +++ b/src/hb-gobject-enums.cc.tmpl @@ -45,13 +45,12 @@ /*** END file-production ***/ /*** BEGIN value-header ***/ -inline static /* TODO(behdad) disable these for now until we fix them... */ GType @enum_name@_get_type (void) { - static volatile gsize g_define_type_id__volatile = 0; + static gsize type_id = 0; - if (g_once_init_enter (&g_define_type_id__volatile)) + if (g_once_init_enter (&type_id)) { static const G@Type@Value values[] = { /*** END value-header ***/ @@ -63,12 +62,12 @@ GType /*** BEGIN value-tail ***/ { 0, NULL, NULL } }; - GType g_define_type_id = + GType id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + g_once_init_leave (&type_id, id); } - return g_define_type_id__volatile; + return type_id; } /*** END value-tail ***/ diff --git a/src/hb-gobject-enums.h.tmpl b/src/hb-gobject-enums.h.tmpl new file mode 100644 index 0000000..6ecda06 --- /dev/null +++ b/src/hb-gobject-enums.h.tmpl @@ -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 ***/ +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 ***/ diff --git a/src/hb-gobject-structs.cc b/src/hb-gobject-structs.cc index cec4854..2451b66 100644 --- a/src/hb-gobject-structs.cc +++ b/src/hb-gobject-structs.cc @@ -37,27 +37,84 @@ #include "hb-gobject.h" -#define _HB_DEFINE_BOXED_TYPE(Name,underscore_name,copy_func,free_func) \ +#define HB_DEFINE_BOXED_TYPE(name,copy_func,free_func) \ GType \ -underscore_name##_get_type (void) \ +hb_gobject_##name##_get_type (void) \ { \ - static volatile gsize type = 0; \ - if (g_once_init_enter (&type)) { \ - GType t = g_boxed_type_register_static (g_intern_static_string (#Name), \ - (GBoxedCopyFunc) copy_func, \ - (GBoxedFreeFunc) free_func); \ - g_once_init_leave (&type, t); \ + 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; \ + return type_id; \ } -#define HB_DEFINE_BOXED_TYPE(name) \ - _HB_DEFINE_BOXED_TYPE (hb_##name, hb_gobject_##name, hb_##name##_reference, hb_##name##_destroy); +#define HB_DEFINE_OBJECT_TYPE(name) \ + HB_DEFINE_BOXED_TYPE (name, hb_##name##_reference, hb_##name##_destroy); -HB_DEFINE_BOXED_TYPE (buffer) -HB_DEFINE_BOXED_TYPE (blob) -HB_DEFINE_BOXED_TYPE (face) -HB_DEFINE_BOXED_TYPE (font) -HB_DEFINE_BOXED_TYPE (font_funcs) -HB_DEFINE_BOXED_TYPE (unicode_funcs) +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) + +static hb_feature_t *feature_reference (hb_feature_t *g) +{ + hb_feature_t *c = (hb_feature_t *) calloc (1, sizeof (hb_feature_t)); + if (unlikely (!c)) return NULL; + *c = *g; + return c; +} +static void feature_destroy (hb_feature_t *g) { free (g); } +HB_DEFINE_BOXED_TYPE (feature, feature_reference, feature_destroy) + +static hb_glyph_info_t *glyph_info_reference (hb_glyph_info_t *g) +{ + hb_glyph_info_t *c = (hb_glyph_info_t *) calloc (1, sizeof (hb_glyph_info_t)); + if (unlikely (!c)) return NULL; + *c = *g; + return c; +} +static void glyph_info_destroy (hb_glyph_info_t *g) { free (g); } +HB_DEFINE_BOXED_TYPE (glyph_info, glyph_info_reference, glyph_info_destroy) + +static hb_glyph_position_t *glyph_position_reference (hb_glyph_position_t *g) +{ + hb_glyph_position_t *c = (hb_glyph_position_t *) calloc (1, sizeof (hb_glyph_position_t)); + if (unlikely (!c)) return NULL; + *c = *g; + return c; +} +static void glyph_position_destroy (hb_glyph_position_t *g) { free (g); } +HB_DEFINE_BOXED_TYPE (glyph_position, glyph_position_reference, glyph_position_destroy) + +static hb_segment_properties_t *segment_properties_reference (hb_segment_properties_t *g) +{ + hb_segment_properties_t *c = (hb_segment_properties_t *) calloc (1, sizeof (hb_segment_properties_t)); + if (unlikely (!c)) return NULL; + *c = *g; + return c; +} +static void segment_properties_destroy (hb_segment_properties_t *g) { free (g); } +HB_DEFINE_BOXED_TYPE (segment_properties, segment_properties_reference, segment_properties_destroy) + +static hb_user_data_key_t user_data_key_reference (hb_user_data_key_t l) { return l; } +static void user_data_key_destroy (hb_user_data_key_t l) { } +HB_DEFINE_BOXED_TYPE (user_data_key, user_data_key_reference, user_data_key_destroy) + + +static hb_language_t *language_reference (hb_language_t *l) +{ + hb_language_t *c = (hb_language_t *) calloc (1, sizeof (hb_language_t)); + if (unlikely (!c)) return NULL; + *c = *l; + return c; +} +static void language_destroy (hb_language_t *l) { free (l); } +HB_DEFINE_BOXED_TYPE (language, language_reference, language_destroy) diff --git a/src/hb-gobject-structs.h b/src/hb-gobject-structs.h new file mode 100644 index 0000000..4a88d56 --- /dev/null +++ b/src/hb-gobject-structs.h @@ -0,0 +1,95 @@ +/* + * 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 */ + +GType hb_gobject_blob_get_type (void); +#define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) + +GType hb_gobject_buffer_get_type (void); +#define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) + +GType hb_gobject_face_get_type (void); +#define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) + +GType hb_gobject_font_get_type (void); +#define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) + +GType hb_gobject_font_funcs_get_type (void); +#define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) + +GType hb_gobject_set_get_type (void); +#define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ()) + +GType hb_gobject_shape_plan_get_type (void); +#define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) + +GType hb_gobject_unicode_funcs_get_type (void); +#define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) + +/* Value types */ + +GType hb_gobject_feature_get_type (void); +#define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ()) + +GType hb_gobject_glyph_info_get_type (void); +#define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ()) + +GType hb_gobject_glyph_position_get_type (void); +#define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ()) + +GType hb_gobject_segment_properties_get_type (void); +#define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ()) + +GType hb_gobject_user_data_key_get_type (void); +#define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ()) + +/* Currently gobject-introspection doesn't understand that hb_language_t + * can be passed by-value. As such we box it up. May remove in the + * future. + * + * https://bugzilla.gnome.org/show_bug.cgi?id=707656 + */ +GType hb_gobject_language_get_type (void); +#define HB_GOBJECT_TYPE_LANGUAGE (hb_gobject_language_get_type ()) + +HB_END_DECLS + +#endif /* HB_GOBJECT_H */ diff --git a/src/hb-gobject.h b/src/hb-gobject.h index 4f23fdd..ea1bd25 100644 --- a/src/hb-gobject.h +++ b/src/hb-gobject.h @@ -26,44 +26,15 @@ #ifndef HB_GOBJECT_H #define HB_GOBJECT_H +#define HB_GOBJECT_H_IN #include "hb.h" -#include <glib-object.h> +#include "hb-gobject-enums.h" +#include "hb-gobject-structs.h" HB_BEGIN_DECLS - - -/* Objects */ - -#define HB_GOBJECT_TYPE_BLOB hb_gobject_blob_get_type () -GType -hb_gobject_blob_get_type (void); - -#define HB_GOBJECT_TYPE_BUFFER hb_gobject_buffer_get_type () -GType -hb_gobject_buffer_get_type (void); - -#define HB_GOBJECT_TYPE_FACE hb_gobject_face_get_type () -GType -hb_gobject_face_get_type (void); - -#define HB_GOBJECT_TYPE_FONT hb_gobject_font_get_type () -GType -hb_gobject_font_get_type (void); - -#define HB_GOBJECT_TYPE_FONT_FUNCS hb_gobject_font_funcs_get_type () -GType -hb_gobject_font_funcs_get_type (void); - -#define HB_GOBJECT_TYPE_UNICODE_FUNCS hb_gobject_unicode_funcs_get_type () -GType -hb_gobject_unicode_funcs_get_type (void); - - -/* Enums */ - - HB_END_DECLS +#undef HB_GOBJECT_H_IN #endif /* HB_GOBJECT_H */ diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index 16ef9a4..807c330 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -30,12 +30,9 @@ #define hb_graphite2_shaper_font_data_t gr_font #include "hb-shaper-impl-private.hh" -#include <graphite2/Font.h> -#include <graphite2/Segment.h> - #include "hb-graphite2.h" -#include "hb-ot-tag.h" +#include <graphite2/Segment.h> HB_SHAPER_DATA_ENSURE_DECLARE(graphite2, face) @@ -110,7 +107,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face) 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)) - hb_blob_destroy (silf_blob); + return NULL; data->face = face; data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll); @@ -212,6 +209,7 @@ struct hb_graphite2_cluster_t { unsigned int num_chars; unsigned int base_glyph; unsigned int num_glyphs; + unsigned int cluster; }; hb_bool_t @@ -226,7 +224,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, gr_font *grfont = HB_SHAPER_DATA_GET (font); const char *lang = hb_language_to_string (hb_buffer_get_language (buffer)); - const char *lang_end = strchr (lang, '-'); + 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); @@ -244,14 +242,9 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, float curradvx = 0., curradvy = 0.; unsigned int scratch_size; - char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); - -#define ALLOCATE_ARRAY(Type, name, len) \ - Type *name = (Type *) scratch; \ - scratch += (len) * sizeof ((name)[0]); \ - scratch_size -= (len) * sizeof ((name)[0]); + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); - ALLOCATE_ARRAY (uint32_t, chars, buffer->len); + uint32_t *chars = (uint32_t *) scratch; for (unsigned int i = 0; i < buffer->len; ++i) chars[i] = buffer->info[i].codepoint; @@ -277,25 +270,37 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, return false; } - scratch = (char *) buffer->get_scratch_buffer (&scratch_size); - while ((sizeof (hb_graphite2_cluster_t) * buffer->len + - sizeof (hb_codepoint_t) * glyph_count) > scratch_size) + 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) { - buffer->ensure (buffer->allocated * 2); - if (unlikely (buffer->in_error)) { + if (unlikely (!buffer->ensure (buffer->allocated * 2))) + { if (feats) gr_featureval_destroy (feats); gr_seg_destroy (seg); return false; } - scratch = (char *) buffer->get_scratch_buffer (&scratch_size); + 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; 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); @@ -313,6 +318,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, { 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; @@ -332,7 +338,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, { hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j]; info->codepoint = gids[clusters[i].base_glyph + j]; - info->cluster = gr_cinfo_base(gr_seg_cinfo(seg, clusters[i].base_char)); + info->cluster = clusters[i].cluster; } } buffer->len = glyph_count; diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h index bea68f9..3eae54a 100644 --- a/src/hb-graphite2.h +++ b/src/hb-graphite2.h @@ -28,6 +28,8 @@ #include "hb.h" +#include <graphite2/Font.h> + HB_BEGIN_DECLS diff --git a/src/hb-icu-le.cc b/src/hb-icu-le.cc deleted file mode 100644 index c05d330..0000000 --- a/src/hb-icu-le.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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 - */ - -#define HB_SHAPER icu_le -#define hb_icu_le_shaper_font_data_t PortableFontInstance -#include "hb-shaper-impl-private.hh" - -#include "hb-icu-le/PortableFontInstance.h" - -#include "layout/loengine.h" -#include "unicode/unistr.h" - -#include "hb-icu.h" - - -/* - * shaper face data - */ - -struct hb_icu_le_shaper_face_data_t {}; - -hb_icu_le_shaper_face_data_t * -_hb_icu_le_shaper_face_data_create (hb_face_t *face HB_UNUSED) -{ - return (hb_icu_le_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data HB_UNUSED) -{ -} - - -/* - * shaper font data - */ - -hb_icu_le_shaper_font_data_t * -_hb_icu_le_shaper_font_data_create (hb_font_t *font) -{ - LEErrorCode status = LE_NO_ERROR; - hb_icu_le_shaper_font_data_t *data = new PortableFontInstance (font->face, - font->x_scale, - font->y_scale, - status); - if (status != LE_NO_ERROR) { - delete (data); - return NULL; - } - - return data; -} - -void -_hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data) -{ - delete (data); -} - - -/* - * shaper shape_plan data - */ - -struct hb_icu_le_shaper_shape_plan_data_t {}; - -hb_icu_le_shaper_shape_plan_data_t * -_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features, - unsigned int num_user_features) -{ - return (hb_icu_le_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_icu_le_shaper_shape_plan_data_destroy (hb_icu_le_shaper_shape_plan_data_t *data) -{ -} - - -/* - * shaper - */ - -hb_bool_t -_hb_icu_le_shape (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) -{ - LEFontInstance *font_instance = HB_SHAPER_DATA_GET (font); - le_int32 script_code = hb_icu_script_from_script (shape_plan->props.script); - le_int32 language_code = -1 /* TODO */; - le_int32 typography_flags = 3; /* Needed for ligatures and kerning */ - LEErrorCode status = LE_NO_ERROR; - le_engine *le = le_create ((const le_font *) font_instance, - script_code, - language_code, - typography_flags, - &status); - if (status != LE_NO_ERROR) - { le_close (le); return false; } - -retry: - - unsigned int scratch_size; - char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); - -#define ALLOCATE_ARRAY(Type, name, len) \ - Type *name = (Type *) scratch; \ - scratch += (len) * sizeof ((name)[0]); \ - scratch_size -= (len) * sizeof ((name)[0]); - - ALLOCATE_ARRAY (LEUnicode, chars, buffer->len); - ALLOCATE_ARRAY (unsigned int, clusters, buffer->len); - - /* XXX Use UTF-16 decoder! */ - for (unsigned int i = 0; i < buffer->len; i++) { - chars[i] = buffer->info[i].codepoint; - clusters[i] = buffer->info[i].cluster; - } - - unsigned int glyph_count = le_layoutChars (le, - chars, - 0, - buffer->len, - buffer->len, - HB_DIRECTION_IS_BACKWARD (buffer->props.direction), - 0., 0., - &status); - if (status != LE_NO_ERROR) - { le_close (le); return false; } - - unsigned int num_glyphs = scratch_size / (sizeof (LEGlyphID) + - sizeof (le_int32) + - sizeof (float) * 2); - - if (unlikely (glyph_count >= num_glyphs || glyph_count > buffer->allocated)) { - buffer->ensure (buffer->allocated * 2); - if (buffer->in_error) - { le_close (le); return false; } - goto retry; - } - - ALLOCATE_ARRAY (LEGlyphID, glyphs, glyph_count); - ALLOCATE_ARRAY (le_int32, indices, glyph_count); - ALLOCATE_ARRAY (float, positions, glyph_count * 2 + 2); - - le_getGlyphs (le, glyphs, &status); - le_getCharIndices (le, indices, &status); - le_getGlyphPositions (le, positions, &status); - -#undef ALLOCATE_ARRAY - - /* Ok, we've got everything we need, now compose output buffer, - * very, *very*, carefully! */ - - unsigned int j = 0; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < glyph_count; i++) - { - if (glyphs[i] >= 0xFFFE) - continue; - - info[j].codepoint = glyphs[i]; - info[j].cluster = clusters[indices[i]]; - - /* icu-le doesn't seem to have separate advance values. */ - info[j].mask = positions[2 * i + 2] - positions[2 * i]; - info[j].var1.u32 = 0; - info[j].var2.u32 = -positions[2 * i + 1]; - - j++; - } - buffer->len = j; - - buffer->clear_positions (); - - for (unsigned int i = 0; i < buffer->len; i++) { - hb_glyph_info_t *info = &buffer->info[i]; - hb_glyph_position_t *pos = &buffer->pos[i]; - - /* TODO vertical */ - pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; - } - - le_close (le); - return true; -} diff --git a/src/hb-icu-le/COPYING b/src/hb-icu-le/COPYING deleted file mode 100644 index 8080968..0000000 --- a/src/hb-icu-le/COPYING +++ /dev/null @@ -1,2 +0,0 @@ -The contents of this directory are licensed under the ICU license. -See file license.html. diff --git a/src/hb-icu-le/FontTableCache.cpp b/src/hb-icu-le/FontTableCache.cpp deleted file mode 100644 index 93db6cc..0000000 --- a/src/hb-icu-le/FontTableCache.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - ********************************************************************** - * Copyright (C) 2003-2008, International Business Machines - * Corporation and others. All Rights Reserved. - ********************************************************************** - */ - -#include "layout/LETypes.h" - -#include "letest.h" -#include "FontTableCache.h" - -#define TABLE_CACHE_INIT 5 -#define TABLE_CACHE_GROW 5 - -struct FontTableCacheEntry -{ - LETag tag; - hb_blob_t *blob; -}; - -FontTableCache::FontTableCache() - : fTableCacheCurr(0), fTableCacheSize(TABLE_CACHE_INIT) -{ - fTableCache = NEW_ARRAY(FontTableCacheEntry, fTableCacheSize); - - if (fTableCache == NULL) { - fTableCacheSize = 0; - return; - } - - for (int i = 0; i < fTableCacheSize; i += 1) { - fTableCache[i].tag = 0; - fTableCache[i].blob = NULL; - } -} - -FontTableCache::~FontTableCache() -{ - for (int i = fTableCacheCurr - 1; i >= 0; i -= 1) { - hb_blob_destroy(fTableCache[i].blob); - - fTableCache[i].tag = 0; - fTableCache[i].blob = NULL; - } - - fTableCacheCurr = 0; - - DELETE_ARRAY(fTableCache); -} - -void FontTableCache::freeFontTable(hb_blob_t *blob) const -{ - hb_blob_destroy(blob); -} - -const void *FontTableCache::find(LETag tableTag) const -{ - for (int i = 0; i < fTableCacheCurr; i += 1) { - if (fTableCache[i].tag == tableTag) { - return hb_blob_get_data(fTableCache[i].blob, NULL); - } - } - - hb_blob_t *blob = readFontTable(tableTag); - - ((FontTableCache *) this)->add(tableTag, blob); - - return hb_blob_get_data (blob, NULL); -} - -void FontTableCache::add(LETag tableTag, hb_blob_t *blob) -{ - if (fTableCacheCurr >= fTableCacheSize) { - le_int32 newSize = fTableCacheSize + TABLE_CACHE_GROW; - - fTableCache = (FontTableCacheEntry *) GROW_ARRAY(fTableCache, newSize); - - for (le_int32 i = fTableCacheSize; i < newSize; i += 1) { - fTableCache[i].tag = 0; - fTableCache[i].blob = NULL; - } - - fTableCacheSize = newSize; - } - - fTableCache[fTableCacheCurr].tag = tableTag; - fTableCache[fTableCacheCurr].blob = blob; - - fTableCacheCurr += 1; -} diff --git a/src/hb-icu-le/FontTableCache.h b/src/hb-icu-le/FontTableCache.h deleted file mode 100644 index f956f88..0000000 --- a/src/hb-icu-le/FontTableCache.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - ********************************************************************** - * Copyright (C) 2003-2008, International Business Machines - * Corporation and others. All Rights Reserved. - ********************************************************************** - */ - -#ifndef __FONTTABLECACHE_H - -#define __FONTTABLECACHE_H - -#define HB_H_IN -#include <hb-blob.h> - -#include "layout/LETypes.h" -#include "letest.h" - -HB_BEGIN_VISIBILITY - -U_NAMESPACE_USE - -struct FontTableCacheEntry; - -class FontTableCache -{ -public: - FontTableCache(); - - virtual ~FontTableCache(); - - const void *find(LETag tableTag) const; - -protected: - virtual hb_blob_t *readFontTable(LETag tableTag) const = 0; - virtual void freeFontTable(hb_blob_t *blob) const; - -private: - - void add(LETag tableTag, hb_blob_t *blob); - - FontTableCacheEntry *fTableCache; - le_int32 fTableCacheCurr; - le_int32 fTableCacheSize; -}; - -HB_END_VISIBILITY - -#endif diff --git a/src/hb-icu-le/Makefile.am b/src/hb-icu-le/Makefile.am deleted file mode 100644 index e3b103c..0000000 --- a/src/hb-icu-le/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -## Process this file with automake to produce Makefile.in - -noinst_LTLIBRARIES = libhb-icu-le.la - - -libhb_icu_le_la_SOURCES = \ - FontTableCache.cpp \ - FontTableCache.h \ - PortableFontInstance.cpp \ - PortableFontInstance.h \ - cmaps.cpp \ - cmaps.h \ - letest.h \ - sfnt.h -libhb_icu_le_la_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/src \ - -I$(top_builddir)/src \ - $(ICU_LE_CFLAGS) -libhb_icu_le_la_LIBADD = \ - $(ICU_LE_LIBS) - -EXTRA_DIST = README license.html COPYING - --include $(top_srcdir)/git.mk diff --git a/src/hb-icu-le/Makefile.in b/src/hb-icu-le/Makefile.in deleted file mode 100644 index 0f59f13..0000000 --- a/src/hb-icu-le/Makefile.in +++ /dev/null @@ -1,593 +0,0 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/hb-icu-le -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - COPYING -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -am__DEPENDENCIES_1 = -libhb_icu_le_la_DEPENDENCIES = $(am__DEPENDENCIES_1) -am_libhb_icu_le_la_OBJECTS = libhb_icu_le_la-FontTableCache.lo \ - libhb_icu_le_la-PortableFontInstance.lo \ - libhb_icu_le_la-cmaps.lo -libhb_icu_le_la_OBJECTS = $(am_libhb_icu_le_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libhb_icu_le_la_SOURCES) -DIST_SOURCES = $(libhb_icu_le_la_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CAIRO_CFLAGS = @CAIRO_CFLAGS@ -CAIRO_FT_CFLAGS = @CAIRO_FT_CFLAGS@ -CAIRO_FT_LIBS = @CAIRO_FT_LIBS@ -CAIRO_LIBS = @CAIRO_LIBS@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CORETEXT_CFLAGS = @CORETEXT_CFLAGS@ -CORETEXT_LIBS = @CORETEXT_LIBS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ -FREETYPE_LIBS = @FREETYPE_LIBS@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ -GOBJECT_LIBS = @GOBJECT_LIBS@ -GRAPHITE2_CFLAGS = @GRAPHITE2_CFLAGS@ -GRAPHITE2_LIBS = @GRAPHITE2_LIBS@ -GREP = @GREP@ -GTHREAD_CFLAGS = @GTHREAD_CFLAGS@ -GTHREAD_LIBS = @GTHREAD_LIBS@ -HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@ -HB_VERSION = @HB_VERSION@ -HB_VERSION_MAJOR = @HB_VERSION_MAJOR@ -HB_VERSION_MICRO = @HB_VERSION_MICRO@ -HB_VERSION_MINOR = @HB_VERSION_MINOR@ -ICU_CFLAGS = @ICU_CFLAGS@ -ICU_LE_CFLAGS = @ICU_LE_CFLAGS@ -ICU_LE_LIBS = @ICU_LE_LIBS@ -ICU_LIBS = @ICU_LIBS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -UNISCRIBE_CFLAGS = @UNISCRIBE_CFLAGS@ -UNISCRIBE_LIBS = @UNISCRIBE_LIBS@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = libhb-icu-le.la -libhb_icu_le_la_SOURCES = \ - FontTableCache.cpp \ - FontTableCache.h \ - PortableFontInstance.cpp \ - PortableFontInstance.h \ - cmaps.cpp \ - cmaps.h \ - letest.h \ - sfnt.h - -libhb_icu_le_la_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/src \ - -I$(top_builddir)/src \ - $(ICU_LE_CFLAGS) - -libhb_icu_le_la_LIBADD = \ - $(ICU_LE_LIBS) - -EXTRA_DIST = README license.html COPYING -all: all-am - -.SUFFIXES: -.SUFFIXES: .cpp .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits src/hb-icu-le/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnits src/hb-icu-le/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libhb-icu-le.la: $(libhb_icu_le_la_OBJECTS) $(libhb_icu_le_la_DEPENDENCIES) $(EXTRA_libhb_icu_le_la_DEPENDENCIES) - $(AM_V_CXXLD)$(CXXLINK) $(libhb_icu_le_la_OBJECTS) $(libhb_icu_le_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_icu_le_la-FontTableCache.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_icu_le_la-PortableFontInstance.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_icu_le_la-cmaps.Plo@am__quote@ - -.cpp.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cpp.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cpp.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -libhb_icu_le_la-FontTableCache.lo: FontTableCache.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_icu_le_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhb_icu_le_la-FontTableCache.lo -MD -MP -MF $(DEPDIR)/libhb_icu_le_la-FontTableCache.Tpo -c -o libhb_icu_le_la-FontTableCache.lo `test -f 'FontTableCache.cpp' || echo '$(srcdir)/'`FontTableCache.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_icu_le_la-FontTableCache.Tpo $(DEPDIR)/libhb_icu_le_la-FontTableCache.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FontTableCache.cpp' object='libhb_icu_le_la-FontTableCache.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_icu_le_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhb_icu_le_la-FontTableCache.lo `test -f 'FontTableCache.cpp' || echo '$(srcdir)/'`FontTableCache.cpp - -libhb_icu_le_la-PortableFontInstance.lo: PortableFontInstance.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_icu_le_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhb_icu_le_la-PortableFontInstance.lo -MD -MP -MF $(DEPDIR)/libhb_icu_le_la-PortableFontInstance.Tpo -c -o libhb_icu_le_la-PortableFontInstance.lo `test -f 'PortableFontInstance.cpp' || echo '$(srcdir)/'`PortableFontInstance.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_icu_le_la-PortableFontInstance.Tpo $(DEPDIR)/libhb_icu_le_la-PortableFontInstance.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PortableFontInstance.cpp' object='libhb_icu_le_la-PortableFontInstance.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_icu_le_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhb_icu_le_la-PortableFontInstance.lo `test -f 'PortableFontInstance.cpp' || echo '$(srcdir)/'`PortableFontInstance.cpp - -libhb_icu_le_la-cmaps.lo: cmaps.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_icu_le_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhb_icu_le_la-cmaps.lo -MD -MP -MF $(DEPDIR)/libhb_icu_le_la-cmaps.Tpo -c -o libhb_icu_le_la-cmaps.lo `test -f 'cmaps.cpp' || echo '$(srcdir)/'`cmaps.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_icu_le_la-cmaps.Tpo $(DEPDIR)/libhb_icu_le_la-cmaps.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cmaps.cpp' object='libhb_icu_le_la-cmaps.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_icu_le_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhb_icu_le_la-cmaps.lo `test -f 'cmaps.cpp' || echo '$(srcdir)/'`cmaps.cpp - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - --include $(top_srcdir)/git.mk - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/hb-icu-le/PortableFontInstance.cpp b/src/hb-icu-le/PortableFontInstance.cpp deleted file mode 100644 index c38e2b1..0000000 --- a/src/hb-icu-le/PortableFontInstance.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - ******************************************************************************* - * - * Copyright (C) 1999-2008, International Business Machines - * Corporation and others. All Rights Reserved. - * - ******************************************************************************* - * file name: PortableFontInstance.cpp - * - * created on: 11/22/1999 - * created by: Eric R. Mader - */ - -#include <stdio.h> - -#include "layout/LETypes.h" -#include "layout/LEFontInstance.h" -#include "layout/LESwaps.h" - -#include "PortableFontInstance.h" - -#include "letest.h" -#include "sfnt.h" - -#include <string.h> - - -PortableFontInstance::PortableFontInstance(hb_face_t *face, float xScale, float yScale, LEErrorCode &status) - : fFace(face), fXScale(xScale), fYScale(yScale), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0), - fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0) -{ - if (LE_FAILURE(status)) { - return; - } - - const LETag hheaTag = LE_HHEA_TABLE_TAG; - const HHEATable *hheaTable = NULL; - - fUnitsPerEM = hb_face_get_upem (face); - - hheaTable = (HHEATable *) getFontTable(hheaTag); - - if (hheaTable == NULL) { - status = LE_MISSING_FONT_TABLE_ERROR; - return; - } - - fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent)); - fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent)); - fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap)); - - fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics); - - fCMAPMapper = findUnicodeMapper(); - - if (fCMAPMapper == NULL) { - status = LE_MISSING_FONT_TABLE_ERROR; - return; - } -} - -PortableFontInstance::~PortableFontInstance() -{ - if (fCMAPMapper) - delete fCMAPMapper; -} - -const void *PortableFontInstance::getFontTable(LETag tableTag) const -{ - return FontTableCache::find(tableTag); -} - -hb_blob_t *PortableFontInstance::readFontTable(LETag tableTag) const -{ - return hb_face_reference_table(fFace, tableTag); -} - -CMAPMapper *PortableFontInstance::findUnicodeMapper() -{ - LETag cmapTag = LE_CMAP_TABLE_TAG; - const CMAPTable *cmap = (CMAPTable *) getFontTable(cmapTag); - - if (cmap == NULL) { - return NULL; - } - - return CMAPMapper::createUnicodeMapper(cmap); -} - -const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const -{ - if (fNAMETable == NULL) { - LETag nameTag = LE_NAME_TABLE_TAG; - PortableFontInstance *realThis = (PortableFontInstance *) this; - - realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag); - - if (realThis->fNAMETable != NULL) { - realThis->fNameCount = SWAPW(realThis->fNAMETable->count); - realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset); - } - } - - for(le_int32 i = 0; i < fNameCount; i += 1) { - const NameRecord *nameRecord = &fNAMETable->nameRecords[i]; - - if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID && - SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) { - char *name = ((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset); - le_uint16 length = SWAPW(nameRecord->length); - char *result = NEW_ARRAY(char, length + 2); - - ARRAY_COPY(result, name, length); - result[length] = result[length + 1] = 0; - - return result; - } - } - - return NULL; -} - -const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const -{ - if (fNAMETable == NULL) { - LETag nameTag = LE_NAME_TABLE_TAG; - PortableFontInstance *realThis = (PortableFontInstance *) this; - - realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag); - - if (realThis->fNAMETable != NULL) { - realThis->fNameCount = SWAPW(realThis->fNAMETable->count); - realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset); - } - } - - for(le_int32 i = 0; i < fNameCount; i += 1) { - const NameRecord *nameRecord = &fNAMETable->nameRecords[i]; - - if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID && - SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) { - LEUnicode16 *name = (LEUnicode16 *) (((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset)); - le_uint16 length = SWAPW(nameRecord->length) / 2; - LEUnicode16 *result = NEW_ARRAY(LEUnicode16, length + 2); - - for (le_int32 c = 0; c < length; c += 1) { - result[c] = SWAPW(name[c]); - } - - result[length] = 0; - - return result; - } - } - - return NULL; -} - -void PortableFontInstance::deleteNameString(const char *name) const -{ - DELETE_ARRAY(name); -} - -void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const -{ - DELETE_ARRAY(name); -} - -void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const -{ - TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph); - - if (fHMTXTable == NULL) { - LETag maxpTag = LE_MAXP_TABLE_TAG; - LETag hmtxTag = LE_HMTX_TABLE_TAG; - const MAXPTable *maxpTable = (MAXPTable *) getFontTable(maxpTag); - PortableFontInstance *realThis = (PortableFontInstance *) this; - - if (maxpTable != NULL) { - realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs); - } - - realThis->fHMTXTable = (const HMTXTable *) getFontTable(hmtxTag); - } - - le_uint16 index = ttGlyph; - - if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) { - advance.fX = advance.fY = 0; - return; - } - - if (ttGlyph >= fNumLongHorMetrics) { - index = fNumLongHorMetrics - 1; - } - - advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth)); - advance.fY = 0; -} - -le_bool PortableFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const -{ - return FALSE; -} - -le_int32 PortableFontInstance::getUnitsPerEM() const -{ - return fUnitsPerEM; -} - -le_uint32 PortableFontInstance::getFontChecksum() const -{ - return 0; -} - -le_int32 PortableFontInstance::getAscent() const -{ - return fAscent; -} - -le_int32 PortableFontInstance::getDescent() const -{ - return fDescent; -} - -le_int32 PortableFontInstance::getLeading() const -{ - return fLeading; -} - -// We really want to inherit this method from the superclass, but some compilers -// issue a warning if we don't implement it... -LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const -{ - return LEFontInstance::mapCharToGlyph(ch, mapper, filterZeroWidth); -} - -// We really want to inherit this method from the superclass, but some compilers -// issue a warning if we don't implement it... -LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const -{ - return LEFontInstance::mapCharToGlyph(ch, mapper); -} - -LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const -{ - return fCMAPMapper->unicodeToGlyph(ch); -} - -float PortableFontInstance::getXPixelsPerEm() const -{ - return fXScale; -} - -float PortableFontInstance::getYPixelsPerEm() const -{ - return fYScale; -} - -float PortableFontInstance::getScaleFactorX() const -{ - return 1.0; -} - -float PortableFontInstance::getScaleFactorY() const -{ - return 1.0; -} diff --git a/src/hb-icu-le/PortableFontInstance.h b/src/hb-icu-le/PortableFontInstance.h deleted file mode 100644 index 0794560..0000000 --- a/src/hb-icu-le/PortableFontInstance.h +++ /dev/null @@ -1,112 +0,0 @@ - -/* - ******************************************************************************* - * - * Copyright (C) 1999-2008, International Business Machines - * Corporation and others. All Rights Reserved. - * - ******************************************************************************* - * file name: PortableFontInstance.h - * - * created on: 11/12/1999 - * created by: Eric R. Mader - */ - -#ifndef __PORTABLEFONTINSTANCE_H -#define __PORTABLEFONTINSTANCE_H - -#define HB_H_IN -#include <hb-font.h> -#include <hb-blob.h> - -#include "layout/LETypes.h" -#include "layout/LEFontInstance.h" -#include "letest.h" - -#include "FontTableCache.h" - -#include "cmaps.h" - -HB_BEGIN_VISIBILITY - -class PortableFontInstance : public LEFontInstance, protected FontTableCache -{ -private: - hb_face_t *fFace; - - float fXScale; - float fYScale; - le_int32 fUnitsPerEM; - le_int32 fAscent; - le_int32 fDescent; - le_int32 fLeading; - - const NAMETable *fNAMETable; - le_uint16 fNameCount; - le_uint16 fNameStringOffset; - - CMAPMapper *fCMAPMapper; - - const HMTXTable *fHMTXTable; - le_uint16 fNumGlyphs; - le_uint16 fNumLongHorMetrics; - - void getMetrics(); - - CMAPMapper *findUnicodeMapper(); - -protected: - hb_blob_t *readFontTable(LETag tableTag) const; - -public: - PortableFontInstance(hb_face_t *face, float xScale, float yScale, LEErrorCode &status); - - virtual ~PortableFontInstance(); - - virtual const void *getFontTable(LETag tableTag) const; - - virtual const char *getNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const; - - virtual const LEUnicode16 *getUnicodeNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const; - - virtual void deleteNameString(const char *name) const; - - virtual void deleteNameString(const LEUnicode16 *name) const; - - virtual le_int32 getUnitsPerEM() const; - - virtual le_uint32 getFontChecksum() const; - - virtual le_int32 getAscent() const; - - virtual le_int32 getDescent() const; - - virtual le_int32 getLeading() const; - - // We really want to inherit this method from the superclass, but some compilers - // issue a warning if we don't implement it... - virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const; - - // We really want to inherit this method from the superclass, but some compilers - // issue a warning if we don't implement it... - virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const; - - virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch) const; - - virtual void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const; - - virtual le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const; - - virtual float getXPixelsPerEm() const; - - virtual float getYPixelsPerEm() const; - - virtual float getScaleFactorX() const; - - virtual float getScaleFactorY() const; - -}; - -HB_END_VISIBILITY - -#endif diff --git a/src/hb-icu-le/README b/src/hb-icu-le/README deleted file mode 100644 index 329a218..0000000 --- a/src/hb-icu-le/README +++ /dev/null @@ -1,3 +0,0 @@ -This is PortableFontInstance from icu/test/testle of ICU50. -Modified to use a hb_face_t. -For license information, see the file license.html. diff --git a/src/hb-icu-le/cmaps.cpp b/src/hb-icu-le/cmaps.cpp deleted file mode 100644 index d03ee71..0000000 --- a/src/hb-icu-le/cmaps.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/*************************************************************************** -* -* Copyright (C) 1998-2003, International Business Machines -* Corporation and others. All Rights Reserved. -* -************************************************************************/ - -#include "layout/LETypes.h" -#include "layout/LESwaps.h" - -#include "sfnt.h" -#include "cmaps.h" - -#define SWAPU16(code) ((LEUnicode16) SWAPW(code)) -#define SWAPU32(code) ((LEUnicode32) SWAPL(code)) - -// -// Finds the high bit by binary searching -// through the bits in value. -// -static inline le_int8 highBit(le_uint32 value) -{ - le_uint8 bit = 0; - - if (value >= 1 << 16) { - value >>= 16; - bit += 16; - } - - if (value >= 1 << 8) { - value >>= 8; - bit += 8; - } - - if (value >= 1 << 4) { - value >>= 4; - bit += 4; - } - - if (value >= 1 << 2) { - value >>= 2; - bit += 2; - } - - if (value >= 1 << 1) { - value >>= 1; - bit += 1; - } - - return bit; -} - -CMAPMapper *CMAPMapper::createUnicodeMapper(const CMAPTable *cmap) -{ - le_uint16 i; - le_uint16 nSubtables = SWAPW(cmap->numberSubtables); - const CMAPEncodingSubtable *subtable = NULL; - le_uint32 offset1 = 0, offset10 = 0; - - for (i = 0; i < nSubtables; i += 1) { - const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i]; - - if (SWAPW(esh->platformID) == 3) { - switch (SWAPW(esh->platformSpecificID)) { - case 1: - offset1 = SWAPL(esh->encodingOffset); - break; - - case 10: - offset10 = SWAPL(esh->encodingOffset); - break; - } - } - } - - - if (offset10 != 0) - { - subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset10); - } else if (offset1 != 0) { - subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset1); - } else { - return NULL; - } - - switch (SWAPW(subtable->format)) { - case 4: - return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable); - - case 12: - { - const CMAPFormat12Encoding *encoding = (const CMAPFormat12Encoding *) subtable; - - return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups)); - } - - default: - break; - } - - return NULL; -} - -CMAPFormat4Mapper::CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header) - : CMAPMapper(cmap) -{ - le_uint16 segCount = SWAPW(header->segCountX2) / 2; - - fEntrySelector = SWAPW(header->entrySelector); - fRangeShift = SWAPW(header->rangeShift) / 2; - fEndCodes = &header->endCodes[0]; - fStartCodes = &header->endCodes[segCount + 1]; // + 1 for reservedPad... - fIdDelta = &fStartCodes[segCount]; - fIdRangeOffset = &fIdDelta[segCount]; -} - -LEGlyphID CMAPFormat4Mapper::unicodeToGlyph(LEUnicode32 unicode32) const -{ - if (unicode32 >= 0x10000) { - return 0; - } - - LEUnicode16 unicode = (LEUnicode16) unicode32; - le_uint16 index = 0; - le_uint16 probe = 1 << fEntrySelector; - TTGlyphID result = 0; - - if (SWAPU16(fStartCodes[fRangeShift]) <= unicode) { - index = fRangeShift; - } - - while (probe > (1 << 0)) { - probe >>= 1; - - if (SWAPU16(fStartCodes[index + probe]) <= unicode) { - index += probe; - } - } - - if (unicode >= SWAPU16(fStartCodes[index]) && unicode <= SWAPU16(fEndCodes[index])) { - if (fIdRangeOffset[index] == 0) { - result = (TTGlyphID) unicode; - } else { - le_uint16 offset = unicode - SWAPU16(fStartCodes[index]); - le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]); - le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &fIdRangeOffset[index] + rangeOffset); - - result = SWAPW(glyphIndexTable[offset]); - } - - result += SWAPW(fIdDelta[index]); - } else { - result = 0; - } - - return LE_SET_GLYPH(0, result); -} - -CMAPFormat4Mapper::~CMAPFormat4Mapper() -{ - // parent destructor does it all -} - -CMAPGroupMapper::CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups) - : CMAPMapper(cmap), fGroups(groups) -{ - le_uint8 bit = highBit(nGroups); - fPower = 1 << bit; - fRangeOffset = nGroups - fPower; -} - -LEGlyphID CMAPGroupMapper::unicodeToGlyph(LEUnicode32 unicode32) const -{ - le_int32 probe = fPower; - le_int32 range = 0; - - if (SWAPU32(fGroups[fRangeOffset].startCharCode) <= unicode32) { - range = fRangeOffset; - } - - while (probe > (1 << 0)) { - probe >>= 1; - - if (SWAPU32(fGroups[range + probe].startCharCode) <= unicode32) { - range += probe; - } - } - - if (SWAPU32(fGroups[range].startCharCode) <= unicode32 && SWAPU32(fGroups[range].endCharCode) >= unicode32) { - return (LEGlyphID) (SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode)); - } - - return 0; -} - -CMAPGroupMapper::~CMAPGroupMapper() -{ - // parent destructor does it all -} - diff --git a/src/hb-icu-le/cmaps.h b/src/hb-icu-le/cmaps.h deleted file mode 100644 index cf73f3a..0000000 --- a/src/hb-icu-le/cmaps.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** -* -* Copyright (C) 1998-2006, International Business Machines -* Corporation and others. All Rights Reserved. -* -************************************************************************/ - - -#ifndef __CMAPS_H -#define __CMAPS_H - -#include "layout/LETypes.h" -#include "letest.h" -#include "sfnt.h" - -HB_BEGIN_VISIBILITY - -class CMAPMapper -{ -public: - virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const = 0; - - virtual ~CMAPMapper(); - - static CMAPMapper *createUnicodeMapper(const CMAPTable *cmap); - -protected: - CMAPMapper(const CMAPTable *cmap); - - CMAPMapper() {}; - -private: - const CMAPTable *fcmap; -}; - -class CMAPFormat4Mapper : public CMAPMapper -{ -public: - CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header); - - virtual ~CMAPFormat4Mapper(); - - virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const; - -protected: - CMAPFormat4Mapper() {}; - -private: - le_uint16 fEntrySelector; - le_uint16 fRangeShift; - const le_uint16 *fEndCodes; - const le_uint16 *fStartCodes; - const le_uint16 *fIdDelta; - const le_uint16 *fIdRangeOffset; -}; - -class CMAPGroupMapper : public CMAPMapper -{ -public: - CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups); - - virtual ~CMAPGroupMapper(); - - virtual LEGlyphID unicodeToGlyph(LEUnicode32 unicode32) const; - -protected: - CMAPGroupMapper() {}; - -private: - le_int32 fPower; - le_int32 fRangeOffset; - const CMAPGroup *fGroups; -}; - -inline CMAPMapper::CMAPMapper(const CMAPTable *cmap) - : fcmap(cmap) -{ - // nothing else to do -} - -inline CMAPMapper::~CMAPMapper() -{ -} - -HB_END_VISIBILITY - -#endif diff --git a/src/hb-icu-le/letest.h b/src/hb-icu-le/letest.h deleted file mode 100644 index ff564ba..0000000 --- a/src/hb-icu-le/letest.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - ******************************************************************************* - * - * Copyright (C) 1999-2011, International Business Machines - * Corporation and others. All Rights Reserved. - * - ******************************************************************************* - * file name: letest.h - * - * created on: 11/06/2000 - * created by: Eric R. Mader - */ - -#ifndef __LETEST_H -#define __LETEST_H - - -#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) -# define HB_BEGIN_VISIBILITY _Pragma ("GCC visibility push(hidden)") -# define HB_END_VISIBILITY _Pragma ("GCC visibility pop") -#else -# define HB_BEGIN_VISIBILITY -# define HB_END_VISIBILITY -#endif - - -#include "layout/LETypes.h" -/*#include "unicode/ctest.h"*/ - -#include <stdlib.h> -#include <string.h> - -HB_BEGIN_VISIBILITY - -U_NAMESPACE_USE - -#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) - -#define ARRAY_COPY(dst, src, count) memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0]) - -#define NEW_ARRAY(type,count) (type *) malloc((count) * sizeof(type)) - -#define DELETE_ARRAY(array) free((void *) (array)) - -#define GROW_ARRAY(array,newSize) realloc((void *) (array), (newSize) * sizeof (array)[0]) - -struct TestResult -{ - le_int32 glyphCount; - LEGlyphID *glyphs; - le_int32 *indices; - float *positions; -}; - -#ifndef __cplusplus -typedef struct TestResult TestResult; -#endif - -//U_CFUNC void addCTests(TestNode **root); - -HB_END_VISIBILITY - -#endif diff --git a/src/hb-icu-le/license.html b/src/hb-icu-le/license.html deleted file mode 100644 index d078d05..0000000 --- a/src/hb-icu-le/license.html +++ /dev/null @@ -1,51 +0,0 @@ -<html> - -<head> -<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></meta> -<title>ICU License - ICU 1.8.1 and later</title> -</head> - -<body BGCOLOR="#ffffff"> -<h2>ICU License - ICU 1.8.1 and later</h2> - -<p>COPYRIGHT AND PERMISSION NOTICE</p> - -<p> -Copyright (c) 1995-2012 International Business Machines Corporation and others -</p> -<p> -All rights reserved. -</p> -<p> -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, and/or sell -copies of the Software, and to permit persons -to whom the Software is furnished to do so, provided that the above -copyright notice(s) and this permission notice appear in all copies -of the Software and that both the above copyright notice(s) and this -permission notice appear in supporting documentation. -</p> -<p> -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL -THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, -OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -USE OR PERFORMANCE OF THIS SOFTWARE. -</p> -<p> -Except as contained in this notice, the name of a copyright holder shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization of the copyright holder. -</p> - -<hr> -<p><small> -All trademarks and registered trademarks mentioned herein are the property of their respective owners. -</small></p> -</body> -</html> diff --git a/src/hb-icu-le/sfnt.h b/src/hb-icu-le/sfnt.h deleted file mode 100644 index feec0ad..0000000 --- a/src/hb-icu-le/sfnt.h +++ /dev/null @@ -1,453 +0,0 @@ -/*************************************************************************** -* -* Copyright (C) 1998-2011, International Business Machines -* Corporation and others. All Rights Reserved. -* -************************************************************************/ - -#ifndef __SFNT_H -#define __SFNT_H - -#include "layout/LETypes.h" -#include "letest.h" - -HB_BEGIN_VISIBILITY - -U_NAMESPACE_USE - -#ifndef ANY_NUMBER -#define ANY_NUMBER 1 -#endif - -struct DirectoryEntry -{ - le_uint32 tag; - le_uint32 checksum; - le_uint32 offset; - le_uint32 length; -}; - -#ifndef __cplusplus -typedef struct DirectoryEntry DirectoryEntry; -#endif - -struct SFNTDirectory -{ - le_uint32 scalerType; - le_uint16 numTables; - le_uint16 searchRange; - le_uint16 entrySelector; - le_uint16 rangeShift; - DirectoryEntry tableDirectory[ANY_NUMBER]; -}; - -#ifndef __cplusplus -typedef struct SFNTDirectory SFNTDirectory; -#endif - - -struct CMAPEncodingSubtableHeader -{ - le_uint16 platformID; - le_uint16 platformSpecificID; - le_uint32 encodingOffset; -}; - -#ifndef __cplusplus -typedef struct CMAPEncodingSubtableHeader CMAPEncodingSubtableHeader; -#endif - -struct CMAPTable -{ - le_uint16 version; - le_uint16 numberSubtables; - CMAPEncodingSubtableHeader encodingSubtableHeaders[ANY_NUMBER]; -}; - -#ifndef __cplusplus -typedef struct CMAPTable CMAPTable; -#endif - -struct CMAPEncodingSubtable -{ - le_uint16 format; - le_uint16 length; - le_uint16 language; -}; - -#ifndef __cplusplus -typedef struct CMAPEncodingSubtable CMAPEncodingSubtable; -#endif - -#ifdef __cplusplus -struct CMAPFormat0Encoding : CMAPEncodingSubtable -{ - le_uint8 glyphIndexArray[256]; -}; -#else -struct CMAPFormat0Encoding -{ - CMAPEncodingSubtable base; - - le_uint8 glyphIndexArray[256]; -}; - -typedef struct CMAPFormat0Encoding CMAPFormat0Encoding; -#endif - -struct CMAPFormat2Subheader -{ - le_uint16 firstCode; - le_uint16 entryCount; - le_int16 idDelta; - le_uint16 idRangeOffset; -}; - -#ifndef __cplusplus -typedef struct CMAPFormat2Subheader CMAPFormat2Subheader; -#endif - -#ifdef __cplusplus -struct CMAPFormat2Encoding : CMAPEncodingSubtable -{ - le_uint16 subHeadKeys[256]; - CMAPFormat2Subheader subheaders[ANY_NUMBER]; -}; -#else -struct CMAPFormat2Encoding -{ - CMAPEncodingSubtable base; - - le_uint16 subHeadKeys[256]; - CMAPFormat2Subheader subheaders[ANY_NUMBER]; -}; - -typedef struct CMAPFormat2Encoding CMAPFormat2Encoding; -#endif - -#ifdef __cplusplus -struct CMAPFormat4Encoding : CMAPEncodingSubtable -{ - le_uint16 segCountX2; - le_uint16 searchRange; - le_uint16 entrySelector; - le_uint16 rangeShift; - le_uint16 endCodes[ANY_NUMBER]; -/* - le_uint16 reservedPad; - le_uint16 startCodes[ANY_NUMBER]; - le_uint16 idDelta[ANY_NUMBER]; - le_uint16 idRangeOffset[ANY_NUMBER]; - le_uint16 glyphIndexArray[ANY_NUMBER]; -*/ -}; -#else -struct CMAPFormat4Encoding -{ - CMAPEncodingSubtable base; - - le_uint16 segCountX2; - le_uint16 searchRange; - le_uint16 entrySelector; - le_uint16 rangeShift; - le_uint16 endCodes[ANY_NUMBER]; -/* -// le_uint16 reservedPad; -// le_uint16 startCodes[ANY_NUMBER]; -// le_uint16 idDelta[ANY_NUMBER]; -// le_uint16 idRangeOffset[ANY_NUMBER]; -// le_uint16 glyphIndexArray[ANY_NUMBER]; -*/ -}; - -typedef struct CMAPFormat4Encoding CMAPFormat4Encoding; -#endif - -#ifdef __cplusplus -struct CMAPFormat6Encoding : CMAPEncodingSubtable -{ - le_uint16 firstCode; - le_uint16 entryCount; - le_uint16 glyphIndexArray[ANY_NUMBER]; -}; -#else -struct CMAPFormat6Encoding -{ - CMAPEncodingSubtable base; - - le_uint16 firstCode; - le_uint16 entryCount; - le_uint16 glyphIndexArray[ANY_NUMBER]; -}; - -typedef struct CMAPFormat6Encoding CMAPFormat6Encoding; -#endif - -struct CMAPEncodingSubtable32 -{ - le_uint32 format; - le_uint32 length; - le_uint32 language; -}; - -#ifndef __cplusplus -typedef struct CMAPEncodingSubtable32 CMAPEncodingSubtable32; -#endif - -struct CMAPGroup -{ - le_uint32 startCharCode; - le_uint32 endCharCode; - le_uint32 startGlyphCode; -}; - -#ifndef __cplusplus -typedef struct CMAPGroup CMAPGroup; -#endif - -#ifdef __cplusplus -struct CMAPFormat8Encoding : CMAPEncodingSubtable32 -{ - le_uint32 is32[65536/32]; - le_uint32 nGroups; - CMAPGroup groups[ANY_NUMBER]; -}; -#else -struct CMAPFormat8Encoding -{ - CMAPEncodingSubtable32 base; - - le_uint32 is32[65536/32]; - le_uint32 nGroups; - CMAPGroup groups[ANY_NUMBER]; -}; - -typedef struct CMAPFormat8Encoding CMAPFormat8Encoding; -#endif - -#ifdef __cplusplus -struct CMAPFormat10Encoding : CMAPEncodingSubtable32 -{ - le_uint32 startCharCode; - le_uint32 numCharCodes; - le_uint16 glyphs[ANY_NUMBER]; -}; -#else -struct CMAPFormat10Encoding -{ - CMAPEncodingSubtable32 base; - - le_uint32 startCharCode; - le_uint32 numCharCodes; - le_uint16 glyphs[ANY_NUMBER]; -}; - -typedef struct CMAPFormat10Encoding CMAPFormat10Encoding; -#endif - -#ifdef __cplusplus -struct CMAPFormat12Encoding : CMAPEncodingSubtable32 -{ - le_uint32 nGroups; - CMAPGroup groups[ANY_NUMBER]; -}; -#else -struct CMAPFormat12Encoding -{ - CMAPEncodingSubtable32 base; - - le_uint32 nGroups; - CMAPGroup groups[ANY_NUMBER]; -}; - -typedef struct CMAPFormat12Encoding CMAPFormat12Encoding; -#endif - -typedef le_int32 fixed; - -struct BigDate -{ - le_uint32 bc; - le_uint32 ad; -}; - -#ifndef __cplusplus -typedef struct BigDate BigDate; -#endif - -struct HEADTable -{ - fixed version; - fixed fontRevision; - le_uint32 checksumAdjustment; - le_uint32 magicNumber; - le_uint16 flags; - le_uint16 unitsPerEm; - BigDate created; - BigDate modified; - le_int16 xMin; - le_int16 yMin; - le_int16 xMax; - le_int16 yMax; - le_int16 lowestRecPPEM; - le_int16 fontDirectionHint; - le_int16 indexToLocFormat; - le_int16 glyphDataFormat; -}; - -#ifndef __cplusplus -typedef struct HEADTable HEADTable; -#endif - -struct MAXPTable -{ - fixed version; - le_uint16 numGlyphs; - le_uint16 maxPoints; - le_uint16 maxContours; - le_uint16 maxComponentPoints; - le_uint16 maxComponentContours; - le_uint16 maxZones; - le_uint16 maxTwilightPoints; - le_uint16 maxStorage; - le_uint16 maxFunctionDefs; - le_uint16 maxInstructionDefs; - le_uint16 maxStackElements; - le_uint16 maxSizeOfInstructions; - le_uint16 maxComponentElements; - le_uint16 maxComponentDepth; -}; - -#ifndef __cplusplus -typedef struct MAXPTable MAXPTable; -#endif - -struct HHEATable -{ - fixed version; - le_int16 ascent; - le_int16 descent; - le_int16 lineGap; - le_uint16 advanceWidthMax; - le_int16 minLeftSideBearing; - le_int16 minRightSideBearing; - le_int16 xMaxExtent; - le_int16 caretSlopeRise; - le_int16 caretSlopeRun; - le_int16 caretOffset; - le_int16 reserved1; - le_int16 reserved2; - le_int16 reserved3; - le_int16 reserved4; - le_int16 metricDataFormat; - le_uint16 numOfLongHorMetrics; -}; - -#ifndef __cplusplus -typedef struct HHEATable HHEATable; -#endif - -struct LongHorMetric -{ - le_uint16 advanceWidth; - le_int16 leftSideBearing; -}; - -#ifndef __cplusplus -typedef struct LongHorMetric LongHorMetric; -#endif - -struct HMTXTable -{ - LongHorMetric hMetrics[ANY_NUMBER]; /* ANY_NUMBER = numOfLongHorMetrics from hhea table */ -/* le_int16 leftSideBearing[ANY_NUMBER]; ANY_NUMBER = numGlyphs - numOfLongHorMetrics */ -}; - -#ifndef __cplusplus -typedef struct HMTXTable HMTXTable; -#endif - -enum PlatformID -{ - PLATFORM_UNICODE = 0, - PLATFORM_MACINTOSH = 1, - PLATFORM_ISO = 2, - PLATFORM_MICROSOFT = 3, - PLATFORM_CUSTOM = 4 -}; - -enum MacintoshEncodingID -{ - MACINTOSH_ROMAN = 0 -}; - -enum MacintoshLanguageID -{ - MACINTOSH_ENGLISH = 0 -}; - -enum MicrosoftEncodingID -{ - MICROSOFT_UNICODE_BMP = 1, - MICROSOFT_UNICODE_FULL = 10 -}; - -enum MicrosoftLanguageID -{ - MICROSOFT_ENGLISH = 0x409 -}; - -enum NameID -{ - NAME_COPYRIGHT_NOTICE = 0, - NAME_FONT_FAMILY = 1, - NAME_FONT_SUB_FAMILY = 2, - NAME_UNIQUE_FONT_ID = 3, - NAME_FULL_FONT_NAME = 4, - NAME_VERSION_STRING = 5, - NAME_POSTSCRIPT_NAME = 6, - NAME_TRADEMARK = 7, - NAME_MANUFACTURER = 8, - NAME_DESIGNER = 9, - NAME_DESCRIPTION = 10, - NAME_VENDOR_URL = 11, - NAME_DESIGNER_URL = 12, - NAME_LICENSE_DESCRIPTION = 13, - NAME_LICENSE_URL = 14, - NAME_RESERVED = 15, - NAME_PREFERRED_FAMILY = 16, - NAME_PREFERRED_SUB_FAMILY = 17, - NAME_COMPATIBLE_FULL = 18, - NAME_SAMPLE_TEXT = 19, - NAME_POSTSCRIPT_CID = 20 -}; - -struct NameRecord -{ - le_uint16 platformID; - le_uint16 encodingID; - le_uint16 languageID; - le_uint16 nameID; - le_uint16 length; - le_uint16 offset; -}; - -#ifndef __cplusplus -typedef struct NameRecord NameRecord; -#endif - -struct NAMETable -{ - le_uint16 version; - le_uint16 count; - le_uint16 stringOffset; - NameRecord nameRecords[ANY_NUMBER]; -}; - -#ifndef __cplusplus -typedef struct NAMETable NAMETable; -#endif - -HB_END_VISIBILITY - -#endif diff --git a/src/hb-icu.cc b/src/hb-icu.cc index c177be2..86c8b5c 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -323,7 +323,7 @@ hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED, /* Copy @u into a UTF-16 array to be passed to ICU. */ len = 0; - err = FALSE; + err = false; U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err); if (err) return 0; diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh index 5b3a17e..6281201 100644 --- a/src/hb-mutex-private.hh +++ b/src/hb-mutex-private.hh @@ -42,12 +42,11 @@ #if 0 -#elif !defined(HB_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__) +#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) -#define WIN32_LEAN_AND_MEAN #include <windows.h> typedef CRITICAL_SECTION hb_mutex_impl_t; -#define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 } +#define HB_MUTEX_IMPL_INIT {0} #define hb_mutex_impl_init(M) InitializeCriticalSection (M) #define hb_mutex_impl_lock(M) EnterCriticalSection (M) #define hb_mutex_impl_unlock(M) LeaveCriticalSection (M) diff --git a/src/hb-old.cc b/src/hb-old.cc deleted file mode 100644 index a7ea8ed..0000000 --- a/src/hb-old.cc +++ /dev/null @@ -1,410 +0,0 @@ -/* - * 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 - */ - -#define HB_SHAPER old -#define hb_old_shaper_face_data_t HB_FaceRec_ -#define hb_old_shaper_font_data_t HB_Font_ -#include "hb-shaper-impl-private.hh" - -#include <harfbuzz.h> - - -#ifndef HB_DEBUG_OLD -#define HB_DEBUG_OLD (HB_DEBUG+0) -#endif - - -static HB_Script -hb_old_script_from_script (hb_script_t script) -{ - switch ((hb_tag_t) script) - { - default: - case HB_SCRIPT_COMMON: return HB_Script_Common; - case HB_SCRIPT_GREEK: return HB_Script_Greek; - case HB_SCRIPT_CYRILLIC: return HB_Script_Cyrillic; - case HB_SCRIPT_ARMENIAN: return HB_Script_Armenian; - case HB_SCRIPT_HEBREW: return HB_Script_Hebrew; - case HB_SCRIPT_ARABIC: return HB_Script_Arabic; - case HB_SCRIPT_SYRIAC: return HB_Script_Syriac; - case HB_SCRIPT_THAANA: return HB_Script_Thaana; - case HB_SCRIPT_DEVANAGARI: return HB_Script_Devanagari; - case HB_SCRIPT_BENGALI: return HB_Script_Bengali; - case HB_SCRIPT_GURMUKHI: return HB_Script_Gurmukhi; - case HB_SCRIPT_GUJARATI: return HB_Script_Gujarati; - case HB_SCRIPT_ORIYA: return HB_Script_Oriya; - case HB_SCRIPT_TAMIL: return HB_Script_Tamil; - case HB_SCRIPT_TELUGU: return HB_Script_Telugu; - case HB_SCRIPT_KANNADA: return HB_Script_Kannada; - case HB_SCRIPT_MALAYALAM: return HB_Script_Malayalam; - case HB_SCRIPT_SINHALA: return HB_Script_Sinhala; - case HB_SCRIPT_THAI: return HB_Script_Thai; - case HB_SCRIPT_LAO: return HB_Script_Lao; - case HB_SCRIPT_TIBETAN: return HB_Script_Tibetan; - case HB_SCRIPT_MYANMAR: return HB_Script_Myanmar; - case HB_SCRIPT_GEORGIAN: return HB_Script_Georgian; - case HB_SCRIPT_HANGUL: return HB_Script_Hangul; - case HB_SCRIPT_OGHAM: return HB_Script_Ogham; - case HB_SCRIPT_RUNIC: return HB_Script_Runic; - case HB_SCRIPT_KHMER: return HB_Script_Khmer; - case HB_SCRIPT_NKO: return HB_Script_Nko; - case HB_SCRIPT_INHERITED: return HB_Script_Inherited; - } -} - - -static HB_Bool -hb_old_convertStringToGlyphIndices (HB_Font old_font, - const HB_UChar16 *string, - hb_uint32 length, - HB_Glyph *glyphs, - hb_uint32 *numGlyphs, - HB_Bool rightToLeft) -{ - hb_font_t *font = (hb_font_t *) old_font->userData; - - for (unsigned int i = 0; i < length; i++) - { - hb_codepoint_t u; - - /* XXX Handle UTF-16. Ugh */ - u = string[i]; - - if (rightToLeft) - u = hb_unicode_funcs_get_default ()->mirroring (u); - - font->get_glyph (u, 0, &u); /* TODO Variation selectors */ - - glyphs[i] = u; - } - *numGlyphs = length; /* XXX */ - - return true; -} - -static void -hb_old_getGlyphAdvances (HB_Font old_font, - const HB_Glyph *glyphs, - hb_uint32 numGlyphs, - HB_Fixed *advances, - int flags /*HB_ShaperFlag*/ HB_UNUSED) -{ - hb_font_t *font = (hb_font_t *) old_font->userData; - - for (unsigned int i = 0; i < numGlyphs; i++) - advances[i] = font->get_glyph_h_advance (glyphs[i]); -} - -static HB_Bool -hb_old_canRender (HB_Font old_font, - const HB_UChar16 *string, - hb_uint32 length) -{ - return true; /* TODO */ -} - -static HB_Error -hb_old_getPointInOutline (HB_Font old_font, - HB_Glyph glyph, - int flags /*HB_ShaperFlag*/, - hb_uint32 point, - HB_Fixed *xpos, - HB_Fixed *ypos, - hb_uint32 *nPoints) -{ - return HB_Err_Ok; /* TODO */ -} - -static void -hb_old_getGlyphMetrics (HB_Font old_font, - HB_Glyph glyph, - HB_GlyphMetrics *metrics) -{ - hb_font_t *font = (hb_font_t *) old_font->userData; - - hb_glyph_extents_t extents; - - font->get_glyph_extents (glyph, &extents); - - metrics->x = extents.x_bearing; - metrics->y = extents.y_bearing; - metrics->width = extents.width; - metrics->height = extents.height; - metrics->xOffset = font->get_glyph_h_advance (glyph); - metrics->yOffset = 0; -} - -static HB_Fixed -hb_old_getFontMetric (HB_Font old_font, - HB_FontMetric metric) -{ - hb_font_t *font = (hb_font_t *) old_font->userData; - - switch (metric) - { - case HB_FontAscent: - return font->y_scale; /* XXX We don't have ascent data yet. */ - - default: - return 0; - } -} - -static const HB_FontClass hb_old_font_class = { - hb_old_convertStringToGlyphIndices, - hb_old_getGlyphAdvances, - hb_old_canRender, - hb_old_getPointInOutline, - hb_old_getGlyphMetrics, - hb_old_getFontMetric -}; - - - -static HB_Error -table_func (void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length) -{ - hb_face_t *face = (hb_face_t *) font; - hb_blob_t *blob = face->reference_table ((hb_tag_t) tag); - unsigned int capacity = *length; - *length = hb_blob_get_length (blob); - memcpy (buffer, hb_blob_get_data (blob, NULL), MIN (capacity, *length)); - hb_blob_destroy (blob); - return HB_Err_Ok; -} - - -/* - * shaper face data - */ - -hb_old_shaper_face_data_t * -_hb_old_shaper_face_data_create (hb_face_t *face) -{ - return HB_NewFace (face, table_func); -} - -void -_hb_old_shaper_face_data_destroy (hb_old_shaper_face_data_t *data) -{ - HB_FreeFace (data); -} - - -/* - * shaper font data - */ - -hb_old_shaper_font_data_t * -_hb_old_shaper_font_data_create (hb_font_t *font) -{ - HB_FontRec *data = (HB_FontRec *) calloc (1, sizeof (HB_FontRec)); - if (unlikely (!data)) { - DEBUG_MSG (OLD, font, "malloc()ing HB_Font failed"); - return NULL; - } - - data->klass = &hb_old_font_class; - data->x_ppem = font->x_ppem; - data->y_ppem = font->y_ppem; - data->x_scale = font->x_scale; /* XXX */ - data->y_scale = font->y_scale; /* XXX */ - data->userData = font; - - return data; -} - -void -_hb_old_shaper_font_data_destroy (hb_old_shaper_font_data_t *data) -{ - free (data); -} - - -/* - * shaper shape_plan data - */ - -struct hb_old_shaper_shape_plan_data_t {}; - -hb_old_shaper_shape_plan_data_t * -_hb_old_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) -{ - return (hb_old_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_old_shaper_shape_plan_data_destroy (hb_old_shaper_shape_plan_data_t *data HB_UNUSED) -{ -} - - -/* - * shaper - */ - -hb_bool_t -_hb_old_shape (hb_shape_plan_t *shape_plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) -{ - hb_face_t *face = font->face; - HB_Face old_face = HB_SHAPER_DATA_GET (face); - HB_Font old_font = HB_SHAPER_DATA_GET (font); - - bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - -retry: - - unsigned int scratch_size; - char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); - -#define utf16_index() var1.u32 - HB_UChar16 *pchars = (HB_UChar16 *) scratch; - 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 < 0x10000)) - pchars[chars_len++] = c; - else if (unlikely (c >= 0x110000)) - pchars[chars_len++] = 0xFFFD; - else { - pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); - pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); - } - } - - -#define ALLOCATE_ARRAY(Type, name, len) \ - name = (Type *) scratch; \ - scratch += (len) * sizeof ((name)[0]); \ - scratch_size -= (len) * sizeof ((name)[0]); - - - HB_ShaperItem item = {0}; - - ALLOCATE_ARRAY (const HB_UChar16, item.string, chars_len); - ALLOCATE_ARRAY (unsigned short, item.log_clusters, chars_len + 2); - item.stringLength = chars_len; - item.item.pos = 0; - item.item.length = item.stringLength; - item.item.script = hb_old_script_from_script (buffer->props.script); - item.item.bidiLevel = backward ? 1 : 0; - - item.font = old_font; - item.face = old_face; - item.shaperFlags = 0; - - item.glyphIndicesPresent = false; - - /* TODO Alignment. */ - unsigned int num_glyphs = scratch_size / (sizeof (HB_Glyph) + - sizeof (HB_GlyphAttributes) + - sizeof (HB_Fixed) + - sizeof (HB_FixedPoint) + - sizeof (uint32_t)); - - item.num_glyphs = num_glyphs; - ALLOCATE_ARRAY (HB_Glyph, item.glyphs, num_glyphs); - ALLOCATE_ARRAY (HB_GlyphAttributes, item.attributes, num_glyphs); - ALLOCATE_ARRAY (HB_Fixed, item.advances, num_glyphs); - ALLOCATE_ARRAY (HB_FixedPoint, item.offsets, num_glyphs); - /* Apparently in some cases the offsets array will not be fully assigned to. - * Clear it. */ - memset (item.offsets, 0, num_glyphs * sizeof (item.offsets[0])); - uint32_t *vis_clusters; - ALLOCATE_ARRAY (uint32_t, vis_clusters, num_glyphs); - -#undef ALLOCATE_ARRAY - - if (!HB_ShapeItem (&item)) - { - if (unlikely (item.num_glyphs > num_glyphs)) - { - buffer->ensure (buffer->allocated * 2); - if (buffer->in_error) - return false; - goto retry; - } - return false; - } - num_glyphs = item.num_glyphs; - - /* 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 < num_glyphs; i++) - vis_clusters[i] = -1; - for (unsigned int i = 0; i < buffer->len; i++) { - uint32_t *p = &vis_clusters[item.log_clusters[buffer->info[i].utf16_index()]]; - *p = MIN (*p, buffer->info[i].cluster); - } - for (unsigned int i = 1; i < num_glyphs; i++) - if (vis_clusters[i] == (uint32_t) -1) - vis_clusters[i] = vis_clusters[i - 1]; - -#undef utf16_index - - buffer->ensure (num_glyphs); - if (buffer->in_error) - return false; - - - buffer->len = num_glyphs; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < num_glyphs; i++) - { - info[i].codepoint = item.glyphs[i]; - info[i].cluster = vis_clusters[i]; - - info[i].mask = item.advances[i]; - info[i].var1.u32 = item.offsets[i].x; - info[i].var2.u32 = item.offsets[i].y; - } - - buffer->clear_positions (); - - for (unsigned int i = 0; i < num_glyphs; ++i) { - hb_glyph_info_t *info = &buffer->info[i]; - hb_glyph_position_t *pos = &buffer->pos[i]; - - /* TODO vertical */ - pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; - } - - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - buffer->reverse (); - - return true; -} diff --git a/src/hb-old/COPYING b/src/hb-old/COPYING deleted file mode 100644 index f7c0e97..0000000 --- a/src/hb-old/COPYING +++ /dev/null @@ -1,24 +0,0 @@ -HarfBuzz-old was previously licensed under different licenses. This was -changed in January 2008. If you need to relicense your old copies, -consult the announcement of the license change on the internet. -Other than that, each copy of HarfBuzz-old is licensed under the COPYING -file included with it. The actual license follows: - - -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. diff --git a/src/hb-old/Makefile.am b/src/hb-old/Makefile.am deleted file mode 100644 index 39830a6..0000000 --- a/src/hb-old/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -## Process this file with automake to produce Makefile.in - -noinst_LTLIBRARIES = libhb-old.la - -MAINSOURCES = \ - harfbuzz-buffer.c \ - harfbuzz-stream.c \ - harfbuzz-gdef.c \ - harfbuzz-gpos.c \ - harfbuzz-gsub.c \ - harfbuzz-impl.c \ - harfbuzz-open.c \ - harfbuzz-shaper.cpp \ - harfbuzz-greek.c \ - harfbuzz-tibetan.c \ - harfbuzz-khmer.c \ - harfbuzz-indic.cpp \ - harfbuzz-hebrew.c \ - harfbuzz-arabic.c \ - harfbuzz-hangul.c \ - harfbuzz-myanmar.c - -PUBLICHEADERS = \ - harfbuzz.h \ - harfbuzz-buffer.h \ - harfbuzz-gdef.h \ - harfbuzz-gpos.h \ - harfbuzz-gsub.h \ - harfbuzz-open.h \ - harfbuzz-global.h \ - harfbuzz-external.h \ - harfbuzz-shaper.h \ - harfbuzz-stream.h - -PRIVATEHEADERS = \ - harfbuzz-impl.h \ - harfbuzz-buffer-private.h \ - harfbuzz-stream-private.h \ - harfbuzz-gdef-private.h \ - harfbuzz-gpos-private.h \ - harfbuzz-gsub-private.h \ - harfbuzz-open-private.h \ - harfbuzz-shaper-private.h - -libhb_old_la_SOURCES = \ - $(MAINSOURCES) \ - $(PUBLICHEADERS) \ - $(PRIVATEHEADERS) -libhb_old_la_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/src \ - -I$(top_builddir)/src - -EXTRA_DIST = README COPYING - --include $(top_srcdir)/git.mk diff --git a/src/hb-old/Makefile.in b/src/hb-old/Makefile.in deleted file mode 100644 index 01e1a67..0000000 --- a/src/hb-old/Makefile.in +++ /dev/null @@ -1,759 +0,0 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/hb-old -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - COPYING -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libhb_old_la_LIBADD = -am__objects_1 = libhb_old_la-harfbuzz-buffer.lo \ - libhb_old_la-harfbuzz-stream.lo libhb_old_la-harfbuzz-gdef.lo \ - libhb_old_la-harfbuzz-gpos.lo libhb_old_la-harfbuzz-gsub.lo \ - libhb_old_la-harfbuzz-impl.lo libhb_old_la-harfbuzz-open.lo \ - libhb_old_la-harfbuzz-shaper.lo libhb_old_la-harfbuzz-greek.lo \ - libhb_old_la-harfbuzz-tibetan.lo \ - libhb_old_la-harfbuzz-khmer.lo libhb_old_la-harfbuzz-indic.lo \ - libhb_old_la-harfbuzz-hebrew.lo \ - libhb_old_la-harfbuzz-arabic.lo \ - libhb_old_la-harfbuzz-hangul.lo \ - libhb_old_la-harfbuzz-myanmar.lo -am__objects_2 = -am_libhb_old_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ - $(am__objects_2) -libhb_old_la_OBJECTS = $(am_libhb_old_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libhb_old_la_SOURCES) -DIST_SOURCES = $(libhb_old_la_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CAIRO_CFLAGS = @CAIRO_CFLAGS@ -CAIRO_FT_CFLAGS = @CAIRO_FT_CFLAGS@ -CAIRO_FT_LIBS = @CAIRO_FT_LIBS@ -CAIRO_LIBS = @CAIRO_LIBS@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CORETEXT_CFLAGS = @CORETEXT_CFLAGS@ -CORETEXT_LIBS = @CORETEXT_LIBS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ -FREETYPE_LIBS = @FREETYPE_LIBS@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ -GOBJECT_LIBS = @GOBJECT_LIBS@ -GRAPHITE2_CFLAGS = @GRAPHITE2_CFLAGS@ -GRAPHITE2_LIBS = @GRAPHITE2_LIBS@ -GREP = @GREP@ -GTHREAD_CFLAGS = @GTHREAD_CFLAGS@ -GTHREAD_LIBS = @GTHREAD_LIBS@ -HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@ -HB_VERSION = @HB_VERSION@ -HB_VERSION_MAJOR = @HB_VERSION_MAJOR@ -HB_VERSION_MICRO = @HB_VERSION_MICRO@ -HB_VERSION_MINOR = @HB_VERSION_MINOR@ -ICU_CFLAGS = @ICU_CFLAGS@ -ICU_LE_CFLAGS = @ICU_LE_CFLAGS@ -ICU_LE_LIBS = @ICU_LE_LIBS@ -ICU_LIBS = @ICU_LIBS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -UNISCRIBE_CFLAGS = @UNISCRIBE_CFLAGS@ -UNISCRIBE_LIBS = @UNISCRIBE_LIBS@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = libhb-old.la -MAINSOURCES = \ - harfbuzz-buffer.c \ - harfbuzz-stream.c \ - harfbuzz-gdef.c \ - harfbuzz-gpos.c \ - harfbuzz-gsub.c \ - harfbuzz-impl.c \ - harfbuzz-open.c \ - harfbuzz-shaper.cpp \ - harfbuzz-greek.c \ - harfbuzz-tibetan.c \ - harfbuzz-khmer.c \ - harfbuzz-indic.cpp \ - harfbuzz-hebrew.c \ - harfbuzz-arabic.c \ - harfbuzz-hangul.c \ - harfbuzz-myanmar.c - -PUBLICHEADERS = \ - harfbuzz.h \ - harfbuzz-buffer.h \ - harfbuzz-gdef.h \ - harfbuzz-gpos.h \ - harfbuzz-gsub.h \ - harfbuzz-open.h \ - harfbuzz-global.h \ - harfbuzz-external.h \ - harfbuzz-shaper.h \ - harfbuzz-stream.h - -PRIVATEHEADERS = \ - harfbuzz-impl.h \ - harfbuzz-buffer-private.h \ - harfbuzz-stream-private.h \ - harfbuzz-gdef-private.h \ - harfbuzz-gpos-private.h \ - harfbuzz-gsub-private.h \ - harfbuzz-open-private.h \ - harfbuzz-shaper-private.h - -libhb_old_la_SOURCES = \ - $(MAINSOURCES) \ - $(PUBLICHEADERS) \ - $(PRIVATEHEADERS) - -libhb_old_la_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/src \ - -I$(top_builddir)/src - -EXTRA_DIST = README COPYING -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .cpp .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits src/hb-old/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnits src/hb-old/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libhb-old.la: $(libhb_old_la_OBJECTS) $(libhb_old_la_DEPENDENCIES) $(EXTRA_libhb_old_la_DEPENDENCIES) - $(AM_V_CXXLD)$(CXXLINK) $(libhb_old_la_OBJECTS) $(libhb_old_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-arabic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-buffer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-gdef.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-gpos.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-greek.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-gsub.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-hangul.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-hebrew.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-impl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-indic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-khmer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-myanmar.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-open.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-shaper.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-stream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_old_la-harfbuzz-tibetan.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -libhb_old_la-harfbuzz-buffer.lo: harfbuzz-buffer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-buffer.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-buffer.Tpo -c -o libhb_old_la-harfbuzz-buffer.lo `test -f 'harfbuzz-buffer.c' || echo '$(srcdir)/'`harfbuzz-buffer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-buffer.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-buffer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-buffer.c' object='libhb_old_la-harfbuzz-buffer.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-buffer.lo `test -f 'harfbuzz-buffer.c' || echo '$(srcdir)/'`harfbuzz-buffer.c - -libhb_old_la-harfbuzz-stream.lo: harfbuzz-stream.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-stream.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-stream.Tpo -c -o libhb_old_la-harfbuzz-stream.lo `test -f 'harfbuzz-stream.c' || echo '$(srcdir)/'`harfbuzz-stream.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-stream.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-stream.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-stream.c' object='libhb_old_la-harfbuzz-stream.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-stream.lo `test -f 'harfbuzz-stream.c' || echo '$(srcdir)/'`harfbuzz-stream.c - -libhb_old_la-harfbuzz-gdef.lo: harfbuzz-gdef.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-gdef.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-gdef.Tpo -c -o libhb_old_la-harfbuzz-gdef.lo `test -f 'harfbuzz-gdef.c' || echo '$(srcdir)/'`harfbuzz-gdef.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-gdef.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-gdef.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-gdef.c' object='libhb_old_la-harfbuzz-gdef.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-gdef.lo `test -f 'harfbuzz-gdef.c' || echo '$(srcdir)/'`harfbuzz-gdef.c - -libhb_old_la-harfbuzz-gpos.lo: harfbuzz-gpos.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-gpos.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-gpos.Tpo -c -o libhb_old_la-harfbuzz-gpos.lo `test -f 'harfbuzz-gpos.c' || echo '$(srcdir)/'`harfbuzz-gpos.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-gpos.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-gpos.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-gpos.c' object='libhb_old_la-harfbuzz-gpos.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-gpos.lo `test -f 'harfbuzz-gpos.c' || echo '$(srcdir)/'`harfbuzz-gpos.c - -libhb_old_la-harfbuzz-gsub.lo: harfbuzz-gsub.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-gsub.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-gsub.Tpo -c -o libhb_old_la-harfbuzz-gsub.lo `test -f 'harfbuzz-gsub.c' || echo '$(srcdir)/'`harfbuzz-gsub.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-gsub.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-gsub.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-gsub.c' object='libhb_old_la-harfbuzz-gsub.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-gsub.lo `test -f 'harfbuzz-gsub.c' || echo '$(srcdir)/'`harfbuzz-gsub.c - -libhb_old_la-harfbuzz-impl.lo: harfbuzz-impl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-impl.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-impl.Tpo -c -o libhb_old_la-harfbuzz-impl.lo `test -f 'harfbuzz-impl.c' || echo '$(srcdir)/'`harfbuzz-impl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-impl.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-impl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-impl.c' object='libhb_old_la-harfbuzz-impl.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-impl.lo `test -f 'harfbuzz-impl.c' || echo '$(srcdir)/'`harfbuzz-impl.c - -libhb_old_la-harfbuzz-open.lo: harfbuzz-open.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-open.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-open.Tpo -c -o libhb_old_la-harfbuzz-open.lo `test -f 'harfbuzz-open.c' || echo '$(srcdir)/'`harfbuzz-open.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-open.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-open.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-open.c' object='libhb_old_la-harfbuzz-open.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-open.lo `test -f 'harfbuzz-open.c' || echo '$(srcdir)/'`harfbuzz-open.c - -libhb_old_la-harfbuzz-greek.lo: harfbuzz-greek.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-greek.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-greek.Tpo -c -o libhb_old_la-harfbuzz-greek.lo `test -f 'harfbuzz-greek.c' || echo '$(srcdir)/'`harfbuzz-greek.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-greek.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-greek.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-greek.c' object='libhb_old_la-harfbuzz-greek.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-greek.lo `test -f 'harfbuzz-greek.c' || echo '$(srcdir)/'`harfbuzz-greek.c - -libhb_old_la-harfbuzz-tibetan.lo: harfbuzz-tibetan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-tibetan.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-tibetan.Tpo -c -o libhb_old_la-harfbuzz-tibetan.lo `test -f 'harfbuzz-tibetan.c' || echo '$(srcdir)/'`harfbuzz-tibetan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-tibetan.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-tibetan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-tibetan.c' object='libhb_old_la-harfbuzz-tibetan.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-tibetan.lo `test -f 'harfbuzz-tibetan.c' || echo '$(srcdir)/'`harfbuzz-tibetan.c - -libhb_old_la-harfbuzz-khmer.lo: harfbuzz-khmer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-khmer.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-khmer.Tpo -c -o libhb_old_la-harfbuzz-khmer.lo `test -f 'harfbuzz-khmer.c' || echo '$(srcdir)/'`harfbuzz-khmer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-khmer.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-khmer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-khmer.c' object='libhb_old_la-harfbuzz-khmer.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-khmer.lo `test -f 'harfbuzz-khmer.c' || echo '$(srcdir)/'`harfbuzz-khmer.c - -libhb_old_la-harfbuzz-hebrew.lo: harfbuzz-hebrew.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-hebrew.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-hebrew.Tpo -c -o libhb_old_la-harfbuzz-hebrew.lo `test -f 'harfbuzz-hebrew.c' || echo '$(srcdir)/'`harfbuzz-hebrew.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-hebrew.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-hebrew.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-hebrew.c' object='libhb_old_la-harfbuzz-hebrew.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-hebrew.lo `test -f 'harfbuzz-hebrew.c' || echo '$(srcdir)/'`harfbuzz-hebrew.c - -libhb_old_la-harfbuzz-arabic.lo: harfbuzz-arabic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-arabic.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-arabic.Tpo -c -o libhb_old_la-harfbuzz-arabic.lo `test -f 'harfbuzz-arabic.c' || echo '$(srcdir)/'`harfbuzz-arabic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-arabic.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-arabic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-arabic.c' object='libhb_old_la-harfbuzz-arabic.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-arabic.lo `test -f 'harfbuzz-arabic.c' || echo '$(srcdir)/'`harfbuzz-arabic.c - -libhb_old_la-harfbuzz-hangul.lo: harfbuzz-hangul.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-hangul.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-hangul.Tpo -c -o libhb_old_la-harfbuzz-hangul.lo `test -f 'harfbuzz-hangul.c' || echo '$(srcdir)/'`harfbuzz-hangul.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-hangul.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-hangul.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-hangul.c' object='libhb_old_la-harfbuzz-hangul.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-hangul.lo `test -f 'harfbuzz-hangul.c' || echo '$(srcdir)/'`harfbuzz-hangul.c - -libhb_old_la-harfbuzz-myanmar.lo: harfbuzz-myanmar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_old_la-harfbuzz-myanmar.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-myanmar.Tpo -c -o libhb_old_la-harfbuzz-myanmar.lo `test -f 'harfbuzz-myanmar.c' || echo '$(srcdir)/'`harfbuzz-myanmar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-myanmar.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-myanmar.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='harfbuzz-myanmar.c' object='libhb_old_la-harfbuzz-myanmar.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_old_la-harfbuzz-myanmar.lo `test -f 'harfbuzz-myanmar.c' || echo '$(srcdir)/'`harfbuzz-myanmar.c - -.cpp.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cpp.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cpp.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -libhb_old_la-harfbuzz-shaper.lo: harfbuzz-shaper.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhb_old_la-harfbuzz-shaper.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-shaper.Tpo -c -o libhb_old_la-harfbuzz-shaper.lo `test -f 'harfbuzz-shaper.cpp' || echo '$(srcdir)/'`harfbuzz-shaper.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-shaper.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-shaper.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='harfbuzz-shaper.cpp' object='libhb_old_la-harfbuzz-shaper.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhb_old_la-harfbuzz-shaper.lo `test -f 'harfbuzz-shaper.cpp' || echo '$(srcdir)/'`harfbuzz-shaper.cpp - -libhb_old_la-harfbuzz-indic.lo: harfbuzz-indic.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhb_old_la-harfbuzz-indic.lo -MD -MP -MF $(DEPDIR)/libhb_old_la-harfbuzz-indic.Tpo -c -o libhb_old_la-harfbuzz-indic.lo `test -f 'harfbuzz-indic.cpp' || echo '$(srcdir)/'`harfbuzz-indic.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_old_la-harfbuzz-indic.Tpo $(DEPDIR)/libhb_old_la-harfbuzz-indic.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='harfbuzz-indic.cpp' object='libhb_old_la-harfbuzz-indic.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_old_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhb_old_la-harfbuzz-indic.lo `test -f 'harfbuzz-indic.cpp' || echo '$(srcdir)/'`harfbuzz-indic.cpp - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am - - --include $(top_srcdir)/git.mk - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/hb-old/README b/src/hb-old/README deleted file mode 100644 index a29344a..0000000 --- a/src/hb-old/README +++ /dev/null @@ -1,7 +0,0 @@ -This is HarfBuzz-old, an OpenType Layout engine library. - -To report bugs or post to discussion mailing list, see: - - http://freedesktop.org/wiki/Software/HarfBuzz - -For license information, see the file COPYING. diff --git a/src/hb-old/harfbuzz-arabic.c b/src/hb-old/harfbuzz-arabic.c deleted file mode 100644 index 51f839a..0000000 --- a/src/hb-old/harfbuzz-arabic.c +++ /dev/null @@ -1,1150 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" - -#include <assert.h> - -static const HB_UChar16 ReplacementCharacter = 0xfffd; - -typedef struct { - unsigned char shape; - unsigned char justification; -} HB_ArabicProperties; - -typedef enum { - XIsolated, - XFinal, - XInitial, - XMedial, - /* intermediate state */ - XCausing -} ArabicShape; - -/* -// these groups correspond to the groups defined in the Unicode standard. -// Some of these groups are equal with regards to both joining and line breaking behaviour, -// and thus have the same enum value -// -// I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as -// I couldn't find any better document I'll hope for the best. -*/ -typedef enum { - /* NonJoining */ - ArabicNone, - ArabicSpace, - /* Transparent */ - Transparent, - /* Causing */ - Center, - Kashida, - - /* Arabic */ - /* Dual */ - Beh, - Noon, - Meem = Noon, - Heh = Noon, - KnottedHeh = Noon, - HehGoal = Noon, - SwashKaf = Noon, - Yeh, - Hah, - Seen, - Sad = Seen, - Tah, - Kaf = Tah, - Gaf = Tah, - Lam = Tah, - Ain, - Feh = Ain, - Qaf = Ain, - /* Right */ - Alef, - Waw, - Dal, - TehMarbuta = Dal, - Reh, - HamzaOnHehGoal, - YehWithTail = HamzaOnHehGoal, - YehBarre = HamzaOnHehGoal, - - /* Syriac */ - /* Dual */ - Beth = Beh, - Gamal = Ain, - Heth = Noon, - Teth = Hah, - Yudh = Noon, - Kaph = Noon, - Lamadh = Lam, - Mim = Noon, - Nun = Noon, - Semakh = Noon, - FinalSemakh = Noon, - SyriacE = Ain, - Pe = Ain, - ReversedPe = Hah, - Qaph = Noon, - Shin = Noon, - Fe = Ain, - - /* Right */ - Alaph = Alef, - Dalath = Dal, - He = Dal, - SyriacWaw = Waw, - Zain = Alef, - YudhHe = Waw, - Sadhe = HamzaOnHehGoal, - Taw = Dal, - - /* Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1. */ - Dummy = HamzaOnHehGoal, - ArabicGroupsEnd -} ArabicGroup; - -static const unsigned char arabic_group[0x150] = { - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - - Transparent, Transparent, Transparent, Transparent, - Transparent, Transparent, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - - ArabicNone, ArabicNone, Alef, Alef, - Waw, Alef, Yeh, Alef, - Beh, TehMarbuta, Beh, Beh, - Hah, Hah, Hah, Dal, - - Dal, Reh, Reh, Seen, - Seen, Sad, Sad, Tah, - Tah, Ain, Ain, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - - /* 0x640 */ - Kashida, Feh, Qaf, Kaf, - Lam, Meem, Noon, Heh, - Waw, Yeh, Yeh, Transparent, - Transparent, Transparent, Transparent, Transparent, - - Transparent, Transparent, Transparent, Transparent, - Transparent, Transparent, Transparent, Transparent, - Transparent, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, Beh, Qaf, - - Transparent, Alef, Alef, Alef, - ArabicNone, Alef, Waw, Waw, - Yeh, Beh, Beh, Beh, - Beh, Beh, Beh, Beh, - - /* 0x680 */ - Beh, Hah, Hah, Hah, - Hah, Hah, Hah, Hah, - Dal, Dal, Dal, Dal, - Dal, Dal, Dal, Dal, - - Dal, Reh, Reh, Reh, - Reh, Reh, Reh, Reh, - Reh, Reh, Seen, Seen, - Seen, Sad, Sad, Tah, - - Ain, Feh, Feh, Feh, - Feh, Feh, Feh, Qaf, - Qaf, Gaf, SwashKaf, Gaf, - Kaf, Kaf, Kaf, Gaf, - - Gaf, Gaf, Gaf, Gaf, - Gaf, Lam, Lam, Lam, - Lam, Noon, Noon, Noon, - Noon, Noon, KnottedHeh, Hah, - - /* 0x6c0 */ - TehMarbuta, HehGoal, HamzaOnHehGoal, HamzaOnHehGoal, - Waw, Waw, Waw, Waw, - Waw, Waw, Waw, Waw, - Yeh, YehWithTail, Yeh, Waw, - - Yeh, Yeh, YehBarre, YehBarre, - ArabicNone, TehMarbuta, Transparent, Transparent, - Transparent, Transparent, Transparent, Transparent, - Transparent, ArabicNone, ArabicNone, Transparent, - - Transparent, Transparent, Transparent, Transparent, - Transparent, ArabicNone, ArabicNone, Transparent, - Transparent, ArabicNone, Transparent, Transparent, - Transparent, Transparent, Dal, Reh, - - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, Seen, Sad, - Ain, ArabicNone, ArabicNone, KnottedHeh, - - /* 0x700 */ - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - ArabicNone, ArabicNone, ArabicNone, ArabicNone, - - Alaph, Transparent, Beth, Gamal, - Gamal, Dalath, Dalath, He, - SyriacWaw, Zain, Heth, Teth, - Teth, Yudh, YudhHe, Kaph, - - Lamadh, Mim, Nun, Semakh, - FinalSemakh, SyriacE, Pe, ReversedPe, - Sadhe, Qaph, Dalath, Shin, - Taw, Beth, Gamal, Dalath, - - Transparent, Transparent, Transparent, Transparent, - Transparent, Transparent, Transparent, Transparent, - Transparent, Transparent, Transparent, Transparent, - Transparent, Transparent, Transparent, Transparent, - - Transparent, Transparent, Transparent, Transparent, - Transparent, Transparent, Transparent, Transparent, - Transparent, Transparent, Transparent, ArabicNone, - ArabicNone, Zain, Kaph, Fe, -}; - -static ArabicGroup arabicGroup(unsigned short uc) -{ - if (uc >= 0x0600 && uc < 0x750) - return (ArabicGroup) arabic_group[uc-0x600]; - else if (uc == 0x200d) - return Center; - else if (HB_GetUnicodeCharCategory(uc) == HB_Separator_Space) - return ArabicSpace; - else - return ArabicNone; -} - - -/* - Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on - arabic). - - Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent). - transparent joining is not encoded in HB_UChar16::joining(), but applies to all combining marks and format marks. - - Right join-causing: dual + center - Left join-causing: dual + right + center - - Rules are as follows (for a string already in visual order, as we have it here): - - R1 Transparent characters do not affect joining behaviour. - R2 A right joining character, that has a right join-causing char on the right will get form XRight - (R3 A left joining character, that has a left join-causing char on the left will get form XLeft) - Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode - R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on - the right will get form XMedial - R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left - will get form XRight - R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right - will get form XLeft - R7 Otherwise the character will get form XIsolated - - Additionally we have to do the minimal ligature support for lam-alef ligatures: - - L1 Transparent characters do not affect ligature behaviour. - L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft) - L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated) - - The state table below handles rules R1-R7. -*/ - -typedef enum { - JNone, - JCausing, - JDual, - JRight, - JTransparent -} Joining; - -static const Joining joining_for_group[ArabicGroupsEnd] = { - /* NonJoining */ - JNone, /* ArabicNone */ - JNone, /* ArabicSpace */ - /* Transparent */ - JTransparent, /* Transparent */ - /* Causing */ - JCausing, /* Center */ - JCausing, /* Kashida */ - /* Dual */ - JDual, /* Beh */ - JDual, /* Noon */ - JDual, /* Yeh */ - JDual, /* Hah */ - JDual, /* Seen */ - JDual, /* Tah */ - JDual, /* Ain */ - /* Right */ - JRight, /* Alef */ - JRight, /* Waw */ - JRight, /* Dal */ - JRight, /* Reh */ - JRight /* HamzaOnHehGoal */ -}; - - -typedef struct { - ArabicShape form1; - ArabicShape form2; -} JoiningPair; - -static const JoiningPair joining_table[5][4] = -/* None, Causing, Dual, Right */ -{ - { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, /* XIsolated */ - { { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, /* XFinal */ - { { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, /* XInitial */ - { { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, /* XMedial */ - { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, /* XCausing */ -}; - - -/* -According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp - -1. Find the priority of the connecting opportunities in each word -2. Add expansion at the highest priority connection opportunity -3. If more than one connection opportunity have the same highest value, - use the opportunity closest to the end of the word. - -Following is a chart that provides the priority for connection -opportunities and where expansion occurs. The character group names -are those in table 6.6 of the UNICODE 2.0 book. - - -PrioritY Glyph Condition Kashida Location - -Arabic_Kashida User inserted Kashida The user entered a Kashida in a position. After the user - (Shift+j or Shift+[E with hat]) Thus, it is the highest priority to insert an inserted kashida - automatic kashida. - -Arabic_Seen Seen, Sad Connecting to the next character. After the character. - (Initial or medial form). - -Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form - of these characters. - -Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form - Kaf and Gaf of these characters. - -Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial Baa - -Arabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of - these characters. - -Arabic_Normal Other connecting Connecting to previous character. Before the final form - characters of these characters. - - - -This seems to imply that we have at most one kashida point per arabic word. - -*/ - -static void getArabicProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties) -{ -/* qDebug("arabicSyriacOpenTypeShape: properties:"); */ - int lastPos = 0; - int lastGroup = ArabicNone; - int i = 0; - - ArabicGroup group = arabicGroup(chars[0]); - Joining j = joining_for_group[group]; - ArabicShape shape = joining_table[XIsolated][j].form2; - properties[0].justification = HB_NoJustification; - - for (i = 1; i < len; ++i) { - /* #### fix handling for spaces and punktuation */ - properties[i].justification = HB_NoJustification; - - group = arabicGroup(chars[i]); - j = joining_for_group[group]; - - if (j == JTransparent) { - properties[i].shape = XIsolated; - continue; - } - - properties[lastPos].shape = joining_table[shape][j].form1; - shape = joining_table[shape][j].form2; - - switch(lastGroup) { - case Seen: - if (properties[lastPos].shape == XInitial || properties[lastPos].shape == XMedial) - properties[i-1].justification = HB_Arabic_Seen; - break; - case Hah: - if (properties[lastPos].shape == XFinal) - properties[lastPos-1].justification = HB_Arabic_HaaDal; - break; - case Alef: - if (properties[lastPos].shape == XFinal) - properties[lastPos-1].justification = HB_Arabic_Alef; - break; - case Ain: - if (properties[lastPos].shape == XFinal) - properties[lastPos-1].justification = HB_Arabic_Waw; - break; - case Noon: - if (properties[lastPos].shape == XFinal) - properties[lastPos-1].justification = HB_Arabic_Normal; - break; - case ArabicNone: - break; - - default: - assert(FALSE); - } - - lastGroup = ArabicNone; - - switch(group) { - case ArabicNone: - case Transparent: - /* ### Center should probably be treated as transparent when it comes to justification. */ - case Center: - break; - case ArabicSpace: - properties[i].justification = HB_Arabic_Space; - break; - case Kashida: - properties[i].justification = HB_Arabic_Kashida; - break; - case Seen: - lastGroup = Seen; - break; - - case Hah: - case Dal: - lastGroup = Hah; - break; - - case Alef: - case Tah: - lastGroup = Alef; - break; - - case Yeh: - case Reh: - if (properties[lastPos].shape == XMedial && arabicGroup(chars[lastPos]) == Beh) - properties[lastPos-1].justification = HB_Arabic_BaRa; - break; - - case Ain: - case Waw: - lastGroup = Ain; - break; - - case Noon: - case Beh: - case HamzaOnHehGoal: - lastGroup = Noon; - break; - case ArabicGroupsEnd: - assert(FALSE); - } - - lastPos = i; - } - properties[lastPos].shape = joining_table[shape][JNone].form1; - - - /* - for (int i = 0; i < len; ++i) - qDebug("arabic properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification); - */ -} - -static Joining getNkoJoining(unsigned short uc) -{ - if (uc < 0x7ca) - return JNone; - if (uc <= 0x7ea) - return JDual; - if (uc <= 0x7f3) - return JTransparent; - if (uc <= 0x7f9) - return JNone; - if (uc == 0x7fa) - return JCausing; - return JNone; -} - -static void getNkoProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties) -{ - int lastPos = 0; - int i = 0; - - Joining j = getNkoJoining(chars[0]); - ArabicShape shape = joining_table[XIsolated][j].form2; - properties[0].justification = HB_NoJustification; - - for (i = 1; i < len; ++i) { - properties[i].justification = (HB_GetUnicodeCharCategory(chars[i]) == HB_Separator_Space) ? - ArabicSpace : ArabicNone; - - j = getNkoJoining(chars[i]); - - if (j == JTransparent) { - properties[i].shape = XIsolated; - continue; - } - - properties[lastPos].shape = joining_table[shape][j].form1; - shape = joining_table[shape][j].form2; - - - lastPos = i; - } - properties[lastPos].shape = joining_table[shape][JNone].form1; - - - /* - for (int i = 0; i < len; ++i) - qDebug("nko properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification); - */ -} - -/* -// The unicode to unicode shaping codec. -// does only presentation forms B at the moment, but that should be enough for -// simple display -*/ -static const hb_uint16 arabicUnicodeMapping[256][2] = { - /* base of shaped forms, and number-1 of them (0 for non shaping, - 1 for right binding and 3 for dual binding */ - - /* These are just the glyphs available in Unicode, - some characters are in R class, but have no glyphs in Unicode. */ - - { 0x0600, 0 }, /* 0x0600 */ - { 0x0601, 0 }, /* 0x0601 */ - { 0x0602, 0 }, /* 0x0602 */ - { 0x0603, 0 }, /* 0x0603 */ - { 0x0604, 0 }, /* 0x0604 */ - { 0x0605, 0 }, /* 0x0605 */ - { 0x0606, 0 }, /* 0x0606 */ - { 0x0607, 0 }, /* 0x0607 */ - { 0x0608, 0 }, /* 0x0608 */ - { 0x0609, 0 }, /* 0x0609 */ - { 0x060A, 0 }, /* 0x060A */ - { 0x060B, 0 }, /* 0x060B */ - { 0x060C, 0 }, /* 0x060C */ - { 0x060D, 0 }, /* 0x060D */ - { 0x060E, 0 }, /* 0x060E */ - { 0x060F, 0 }, /* 0x060F */ - - { 0x0610, 0 }, /* 0x0610 */ - { 0x0611, 0 }, /* 0x0611 */ - { 0x0612, 0 }, /* 0x0612 */ - { 0x0613, 0 }, /* 0x0613 */ - { 0x0614, 0 }, /* 0x0614 */ - { 0x0615, 0 }, /* 0x0615 */ - { 0x0616, 0 }, /* 0x0616 */ - { 0x0617, 0 }, /* 0x0617 */ - { 0x0618, 0 }, /* 0x0618 */ - { 0x0619, 0 }, /* 0x0619 */ - { 0x061A, 0 }, /* 0x061A */ - { 0x061B, 0 }, /* 0x061B */ - { 0x061C, 0 }, /* 0x061C */ - { 0x061D, 0 }, /* 0x061D */ - { 0x061E, 0 }, /* 0x061E */ - { 0x061F, 0 }, /* 0x061F */ - - { 0x0620, 0 }, /* 0x0620 */ - { 0xFE80, 0 }, /* 0x0621 HAMZA */ - { 0xFE81, 1 }, /* 0x0622 R ALEF WITH MADDA ABOVE */ - { 0xFE83, 1 }, /* 0x0623 R ALEF WITH HAMZA ABOVE */ - { 0xFE85, 1 }, /* 0x0624 R WAW WITH HAMZA ABOVE */ - { 0xFE87, 1 }, /* 0x0625 R ALEF WITH HAMZA BELOW */ - { 0xFE89, 3 }, /* 0x0626 D YEH WITH HAMZA ABOVE */ - { 0xFE8D, 1 }, /* 0x0627 R ALEF */ - { 0xFE8F, 3 }, /* 0x0628 D BEH */ - { 0xFE93, 1 }, /* 0x0629 R TEH MARBUTA */ - { 0xFE95, 3 }, /* 0x062A D TEH */ - { 0xFE99, 3 }, /* 0x062B D THEH */ - { 0xFE9D, 3 }, /* 0x062C D JEEM */ - { 0xFEA1, 3 }, /* 0x062D D HAH */ - { 0xFEA5, 3 }, /* 0x062E D KHAH */ - { 0xFEA9, 1 }, /* 0x062F R DAL */ - - { 0xFEAB, 1 }, /* 0x0630 R THAL */ - { 0xFEAD, 1 }, /* 0x0631 R REH */ - { 0xFEAF, 1 }, /* 0x0632 R ZAIN */ - { 0xFEB1, 3 }, /* 0x0633 D SEEN */ - { 0xFEB5, 3 }, /* 0x0634 D SHEEN */ - { 0xFEB9, 3 }, /* 0x0635 D SAD */ - { 0xFEBD, 3 }, /* 0x0636 D DAD */ - { 0xFEC1, 3 }, /* 0x0637 D TAH */ - { 0xFEC5, 3 }, /* 0x0638 D ZAH */ - { 0xFEC9, 3 }, /* 0x0639 D AIN */ - { 0xFECD, 3 }, /* 0x063A D GHAIN */ - { 0x063B, 0 }, /* 0x063B */ - { 0x063C, 0 }, /* 0x063C */ - { 0x063D, 0 }, /* 0x063D */ - { 0x063E, 0 }, /* 0x063E */ - { 0x063F, 0 }, /* 0x063F */ - - { 0x0640, 0 }, /* 0x0640 C TATWEEL // ### Join Causing, only one glyph */ - { 0xFED1, 3 }, /* 0x0641 D FEH */ - { 0xFED5, 3 }, /* 0x0642 D QAF */ - { 0xFED9, 3 }, /* 0x0643 D KAF */ - { 0xFEDD, 3 }, /* 0x0644 D LAM */ - { 0xFEE1, 3 }, /* 0x0645 D MEEM */ - { 0xFEE5, 3 }, /* 0x0646 D NOON */ - { 0xFEE9, 3 }, /* 0x0647 D HEH */ - { 0xFEED, 1 }, /* 0x0648 R WAW */ - { 0x0649, 3 }, /* 0x0649 ALEF MAKSURA // ### Dual, glyphs not consecutive, handle in code. */ - { 0xFEF1, 3 }, /* 0x064A D YEH */ - { 0x064B, 0 }, /* 0x064B */ - { 0x064C, 0 }, /* 0x064C */ - { 0x064D, 0 }, /* 0x064D */ - { 0x064E, 0 }, /* 0x064E */ - { 0x064F, 0 }, /* 0x064F */ - - { 0x0650, 0 }, /* 0x0650 */ - { 0x0651, 0 }, /* 0x0651 */ - { 0x0652, 0 }, /* 0x0652 */ - { 0x0653, 0 }, /* 0x0653 */ - { 0x0654, 0 }, /* 0x0654 */ - { 0x0655, 0 }, /* 0x0655 */ - { 0x0656, 0 }, /* 0x0656 */ - { 0x0657, 0 }, /* 0x0657 */ - { 0x0658, 0 }, /* 0x0658 */ - { 0x0659, 0 }, /* 0x0659 */ - { 0x065A, 0 }, /* 0x065A */ - { 0x065B, 0 }, /* 0x065B */ - { 0x065C, 0 }, /* 0x065C */ - { 0x065D, 0 }, /* 0x065D */ - { 0x065E, 0 }, /* 0x065E */ - { 0x065F, 0 }, /* 0x065F */ - - { 0x0660, 0 }, /* 0x0660 */ - { 0x0661, 0 }, /* 0x0661 */ - { 0x0662, 0 }, /* 0x0662 */ - { 0x0663, 0 }, /* 0x0663 */ - { 0x0664, 0 }, /* 0x0664 */ - { 0x0665, 0 }, /* 0x0665 */ - { 0x0666, 0 }, /* 0x0666 */ - { 0x0667, 0 }, /* 0x0667 */ - { 0x0668, 0 }, /* 0x0668 */ - { 0x0669, 0 }, /* 0x0669 */ - { 0x066A, 0 }, /* 0x066A */ - { 0x066B, 0 }, /* 0x066B */ - { 0x066C, 0 }, /* 0x066C */ - { 0x066D, 0 }, /* 0x066D */ - { 0x066E, 0 }, /* 0x066E */ - { 0x066F, 0 }, /* 0x066F */ - - { 0x0670, 0 }, /* 0x0670 */ - { 0xFB50, 1 }, /* 0x0671 R ALEF WASLA */ - { 0x0672, 0 }, /* 0x0672 */ - { 0x0673, 0 }, /* 0x0673 */ - { 0x0674, 0 }, /* 0x0674 */ - { 0x0675, 0 }, /* 0x0675 */ - { 0x0676, 0 }, /* 0x0676 */ - { 0x0677, 0 }, /* 0x0677 */ - { 0x0678, 0 }, /* 0x0678 */ - { 0xFB66, 3 }, /* 0x0679 D TTEH */ - { 0xFB5E, 3 }, /* 0x067A D TTEHEH */ - { 0xFB52, 3 }, /* 0x067B D BEEH */ - { 0x067C, 0 }, /* 0x067C */ - { 0x067D, 0 }, /* 0x067D */ - { 0xFB56, 3 }, /* 0x067E D PEH */ - { 0xFB62, 3 }, /* 0x067F D TEHEH */ - - { 0xFB5A, 3 }, /* 0x0680 D BEHEH */ - { 0x0681, 0 }, /* 0x0681 */ - { 0x0682, 0 }, /* 0x0682 */ - { 0xFB76, 3 }, /* 0x0683 D NYEH */ - { 0xFB72, 3 }, /* 0x0684 D DYEH */ - { 0x0685, 0 }, /* 0x0685 */ - { 0xFB7A, 3 }, /* 0x0686 D TCHEH */ - { 0xFB7E, 3 }, /* 0x0687 D TCHEHEH */ - { 0xFB88, 1 }, /* 0x0688 R DDAL */ - { 0x0689, 0 }, /* 0x0689 */ - { 0x068A, 0 }, /* 0x068A */ - { 0x068B, 0 }, /* 0x068B */ - { 0xFB84, 1 }, /* 0x068C R DAHAL */ - { 0xFB82, 1 }, /* 0x068D R DDAHAL */ - { 0xFB86, 1 }, /* 0x068E R DUL */ - { 0x068F, 0 }, /* 0x068F */ - - { 0x0690, 0 }, /* 0x0690 */ - { 0xFB8C, 1 }, /* 0x0691 R RREH */ - { 0x0692, 0 }, /* 0x0692 */ - { 0x0693, 0 }, /* 0x0693 */ - { 0x0694, 0 }, /* 0x0694 */ - { 0x0695, 0 }, /* 0x0695 */ - { 0x0696, 0 }, /* 0x0696 */ - { 0x0697, 0 }, /* 0x0697 */ - { 0xFB8A, 1 }, /* 0x0698 R JEH */ - { 0x0699, 0 }, /* 0x0699 */ - { 0x069A, 0 }, /* 0x069A */ - { 0x069B, 0 }, /* 0x069B */ - { 0x069C, 0 }, /* 0x069C */ - { 0x069D, 0 }, /* 0x069D */ - { 0x069E, 0 }, /* 0x069E */ - { 0x069F, 0 }, /* 0x069F */ - - { 0x06A0, 0 }, /* 0x06A0 */ - { 0x06A1, 0 }, /* 0x06A1 */ - { 0x06A2, 0 }, /* 0x06A2 */ - { 0x06A3, 0 }, /* 0x06A3 */ - { 0xFB6A, 3 }, /* 0x06A4 D VEH */ - { 0x06A5, 0 }, /* 0x06A5 */ - { 0xFB6E, 3 }, /* 0x06A6 D PEHEH */ - { 0x06A7, 0 }, /* 0x06A7 */ - { 0x06A8, 0 }, /* 0x06A8 */ - { 0xFB8E, 3 }, /* 0x06A9 D KEHEH */ - { 0x06AA, 0 }, /* 0x06AA */ - { 0x06AB, 0 }, /* 0x06AB */ - { 0x06AC, 0 }, /* 0x06AC */ - { 0xFBD3, 3 }, /* 0x06AD D NG */ - { 0x06AE, 0 }, /* 0x06AE */ - { 0xFB92, 3 }, /* 0x06AF D GAF */ - - { 0x06B0, 0 }, /* 0x06B0 */ - { 0xFB9A, 3 }, /* 0x06B1 D NGOEH */ - { 0x06B2, 0 }, /* 0x06B2 */ - { 0xFB96, 3 }, /* 0x06B3 D GUEH */ - { 0x06B4, 0 }, /* 0x06B4 */ - { 0x06B5, 0 }, /* 0x06B5 */ - { 0x06B6, 0 }, /* 0x06B6 */ - { 0x06B7, 0 }, /* 0x06B7 */ - { 0x06B8, 0 }, /* 0x06B8 */ - { 0x06B9, 0 }, /* 0x06B9 */ - { 0xFB9E, 1 }, /* 0x06BA R NOON GHUNNA */ - { 0xFBA0, 3 }, /* 0x06BB D RNOON */ - { 0x06BC, 0 }, /* 0x06BC */ - { 0x06BD, 0 }, /* 0x06BD */ - { 0xFBAA, 3 }, /* 0x06BE D HEH DOACHASHMEE */ - { 0x06BF, 0 }, /* 0x06BF */ - - { 0xFBA4, 1 }, /* 0x06C0 R HEH WITH YEH ABOVE */ - { 0xFBA6, 3 }, /* 0x06C1 D HEH GOAL */ - { 0x06C2, 0 }, /* 0x06C2 */ - { 0x06C3, 0 }, /* 0x06C3 */ - { 0x06C4, 0 }, /* 0x06C4 */ - { 0xFBE0, 1 }, /* 0x06C5 R KIRGHIZ OE */ - { 0xFBD9, 1 }, /* 0x06C6 R OE */ - { 0xFBD7, 1 }, /* 0x06C7 R U */ - { 0xFBDB, 1 }, /* 0x06C8 R YU */ - { 0xFBE2, 1 }, /* 0x06C9 R KIRGHIZ YU */ - { 0x06CA, 0 }, /* 0x06CA */ - { 0xFBDE, 1 }, /* 0x06CB R VE */ - { 0xFBFC, 3 }, /* 0x06CC D FARSI YEH */ - { 0x06CD, 0 }, /* 0x06CD */ - { 0x06CE, 0 }, /* 0x06CE */ - { 0x06CF, 0 }, /* 0x06CF */ - - { 0xFBE4, 3 }, /* 0x06D0 D E */ - { 0x06D1, 0 }, /* 0x06D1 */ - { 0xFBAE, 1 }, /* 0x06D2 R YEH BARREE */ - { 0xFBB0, 1 }, /* 0x06D3 R YEH BARREE WITH HAMZA ABOVE */ - { 0x06D4, 0 }, /* 0x06D4 */ - { 0x06D5, 0 }, /* 0x06D5 */ - { 0x06D6, 0 }, /* 0x06D6 */ - { 0x06D7, 0 }, /* 0x06D7 */ - { 0x06D8, 0 }, /* 0x06D8 */ - { 0x06D9, 0 }, /* 0x06D9 */ - { 0x06DA, 0 }, /* 0x06DA */ - { 0x06DB, 0 }, /* 0x06DB */ - { 0x06DC, 0 }, /* 0x06DC */ - { 0x06DD, 0 }, /* 0x06DD */ - { 0x06DE, 0 }, /* 0x06DE */ - { 0x06DF, 0 }, /* 0x06DF */ - - { 0x06E0, 0 }, /* 0x06E0 */ - { 0x06E1, 0 }, /* 0x06E1 */ - { 0x06E2, 0 }, /* 0x06E2 */ - { 0x06E3, 0 }, /* 0x06E3 */ - { 0x06E4, 0 }, /* 0x06E4 */ - { 0x06E5, 0 }, /* 0x06E5 */ - { 0x06E6, 0 }, /* 0x06E6 */ - { 0x06E7, 0 }, /* 0x06E7 */ - { 0x06E8, 0 }, /* 0x06E8 */ - { 0x06E9, 0 }, /* 0x06E9 */ - { 0x06EA, 0 }, /* 0x06EA */ - { 0x06EB, 0 }, /* 0x06EB */ - { 0x06EC, 0 }, /* 0x06EC */ - { 0x06ED, 0 }, /* 0x06ED */ - { 0x06EE, 0 }, /* 0x06EE */ - { 0x06EF, 0 }, /* 0x06EF */ - - { 0x06F0, 0 }, /* 0x06F0 */ - { 0x06F1, 0 }, /* 0x06F1 */ - { 0x06F2, 0 }, /* 0x06F2 */ - { 0x06F3, 0 }, /* 0x06F3 */ - { 0x06F4, 0 }, /* 0x06F4 */ - { 0x06F5, 0 }, /* 0x06F5 */ - { 0x06F6, 0 }, /* 0x06F6 */ - { 0x06F7, 0 }, /* 0x06F7 */ - { 0x06F8, 0 }, /* 0x06F8 */ - { 0x06F9, 0 }, /* 0x06F9 */ - { 0x06FA, 0 }, /* 0x06FA */ - { 0x06FB, 0 }, /* 0x06FB */ - { 0x06FC, 0 }, /* 0x06FC */ - { 0x06FD, 0 }, /* 0x06FD */ - { 0x06FE, 0 }, /* 0x06FE */ - { 0x06FF, 0 } /* 0x06FF */ -}; - -/* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, this table does */ -static const hb_uint16 alefMaksura[4] = {0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9}; - -/* -// this is a bit tricky. Alef always binds to the right, so the second parameter descibing the shape -// of the lam can be either initial of medial. So initial maps to the isolated form of the ligature, -// medial to the final form -*/ -static const hb_uint16 arabicUnicodeLamAlefMapping[6][4] = { - { 0xfffd, 0xfffd, 0xfef5, 0xfef6 }, /* 0x622 R Alef with Madda above */ - { 0xfffd, 0xfffd, 0xfef7, 0xfef8 }, /* 0x623 R Alef with Hamza above */ - { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x624 // Just to fill the table ;-) */ - { 0xfffd, 0xfffd, 0xfef9, 0xfefa }, /* 0x625 R Alef with Hamza below */ - { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x626 // Just to fill the table ;-) */ - { 0xfffd, 0xfffd, 0xfefb, 0xfefc } /* 0x627 R Alef */ -}; - -static int getShape(hb_uint8 cell, int shape) -{ - /* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, handle this here */ - int ch = (cell != 0x49) - ? (shape ? arabicUnicodeMapping[cell][0] + shape : 0x600+cell) - : alefMaksura[shape] ; - return ch; -} - - -/* - Two small helper functions for arabic shaping. -*/ -static HB_UChar16 prevChar(const HB_UChar16 *str, int pos) -{ - /*qDebug("leftChar: pos=%d", pos); */ - const HB_UChar16 *ch = str + pos - 1; - pos--; - while(pos > -1) { - if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing) - return *ch; - pos--; - ch--; - } - return ReplacementCharacter; -} - -static HB_UChar16 nextChar(const HB_UChar16 *str, hb_uint32 len, hb_uint32 pos) -{ - const HB_UChar16 *ch = str + pos + 1; - pos++; - while(pos < len) { - /*qDebug("rightChar: %d isLetter=%d, joining=%d", pos, ch.isLetter(), ch.joining()); */ - if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing) - return *ch; - /* assume it's a transparent char, this might not be 100% correct */ - pos++; - ch++; - } - return ReplacementCharacter; -} - -static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 from, hb_uint32 len, HB_UChar16 *shapeBuffer, int *shapedLength, - HB_Bool reverse, HB_GlyphAttributes *attributes, unsigned short *logClusters) -{ - HB_ArabicProperties *properties; - hb_int32 f = from; - hb_uint32 l = len; - const HB_UChar16 *ch; - HB_UChar16 *data; - int clusterStart; - hb_uint32 i; - HB_STACKARRAY(HB_ArabicProperties, props, len + 2); - properties = props; - - assert(stringLength >= from + len); - - if(len == 0) { - *shapedLength = 0; - return; - } - - if (from > 0) { - --f; - ++l; - ++properties; - } - if (f + l < stringLength) - ++l; - getArabicProperties(uc+f, l, props); - - ch = uc + from; - data = shapeBuffer; - clusterStart = 0; - - for (i = 0; i < len; i++) { - hb_uint8 r = *ch >> 8; - int gpos = data - shapeBuffer; - - if (r != 0x06) { - if (r == 0x20) { - if (*ch == 0x200c || *ch == 0x200d) - /* remove ZWJ and ZWNJ */ - goto skip; - } - if (reverse) - *data = HB_GetMirroredChar(*ch); - else - *data = *ch; - } else { - hb_uint8 c = *ch & 0xff; - int pos = i + from; - int shape = properties[i].shape; -/* qDebug("mapping U+%x to shape %d glyph=0x%x", ch->unicode(), shape, getShape(c, shape)); */ - /* take care of lam-alef ligatures (lam right of alef) */ - hb_uint16 map; - switch (c) { - case 0x44: { /* lam */ - const HB_UChar16 pch = nextChar(uc, stringLength, pos); - if ((pch >> 8) == 0x06) { - switch (pch & 0xff) { - case 0x22: - case 0x23: - case 0x25: - case 0x27: -/* qDebug(" lam of lam-alef ligature"); */ - map = arabicUnicodeLamAlefMapping[(pch & 0xff) - 0x22][shape]; - goto next; - default: - break; - } - } - break; - } - case 0x22: /* alef with madda */ - case 0x23: /* alef with hamza above */ - case 0x25: /* alef with hamza below */ - case 0x27: /* alef */ - if (prevChar(uc, pos) == 0x0644) { - /* have a lam alef ligature */ - /*qDebug(" alef of lam-alef ligature"); */ - goto skip; - } - default: - break; - } - map = getShape(c, shape); - next: - *data = map; - } - /* ##### Fixme */ - /*glyphs[gpos].attributes.zeroWidth = zeroWidth; */ - if (HB_GetUnicodeCharCategory(*ch) == HB_Mark_NonSpacing) { - attributes[gpos].mark = TRUE; -/* qDebug("glyph %d (char %d) is mark!", gpos, i); */ - } else { - attributes[gpos].mark = FALSE; - clusterStart = data - shapeBuffer; - } - attributes[gpos].clusterStart = !attributes[gpos].mark; - attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch); - attributes[gpos].justification = properties[i].justification; -/* qDebug("data[%d] = %x (from %x)", gpos, (uint)data->unicode(), ch->unicode());*/ - data++; - skip: - ch++; - logClusters[i] = clusterStart; - } - *shapedLength = data - shapeBuffer; - - HB_FREE_STACKARRAY(props); -} - -#ifndef NO_OPENTYPE - -static const HB_OpenTypeFeature arabic_features[] = { - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty }, - { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty }, - { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty }, - { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, - { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty }, - { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty }, - { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty }, - { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty }, - { HB_MAKE_TAG('c', 's', 'w', 'h'), CswhProperty }, - /* mset is used in old Win95 fonts that don't have a 'mark' positioning table. */ - { HB_MAKE_TAG('m', 's', 'e', 't'), MsetProperty }, - {0, 0} -}; - -static const HB_OpenTypeFeature syriac_features[] = { - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty }, - { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty }, - { HB_MAKE_TAG('f', 'i', 'n', '2'), FinaProperty }, - { HB_MAKE_TAG('f', 'i', 'n', '3'), FinaProperty }, - { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty }, - { HB_MAKE_TAG('m', 'e', 'd', '2'), MediProperty }, - { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, - { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty }, - { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty }, - { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty }, - { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty }, - {0, 0} -}; - -static HB_Bool arabicSyriacOpenTypeShape(HB_ShaperItem *item, HB_Bool *ot_ok) -{ - const HB_UChar16 *uc; - const int nglyphs = item->num_glyphs; - hb_int32 f; - hb_uint32 l; - HB_ArabicProperties *properties; - HB_DECLARE_STACKARRAY(HB_ArabicProperties, props) - HB_DECLARE_STACKARRAY(hb_uint32, apply) - HB_Bool shaped; - int i = 0; - - *ot_ok = TRUE; - - if (!HB_ConvertStringToGlyphIndices(item)) - return FALSE; - HB_HeuristicSetGlyphAttributes(item); - - HB_INIT_STACKARRAY(HB_ArabicProperties, props, item->item.length + 2); - HB_INIT_STACKARRAY(hb_uint32, apply, item->num_glyphs); - - uc = item->string + item->item.pos; - - properties = props; - f = 0; - l = item->item.length; - if (item->item.pos > 0) { - --f; - ++l; - ++properties; - } - if (f + l + item->item.pos < item->stringLength) { - ++l; - } - if (item->item.script == HB_Script_Nko) - getNkoProperties(uc+f, l, props); - else - getArabicProperties(uc+f, l, props); - - for (i = 0; i < (int)item->num_glyphs; i++) { - apply[i] = 0; - - if (properties[i].shape == XIsolated) - apply[i] |= MediProperty|FinaProperty|InitProperty; - else if (properties[i].shape == XMedial) - apply[i] |= IsolProperty|FinaProperty|InitProperty; - else if (properties[i].shape == XFinal) - apply[i] |= IsolProperty|MediProperty|InitProperty; - else if (properties[i].shape == XInitial) - apply[i] |= IsolProperty|MediProperty|FinaProperty; - - item->attributes[i].justification = properties[i].justification; - } - - HB_FREE_STACKARRAY(props); - - shaped = HB_OpenTypeShape(item, apply); - - HB_FREE_STACKARRAY(apply); - - if (!shaped) { - *ot_ok = FALSE; - return FALSE; - } - return HB_OpenTypePosition(item, nglyphs, /*doLogClusters*/TRUE); -} - -#endif - -/* #### stil missing: identify invalid character combinations */ -HB_Bool HB_ArabicShape(HB_ShaperItem *item) -{ - int slen; - HB_Bool haveGlyphs; - HB_STACKARRAY(HB_UChar16, shapedChars, item->item.length); - - assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac - || item->item.script == HB_Script_Nko); - -#ifndef NO_OPENTYPE - - if (HB_SelectScript(item, item->item.script == HB_Script_Arabic ? arabic_features : syriac_features)) { - HB_Bool ot_ok; - if (arabicSyriacOpenTypeShape(item, &ot_ok)) { - HB_FREE_STACKARRAY(shapedChars); - return TRUE; - } - if (ot_ok) { - HB_FREE_STACKARRAY(shapedChars); - return FALSE; - /* fall through to the non OT code*/ - } - } -#endif - - if (item->item.script != HB_Script_Arabic) { - HB_FREE_STACKARRAY(shapedChars); - return HB_BasicShape(item); - } - - shapedString(item->string, item->stringLength, item->item.pos, item->item.length, shapedChars, &slen, - item->item.bidiLevel % 2, - item->attributes, item->log_clusters); - - haveGlyphs = item->font->klass - ->convertStringToGlyphIndices(item->font, - shapedChars, slen, - item->glyphs, &item->num_glyphs, - item->item.bidiLevel % 2); - - HB_FREE_STACKARRAY(shapedChars); - - if (!haveGlyphs) - return FALSE; - - HB_HeuristicPosition(item); - return TRUE; -} - - diff --git a/src/hb-old/harfbuzz-buffer-private.h b/src/hb-old/harfbuzz-buffer-private.h deleted file mode 100644 index 5065f2e..0000000 --- a/src/hb-old/harfbuzz-buffer-private.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2004,2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 - */ - -#ifndef HARFBUZZ_BUFFER_PRIVATE_H -#define HARFBUZZ_BUFFER_PRIVATE_H - -#include "harfbuzz-impl.h" -#include "harfbuzz-buffer.h" - -HB_BEGIN_HEADER - -#define HB_GLYPH_PROPERTIES_UNKNOWN 0xFFFF - -HB_INTERNAL void -_hb_buffer_swap( HB_Buffer buffer ); - -HB_INTERNAL void -_hb_buffer_clear_output( HB_Buffer buffer ); - -HB_INTERNAL HB_Error -_hb_buffer_clear_positions( HB_Buffer buffer ); - -HB_INTERNAL HB_Error -_hb_buffer_add_output_glyphs( HB_Buffer buffer, - HB_UShort num_in, - HB_UShort num_out, - HB_UShort *glyph_data, - HB_UShort component, - HB_UShort ligID ); - -HB_INTERNAL HB_Error -_hb_buffer_add_output_glyph ( HB_Buffer buffer, - HB_UInt glyph_index, - HB_UShort component, - HB_UShort ligID ); - -HB_INTERNAL HB_Error -_hb_buffer_copy_output_glyph ( HB_Buffer buffer ); - -HB_INTERNAL HB_Error -_hb_buffer_replace_output_glyph ( HB_Buffer buffer, - HB_UInt glyph_index, - HB_Bool inplace ); - -HB_INTERNAL HB_UShort -_hb_buffer_allocate_ligid( HB_Buffer buffer ); - - -/* convenience macros */ - -#define IN_GLYPH( pos ) (buffer->in_string[(pos)].gindex) -#define IN_ITEM( pos ) (&buffer->in_string[(pos)]) -#define IN_CURGLYPH() (buffer->in_string[buffer->in_pos].gindex) -#define IN_CURITEM() (&buffer->in_string[buffer->in_pos]) -#define IN_PROPERTIES( pos ) (buffer->in_string[(pos)].properties) -#define IN_LIGID( pos ) (buffer->in_string[(pos)].ligID) -#define IN_COMPONENT( pos ) (buffer->in_string[(pos)].component) -#define POSITION( pos ) (&buffer->positions[(pos)]) -#define OUT_GLYPH( pos ) (buffer->out_string[(pos)].gindex) -#define OUT_ITEM( pos ) (&buffer->out_string[(pos)]) - -#define CHECK_Property( gdef, index, flags, property ) \ - ( ( error = _HB_GDEF_Check_Property( (gdef), (index), (flags), \ - (property) ) ) != HB_Err_Ok ) - -#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \ - ( ( error = _hb_buffer_add_output_glyphs( (buffer), \ - (num_in), (num_out), \ - (glyph_data), (component), (ligID) \ - ) ) != HB_Err_Ok ) -#define ADD_Glyph( buffer, glyph_index, component, ligID ) \ - ( ( error = _hb_buffer_add_output_glyph( (buffer), \ - (glyph_index), (component), (ligID) \ - ) ) != HB_Err_Ok ) -#define REPLACE_Glyph( buffer, glyph_index, nesting_level ) \ - ( ( error = _hb_buffer_replace_output_glyph( (buffer), (glyph_index), \ - (nesting_level) == 1 ) ) != HB_Err_Ok ) -#define COPY_Glyph( buffer ) \ - ( (error = _hb_buffer_copy_output_glyph ( buffer ) ) != HB_Err_Ok ) - -HB_END_HEADER - -#endif /* HARFBUZZ_BUFFER_PRIVATE_H */ diff --git a/src/hb-old/harfbuzz-buffer.c b/src/hb-old/harfbuzz-buffer.c deleted file mode 100644 index a85ee8d..0000000 --- a/src/hb-old/harfbuzz-buffer.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2004,2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 - */ - -#include "harfbuzz-impl.h" -#include "harfbuzz-buffer-private.h" -#include "harfbuzz-gsub-private.h" -#include "harfbuzz-gpos-private.h" - -/* Here is how the buffer works internally: - * - * There are two string pointers: in_string and out_string. They - * always have same allocated size, but different length and positions. - * - * As an optimization, both in_string and out_string may point to the - * same piece of memory, which is owned by in_string. This remains the - * case as long as: - * - * - copy_glyph() is called - * - replace_glyph() is called with inplace=TRUE - * - add_output_glyph() and add_output_glyphs() are not called - * - * In that case swap(), and copy_glyph(), and replace_glyph() are all - * mostly no-op. - * - * As soon an add_output_glyph[s]() or replace_glyph() with inplace=FALSE is - * called, out_string is moved over to an alternate buffer (alt_string), and - * its current contents (out_length entries) are copied to the alt buffer. - * This should all remain transparent to the user. swap() then switches - * in_string and alt_string. alt_string is not allocated until its needed, - * but after that it's grown with in_string unconditionally. - * - * The buffer->separate_out boolean keeps status of whether out_string points - * to in_string (FALSE) or alt_string (TRUE). - */ - -/* Internal API */ - -static HB_Error -HB_Buffer_ensure( HB_Buffer buffer, - HB_UInt size ) -{ - HB_UInt new_allocated = buffer->allocated; - - if (size > new_allocated) - { - HB_Error error; - - while (size > new_allocated) - new_allocated += (new_allocated >> 1) + 8; - - if ( buffer->positions ) - { - if ( REALLOC_ARRAY( buffer->positions, new_allocated, HB_PositionRec ) ) - return error; - } - - if ( REALLOC_ARRAY( buffer->in_string, new_allocated, HB_GlyphItemRec ) ) - return error; - - if ( buffer->separate_out ) - { - if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) ) - return error; - - buffer->out_string = buffer->alt_string; - } - else - { - buffer->out_string = buffer->in_string; - - if ( buffer->alt_string ) - { - if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) ) - return error; - } - } - - buffer->allocated = new_allocated; - } - - return HB_Err_Ok; -} - -static HB_Error -HB_Buffer_duplicate_out_buffer( HB_Buffer buffer ) -{ - if ( !buffer->alt_string ) - { - HB_Error error; - - if ( ALLOC_ARRAY( buffer->alt_string, buffer->allocated, HB_GlyphItemRec ) ) - return error; - } - - buffer->out_string = buffer->alt_string; - memcpy( buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]) ); - buffer->separate_out = TRUE; - - return HB_Err_Ok; -} - -/* Public API */ - -HB_Error -HB_Buffer_new( HB_Buffer *pbuffer ) -{ - HB_Buffer buffer; - HB_Error error; - - if ( ALLOC( buffer, sizeof( HB_BufferRec ) ) ) - return error; - - buffer->allocated = 0; - buffer->in_string = NULL; - buffer->alt_string = NULL; - buffer->positions = NULL; - - HB_Buffer_clear( buffer ); - - *pbuffer = buffer; - - return HB_Err_Ok; -} - -void -HB_Buffer_free( HB_Buffer buffer ) -{ - FREE( buffer->in_string ); - FREE( buffer->alt_string ); - buffer->out_string = NULL; - FREE( buffer->positions ); - FREE( buffer ); -} - -void -HB_Buffer_clear( HB_Buffer buffer ) -{ - buffer->in_length = 0; - buffer->out_length = 0; - buffer->in_pos = 0; - buffer->out_pos = 0; - buffer->out_string = buffer->in_string; - buffer->separate_out = FALSE; - buffer->max_ligID = 0; -} - -HB_Error -HB_Buffer_add_glyph( HB_Buffer buffer, - HB_UInt glyph_index, - HB_UInt properties, - HB_UInt cluster ) -{ - HB_Error error; - HB_GlyphItem glyph; - - error = HB_Buffer_ensure( buffer, buffer->in_length + 1 ); - if ( error ) - return error; - - glyph = &buffer->in_string[buffer->in_length]; - glyph->gindex = glyph_index; - glyph->properties = properties; - glyph->cluster = cluster; - glyph->component = 0; - glyph->ligID = 0; - glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN; - - buffer->in_length++; - - return HB_Err_Ok; -} - -/* HarfBuzz-Internal API */ - -HB_INTERNAL void -_hb_buffer_clear_output( HB_Buffer buffer ) -{ - buffer->out_length = 0; - buffer->out_pos = 0; - buffer->out_string = buffer->in_string; - buffer->separate_out = FALSE; -} - -HB_INTERNAL HB_Error -_hb_buffer_clear_positions( HB_Buffer buffer ) -{ - if ( !buffer->positions ) - { - HB_Error error; - - if ( ALLOC_ARRAY( buffer->positions, buffer->allocated, HB_PositionRec ) ) - return error; - } - - memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length); - - return HB_Err_Ok; -} - -HB_INTERNAL void -_hb_buffer_swap( HB_Buffer buffer ) -{ - HB_GlyphItem tmp_string; - int tmp_length; - int tmp_pos; - - if ( buffer->separate_out ) - { - tmp_string = buffer->in_string; - buffer->in_string = buffer->out_string; - buffer->out_string = tmp_string; - buffer->alt_string = buffer->out_string; - } - - tmp_length = buffer->in_length; - buffer->in_length = buffer->out_length; - buffer->out_length = tmp_length; - - tmp_pos = buffer->in_pos; - buffer->in_pos = buffer->out_pos; - buffer->out_pos = tmp_pos; -} - -/* The following function copies `num_out' elements from `glyph_data' - to `buffer->out_string', advancing the in array pointer in the structure - by `num_in' elements, and the out array pointer by `num_out' elements. - Finally, it sets the `length' field of `out' equal to - `pos' of the `out' structure. - - If `component' is 0xFFFF, the component value from buffer->in_pos - will copied `num_out' times, otherwise `component' itself will - be used to fill the `component' fields. - - If `ligID' is 0xFFFF, the ligID value from buffer->in_pos - will copied `num_out' times, otherwise `ligID' itself will - be used to fill the `ligID' fields. - - The properties for all replacement glyphs are taken - from the glyph at position `buffer->in_pos'. - - The cluster value for the glyph at position buffer->in_pos is used - for all replacement glyphs */ -HB_INTERNAL HB_Error -_hb_buffer_add_output_glyphs( HB_Buffer buffer, - HB_UShort num_in, - HB_UShort num_out, - HB_UShort *glyph_data, - HB_UShort component, - HB_UShort ligID ) -{ - HB_Error error; - HB_UShort i; - HB_UInt properties; - HB_UInt cluster; - - error = HB_Buffer_ensure( buffer, buffer->out_pos + num_out ); - if ( error ) - return error; - - if ( !buffer->separate_out ) - { - error = HB_Buffer_duplicate_out_buffer( buffer ); - if ( error ) - return error; - } - - properties = buffer->in_string[buffer->in_pos].properties; - cluster = buffer->in_string[buffer->in_pos].cluster; - if ( component == 0xFFFF ) - component = buffer->in_string[buffer->in_pos].component; - if ( ligID == 0xFFFF ) - ligID = buffer->in_string[buffer->in_pos].ligID; - - for ( i = 0; i < num_out; i++ ) - { - HB_GlyphItem item = &buffer->out_string[buffer->out_pos + i]; - - item->gindex = glyph_data[i]; - item->properties = properties; - item->cluster = cluster; - item->component = component; - item->ligID = ligID; - item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN; - } - - buffer->in_pos += num_in; - buffer->out_pos += num_out; - - buffer->out_length = buffer->out_pos; - - return HB_Err_Ok; -} - -HB_INTERNAL HB_Error -_hb_buffer_add_output_glyph( HB_Buffer buffer, - HB_UInt glyph_index, - HB_UShort component, - HB_UShort ligID ) -{ - HB_UShort glyph_data = glyph_index; - - return _hb_buffer_add_output_glyphs ( buffer, 1, 1, - &glyph_data, component, ligID ); -} - -HB_INTERNAL HB_Error -_hb_buffer_copy_output_glyph ( HB_Buffer buffer ) -{ - HB_Error error; - - error = HB_Buffer_ensure( buffer, buffer->out_pos + 1 ); - if ( error ) - return error; - - if ( buffer->separate_out ) - { - buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos]; - } - - buffer->in_pos++; - buffer->out_pos++; - buffer->out_length = buffer->out_pos; - - return HB_Err_Ok; -} - -HB_INTERNAL HB_Error -_hb_buffer_replace_output_glyph( HB_Buffer buffer, - HB_UInt glyph_index, - HB_Bool inplace ) -{ - - HB_Error error; - - if ( inplace ) - { - error = _hb_buffer_copy_output_glyph ( buffer ); - if ( error ) - return error; - - buffer->out_string[buffer->out_pos-1].gindex = glyph_index; - } - else - { - return _hb_buffer_add_output_glyph( buffer, glyph_index, 0xFFFF, 0xFFFF ); - } - - return HB_Err_Ok; -} - -HB_INTERNAL HB_UShort -_hb_buffer_allocate_ligid( HB_Buffer buffer ) -{ - buffer->max_ligID++; - if (HB_UNLIKELY (buffer->max_ligID == 0)) - buffer->max_ligID++; - - return buffer->max_ligID; -} diff --git a/src/hb-old/harfbuzz-buffer.h b/src/hb-old/harfbuzz-buffer.h deleted file mode 100644 index ea5d404..0000000 --- a/src/hb-old/harfbuzz-buffer.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2004,2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 - */ - -#ifndef HARFBUZZ_BUFFER_H -#define HARFBUZZ_BUFFER_H - -#include "harfbuzz-global.h" - -HB_BEGIN_HEADER - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -typedef struct HB_GlyphItemRec_ { - HB_UInt gindex; - HB_UInt properties; - HB_UInt cluster; - HB_UShort component; - HB_UShort ligID; - HB_UShort gproperties; -} HB_GlyphItemRec, *HB_GlyphItem; - -typedef struct HB_PositionRec_ { - HB_Fixed x_pos; - HB_Fixed y_pos; - HB_Fixed x_advance; - HB_Fixed y_advance; - HB_UShort back; /* number of glyphs to go back - for drawing current glyph */ - HB_Short cursive_chain; /* character to which this connects, - may be positive or negative; used - only internally */ - HB_Bool new_advance; /* if set, the advance width values are - absolute, i.e., they won't be - added to the original glyph's value - but rather replace them. */ -} HB_PositionRec, *HB_Position; - - -typedef struct HB_BufferRec_{ - HB_UInt allocated; - - HB_UInt in_length; - HB_UInt out_length; - HB_UInt in_pos; - HB_UInt out_pos; - - HB_GlyphItem in_string; - HB_GlyphItem out_string; - HB_GlyphItem alt_string; - HB_Position positions; - HB_UShort max_ligID; - HB_Bool separate_out; -} HB_BufferRec, *HB_Buffer; - -HB_Error -HB_Buffer_new( HB_Buffer *buffer ); - -void -HB_Buffer_free( HB_Buffer buffer ); - -void -HB_Buffer_clear( HB_Buffer buffer ); - -HB_Error -HB_Buffer_add_glyph( HB_Buffer buffer, - HB_UInt glyph_index, - HB_UInt properties, - HB_UInt cluster ); - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -HB_END_HEADER - -#endif /* HARFBUZZ_BUFFER_H */ diff --git a/src/hb-old/harfbuzz-external.h b/src/hb-old/harfbuzz-external.h deleted file mode 100644 index 13ec15f..0000000 --- a/src/hb-old/harfbuzz-external.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_EXTERNAL_H -#define HARFBUZZ_EXTERNAL_H - -#define HB_H_IN -#include <hb-unicode.h> -#include "harfbuzz-global.h" - -HB_BEGIN_HEADER - -/* This header contains some methods that are not part of - Harfbuzz itself, but referenced by it. - They need to be provided by the application/library -*/ - - -typedef enum -{ - HB_Mark_NonSpacing = HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK, /* Mn */ - HB_Mark_SpacingCombining = HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK, /* Mc */ - HB_Mark_Enclosing = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK, /* Me */ - - HB_Number_DecimalDigit = HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER, /* Nd */ - HB_Number_Letter = HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER, /* Nl */ - HB_Number_Other = HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER, /* No */ - - HB_Separator_Space = HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR, /* Zs */ - HB_Separator_Line = HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR, /* Zl */ - HB_Separator_Paragraph = HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR, /* Zp */ - - HB_Other_Control = HB_UNICODE_GENERAL_CATEGORY_CONTROL, /* Cc */ - HB_Other_Format = HB_UNICODE_GENERAL_CATEGORY_FORMAT, /* Cf */ - HB_Other_Surrogate = HB_UNICODE_GENERAL_CATEGORY_SURROGATE, /* Cs */ - HB_Other_PrivateUse = HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE, /* Co */ - HB_Other_NotAssigned = HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED, /* Cn */ - - HB_Letter_Uppercase = HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER, /* Lu */ - HB_Letter_Lowercase = HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER, /* Ll */ - HB_Letter_Titlecase = HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER, /* Lt */ - HB_Letter_Modifier = HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER, /* Lm */ - HB_Letter_Other = HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER, /* Lo */ - - HB_Punctuation_Connector = HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION, /* Pc */ - HB_Punctuation_Dash = HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION, /* Pd */ - HB_Punctuation_Open = HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION, /* Ps */ - HB_Punctuation_Close = HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION, /* Pe */ - HB_Punctuation_InitialQuote = HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION, /* Pi */ - HB_Punctuation_FinalQuote = HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION, /* Pf */ - HB_Punctuation_Other = HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION, /* Po */ - - HB_Symbol_Math = HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL, /* Sm */ - HB_Symbol_Currency = HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL, /* Sc */ - HB_Symbol_Modifier = HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL, /* Sk */ - HB_Symbol_Other = HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL /* So */ -} HB_CharCategory; - - -static inline HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch) -{ - return (HB_CharCategory) hb_unicode_general_category (hb_unicode_funcs_get_default (), ch); -} - -static inline int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch) -{ - return hb_unicode_combining_class (hb_unicode_funcs_get_default (), ch); -} - -static inline HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch) -{ - return hb_unicode_mirroring (hb_unicode_funcs_get_default (), ch); -} - -static inline void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass) -{ - if (category) - *category = HB_GetUnicodeCharCategory (ch); - if (combiningClass) - *combiningClass = HB_GetUnicodeCharCombiningClass (ch); -} - -HB_END_HEADER - -#endif diff --git a/src/hb-old/harfbuzz-gdef-private.h b/src/hb-old/harfbuzz-gdef-private.h deleted file mode 100644 index 2a6d958..0000000 --- a/src/hb-old/harfbuzz-gdef-private.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GDEF_PRIVATE_H -#define HARFBUZZ_GDEF_PRIVATE_H - -#include "harfbuzz-impl.h" -#include "harfbuzz-stream-private.h" -#include "harfbuzz-buffer-private.h" -#include "harfbuzz-gdef.h" - -HB_BEGIN_HEADER - - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -/* Attachment related structures */ - -struct HB_AttachPoint_ -{ - HB_UShort* PointIndex; /* array of contour points */ - HB_UShort PointCount; /* size of the PointIndex array */ -}; - -/* Ligature Caret related structures */ - -struct HB_CaretValueFormat1_ -{ - HB_Short Coordinate; /* x or y value (in design units) */ -}; - -typedef struct HB_CaretValueFormat1_ HB_CaretValueFormat1; - - -struct HB_CaretValueFormat2_ -{ - HB_UShort CaretValuePoint; /* contour point index on glyph */ -}; - -typedef struct HB_CaretValueFormat2_ HB_CaretValueFormat2; - - -struct HB_CaretValueFormat3_ -{ - HB_Device* Device; /* Device table for x or y value */ - HB_Short Coordinate; /* x or y value (in design units) */ -}; - -typedef struct HB_CaretValueFormat3_ HB_CaretValueFormat3; - - -#ifdef HB_SUPPORT_MULTIPLE_MASTER -struct HB_CaretValueFormat4_ -{ - HB_UShort IdCaretValue; /* metric ID */ -}; - -typedef struct HB_CaretValueFormat4_ HB_CaretValueFormat4; -#endif - - -struct HB_CaretValue_ -{ - union - { - HB_CaretValueFormat1 cvf1; - HB_CaretValueFormat2 cvf2; - HB_CaretValueFormat3 cvf3; -#ifdef HB_SUPPORT_MULTIPLE_MASTER - HB_CaretValueFormat4 cvf4; -#endif - } cvf; - - HB_Byte CaretValueFormat; /* 1, 2, 3, or 4 */ -}; - -typedef struct HB_CaretValue_ HB_CaretValue; - - -struct HB_LigGlyph_ -{ - HB_CaretValue* CaretValue; /* array of caret values */ - HB_UShort CaretCount; /* number of caret values */ - HB_Bool loaded; -}; - - -HB_INTERNAL HB_Error -_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef, - HB_UShort glyphID, - HB_UShort property ); - -HB_INTERNAL HB_Error -_HB_GDEF_Check_Property( HB_GDEFHeader* gdef, - HB_GlyphItem item, - HB_UShort flags, - HB_UShort* property ); - -HB_INTERNAL HB_Error -_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef, - HB_Stream input, - HB_Lookup* lo, - HB_UShort num_lookups ); - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -HB_END_HEADER - -#endif /* HARFBUZZ_GDEF_PRIVATE_H */ diff --git a/src/hb-old/harfbuzz-gdef.c b/src/hb-old/harfbuzz-gdef.c deleted file mode 100644 index 966b167..0000000 --- a/src/hb-old/harfbuzz-gdef.c +++ /dev/null @@ -1,1163 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-impl.h" -#include "harfbuzz-gdef-private.h" -#include "harfbuzz-open-private.h" - -static HB_Error Load_AttachList( HB_AttachList* al, - HB_Stream stream ); -static HB_Error Load_LigCaretList( HB_LigCaretList* lcl, - HB_Stream stream ); - -static void Free_AttachList( HB_AttachList* al); -static void Free_LigCaretList( HB_LigCaretList* lcl); - -static void Free_NewGlyphClasses( HB_GDEFHeader* gdef); - - - -/* GDEF glyph classes */ - -#define UNCLASSIFIED_GLYPH 0 -#define SIMPLE_GLYPH 1 -#define LIGATURE_GLYPH 2 -#define MARK_GLYPH 3 -#define COMPONENT_GLYPH 4 - - - - - - -HB_Error HB_New_GDEF_Table( HB_GDEFHeader** retptr ) -{ - HB_Error error; - - HB_GDEFHeader* gdef; - - if ( !retptr ) - return ERR(HB_Err_Invalid_Argument); - - if ( ALLOC( gdef, sizeof( *gdef ) ) ) - return error; - - gdef->GlyphClassDef.loaded = FALSE; - gdef->AttachList.loaded = FALSE; - gdef->LigCaretList.loaded = FALSE; - gdef->MarkAttachClassDef_offset = 0; - gdef->MarkAttachClassDef.loaded = FALSE; - - gdef->LastGlyph = 0; - gdef->NewGlyphClasses = NULL; - - *retptr = gdef; - - return HB_Err_Ok; -} - - -HB_Error HB_Load_GDEF_Table( HB_Stream stream, - HB_GDEFHeader** retptr ) -{ - HB_Error error; - HB_UInt cur_offset, new_offset, base_offset; - - HB_GDEFHeader* gdef; - - - if ( !retptr ) - return ERR(HB_Err_Invalid_Argument); - - if ( GOTO_Table( TTAG_GDEF ) ) - return error; - - if (( error = HB_New_GDEF_Table ( &gdef ) )) - return error; - - base_offset = FILE_Pos(); - - /* skip version */ - - if ( FILE_Seek( base_offset + 4L ) || - ACCESS_Frame( 2L ) ) - goto Fail0; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - /* all GDEF subtables are optional */ - - if ( new_offset ) - { - new_offset += base_offset; - - /* only classes 1-4 are allowed here */ - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_ClassDefinition( &gdef->GlyphClassDef, 5, - stream ) ) != HB_Err_Ok ) - goto Fail0; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_AttachList( &gdef->AttachList, - stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_LigCaretList( &gdef->LigCaretList, - stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - - /* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We - first have to scan the LookupFlag values to find out whether we - must load it or not. Here we only store the offset of the table. */ - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - gdef->MarkAttachClassDef_offset = new_offset + base_offset; - else - gdef->MarkAttachClassDef_offset = 0; - - *retptr = gdef; - - return HB_Err_Ok; - -Fail3: - Free_LigCaretList( &gdef->LigCaretList ); - -Fail2: - Free_AttachList( &gdef->AttachList ); - -Fail1: - _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef ); - -Fail0: - FREE( gdef ); - - return error; -} - - -HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef ) -{ - Free_LigCaretList( &gdef->LigCaretList ); - Free_AttachList( &gdef->AttachList ); - _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef ); - _HB_OPEN_Free_ClassDefinition( &gdef->MarkAttachClassDef ); - - Free_NewGlyphClasses( gdef ); - - FREE( gdef ); - - return HB_Err_Ok; -} - - - - -/******************************* - * AttachList related functions - *******************************/ - - -/* AttachPoint */ - -static HB_Error Load_AttachPoint( HB_AttachPoint* ap, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* pi; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = ap->PointCount = GET_UShort(); - - FORGET_Frame(); - - ap->PointIndex = NULL; - - if ( count ) - { - if ( ALLOC_ARRAY( ap->PointIndex, count, HB_UShort ) ) - return error; - - pi = ap->PointIndex; - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( pi ); - return error; - } - - for ( n = 0; n < count; n++ ) - pi[n] = GET_UShort(); - - FORGET_Frame(); - } - - return HB_Err_Ok; -} - - -static void Free_AttachPoint( HB_AttachPoint* ap ) -{ - FREE( ap->PointIndex ); -} - - -/* AttachList */ - -static HB_Error Load_AttachList( HB_AttachList* al, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_AttachPoint* ap; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &al->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = al->GlyphCount = GET_UShort(); - - FORGET_Frame(); - - al->AttachPoint = NULL; - - if ( ALLOC_ARRAY( al->AttachPoint, count, HB_AttachPoint ) ) - goto Fail2; - - ap = al->AttachPoint; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_AttachPoint( &ap[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - al->loaded = TRUE; - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_AttachPoint( &ap[m] ); - - FREE( ap ); - -Fail2: - _HB_OPEN_Free_Coverage( &al->Coverage ); - return error; -} - - -static void Free_AttachList( HB_AttachList* al) -{ - HB_UShort n, count; - - HB_AttachPoint* ap; - - - if ( !al->loaded ) - return; - - if ( al->AttachPoint ) - { - count = al->GlyphCount; - ap = al->AttachPoint; - - for ( n = 0; n < count; n++ ) - Free_AttachPoint( &ap[n] ); - - FREE( ap ); - } - - _HB_OPEN_Free_Coverage( &al->Coverage ); -} - - - -/********************************* - * LigCaretList related functions - *********************************/ - - -/* CaretValueFormat1 */ -/* CaretValueFormat2 */ -/* CaretValueFormat3 */ -/* CaretValueFormat4 */ - -static HB_Error Load_CaretValue( HB_CaretValue* cv, - HB_Stream stream ) -{ - HB_Error error; - - HB_UInt cur_offset, new_offset, base_offset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - cv->CaretValueFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( cv->CaretValueFormat ) - { - case 1: - if ( ACCESS_Frame( 2L ) ) - return error; - - cv->cvf.cvf1.Coordinate = GET_Short(); - - FORGET_Frame(); - - break; - - case 2: - if ( ACCESS_Frame( 2L ) ) - return error; - - cv->cvf.cvf2.CaretValuePoint = GET_UShort(); - - FORGET_Frame(); - - break; - - case 3: - if ( ACCESS_Frame( 4L ) ) - return error; - - cv->cvf.cvf3.Coordinate = GET_Short(); - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Device( &cv->cvf.cvf3.Device, - stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - break; - - case 4: - if ( ACCESS_Frame( 2L ) ) - return error; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - cv->cvf.cvf4.IdCaretValue = GET_UShort(); -#else - (void) GET_UShort(); -#endif - - FORGET_Frame(); - break; - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; -} - - -static void Free_CaretValue( HB_CaretValue* cv) -{ - if ( cv->CaretValueFormat == 3 ) - _HB_OPEN_Free_Device( cv->cvf.cvf3.Device ); -} - - -/* LigGlyph */ - -static HB_Error Load_LigGlyph( HB_LigGlyph* lg, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_CaretValue* cv; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = lg->CaretCount = GET_UShort(); - - FORGET_Frame(); - - lg->CaretValue = NULL; - - if ( ALLOC_ARRAY( lg->CaretValue, count, HB_CaretValue ) ) - return error; - - cv = lg->CaretValue; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_CaretValue( &cv[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_CaretValue( &cv[m] ); - - FREE( cv ); - return error; -} - - -static void Free_LigGlyph( HB_LigGlyph* lg) -{ - HB_UShort n, count; - - HB_CaretValue* cv; - - - if ( lg->CaretValue ) - { - count = lg->CaretCount; - cv = lg->CaretValue; - - for ( n = 0; n < count; n++ ) - Free_CaretValue( &cv[n] ); - - FREE( cv ); - } -} - - -/* LigCaretList */ - -static HB_Error Load_LigCaretList( HB_LigCaretList* lcl, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort m, n, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_LigGlyph* lg; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &lcl->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = lcl->LigGlyphCount = GET_UShort(); - - FORGET_Frame(); - - lcl->LigGlyph = NULL; - - if ( ALLOC_ARRAY( lcl->LigGlyph, count, HB_LigGlyph ) ) - goto Fail2; - - lg = lcl->LigGlyph; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_LigGlyph( &lg[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - lcl->loaded = TRUE; - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_LigGlyph( &lg[m] ); - - FREE( lg ); - -Fail2: - _HB_OPEN_Free_Coverage( &lcl->Coverage ); - return error; -} - - -static void Free_LigCaretList( HB_LigCaretList* lcl ) -{ - HB_UShort n, count; - - HB_LigGlyph* lg; - - - if ( !lcl->loaded ) - return; - - if ( lcl->LigGlyph ) - { - count = lcl->LigGlyphCount; - lg = lcl->LigGlyph; - - for ( n = 0; n < count; n++ ) - Free_LigGlyph( &lg[n] ); - - FREE( lg ); - } - - _HB_OPEN_Free_Coverage( &lcl->Coverage ); -} - - - -/*********** - * GDEF API - ***********/ - - -static HB_UShort Get_New_Class( HB_GDEFHeader* gdef, - HB_UShort glyphID, - HB_UShort index ) -{ - HB_UShort glyph_index, array_index, count; - HB_UShort byte, bits; - - HB_ClassRangeRecord* gcrr; - HB_UShort** ngc; - - - if ( glyphID >= gdef->LastGlyph ) - return 0; - - count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount; - gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord; - ngc = gdef->NewGlyphClasses; - - if ( index < count && glyphID < gcrr[index].Start ) - { - array_index = index; - if ( index == 0 ) - glyph_index = glyphID; - else - glyph_index = glyphID - gcrr[index - 1].End - 1; - } - else - { - array_index = index + 1; - glyph_index = glyphID - gcrr[index].End - 1; - } - - byte = ngc[array_index][glyph_index / 4]; - bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 ); - - return bits & 0x000F; -} - - - -HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef, - HB_UShort glyphID, - HB_UShort* property ) -{ - HB_UShort class = 0, index = 0; /* shut compiler up */ - - HB_Error error; - - - if ( !gdef || !property ) - return ERR(HB_Err_Invalid_Argument); - - /* first, we check for mark attach classes */ - - if ( gdef->MarkAttachClassDef.loaded ) - { - error = _HB_OPEN_Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index ); - if ( error && error != HB_Err_Not_Covered ) - return error; - if ( !error ) - { - *property = class << 8; - return HB_Err_Ok; - } - } - - error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index ); - if ( error && error != HB_Err_Not_Covered ) - return error; - - /* if we have a constructed class table, check whether additional - values have been assigned */ - - if ( error == HB_Err_Not_Covered && gdef->NewGlyphClasses ) - class = Get_New_Class( gdef, glyphID, index ); - - switch ( class ) - { - default: - case UNCLASSIFIED_GLYPH: - *property = 0; - break; - - case SIMPLE_GLYPH: - *property = HB_GDEF_BASE_GLYPH; - break; - - case LIGATURE_GLYPH: - *property = HB_GDEF_LIGATURE; - break; - - case MARK_GLYPH: - *property = HB_GDEF_MARK; - break; - - case COMPONENT_GLYPH: - *property = HB_GDEF_COMPONENT; - break; - } - - return HB_Err_Ok; -} - - -static HB_Error Make_ClassRange( HB_ClassDefinition* cd, - HB_UShort start, - HB_UShort end, - HB_UShort class ) -{ - HB_Error error; - HB_UShort index; - - HB_ClassDefFormat2* cdf2; - HB_ClassRangeRecord* crr; - - - cdf2 = &cd->cd.cd2; - - if ( REALLOC_ARRAY( cdf2->ClassRangeRecord, - cdf2->ClassRangeCount + 1 , - HB_ClassRangeRecord ) ) - return error; - - cdf2->ClassRangeCount++; - - crr = cdf2->ClassRangeRecord; - index = cdf2->ClassRangeCount - 1; - - crr[index].Start = start; - crr[index].End = end; - crr[index].Class = class; - - return HB_Err_Ok; -} - - - -HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef, - HB_UShort num_glyphs, - HB_UShort glyph_count, - HB_UShort* glyph_array, - HB_UShort* class_array ) -{ - HB_UShort start, curr_glyph, curr_class; - HB_UShort n, m, count; - HB_Error error; - - HB_ClassDefinition* gcd; - HB_ClassRangeRecord* gcrr; - HB_UShort** ngc; - - - if ( !gdef || !glyph_array || !class_array ) - return ERR(HB_Err_Invalid_Argument); - - gcd = &gdef->GlyphClassDef; - - /* We build a format 2 table */ - - gcd->ClassFormat = 2; - - gcd->cd.cd2.ClassRangeCount = 0; - gcd->cd.cd2.ClassRangeRecord = NULL; - - start = glyph_array[0]; - curr_class = class_array[0]; - curr_glyph = start; - - if ( curr_class >= 5 ) - { - error = ERR(HB_Err_Invalid_Argument); - goto Fail4; - } - - glyph_count--; - - for ( n = 0; n < glyph_count + 1; n++ ) - { - if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] ) - { - if ( n == glyph_count ) - { - if ( ( error = Make_ClassRange( gcd, start, - curr_glyph, - curr_class) ) != HB_Err_Ok ) - goto Fail3; - } - else - { - if ( curr_glyph == 0xFFFF ) - { - error = ERR(HB_Err_Invalid_Argument); - goto Fail3; - } - else - curr_glyph++; - } - } - else - { - if ( ( error = Make_ClassRange( gcd, start, - curr_glyph - 1, - curr_class) ) != HB_Err_Ok ) - goto Fail3; - - if ( curr_glyph > glyph_array[n] ) - { - error = ERR(HB_Err_Invalid_Argument); - goto Fail3; - } - - start = glyph_array[n]; - curr_class = class_array[n]; - curr_glyph = start; - - if ( curr_class >= 5 ) - { - error = ERR(HB_Err_Invalid_Argument); - goto Fail3; - } - - if ( n == glyph_count ) - { - if ( ( error = Make_ClassRange( gcd, start, - curr_glyph, - curr_class) ) != HB_Err_Ok ) - goto Fail3; - } - else - { - if ( curr_glyph == 0xFFFF ) - { - error = ERR(HB_Err_Invalid_Argument); - goto Fail3; - } - else - curr_glyph++; - } - } - } - - /* now prepare the arrays for class values assigned during the lookup - process */ - - if ( ALLOC_ARRAY( gdef->NewGlyphClasses, - gcd->cd.cd2.ClassRangeCount + 1, HB_UShort* ) ) - goto Fail3; - - count = gcd->cd.cd2.ClassRangeCount; - gcrr = gcd->cd.cd2.ClassRangeRecord; - ngc = gdef->NewGlyphClasses; - - /* We allocate arrays for all glyphs not covered by the class range - records. Each element holds four class values. */ - - if ( count > 0 ) - { - if ( gcrr[0].Start ) - { - if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, HB_UShort ) ) - goto Fail2; - } - - for ( n = 1; n < count; n++ ) - { - if ( gcrr[n].Start - gcrr[n - 1].End > 1 ) - if ( ALLOC_ARRAY( ngc[n], - ( gcrr[n].Start - gcrr[n - 1].End + 2 ) / 4, - HB_UShort ) ) - goto Fail1; - } - - if ( gcrr[count - 1].End != num_glyphs - 1 ) - { - if ( ALLOC_ARRAY( ngc[count], - ( num_glyphs - gcrr[count - 1].End + 2 ) / 4, - HB_UShort ) ) - goto Fail1; - } - } - else if ( num_glyphs > 0 ) - { - if ( ALLOC_ARRAY( ngc[count], - ( num_glyphs + 3 ) / 4, - HB_UShort ) ) - goto Fail2; - } - - gdef->LastGlyph = num_glyphs - 1; - - gdef->MarkAttachClassDef_offset = 0L; - gdef->MarkAttachClassDef.loaded = FALSE; - - gcd->loaded = TRUE; - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - FREE( ngc[m] ); - -Fail2: - FREE( gdef->NewGlyphClasses ); - -Fail3: - FREE( gcd->cd.cd2.ClassRangeRecord ); - -Fail4: - return error; -} - - -static void Free_NewGlyphClasses( HB_GDEFHeader* gdef ) -{ - HB_UShort** ngc; - HB_UShort n, count; - - - if ( gdef->NewGlyphClasses ) - { - count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1; - ngc = gdef->NewGlyphClasses; - - for ( n = 0; n < count; n++ ) - FREE( ngc[n] ); - - FREE( ngc ); - } -} - - -HB_INTERNAL HB_Error -_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef, - HB_UShort glyphID, - HB_UShort property ) -{ - HB_Error error; - HB_UShort class, new_class, index = 0; /* shut compiler up */ - HB_UShort byte, bits, mask; - HB_UShort array_index, glyph_index, count; - - HB_ClassRangeRecord* gcrr; - HB_UShort** ngc; - - - error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index ); - if ( error && error != HB_Err_Not_Covered ) - return error; - - /* we don't accept glyphs covered in `GlyphClassDef' */ - - if ( !error ) - return HB_Err_Not_Covered; - - switch ( property ) - { - case 0: - new_class = UNCLASSIFIED_GLYPH; - break; - - case HB_GDEF_BASE_GLYPH: - new_class = SIMPLE_GLYPH; - break; - - case HB_GDEF_LIGATURE: - new_class = LIGATURE_GLYPH; - break; - - case HB_GDEF_MARK: - new_class = MARK_GLYPH; - break; - - case HB_GDEF_COMPONENT: - new_class = COMPONENT_GLYPH; - break; - - default: - return ERR(HB_Err_Invalid_Argument); - } - - count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount; - gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord; - ngc = gdef->NewGlyphClasses; - - if ( index < count && glyphID < gcrr[index].Start ) - { - array_index = index; - if ( index == 0 ) - glyph_index = glyphID; - else - glyph_index = glyphID - gcrr[index - 1].End - 1; - } - else - { - array_index = index + 1; - glyph_index = glyphID - gcrr[index].End - 1; - } - - byte = ngc[array_index][glyph_index / 4]; - bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 ); - class = bits & 0x000F; - - /* we don't overwrite existing entries */ - - if ( !class ) - { - bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 ); - mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) ); - - ngc[array_index][glyph_index / 4] &= mask; - ngc[array_index][glyph_index / 4] |= bits; - } - - return HB_Err_Ok; -} - - -HB_INTERNAL HB_Error -_HB_GDEF_Check_Property( HB_GDEFHeader* gdef, - HB_GlyphItem gitem, - HB_UShort flags, - HB_UShort* property ) -{ - HB_Error error; - - if ( gdef ) - { - HB_UShort basic_glyph_class; - HB_UShort desired_attachment_class; - - if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN ) - { - error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties ); - if ( error ) - return error; - } - - *property = gitem->gproperties; - - /* If the glyph was found in the MarkAttachmentClass table, - * then that class value is the high byte of the result, - * otherwise the low byte contains the basic type of the glyph - * as defined by the GlyphClassDef table. - */ - if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) - basic_glyph_class = HB_GDEF_MARK; - else - basic_glyph_class = *property; - - /* Return Not_Covered, if, for example, basic_glyph_class - * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES - */ - if ( flags & basic_glyph_class ) - return HB_Err_Not_Covered; - - /* The high byte of LookupFlags has the meaning - * "ignore marks of attachment type different than - * the attachment type specified." - */ - desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS; - if ( desired_attachment_class ) - { - if ( basic_glyph_class == HB_GDEF_MARK && - *property != desired_attachment_class ) - return HB_Err_Not_Covered; - } - } else { - *property = 0; - } - - return HB_Err_Ok; -} - -HB_INTERNAL HB_Error -_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef, - HB_Stream stream, - HB_Lookup* lo, - HB_UShort num_lookups) -{ - HB_Error error = HB_Err_Ok; - HB_UShort i; - - /* We now check the LookupFlags for values larger than 0xFF to find - out whether we need to load the `MarkAttachClassDef' field of the - GDEF table -- this hack is necessary for OpenType 1.2 tables since - the version field of the GDEF table hasn't been incremented. - - For constructed GDEF tables, we only load it if - `MarkAttachClassDef_offset' is not zero (nevertheless, a build of - a constructed mark attach table is not supported currently). */ - - if ( gdef && - gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) - { - for ( i = 0; i < num_lookups; i++ ) - { - - if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) - { - if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || - ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef, - 256, stream ) ) != HB_Err_Ok ) - goto Done; - - break; - } - } - } - -Done: - return error; -} - -/* END */ diff --git a/src/hb-old/harfbuzz-gdef.h b/src/hb-old/harfbuzz-gdef.h deleted file mode 100644 index f9a03dd..0000000 --- a/src/hb-old/harfbuzz-gdef.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GDEF_H -#define HARFBUZZ_GDEF_H - -#include "harfbuzz-open.h" -#include "harfbuzz-stream.h" - -HB_BEGIN_HEADER - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -/* GDEF glyph properties. Note that HB_GDEF_COMPONENT has no corresponding - * flag in the LookupFlag field. */ -#define HB_GDEF_BASE_GLYPH 0x0002 -#define HB_GDEF_LIGATURE 0x0004 -#define HB_GDEF_MARK 0x0008 -#define HB_GDEF_COMPONENT 0x0010 - - -typedef struct HB_AttachPoint_ HB_AttachPoint; - - -struct HB_AttachList_ -{ - HB_AttachPoint* AttachPoint; /* array of AttachPoint tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort GlyphCount; /* number of glyphs with - attachments */ - HB_Bool loaded; -}; - -typedef struct HB_AttachList_ HB_AttachList; - -typedef struct HB_LigGlyph_ HB_LigGlyph; - -struct HB_LigCaretList_ -{ - HB_LigGlyph* LigGlyph; /* array of LigGlyph tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort LigGlyphCount; /* number of ligature glyphs */ - HB_Bool loaded; -}; - -typedef struct HB_LigCaretList_ HB_LigCaretList; - - - -/* The `NewGlyphClasses' field is not defined in the TTO specification. - We use it for fonts with a constructed `GlyphClassDef' structure - (i.e., which don't have a GDEF table) to collect glyph classes - assigned during the lookup process. The number of arrays in this - pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth - array then contains the glyph class values of the glyphs not covered - by the ClassRangeRecords structures with index n-1 and n. We store - glyph class values for four glyphs in a single array element. - - `LastGlyph' is identical to the number of glyphs minus one in the - font; we need it only if `NewGlyphClasses' is not NULL (to have an - upper bound for the last array). - - Note that we first store the file offset to the `MarkAttachClassDef' - field (which has been introduced in OpenType 1.2) -- since the - `Version' field value hasn't been increased to indicate that we have - one more field for some obscure reason, we must parse the GSUB table - to find out whether class values refer to this table. Only then we - can finally load the MarkAttachClassDef structure if necessary. */ - -struct HB_GDEFHeader_ -{ - HB_UShort** NewGlyphClasses; - HB_UInt offset; - HB_UInt MarkAttachClassDef_offset; - - HB_16Dot16 Version; - - HB_ClassDefinition GlyphClassDef; - HB_AttachList AttachList; - HB_LigCaretList LigCaretList; - HB_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */ - - HB_UShort LastGlyph; -}; - -typedef struct HB_GDEFHeader_ HB_GDEFHeader; -typedef struct HB_GDEFHeader_* HB_GDEF; - - -HB_Error HB_New_GDEF_Table( HB_GDEFHeader** retptr ); - - -HB_Error HB_Load_GDEF_Table( HB_Stream stream, - HB_GDEFHeader** gdef ); - - -HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef ); - - -HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef, - HB_UShort glyphID, - HB_UShort* property ); - -HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef, - HB_UShort num_glyphs, - HB_UShort glyph_count, - HB_UShort* glyph_array, - HB_UShort* class_array ); - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -HB_END_HEADER - -#endif /* HARFBUZZ_GDEF_H */ diff --git a/src/hb-old/harfbuzz-global.h b/src/hb-old/harfbuzz-global.h deleted file mode 100644 index 9ba5841..0000000 --- a/src/hb-old/harfbuzz-global.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GLOBAL_H -#define HARFBUZZ_GLOBAL_H - -#include <stdlib.h> -#include <string.h> - -#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) -# define HB_BEGIN_VISIBILITY _Pragma ("GCC visibility push(hidden)") -# define HB_END_VISIBILITY _Pragma ("GCC visibility pop") -#else -# define HB_BEGIN_VISIBILITY -# define HB_END_VISIBILITY -#endif -#ifdef __cplusplus -# define HB_BEGIN_HEADER extern "C" { HB_BEGIN_VISIBILITY -# define HB_END_HEADER HB_END_VISIBILITY } -#else -# define HB_BEGIN_HEADER HB_BEGIN_VISIBILITY -# define HB_END_HEADER HB_END_VISIBILITY -#endif - -HB_BEGIN_HEADER - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#define HB_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ - ( ( (HB_UInt)_x1 << 24 ) | \ - ( (HB_UInt)_x2 << 16 ) | \ - ( (HB_UInt)_x3 << 8 ) | \ - (HB_UInt)_x4 ) - -typedef char hb_int8; -typedef unsigned char hb_uint8; -typedef short hb_int16; -typedef unsigned short hb_uint16; -typedef int hb_int32; -typedef unsigned int hb_uint32; - -typedef hb_uint8 HB_Bool; - -typedef hb_uint8 HB_Byte; -typedef hb_uint16 HB_UShort; -typedef hb_uint32 HB_UInt; -typedef hb_int8 HB_Char; -typedef hb_int16 HB_Short; -typedef hb_int32 HB_Int; - -typedef hb_uint16 HB_UChar16; -typedef hb_uint32 HB_UChar32; -typedef hb_uint32 HB_Glyph; -typedef hb_int32 HB_Fixed; /* 26.6 */ - -#define HB_FIXED_CONSTANT(v) ((v) * 64) -#define HB_FIXED_ROUND(v) (((v)+32) & -64) - -typedef hb_int32 HB_16Dot16; /* 16.16 */ - -typedef void * HB_Pointer; -typedef hb_uint32 HB_Tag; - -typedef enum { - /* no error */ - HB_Err_Ok = 0x0000, - HB_Err_Not_Covered = 0xFFFF, - - /* _hb_err() is called whenever returning the following errors, - * and in a couple places for HB_Err_Not_Covered too. */ - - /* programmer error */ - HB_Err_Invalid_Argument = 0x1A66, - - /* font error */ - HB_Err_Invalid_SubTable_Format = 0x157F, - HB_Err_Invalid_SubTable = 0x1570, - HB_Err_Read_Error = 0x6EAD, - - /* system error */ - HB_Err_Out_Of_Memory = 0xDEAD -} HB_Error; - -typedef struct { - HB_Fixed x; - HB_Fixed y; -} HB_FixedPoint; - -typedef struct HB_Font_ *HB_Font; -typedef struct HB_StreamRec_ *HB_Stream; -typedef struct HB_FaceRec_ *HB_Face; - -HB_END_HEADER - -#endif diff --git a/src/hb-old/harfbuzz-gpos-private.h b/src/hb-old/harfbuzz-gpos-private.h deleted file mode 100644 index 39f3159..0000000 --- a/src/hb-old/harfbuzz-gpos-private.h +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GPOS_PRIVATE_H -#define HARFBUZZ_GPOS_PRIVATE_H - -#include "harfbuzz-impl.h" -#include "harfbuzz-stream-private.h" -#include "harfbuzz-gpos.h" - -HB_BEGIN_HEADER - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -/* shared tables */ - -#define VR_X_PLACEMENT_DEVICE 0 -#define VR_Y_PLACEMENT_DEVICE 1 -#define VR_X_ADVANCE_DEVICE 2 -#define VR_Y_ADVANCE_DEVICE 3 - -struct HB_ValueRecord_ -{ - HB_Short XPlacement; /* horizontal adjustment for - placement */ - HB_Short YPlacement; /* vertical adjustment for - placement */ - HB_Short XAdvance; /* horizontal adjustment for - advance */ - HB_Short YAdvance; /* vertical adjustment for - advance */ - - HB_Device** DeviceTables; /* device tables for placement - and advance */ - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - HB_UShort XIdPlacement; /* horizontal placement metric ID */ - HB_UShort YIdPlacement; /* vertical placement metric ID */ - HB_UShort XIdAdvance; /* horizontal advance metric ID */ - HB_UShort YIdAdvance; /* vertical advance metric ID */ -#endif -}; - -typedef struct HB_ValueRecord_ HB_ValueRecord; - - -/* Mask values to scan the value format of the ValueRecord structure. - We always expand compressed ValueRecords of the font. */ - -#define HB_GPOS_FORMAT_HAVE_DEVICE_TABLES 0x00F0 - -#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT 0x0001 -#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT 0x0002 -#define HB_GPOS_FORMAT_HAVE_X_ADVANCE 0x0004 -#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE 0x0008 -#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE 0x0010 -#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE 0x0020 -#define HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE 0x0040 -#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE 0x0080 -#define HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT 0x0100 -#define HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT 0x0200 -#define HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE 0x0400 -#define HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE 0x0800 - - -struct HB_AnchorFormat1_ -{ - HB_Short XCoordinate; /* horizontal value */ - HB_Short YCoordinate; /* vertical value */ -}; - -typedef struct HB_AnchorFormat1_ HB_AnchorFormat1; - - -struct HB_AnchorFormat2_ -{ - HB_Short XCoordinate; /* horizontal value */ - HB_Short YCoordinate; /* vertical value */ - HB_UShort AnchorPoint; /* index to glyph contour point */ -}; - -typedef struct HB_AnchorFormat2_ HB_AnchorFormat2; - -#define AF3_X_DEVICE_TABLE 0 -#define AF3_Y_DEVICE_TABLE 1 - -struct HB_AnchorFormat3_ -{ - HB_Short XCoordinate; /* horizontal value */ - HB_Short YCoordinate; /* vertical value */ - HB_Device** DeviceTables; /* device tables for coordinates */ -}; - -typedef struct HB_AnchorFormat3_ HB_AnchorFormat3; - - -#ifdef HB_SUPPORT_MULTIPLE_MASTER -struct HB_AnchorFormat4_ -{ - HB_UShort XIdAnchor; /* horizontal metric ID */ - HB_UShort YIdAnchor; /* vertical metric ID */ -}; - -typedef struct HB_AnchorFormat4_ HB_AnchorFormat4; -#endif - - -struct HB_Anchor_ -{ - HB_Byte PosFormat; /* 1, 2, 3, or 4 -- 0 indicates - that there is no Anchor table */ - - union - { - HB_AnchorFormat1 af1; - HB_AnchorFormat2 af2; - HB_AnchorFormat3 af3; -#ifdef HB_SUPPORT_MULTIPLE_MASTER - HB_AnchorFormat4 af4; -#endif - } af; -}; - -typedef struct HB_Anchor_ HB_Anchor; - - -struct HB_MarkRecord_ -{ - HB_UShort Class; /* mark class */ - HB_Anchor MarkAnchor; /* anchor table */ -}; - -typedef struct HB_MarkRecord_ HB_MarkRecord; - - -struct HB_MarkArray_ -{ - HB_UShort MarkCount; /* number of MarkRecord tables */ - HB_MarkRecord* MarkRecord; /* array of MarkRecord tables */ -}; - -typedef struct HB_MarkArray_ HB_MarkArray; - - -/* LookupType 1 */ - -struct HB_SinglePosFormat1_ -{ - HB_ValueRecord Value; /* ValueRecord for all covered - glyphs */ -}; - -typedef struct HB_SinglePosFormat1_ HB_SinglePosFormat1; - - -struct HB_SinglePosFormat2_ -{ - HB_UShort ValueCount; /* number of ValueRecord tables */ - HB_ValueRecord* Value; /* array of ValueRecord tables */ -}; - -typedef struct HB_SinglePosFormat2_ HB_SinglePosFormat2; - - -struct HB_SinglePos_ -{ - HB_Byte PosFormat; /* 1 or 2 */ - HB_Coverage Coverage; /* Coverage table */ - - HB_UShort ValueFormat; /* format of ValueRecord table */ - - union - { - HB_SinglePosFormat1 spf1; - HB_SinglePosFormat2 spf2; - } spf; -}; - -typedef struct HB_SinglePos_ HB_SinglePos; - - -/* LookupType 2 */ - -struct HB_PairValueRecord_ -{ - HB_UShort SecondGlyph; /* glyph ID for second glyph */ - HB_ValueRecord Value1; /* pos. data for first glyph */ - HB_ValueRecord Value2; /* pos. data for second glyph */ -}; - -typedef struct HB_PairValueRecord_ HB_PairValueRecord; - - -struct HB_PairSet_ -{ - HB_UShort PairValueCount; - /* number of PairValueRecord tables */ - HB_PairValueRecord* PairValueRecord; - /* array of PairValueRecord tables */ -}; - -typedef struct HB_PairSet_ HB_PairSet; - - -struct HB_PairPosFormat1_ -{ - HB_UShort PairSetCount; /* number of PairSet tables */ - HB_PairSet* PairSet; /* array of PairSet tables */ -}; - -typedef struct HB_PairPosFormat1_ HB_PairPosFormat1; - - -struct HB_Class2Record_ -{ - HB_ValueRecord Value1; /* pos. data for first glyph */ - HB_ValueRecord Value2; /* pos. data for second glyph */ -}; - -typedef struct HB_Class2Record_ HB_Class2Record; - - -struct HB_Class1Record_ -{ - HB_Class2Record* Class2Record; /* array of Class2Record tables */ -}; - -typedef struct HB_Class1Record_ HB_Class1Record; - - -struct HB_PairPosFormat2_ -{ - HB_ClassDefinition ClassDef1; /* class def. for first glyph */ - HB_ClassDefinition ClassDef2; /* class def. for second glyph */ - HB_UShort Class1Count; /* number of classes in ClassDef1 - table */ - HB_UShort Class2Count; /* number of classes in ClassDef2 - table */ - HB_Class1Record* Class1Record; /* array of Class1Record tables */ -}; - -typedef struct HB_PairPosFormat2_ HB_PairPosFormat2; - - -struct HB_PairPos_ -{ - HB_Byte PosFormat; /* 1 or 2 */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort ValueFormat1; /* format of ValueRecord table - for first glyph */ - HB_UShort ValueFormat2; /* format of ValueRecord table - for second glyph */ - - union - { - HB_PairPosFormat1 ppf1; - HB_PairPosFormat2 ppf2; - } ppf; -}; - -typedef struct HB_PairPos_ HB_PairPos; - - -/* LookupType 3 */ - -struct HB_EntryExitRecord_ -{ - HB_Anchor EntryAnchor; /* entry Anchor table */ - HB_Anchor ExitAnchor; /* exit Anchor table */ -}; - - -typedef struct HB_EntryExitRecord_ HB_EntryExitRecord; - -struct HB_CursivePos_ -{ - HB_UShort PosFormat; /* always 1 */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort EntryExitCount; - /* number of EntryExitRecord tables */ - HB_EntryExitRecord* EntryExitRecord; - /* array of EntryExitRecord tables */ -}; - -typedef struct HB_CursivePos_ HB_CursivePos; - - -/* LookupType 4 */ - -struct HB_BaseRecord_ -{ - HB_Anchor* BaseAnchor; /* array of base glyph anchor - tables */ -}; - -typedef struct HB_BaseRecord_ HB_BaseRecord; - - -struct HB_BaseArray_ -{ - HB_UShort BaseCount; /* number of BaseRecord tables */ - HB_BaseRecord* BaseRecord; /* array of BaseRecord tables */ -}; - -typedef struct HB_BaseArray_ HB_BaseArray; - - -struct HB_MarkBasePos_ -{ - HB_UShort PosFormat; /* always 1 */ - HB_Coverage MarkCoverage; /* mark glyph coverage table */ - HB_Coverage BaseCoverage; /* base glyph coverage table */ - HB_UShort ClassCount; /* number of mark classes */ - HB_MarkArray MarkArray; /* mark array table */ - HB_BaseArray BaseArray; /* base array table */ -}; - -typedef struct HB_MarkBasePos_ HB_MarkBasePos; - - -/* LookupType 5 */ - -struct HB_ComponentRecord_ -{ - HB_Anchor* LigatureAnchor; /* array of ligature glyph anchor - tables */ -}; - -typedef struct HB_ComponentRecord_ HB_ComponentRecord; - - -struct HB_LigatureAttach_ -{ - HB_UShort ComponentCount; - /* number of ComponentRecord tables */ - HB_ComponentRecord* ComponentRecord; - /* array of ComponentRecord tables */ -}; - -typedef struct HB_LigatureAttach_ HB_LigatureAttach; - - -struct HB_LigatureArray_ -{ - HB_UShort LigatureCount; /* number of LigatureAttach tables */ - HB_LigatureAttach* LigatureAttach; - /* array of LigatureAttach tables */ -}; - -typedef struct HB_LigatureArray_ HB_LigatureArray; - - -struct HB_MarkLigPos_ -{ - HB_UShort PosFormat; /* always 1 */ - HB_Coverage MarkCoverage; /* mark glyph coverage table */ - HB_Coverage LigatureCoverage; - /* ligature glyph coverage table */ - HB_UShort ClassCount; /* number of mark classes */ - HB_MarkArray MarkArray; /* mark array table */ - HB_LigatureArray LigatureArray; /* ligature array table */ -}; - -typedef struct HB_MarkLigPos_ HB_MarkLigPos; - - -/* LookupType 6 */ - -struct HB_Mark2Record_ -{ - HB_Anchor* Mark2Anchor; /* array of mark glyph anchor - tables */ -}; - -typedef struct HB_Mark2Record_ HB_Mark2Record; - - -struct HB_Mark2Array_ -{ - HB_UShort Mark2Count; /* number of Mark2Record tables */ - HB_Mark2Record* Mark2Record; /* array of Mark2Record tables */ -}; - -typedef struct HB_Mark2Array_ HB_Mark2Array; - - -struct HB_MarkMarkPos_ -{ - HB_UShort PosFormat; /* always 1 */ - HB_Coverage Mark1Coverage; /* first mark glyph coverage table */ - HB_Coverage Mark2Coverage; /* second mark glyph coverave table */ - HB_UShort ClassCount; /* number of combining mark classes */ - HB_MarkArray Mark1Array; /* MarkArray table for first mark */ - HB_Mark2Array Mark2Array; /* MarkArray table for second mark */ -}; - -typedef struct HB_MarkMarkPos_ HB_MarkMarkPos; - - -/* needed by both lookup type 7 and 8 */ - -struct HB_PosLookupRecord_ -{ - HB_UShort SequenceIndex; /* index into current - glyph sequence */ - HB_UShort LookupListIndex; /* Lookup to apply to that pos. */ -}; - -typedef struct HB_PosLookupRecord_ HB_PosLookupRecord; - - -/* LookupType 7 */ - -struct HB_PosRule_ -{ - HB_UShort GlyphCount; /* total number of input glyphs */ - HB_UShort PosCount; /* number of PosLookupRecord tables */ - HB_UShort* Input; /* array of input glyph IDs */ - HB_PosLookupRecord* PosLookupRecord; - /* array of PosLookupRecord tables */ -}; - -typedef struct HB_PosRule_ HB_PosRule; - - -struct HB_PosRuleSet_ -{ - HB_UShort PosRuleCount; /* number of PosRule tables */ - HB_PosRule* PosRule; /* array of PosRule tables */ -}; - -typedef struct HB_PosRuleSet_ HB_PosRuleSet; - - -struct HB_ContextPosFormat1_ -{ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort PosRuleSetCount; /* number of PosRuleSet tables */ - HB_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */ -}; - -typedef struct HB_ContextPosFormat1_ HB_ContextPosFormat1; - - -struct HB_PosClassRule_ -{ - HB_UShort GlyphCount; /* total number of context classes */ - HB_UShort PosCount; /* number of PosLookupRecord tables */ - HB_UShort* Class; /* array of classes */ - HB_PosLookupRecord* PosLookupRecord; - /* array of PosLookupRecord tables */ -}; - -typedef struct HB_PosClassRule_ HB_PosClassRule; - - -struct HB_PosClassSet_ -{ - HB_UShort PosClassRuleCount; - /* number of PosClassRule tables */ - HB_PosClassRule* PosClassRule; /* array of PosClassRule tables */ -}; - -typedef struct HB_PosClassSet_ HB_PosClassSet; - - -/* The `MaxContextLength' field is not defined in the TTO specification - but simplifies the implementation of this format. It holds the - maximal context length used in the context rules. */ - -struct HB_ContextPosFormat2_ -{ - HB_UShort MaxContextLength; - /* maximal context length */ - HB_Coverage Coverage; /* Coverage table */ - HB_ClassDefinition ClassDef; /* ClassDef table */ - HB_UShort PosClassSetCount; - /* number of PosClassSet tables */ - HB_PosClassSet* PosClassSet; /* array of PosClassSet tables */ -}; - -typedef struct HB_ContextPosFormat2_ HB_ContextPosFormat2; - - -struct HB_ContextPosFormat3_ -{ - HB_UShort GlyphCount; /* number of input glyphs */ - HB_UShort PosCount; /* number of PosLookupRecord tables */ - HB_Coverage* Coverage; /* array of Coverage tables */ - HB_PosLookupRecord* PosLookupRecord; - /* array of PosLookupRecord tables */ -}; - -typedef struct HB_ContextPosFormat3_ HB_ContextPosFormat3; - - -struct HB_ContextPos_ -{ - HB_Byte PosFormat; /* 1, 2, or 3 */ - - union - { - HB_ContextPosFormat1 cpf1; - HB_ContextPosFormat2 cpf2; - HB_ContextPosFormat3 cpf3; - } cpf; -}; - -typedef struct HB_ContextPos_ HB_ContextPos; - - -/* LookupType 8 */ - -struct HB_ChainPosRule_ -{ - HB_UShort* Backtrack; /* array of backtrack glyph IDs */ - HB_UShort* Input; /* array of input glyph IDs */ - HB_UShort* Lookahead; /* array of lookahead glyph IDs */ - HB_PosLookupRecord* PosLookupRecord; - /* array of PosLookupRecords */ - HB_UShort BacktrackGlyphCount; - /* total number of backtrack glyphs */ - HB_UShort InputGlyphCount; - /* total number of input glyphs */ - HB_UShort LookaheadGlyphCount; - /* total number of lookahead glyphs */ - HB_UShort PosCount; /* number of PosLookupRecords */ -}; - -typedef struct HB_ChainPosRule_ HB_ChainPosRule; - - -struct HB_ChainPosRuleSet_ -{ - HB_UShort ChainPosRuleCount; - /* number of ChainPosRule tables */ - HB_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */ -}; - -typedef struct HB_ChainPosRuleSet_ HB_ChainPosRuleSet; - - -struct HB_ChainContextPosFormat1_ -{ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort ChainPosRuleSetCount; - /* number of ChainPosRuleSet tables */ - HB_ChainPosRuleSet* ChainPosRuleSet; - /* array of ChainPosRuleSet tables */ -}; - -typedef struct HB_ChainContextPosFormat1_ HB_ChainContextPosFormat1; - - -struct HB_ChainPosClassRule_ -{ - HB_UShort* Backtrack; /* array of backtrack classes */ - HB_UShort* Input; /* array of context classes */ - HB_UShort* Lookahead; /* array of lookahead classes */ - HB_PosLookupRecord* PosLookupRecord; - /* array of substitution lookups */ - HB_UShort BacktrackGlyphCount; - /* total number of backtrack - classes */ - HB_UShort InputGlyphCount; - /* total number of context classes */ - HB_UShort LookaheadGlyphCount; - /* total number of lookahead - classes */ - HB_UShort PosCount; /* number of PosLookupRecords */ -}; - -typedef struct HB_ChainPosClassRule_ HB_ChainPosClassRule; - - -struct HB_ChainPosClassSet_ -{ - HB_UShort ChainPosClassRuleCount; - /* number of ChainPosClassRule - tables */ - HB_ChainPosClassRule* ChainPosClassRule; - /* array of ChainPosClassRule - tables */ -}; - -typedef struct HB_ChainPosClassSet_ HB_ChainPosClassSet; - - -/* The `MaxXXXLength' fields are not defined in the TTO specification - but simplifies the implementation of this format. It holds the - maximal context length used in the specific context rules. */ - -struct HB_ChainContextPosFormat2_ -{ - HB_Coverage Coverage; /* Coverage table */ - - HB_UShort MaxBacktrackLength; - /* maximal backtrack length */ - HB_ClassDefinition BacktrackClassDef; - /* BacktrackClassDef table */ - HB_UShort MaxInputLength; - /* maximal input length */ - HB_ClassDefinition InputClassDef; - /* InputClassDef table */ - HB_UShort MaxLookaheadLength; - /* maximal lookahead length */ - HB_ClassDefinition LookaheadClassDef; - /* LookaheadClassDef table */ - - HB_UShort ChainPosClassSetCount; - /* number of ChainPosClassSet - tables */ - HB_ChainPosClassSet* ChainPosClassSet; - /* array of ChainPosClassSet - tables */ -}; - -typedef struct HB_ChainContextPosFormat2_ HB_ChainContextPosFormat2; - - -struct HB_ChainContextPosFormat3_ -{ - HB_UShort BacktrackGlyphCount; - /* number of backtrack glyphs */ - HB_Coverage* BacktrackCoverage; - /* array of backtrack Coverage - tables */ - HB_UShort InputGlyphCount; - /* number of input glyphs */ - HB_Coverage* InputCoverage; - /* array of input coverage - tables */ - HB_UShort LookaheadGlyphCount; - /* number of lookahead glyphs */ - HB_Coverage* LookaheadCoverage; - /* array of lookahead coverage - tables */ - HB_UShort PosCount; /* number of PosLookupRecords */ - HB_PosLookupRecord* PosLookupRecord; - /* array of substitution lookups */ -}; - -typedef struct HB_ChainContextPosFormat3_ HB_ChainContextPosFormat3; - - -struct HB_ChainContextPos_ -{ - HB_Byte PosFormat; /* 1, 2, or 3 */ - - union - { - HB_ChainContextPosFormat1 ccpf1; - HB_ChainContextPosFormat2 ccpf2; - HB_ChainContextPosFormat3 ccpf3; - } ccpf; -}; - -typedef struct HB_ChainContextPos_ HB_ChainContextPos; - - -#if 0 -/* LookupType 10 */ -struct HB_ExtensionPos_ -{ - HB_UShort PosFormat; /* always 1 */ - HB_UShort LookuptType; /* lookup-type of referenced subtable */ - HB_GPOS_SubTable *subtable; /* referenced subtable */ -}; - -typedef struct HB_ExtensionPos_ HB_ExtensionPos; -#endif - - -union HB_GPOS_SubTable_ -{ - HB_SinglePos single; - HB_PairPos pair; - HB_CursivePos cursive; - HB_MarkBasePos markbase; - HB_MarkLigPos marklig; - HB_MarkMarkPos markmark; - HB_ContextPos context; - HB_ChainContextPos chain; -}; - -typedef union HB_GPOS_SubTable_ HB_GPOS_SubTable; - - - -HB_INTERNAL HB_Error -_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st, - HB_Stream stream, - HB_UShort lookup_type ); - -HB_INTERNAL void -_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st, - HB_UShort lookup_type ); - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -HB_END_HEADER - -#endif /* HARFBUZZ_GPOS_PRIVATE_H */ diff --git a/src/hb-old/harfbuzz-gpos.c b/src/hb-old/harfbuzz-gpos.c deleted file mode 100644 index e969a01..0000000 --- a/src/hb-old/harfbuzz-gpos.c +++ /dev/null @@ -1,6094 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * Copyright (C) 2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 - */ - -#include "harfbuzz-impl.h" -#include "harfbuzz-gpos-private.h" -#include "harfbuzz-open-private.h" -#include "harfbuzz-gdef-private.h" -#include "harfbuzz-shaper.h" - -struct GPOS_Instance_ -{ - HB_GPOSHeader* gpos; - HB_Font font; - HB_Bool dvi; - HB_UShort load_flags; /* how the glyph should be loaded */ - HB_Bool r2l; - - HB_UShort last; /* the last valid glyph -- used - with cursive positioning */ - HB_Fixed anchor_x; /* the coordinates of the anchor point */ - HB_Fixed anchor_y; /* of the last valid glyph */ -}; - -typedef struct GPOS_Instance_ GPOS_Instance; - - -static HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi, - HB_UShort lookup_index, - HB_Buffer buffer, - HB_UShort context_length, - int nesting_level ); - - - -#ifdef HB_SUPPORT_MULTIPLE_MASTER -/* the client application must replace this with something more - meaningful if multiple master fonts are to be supported. */ - -static HB_Error default_mmfunc( HB_Font font, - HB_UShort metric_id, - HB_Fixed* metric_value, - void* data ) -{ - HB_UNUSED(font); - HB_UNUSED(metric_id); - HB_UNUSED(metric_value); - HB_UNUSED(data); - return ERR(HB_Err_Not_Covered); /* ERR() call intended */ -} -#endif - - - -HB_Error HB_Load_GPOS_Table( HB_Stream stream, - HB_GPOSHeader** retptr, - HB_GDEFHeader* gdef, - HB_Stream gdefStream ) -{ - HB_UInt cur_offset, new_offset, base_offset; - - HB_GPOSHeader* gpos; - - HB_Error error; - - - if ( !retptr ) - return ERR(HB_Err_Invalid_Argument); - - if ( GOTO_Table( TTAG_GPOS ) ) - return error; - - base_offset = FILE_Pos(); - - if ( ALLOC ( gpos, sizeof( *gpos ) ) ) - return error; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - gpos->mmfunc = default_mmfunc; -#endif - - /* skip version */ - - if ( FILE_Seek( base_offset + 4L ) || - ACCESS_Frame( 2L ) ) - goto Fail4; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_ScriptList( &gpos->ScriptList, - stream ) ) != HB_Err_Ok ) - goto Fail4; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_FeatureList( &gpos->FeatureList, - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_LookupList( &gpos->LookupList, - stream, HB_Type_GPOS ) ) != HB_Err_Ok ) - goto Fail2; - - gpos->gdef = gdef; /* can be NULL */ - - if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream, - gpos->LookupList.Lookup, - gpos->LookupList.LookupCount ) ) ) - goto Fail1; - - *retptr = gpos; - - return HB_Err_Ok; - -Fail1: - _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS ); - -Fail2: - _HB_OPEN_Free_FeatureList( &gpos->FeatureList ); - -Fail3: - _HB_OPEN_Free_ScriptList( &gpos->ScriptList ); - -Fail4: - FREE( gpos ); - - return error; -} - - -HB_Error HB_Done_GPOS_Table( HB_GPOSHeader* gpos ) -{ - _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS ); - _HB_OPEN_Free_FeatureList( &gpos->FeatureList ); - _HB_OPEN_Free_ScriptList( &gpos->ScriptList ); - - FREE( gpos ); - - return HB_Err_Ok; -} - - -/***************************** - * SubTable related functions - *****************************/ - -/* shared tables */ - -/* ValueRecord */ - -/* There is a subtle difference in the specs between a `table' and a - `record' -- offsets for device tables in ValueRecords are taken from - the parent table and not the parent record. */ - -static HB_Error Load_ValueRecord( HB_ValueRecord* vr, - HB_UShort format, - HB_UInt base_offset, - HB_Stream stream ) -{ - HB_Error error; - - HB_UInt cur_offset, new_offset; - - - if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT ) - { - if ( ACCESS_Frame( 2L ) ) - return error; - - vr->XPlacement = GET_Short(); - - FORGET_Frame(); - } - else - vr->XPlacement = 0; - - if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT ) - { - if ( ACCESS_Frame( 2L ) ) - return error; - - vr->YPlacement = GET_Short(); - - FORGET_Frame(); - } - else - vr->YPlacement = 0; - - if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE ) - { - if ( ACCESS_Frame( 2L ) ) - return error; - - vr->XAdvance = GET_Short(); - - FORGET_Frame(); - } - else - vr->XAdvance = 0; - - if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) - { - if ( ACCESS_Frame( 2L ) ) - return error; - - vr->YAdvance = GET_Short(); - - FORGET_Frame(); - } - else - vr->YAdvance = 0; - - if ( format & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES ) - { - if ( ALLOC_ARRAY( vr->DeviceTables, 4, HB_Device ) ) - return error; - vr->DeviceTables[VR_X_ADVANCE_DEVICE] = 0; - vr->DeviceTables[VR_Y_ADVANCE_DEVICE] = 0; - vr->DeviceTables[VR_X_PLACEMENT_DEVICE] = 0; - vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] = 0; - } - else - { - vr->DeviceTables = 0; - } - - if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_PLACEMENT_DEVICE], - stream ) ) != HB_Err_Ok ) - goto Fail4; - (void)FILE_Seek( cur_offset ); - } - } - - if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_PLACEMENT_DEVICE], - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - } - } - - if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_ADVANCE_DEVICE], - stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - } - - if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_ADVANCE_DEVICE], - stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - } - - if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - vr->XIdPlacement = GET_UShort(); -#else - (void) GET_UShort(); -#endif - - FORGET_Frame(); - } -#ifdef HB_SUPPORT_MULTIPLE_MASTER - else - vr->XIdPlacement = 0; -#endif - - if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - vr->YIdPlacement = GET_UShort(); -#else - (void) GET_UShort(); -#endif - - FORGET_Frame(); - } -#ifdef HB_SUPPORT_MULTIPLE_MASTER - else - vr->YIdPlacement = 0; -#endif - - if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - vr->XIdAdvance = GET_UShort(); -#else - (void) GET_UShort(); -#endif - - FORGET_Frame(); - } -#ifdef HB_SUPPORT_MULTIPLE_MASTER - else - vr->XIdAdvance = 0; -#endif - - if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - vr->YIdAdvance = GET_UShort(); -#else - (void) GET_UShort(); -#endif - - FORGET_Frame(); - } -#ifdef HB_SUPPORT_MULTIPLE_MASTER - else - vr->YIdAdvance = 0; -#endif - - return HB_Err_Ok; - -Fail1: - if ( vr->DeviceTables ) - _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] ); - -Fail2: - if ( vr->DeviceTables ) - _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] ); - -Fail3: - if ( vr->DeviceTables ) - _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] ); - -Fail4: - FREE( vr->DeviceTables ); - return error; -} - - -static void Free_ValueRecord( HB_ValueRecord* vr, - HB_UShort format ) -{ - if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) - _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] ); - if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) - _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] ); - if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) - _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] ); - if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) - _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE] ); - FREE( vr->DeviceTables ); -} - - -static HB_Error Get_ValueRecord( GPOS_Instance* gpi, - HB_ValueRecord* vr, - HB_UShort format, - HB_Position gd ) -{ - HB_Short pixel_value; - HB_Error error = HB_Err_Ok; -#ifdef HB_SUPPORT_MULTIPLE_MASTER - HB_GPOSHeader* gpos = gpi->gpos; - HB_Fixed value; -#endif - - HB_UShort x_ppem, y_ppem; - HB_16Dot16 x_scale, y_scale; - - - if ( !format ) - return HB_Err_Ok; - - x_ppem = gpi->font->x_ppem; - y_ppem = gpi->font->y_ppem; - x_scale = gpi->font->x_scale; - y_scale = gpi->font->y_scale; - - /* design units -> fractional pixel */ - - if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT ) - gd->x_pos += x_scale * vr->XPlacement / 0x10000; - if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT ) - gd->y_pos += y_scale * vr->YPlacement / 0x10000; - if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE ) - gd->x_advance += x_scale * vr->XAdvance / 0x10000; - if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) - gd->y_advance += y_scale * vr->YAdvance / 0x10000; - - if ( !gpi->dvi ) - { - /* pixel -> fractional pixel */ - - if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) - { - _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE], x_ppem, &pixel_value ); - gd->x_pos += pixel_value << 6; - } - if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) - { - _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE], y_ppem, &pixel_value ); - gd->y_pos += pixel_value << 6; - } - if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) - { - _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE], x_ppem, &pixel_value ); - gd->x_advance += pixel_value << 6; - } - if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) - { - _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE], y_ppem, &pixel_value ); - gd->y_advance += pixel_value << 6; - } - } - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - /* values returned from mmfunc() are already in fractional pixels */ - - if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) - { - error = (gpos->mmfunc)( gpi->font, vr->XIdPlacement, - &value, gpos->data ); - if ( error ) - return error; - gd->x_pos += value; - } - if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT ) - { - error = (gpos->mmfunc)( gpi->font, vr->YIdPlacement, - &value, gpos->data ); - if ( error ) - return error; - gd->y_pos += value; - } - if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE ) - { - error = (gpos->mmfunc)( gpi->font, vr->XIdAdvance, - &value, gpos->data ); - if ( error ) - return error; - gd->x_advance += value; - } - if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) - { - error = (gpos->mmfunc)( gpi->font, vr->YIdAdvance, - &value, gpos->data ); - if ( error ) - return error; - gd->y_advance += value; - } -#endif - - return error; -} - - -/* AnchorFormat1 */ -/* AnchorFormat2 */ -/* AnchorFormat3 */ -/* AnchorFormat4 */ - -static HB_Error Load_Anchor( HB_Anchor* an, - HB_Stream stream ) -{ - HB_Error error; - - HB_UInt cur_offset, new_offset, base_offset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - an->PosFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( an->PosFormat ) - { - case 1: - if ( ACCESS_Frame( 4L ) ) - return error; - - an->af.af1.XCoordinate = GET_Short(); - an->af.af1.YCoordinate = GET_Short(); - - FORGET_Frame(); - break; - - case 2: - if ( ACCESS_Frame( 6L ) ) - return error; - - an->af.af2.XCoordinate = GET_Short(); - an->af.af2.YCoordinate = GET_Short(); - an->af.af2.AnchorPoint = GET_UShort(); - - FORGET_Frame(); - break; - - case 3: - if ( ACCESS_Frame( 6L ) ) - return error; - - an->af.af3.XCoordinate = GET_Short(); - an->af.af3.YCoordinate = GET_Short(); - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) ) - return error; - - an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0; - an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0; - - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE], - stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - if ( !an->af.af3.DeviceTables ) - { - if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) ) - return error; - - an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0; - an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0; - } - - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE], - stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - break; - - case 4: - if ( ACCESS_Frame( 4L ) ) - return error; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - an->af.af4.XIdAnchor = GET_UShort(); - an->af.af4.YIdAnchor = GET_UShort(); -#else - (void) GET_UShort(); - (void) GET_UShort(); -#endif - - FORGET_Frame(); - break; - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; - -Fail: - if ( an->af.af3.DeviceTables ) - _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] ); - -Fail2: - FREE( an->af.af3.DeviceTables ); - return error; -} - - -static void Free_Anchor( HB_Anchor* an) -{ - if ( an->PosFormat == 3 && an->af.af3.DeviceTables ) - { - _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] ); - _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] ); - FREE( an->af.af3.DeviceTables ); - } -} - - -static HB_Error Get_Anchor( GPOS_Instance* gpi, - HB_Anchor* an, - HB_UShort glyph_index, - HB_Fixed* x_value, - HB_Fixed* y_value ) -{ - HB_Error error = HB_Err_Ok; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - HB_GPOSHeader* gpos = gpi->gpos; -#endif - HB_UShort ap; - - HB_Short pixel_value; - - HB_UShort x_ppem, y_ppem; - HB_16Dot16 x_scale, y_scale; - - - x_ppem = gpi->font->x_ppem; - y_ppem = gpi->font->y_ppem; - x_scale = gpi->font->x_scale; - y_scale = gpi->font->y_scale; - - switch ( an->PosFormat ) - { - case 0: - /* The special case of an empty AnchorTable */ - default: - - return HB_Err_Not_Covered; - - case 1: - *x_value = x_scale * an->af.af1.XCoordinate / 0x10000; - *y_value = y_scale * an->af.af1.YCoordinate / 0x10000; - break; - - case 2: - if ( !gpi->dvi ) - { - hb_uint32 n_points = 0; - ap = an->af.af2.AnchorPoint; - if (!gpi->font->klass->getPointInOutline) - goto no_contour_point; - error = gpi->font->klass->getPointInOutline(gpi->font, glyph_index, gpi->load_flags, ap, x_value, y_value, &n_points); - if (error) - return error; - /* if n_points is set to zero, we use the design coordinate value pair. - * This can happen e.g. for sbit glyphs. */ - if (!n_points) - goto no_contour_point; - } - else - { - no_contour_point: - *x_value = x_scale * an->af.af3.XCoordinate / 0x10000; - *y_value = y_scale * an->af.af3.YCoordinate / 0x10000; - } - break; - - case 3: - if ( !gpi->dvi ) - { - _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE], x_ppem, &pixel_value ); - *x_value = pixel_value << 6; - _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE], y_ppem, &pixel_value ); - *y_value = pixel_value << 6; - } - else - *x_value = *y_value = 0; - - *x_value += x_scale * an->af.af3.XCoordinate / 0x10000; - *y_value += y_scale * an->af.af3.YCoordinate / 0x10000; - break; - - case 4: -#ifdef HB_SUPPORT_MULTIPLE_MASTER - error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor, - x_value, gpos->data ); - if ( error ) - return error; - - error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor, - y_value, gpos->data ); - if ( error ) - return error; - break; -#else - return ERR(HB_Err_Not_Covered); -#endif - } - - return error; -} - - -/* MarkArray */ - -static HB_Error Load_MarkArray ( HB_MarkArray* ma, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_MarkRecord* mr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = ma->MarkCount = GET_UShort(); - - FORGET_Frame(); - - ma->MarkRecord = NULL; - - if ( ALLOC_ARRAY( ma->MarkRecord, count, HB_MarkRecord ) ) - return error; - - mr = ma->MarkRecord; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 4L ) ) - goto Fail; - - mr[n].Class = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_Anchor( &mr[m].MarkAnchor ); - - FREE( mr ); - return error; -} - - -static void Free_MarkArray( HB_MarkArray* ma ) -{ - HB_UShort n, count; - - HB_MarkRecord* mr; - - - if ( ma->MarkRecord ) - { - count = ma->MarkCount; - mr = ma->MarkRecord; - - for ( n = 0; n < count; n++ ) - Free_Anchor( &mr[n].MarkAnchor ); - - FREE( mr ); - } -} - - -/* LookupType 1 */ - -/* SinglePosFormat1 */ -/* SinglePosFormat2 */ - -static HB_Error Load_SinglePos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_SinglePos* sp = &st->single; - - HB_UShort n, m, count, format; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ValueRecord* vr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 6L ) ) - return error; - - sp->PosFormat = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - format = sp->ValueFormat = GET_UShort(); - - FORGET_Frame(); - - if ( !format ) - return ERR(HB_Err_Invalid_SubTable); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &sp->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - switch ( sp->PosFormat ) - { - case 1: - error = Load_ValueRecord( &sp->spf.spf1.Value, format, - base_offset, stream ); - if ( error ) - goto Fail2; - break; - - case 2: - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = sp->spf.spf2.ValueCount = GET_UShort(); - - FORGET_Frame(); - - sp->spf.spf2.Value = NULL; - - if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, HB_ValueRecord ) ) - goto Fail2; - - vr = sp->spf.spf2.Value; - - for ( n = 0; n < count; n++ ) - { - error = Load_ValueRecord( &vr[n], format, base_offset, stream ); - if ( error ) - goto Fail1; - } - break; - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_ValueRecord( &vr[m], format ); - - FREE( vr ); - -Fail2: - _HB_OPEN_Free_Coverage( &sp->Coverage ); - return error; -} - - -static void Free_SinglePos( HB_GPOS_SubTable* st ) -{ - HB_UShort n, count, format; - HB_SinglePos* sp = &st->single; - - HB_ValueRecord* v; - - - format = sp->ValueFormat; - - switch ( sp->PosFormat ) - { - case 1: - Free_ValueRecord( &sp->spf.spf1.Value, format ); - break; - - case 2: - if ( sp->spf.spf2.Value ) - { - count = sp->spf.spf2.ValueCount; - v = sp->spf.spf2.Value; - - for ( n = 0; n < count; n++ ) - Free_ValueRecord( &v[n], format ); - - FREE( v ); - } - break; - default: - break; - } - - _HB_OPEN_Free_Coverage( &sp->Coverage ); -} - -static HB_Error Lookup_SinglePos( GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - HB_SinglePos* sp = &st->single; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - return HB_Err_Not_Covered; - - if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &sp->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - switch ( sp->PosFormat ) - { - case 1: - error = Get_ValueRecord( gpi, &sp->spf.spf1.Value, - sp->ValueFormat, POSITION( buffer->in_pos ) ); - if ( error ) - return error; - break; - - case 2: - if ( index >= sp->spf.spf2.ValueCount ) - return ERR(HB_Err_Invalid_SubTable); - error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index], - sp->ValueFormat, POSITION( buffer->in_pos ) ); - if ( error ) - return error; - break; - - default: - return ERR(HB_Err_Invalid_SubTable); - } - - (buffer->in_pos)++; - - return HB_Err_Ok; -} - - -/* LookupType 2 */ - -/* PairSet */ - -static HB_Error Load_PairSet ( HB_PairSet* ps, - HB_UShort format1, - HB_UShort format2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt base_offset; - - HB_PairValueRecord* pvr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = ps->PairValueCount = GET_UShort(); - - FORGET_Frame(); - - ps->PairValueRecord = NULL; - - if ( ALLOC_ARRAY( ps->PairValueRecord, count, HB_PairValueRecord ) ) - return error; - - pvr = ps->PairValueRecord; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - pvr[n].SecondGlyph = GET_UShort(); - - FORGET_Frame(); - - if ( format1 ) - { - error = Load_ValueRecord( &pvr[n].Value1, format1, - base_offset, stream ); - if ( error ) - goto Fail; - } - if ( format2 ) - { - error = Load_ValueRecord( &pvr[n].Value2, format2, - base_offset, stream ); - if ( error ) - { - if ( format1 ) - Free_ValueRecord( &pvr[n].Value1, format1 ); - goto Fail; - } - } - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - { - if ( format1 ) - Free_ValueRecord( &pvr[m].Value1, format1 ); - if ( format2 ) - Free_ValueRecord( &pvr[m].Value2, format2 ); - } - - FREE( pvr ); - return error; -} - - -static void Free_PairSet( HB_PairSet* ps, - HB_UShort format1, - HB_UShort format2 ) -{ - HB_UShort n, count; - - HB_PairValueRecord* pvr; - - - if ( ps->PairValueRecord ) - { - count = ps->PairValueCount; - pvr = ps->PairValueRecord; - - for ( n = 0; n < count; n++ ) - { - if ( format1 ) - Free_ValueRecord( &pvr[n].Value1, format1 ); - if ( format2 ) - Free_ValueRecord( &pvr[n].Value2, format2 ); - } - - FREE( pvr ); - } -} - - -/* PairPosFormat1 */ - -static HB_Error Load_PairPos1( HB_PairPosFormat1* ppf1, - HB_UShort format1, - HB_UShort format2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_PairSet* ps; - - - base_offset = FILE_Pos() - 8L; - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = ppf1->PairSetCount = GET_UShort(); - - FORGET_Frame(); - - ppf1->PairSet = NULL; - - if ( ALLOC_ARRAY( ppf1->PairSet, count, HB_PairSet ) ) - return error; - - ps = ppf1->PairSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_PairSet( &ps[n], format1, - format2, stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_PairSet( &ps[m], format1, format2 ); - - FREE( ps ); - return error; -} - - -static void Free_PairPos1( HB_PairPosFormat1* ppf1, - HB_UShort format1, - HB_UShort format2 ) -{ - HB_UShort n, count; - - HB_PairSet* ps; - - - if ( ppf1->PairSet ) - { - count = ppf1->PairSetCount; - ps = ppf1->PairSet; - - for ( n = 0; n < count; n++ ) - Free_PairSet( &ps[n], format1, format2 ); - - FREE( ps ); - } -} - - -/* PairPosFormat2 */ - -static HB_Error Load_PairPos2( HB_PairPosFormat2* ppf2, - HB_UShort format1, - HB_UShort format2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort m, n, k, count1, count2; - HB_UInt cur_offset, new_offset1, new_offset2, base_offset; - - HB_Class1Record* c1r; - HB_Class2Record* c2r; - - - base_offset = FILE_Pos() - 8L; - - if ( ACCESS_Frame( 8L ) ) - return error; - - new_offset1 = GET_UShort() + base_offset; - new_offset2 = GET_UShort() + base_offset; - - /* `Class1Count' and `Class2Count' are the upper limits for class - values, thus we read it now to make additional safety checks. */ - - count1 = ppf2->Class1Count = GET_UShort(); - count2 = ppf2->Class2Count = GET_UShort(); - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset1 ) || - ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef1, count1, - stream ) ) != HB_Err_Ok ) - return error; - if ( FILE_Seek( new_offset2 ) || - ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef2, count2, - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - ppf2->Class1Record = NULL; - - if ( ALLOC_ARRAY( ppf2->Class1Record, count1, HB_Class1Record ) ) - goto Fail2; - - c1r = ppf2->Class1Record; - - for ( m = 0; m < count1; m++ ) - { - c1r[m].Class2Record = NULL; - - if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, HB_Class2Record ) ) - goto Fail1; - - c2r = c1r[m].Class2Record; - - for ( n = 0; n < count2; n++ ) - { - if ( format1 ) - { - error = Load_ValueRecord( &c2r[n].Value1, format1, - base_offset, stream ); - if ( error ) - goto Fail0; - } - if ( format2 ) - { - error = Load_ValueRecord( &c2r[n].Value2, format2, - base_offset, stream ); - if ( error ) - { - if ( format1 ) - Free_ValueRecord( &c2r[n].Value1, format1 ); - goto Fail0; - } - } - } - - continue; - - Fail0: - for ( k = 0; k < n; k++ ) - { - if ( format1 ) - Free_ValueRecord( &c2r[k].Value1, format1 ); - if ( format2 ) - Free_ValueRecord( &c2r[k].Value2, format2 ); - } - goto Fail1; - } - - return HB_Err_Ok; - -Fail1: - for ( k = 0; k < m; k++ ) - { - c2r = c1r[k].Class2Record; - - for ( n = 0; n < count2; n++ ) - { - if ( format1 ) - Free_ValueRecord( &c2r[n].Value1, format1 ); - if ( format2 ) - Free_ValueRecord( &c2r[n].Value2, format2 ); - } - - FREE( c2r ); - } - - FREE( c1r ); -Fail2: - - _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 ); - -Fail3: - _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 ); - return error; -} - - -static void Free_PairPos2( HB_PairPosFormat2* ppf2, - HB_UShort format1, - HB_UShort format2) -{ - HB_UShort m, n, count1, count2; - - HB_Class1Record* c1r; - HB_Class2Record* c2r; - - - if ( ppf2->Class1Record ) - { - c1r = ppf2->Class1Record; - count1 = ppf2->Class1Count; - count2 = ppf2->Class2Count; - - for ( m = 0; m < count1; m++ ) - { - c2r = c1r[m].Class2Record; - - for ( n = 0; n < count2; n++ ) - { - if ( format1 ) - Free_ValueRecord( &c2r[n].Value1, format1 ); - if ( format2 ) - Free_ValueRecord( &c2r[n].Value2, format2 ); - } - - FREE( c2r ); - } - - FREE( c1r ); - - _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 ); - _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 ); - } -} - - -static HB_Error Load_PairPos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_PairPos* pp = &st->pair; - - HB_UShort format1, format2; - HB_UInt cur_offset, new_offset, base_offset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 8L ) ) - return error; - - pp->PosFormat = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - format1 = pp->ValueFormat1 = GET_UShort(); - format2 = pp->ValueFormat2 = GET_UShort(); - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &pp->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - switch ( pp->PosFormat ) - { - case 1: - error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream ); - if ( error ) - goto Fail; - break; - - case 2: - error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream ); - if ( error ) - goto Fail; - break; - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; - -Fail: - _HB_OPEN_Free_Coverage( &pp->Coverage ); - return error; -} - - -static void Free_PairPos( HB_GPOS_SubTable* st ) -{ - HB_UShort format1, format2; - HB_PairPos* pp = &st->pair; - - - format1 = pp->ValueFormat1; - format2 = pp->ValueFormat2; - - switch ( pp->PosFormat ) - { - case 1: - Free_PairPos1( &pp->ppf.ppf1, format1, format2 ); - break; - - case 2: - Free_PairPos2( &pp->ppf.ppf2, format1, format2 ); - break; - - default: - break; - } - - _HB_OPEN_Free_Coverage( &pp->Coverage ); -} - - -static HB_Error Lookup_PairPos1( GPOS_Instance* gpi, - HB_PairPosFormat1* ppf1, - HB_Buffer buffer, - HB_UInt first_pos, - HB_UShort index, - HB_UShort format1, - HB_UShort format2 ) -{ - HB_Error error; - HB_UShort numpvr, glyph2; - - HB_PairValueRecord* pvr; - - - if ( index >= ppf1->PairSetCount ) - return ERR(HB_Err_Invalid_SubTable); - - pvr = ppf1->PairSet[index].PairValueRecord; - if ( !pvr ) - return ERR(HB_Err_Invalid_SubTable); - - glyph2 = IN_CURGLYPH(); - - for ( numpvr = ppf1->PairSet[index].PairValueCount; - numpvr; - numpvr--, pvr++ ) - { - if ( glyph2 == pvr->SecondGlyph ) - { - error = Get_ValueRecord( gpi, &pvr->Value1, format1, - POSITION( first_pos ) ); - if ( error ) - return error; - return Get_ValueRecord( gpi, &pvr->Value2, format2, - POSITION( buffer->in_pos ) ); - } - } - - return HB_Err_Not_Covered; -} - - -static HB_Error Lookup_PairPos2( GPOS_Instance* gpi, - HB_PairPosFormat2* ppf2, - HB_Buffer buffer, - HB_UInt first_pos, - HB_UShort format1, - HB_UShort format2 ) -{ - HB_Error error; - HB_UShort cl1 = 0, cl2 = 0; /* shut compiler up */ - - HB_Class1Record* c1r; - HB_Class2Record* c2r; - - - error = _HB_OPEN_Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ), - &cl1, NULL ); - if ( error && error != HB_Err_Not_Covered ) - return error; - error = _HB_OPEN_Get_Class( &ppf2->ClassDef2, IN_CURGLYPH(), - &cl2, NULL ); - if ( error && error != HB_Err_Not_Covered ) - return error; - - c1r = &ppf2->Class1Record[cl1]; - if ( !c1r ) - return ERR(HB_Err_Invalid_SubTable); - c2r = &c1r->Class2Record[cl2]; - - error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) ); - if ( error ) - return error; - return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) ); -} - - -static HB_Error Lookup_PairPos( GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_Error error; - HB_UShort index, property; - HB_UInt first_pos; - HB_GPOSHeader* gpos = gpi->gpos; - HB_PairPos* pp = &st->pair; - - HB_UNUSED(nesting_level); - - if ( buffer->in_pos >= buffer->in_length - 1 ) - return HB_Err_Not_Covered; /* Not enough glyphs in stream */ - - if ( context_length != 0xFFFF && context_length < 2 ) - return HB_Err_Not_Covered; - - if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &pp->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - /* second glyph */ - - first_pos = buffer->in_pos; - (buffer->in_pos)++; - - while ( CHECK_Property( gpos->gdef, IN_CURITEM(), - flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( buffer->in_pos == buffer->in_length ) - { - buffer->in_pos = first_pos; - return HB_Err_Not_Covered; - } - (buffer->in_pos)++; - - } - - switch ( pp->PosFormat ) - { - case 1: - error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, buffer, - first_pos, index, - pp->ValueFormat1, pp->ValueFormat2 ); - break; - - case 2: - error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, buffer, first_pos, - pp->ValueFormat1, pp->ValueFormat2 ); - break; - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - /* if we don't have coverage for the second glyph don't skip it for - further lookups but reset in_pos back to the first_glyph and let - the caller in Do_String_Lookup increment in_pos */ - if ( error == HB_Err_Not_Covered ) - buffer->in_pos = first_pos; - - /* adjusting the `next' glyph */ - - if ( pp->ValueFormat2 ) - (buffer->in_pos)++; - - return error; -} - - -/* LookupType 3 */ - -/* CursivePosFormat1 */ - -static HB_Error Load_CursivePos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_CursivePos* cp = &st->cursive; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_EntryExitRecord* eer; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - cp->PosFormat = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &cp->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = cp->EntryExitCount = GET_UShort(); - - FORGET_Frame(); - - cp->EntryExitRecord = NULL; - - if ( ALLOC_ARRAY( cp->EntryExitRecord, count, HB_EntryExitRecord ) ) - goto Fail2; - - eer = cp->EntryExitRecord; - - for ( n = 0; n < count; n++ ) - { - HB_UInt entry_offset; - - if ( ACCESS_Frame( 2L ) ) - return error; - - entry_offset = new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Anchor( &eer[n].EntryAnchor, - stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - else - eer[n].EntryAnchor.PosFormat = 0; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Anchor( &eer[n].ExitAnchor, - stream ) ) != HB_Err_Ok ) - { - if ( entry_offset ) - Free_Anchor( &eer[n].EntryAnchor ); - goto Fail1; - } - (void)FILE_Seek( cur_offset ); - } - else - eer[n].ExitAnchor.PosFormat = 0; - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - { - Free_Anchor( &eer[m].EntryAnchor ); - Free_Anchor( &eer[m].ExitAnchor ); - } - - FREE( eer ); - -Fail2: - _HB_OPEN_Free_Coverage( &cp->Coverage ); - return error; -} - - -static void Free_CursivePos( HB_GPOS_SubTable* st ) -{ - HB_UShort n, count; - HB_CursivePos* cp = &st->cursive; - - HB_EntryExitRecord* eer; - - - if ( cp->EntryExitRecord ) - { - count = cp->EntryExitCount; - eer = cp->EntryExitRecord; - - for ( n = 0; n < count; n++ ) - { - Free_Anchor( &eer[n].EntryAnchor ); - Free_Anchor( &eer[n].ExitAnchor ); - } - - FREE( eer ); - } - - _HB_OPEN_Free_Coverage( &cp->Coverage ); -} - - -static HB_Error Lookup_CursivePos( GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - HB_CursivePos* cp = &st->cursive; - - HB_EntryExitRecord* eer; - HB_Fixed entry_x, entry_y; - HB_Fixed exit_x, exit_y; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - { - gpi->last = 0xFFFF; - return HB_Err_Not_Covered; - } - - /* Glyphs not having the right GDEF properties will be ignored, i.e., - gpi->last won't be reset (contrary to user defined properties). */ - - if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) - return error; - - /* We don't handle mark glyphs here. According to Andrei, this isn't - possible, but who knows... */ - - if ( property == HB_GDEF_MARK ) - { - gpi->last = 0xFFFF; - return HB_Err_Not_Covered; - } - - error = _HB_OPEN_Coverage_Index( &cp->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - { - gpi->last = 0xFFFF; - return error; - } - - if ( index >= cp->EntryExitCount ) - return ERR(HB_Err_Invalid_SubTable); - - eer = &cp->EntryExitRecord[index]; - - /* Now comes the messiest part of the whole OpenType - specification. At first glance, cursive connections seem easy - to understand, but there are pitfalls! The reason is that - the specs don't mention how to compute the advance values - resp. glyph offsets. I was told it would be an omission, to - be fixed in the next OpenType version... Again many thanks to - Andrei Burago <andreib@microsoft.com> for clarifications. - - Consider the following example: - - | xadv1 | - +---------+ - | | - +-----+--+ 1 | - | | .| | - | 0+--+------+ - | 2 | - | | - 0+--------+ - | xadv2 | - - glyph1: advance width = 12 - anchor point = (3,1) - - glyph2: advance width = 11 - anchor point = (9,4) - - LSB is 1 for both glyphs (so the boxes drawn above are glyph - bboxes). Writing direction is R2L; `0' denotes the glyph's - coordinate origin. - - Now the surprising part: The advance width of the *left* glyph - (resp. of the *bottom* glyph) will be modified, no matter - whether the writing direction is L2R or R2L (resp. T2B or - B2T)! This assymetry is caused by the fact that the glyph's - coordinate origin is always the lower left corner for all - writing directions. - - Continuing the above example, we can compute the new - (horizontal) advance width of glyph2 as - - 9 - 3 = 6 , - - and the new vertical offset of glyph2 as - - 1 - 4 = -3 . - - - Vertical writing direction is far more complicated: - - a) Assuming that we recompute the advance height of the lower glyph: - - -- - +---------+ - -- | | - +-----+--+ 1 | yadv1 - | | .| | - yadv2 | 0+--+------+ -- BSB1 -- - | 2 | -- -- y_offset - | | - BSB2 -- 0+--------+ -- - -- -- - - glyph1: advance height = 6 - anchor point = (3,1) - - glyph2: advance height = 7 - anchor point = (9,4) - - TSB is 1 for both glyphs; writing direction is T2B. - - - BSB1 = yadv1 - (TSB1 + ymax1) - BSB2 = yadv2 - (TSB2 + ymax2) - y_offset = y2 - y1 - - vertical advance width of glyph2 - = y_offset + BSB2 - BSB1 - = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1)) - = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1) - = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1 - - - b) Assuming that we recompute the advance height of the upper glyph: - - -- -- - +---------+ -- TSB1 - -- -- | | - TSB2 -- +-----+--+ 1 | yadv1 ymax1 - | | .| | - yadv2 | 0+--+------+ -- -- - ymax2 | 2 | -- y_offset - | | - -- 0+--------+ -- - -- - - glyph1: advance height = 6 - anchor point = (3,1) - - glyph2: advance height = 7 - anchor point = (9,4) - - TSB is 1 for both glyphs; writing direction is T2B. - - y_offset = y2 - y1 - - vertical advance width of glyph2 - = TSB1 + ymax1 + y_offset - (TSB2 + ymax2) - = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2 - - - Comparing a) with b) shows that b) is easier to compute. I'll wait - for a reply from Andrei to see what should really be implemented... - - Since horizontal advance widths or vertical advance heights - can be used alone but not together, no ambiguity occurs. */ - - if ( gpi->last == 0xFFFF ) - goto end; - - /* Get_Anchor() returns HB_Err_Not_Covered if there is no anchor - table. */ - - error = Get_Anchor( gpi, &eer->EntryAnchor, IN_CURGLYPH(), - &entry_x, &entry_y ); - if ( error == HB_Err_Not_Covered ) - goto end; - if ( error ) - return error; - - if ( gpi->r2l ) - { - POSITION( buffer->in_pos )->x_advance = entry_x - gpi->anchor_x; - POSITION( buffer->in_pos )->new_advance = TRUE; - } - else - { - POSITION( gpi->last )->x_advance = gpi->anchor_x - entry_x; - POSITION( gpi->last )->new_advance = TRUE; - } - - if ( flags & HB_LOOKUP_FLAG_RIGHT_TO_LEFT ) - { - POSITION( gpi->last )->cursive_chain = gpi->last - buffer->in_pos; - POSITION( gpi->last )->y_pos = entry_y - gpi->anchor_y; - } - else - { - POSITION( buffer->in_pos )->cursive_chain = buffer->in_pos - gpi->last; - POSITION( buffer->in_pos )->y_pos = gpi->anchor_y - entry_y; - } - -end: - error = Get_Anchor( gpi, &eer->ExitAnchor, IN_CURGLYPH(), - &exit_x, &exit_y ); - if ( error == HB_Err_Not_Covered ) - gpi->last = 0xFFFF; - else - { - gpi->last = buffer->in_pos; - gpi->anchor_x = exit_x; - gpi->anchor_y = exit_y; - } - if ( error ) - return error; - - (buffer->in_pos)++; - - return HB_Err_Ok; -} - - -/* LookupType 4 */ - -/* BaseArray */ - -static HB_Error Load_BaseArray( HB_BaseArray* ba, - HB_UShort num_classes, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort m, n, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_BaseRecord *br; - HB_Anchor *ban, *bans; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = ba->BaseCount = GET_UShort(); - - FORGET_Frame(); - - ba->BaseRecord = NULL; - - if ( ALLOC_ARRAY( ba->BaseRecord, count, HB_BaseRecord ) ) - return error; - - br = ba->BaseRecord; - - bans = NULL; - - if ( ALLOC_ARRAY( bans, count * num_classes, HB_Anchor ) ) - goto Fail; - - for ( m = 0; m < count; m++ ) - { - br[m].BaseAnchor = NULL; - - ban = br[m].BaseAnchor = bans + m * num_classes; - - for ( n = 0; n < num_classes; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if (new_offset == base_offset) { - /* XXX - * Doulos SIL Regular is buggy and has zero offsets here. - * Skip it - */ - ban[n].PosFormat = 0; - continue; - } - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Anchor( &ban[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - } - - return HB_Err_Ok; - -Fail: - FREE( bans ); - FREE( br ); - return error; -} - - -static void Free_BaseArray( HB_BaseArray* ba, - HB_UShort num_classes ) -{ - HB_BaseRecord *br; - HB_Anchor *bans; - - if ( ba->BaseRecord ) - { - br = ba->BaseRecord; - - if ( ba->BaseCount ) - { - HB_UShort i, count; - count = num_classes * ba->BaseCount; - bans = br[0].BaseAnchor; - for (i = 0; i < count; i++) - Free_Anchor (&bans[i]); - FREE( bans ); - } - - FREE( br ); - } -} - - -/* MarkBasePosFormat1 */ - -static HB_Error Load_MarkBasePos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_MarkBasePos* mbp = &st->markbase; - - HB_UInt cur_offset, new_offset, base_offset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - mbp->PosFormat = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if (mbp->PosFormat != 1) - return ERR(HB_Err_Invalid_SubTable_Format); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &mbp->MarkCoverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &mbp->BaseCoverage, stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 4L ) ) - goto Fail2; - - mbp->ClassCount = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount, - stream ) ) != HB_Err_Ok ) - goto Fail1; - - return HB_Err_Ok; - -Fail1: - Free_MarkArray( &mbp->MarkArray ); - -Fail2: - _HB_OPEN_Free_Coverage( &mbp->BaseCoverage ); - -Fail3: - _HB_OPEN_Free_Coverage( &mbp->MarkCoverage ); - return error; -} - - -static void Free_MarkBasePos( HB_GPOS_SubTable* st ) -{ - HB_MarkBasePos* mbp = &st->markbase; - - Free_BaseArray( &mbp->BaseArray, mbp->ClassCount ); - Free_MarkArray( &mbp->MarkArray ); - _HB_OPEN_Free_Coverage( &mbp->BaseCoverage ); - _HB_OPEN_Free_Coverage( &mbp->MarkCoverage ); -} - - -static HB_Error Lookup_MarkBasePos( GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort i, j, mark_index, base_index, property, class; - HB_Fixed x_mark_value, y_mark_value, x_base_value, y_base_value; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - HB_MarkBasePos* mbp = &st->markbase; - - HB_MarkArray* ma; - HB_BaseArray* ba; - HB_BaseRecord* br; - HB_Anchor* mark_anchor; - HB_Anchor* base_anchor; - - HB_Position o; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - return HB_Err_Not_Covered; - - if ( flags & HB_LOOKUP_FLAG_IGNORE_BASE_GLYPHS ) - return HB_Err_Not_Covered; - - if ( CHECK_Property( gpos->gdef, IN_CURITEM(), - flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &mbp->MarkCoverage, IN_CURGLYPH(), - &mark_index ); - if ( error ) - return error; - - /* now we search backwards for a non-mark glyph */ - - i = 1; - j = buffer->in_pos - 1; - - while ( i <= buffer->in_pos ) - { - error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ), - &property ); - if ( error ) - return error; - - if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) - break; - - i++; - j--; - } - - /* The following assertion is too strong -- at least for mangal.ttf. */ -#if 0 - if ( property != HB_GDEF_BASE_GLYPH ) - return HB_Err_Not_Covered; -#endif - - if ( i > buffer->in_pos ) - return HB_Err_Not_Covered; - - error = _HB_OPEN_Coverage_Index( &mbp->BaseCoverage, IN_GLYPH( j ), - &base_index ); - if ( error ) - return error; - - ma = &mbp->MarkArray; - - if ( mark_index >= ma->MarkCount ) - return ERR(HB_Err_Invalid_SubTable); - - class = ma->MarkRecord[mark_index].Class; - mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor; - - if ( class >= mbp->ClassCount ) - return ERR(HB_Err_Invalid_SubTable); - - ba = &mbp->BaseArray; - - if ( base_index >= ba->BaseCount ) - return ERR(HB_Err_Invalid_SubTable); - - br = &ba->BaseRecord[base_index]; - base_anchor = &br->BaseAnchor[class]; - - error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(), - &x_mark_value, &y_mark_value ); - if ( error ) - return error; - - error = Get_Anchor( gpi, base_anchor, IN_GLYPH( j ), - &x_base_value, &y_base_value ); - if ( error ) - return error; - - /* anchor points are not cumulative */ - - o = POSITION( buffer->in_pos ); - - o->x_pos = x_base_value - x_mark_value; - o->y_pos = y_base_value - y_mark_value; - o->x_advance = 0; - o->y_advance = 0; - o->back = i; - - (buffer->in_pos)++; - - return HB_Err_Ok; -} - - -/* LookupType 5 */ - -/* LigatureAttach */ - -static HB_Error Load_LigatureAttach( HB_LigatureAttach* lat, - HB_UShort num_classes, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort m, n, k, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ComponentRecord* cr; - HB_Anchor* lan; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = lat->ComponentCount = GET_UShort(); - - FORGET_Frame(); - - lat->ComponentRecord = NULL; - - if ( ALLOC_ARRAY( lat->ComponentRecord, count, HB_ComponentRecord ) ) - return error; - - cr = lat->ComponentRecord; - - for ( m = 0; m < count; m++ ) - { - cr[m].LigatureAnchor = NULL; - - if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, HB_Anchor ) ) - goto Fail; - - lan = cr[m].LigatureAnchor; - - for ( n = 0; n < num_classes; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail0; - - new_offset = GET_UShort(); - - FORGET_Frame(); - - if ( new_offset ) - { - new_offset += base_offset; - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Anchor( &lan[n], stream ) ) != HB_Err_Ok ) - goto Fail0; - (void)FILE_Seek( cur_offset ); - } - else - lan[n].PosFormat = 0; - } - - continue; - Fail0: - for ( k = 0; k < n; k++ ) - Free_Anchor( &lan[k] ); - goto Fail; - } - - return HB_Err_Ok; - -Fail: - for ( k = 0; k < m; k++ ) - { - lan = cr[k].LigatureAnchor; - - for ( n = 0; n < num_classes; n++ ) - Free_Anchor( &lan[n] ); - - FREE( lan ); - } - - FREE( cr ); - return error; -} - - -static void Free_LigatureAttach( HB_LigatureAttach* lat, - HB_UShort num_classes ) -{ - HB_UShort m, n, count; - - HB_ComponentRecord* cr; - HB_Anchor* lan; - - - if ( lat->ComponentRecord ) - { - count = lat->ComponentCount; - cr = lat->ComponentRecord; - - for ( m = 0; m < count; m++ ) - { - lan = cr[m].LigatureAnchor; - - for ( n = 0; n < num_classes; n++ ) - Free_Anchor( &lan[n] ); - - FREE( lan ); - } - - FREE( cr ); - } -} - - -/* LigatureArray */ - -static HB_Error Load_LigatureArray( HB_LigatureArray* la, - HB_UShort num_classes, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_LigatureAttach* lat; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = la->LigatureCount = GET_UShort(); - - FORGET_Frame(); - - la->LigatureAttach = NULL; - - if ( ALLOC_ARRAY( la->LigatureAttach, count, HB_LigatureAttach ) ) - return error; - - lat = la->LigatureAttach; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_LigatureAttach( &lat[n], num_classes, - stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_LigatureAttach( &lat[m], num_classes ); - - FREE( lat ); - return error; -} - - -static void Free_LigatureArray( HB_LigatureArray* la, - HB_UShort num_classes ) -{ - HB_UShort n, count; - - HB_LigatureAttach* lat; - - - if ( la->LigatureAttach ) - { - count = la->LigatureCount; - lat = la->LigatureAttach; - - for ( n = 0; n < count; n++ ) - Free_LigatureAttach( &lat[n], num_classes ); - - FREE( lat ); - } -} - - -/* MarkLigPosFormat1 */ - -static HB_Error Load_MarkLigPos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_MarkLigPos* mlp = &st->marklig; - - HB_UInt cur_offset, new_offset, base_offset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - mlp->PosFormat = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &mlp->MarkCoverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &mlp->LigatureCoverage, - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 4L ) ) - goto Fail2; - - mlp->ClassCount = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, - stream ) ) != HB_Err_Ok ) - goto Fail1; - - return HB_Err_Ok; - -Fail1: - Free_MarkArray( &mlp->MarkArray ); - -Fail2: - _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage ); - -Fail3: - _HB_OPEN_Free_Coverage( &mlp->MarkCoverage ); - return error; -} - - -static void Free_MarkLigPos( HB_GPOS_SubTable* st) -{ - HB_MarkLigPos* mlp = &st->marklig; - - Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount ); - Free_MarkArray( &mlp->MarkArray ); - _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage ); - _HB_OPEN_Free_Coverage( &mlp->MarkCoverage ); -} - - -static HB_Error Lookup_MarkLigPos( GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort i, j, mark_index, lig_index, property, class; - HB_UShort mark_glyph; - HB_Fixed x_mark_value, y_mark_value, x_lig_value, y_lig_value; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - HB_MarkLigPos* mlp = &st->marklig; - - HB_MarkArray* ma; - HB_LigatureArray* la; - HB_LigatureAttach* lat; - HB_ComponentRecord* cr; - HB_UShort comp_index; - HB_Anchor* mark_anchor; - HB_Anchor* lig_anchor; - - HB_Position o; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - return HB_Err_Not_Covered; - - if ( flags & HB_LOOKUP_FLAG_IGNORE_LIGATURES ) - return HB_Err_Not_Covered; - - mark_glyph = IN_CURGLYPH(); - - if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index ); - if ( error ) - return error; - - /* now we search backwards for a non-mark glyph */ - - i = 1; - j = buffer->in_pos - 1; - - while ( i <= buffer->in_pos ) - { - error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ), - &property ); - if ( error ) - return error; - - if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) - break; - - i++; - j--; - } - - /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is - too strong, thus it is commented out. */ -#if 0 - if ( property != HB_GDEF_LIGATURE ) - return HB_Err_Not_Covered; -#endif - - if ( i > buffer->in_pos ) - return HB_Err_Not_Covered; - - error = _HB_OPEN_Coverage_Index( &mlp->LigatureCoverage, IN_GLYPH( j ), - &lig_index ); - if ( error ) - return error; - - ma = &mlp->MarkArray; - - if ( mark_index >= ma->MarkCount ) - return ERR(HB_Err_Invalid_SubTable); - - class = ma->MarkRecord[mark_index].Class; - mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor; - - if ( class >= mlp->ClassCount ) - return ERR(HB_Err_Invalid_SubTable); - - la = &mlp->LigatureArray; - - if ( lig_index >= la->LigatureCount ) - return ERR(HB_Err_Invalid_SubTable); - - lat = &la->LigatureAttach[lig_index]; - - /* We must now check whether the ligature ID of the current mark glyph - is identical to the ligature ID of the found ligature. If yes, we - can directly use the component index. If not, we attach the mark - glyph to the last component of the ligature. */ - - if ( IN_LIGID( j ) == IN_LIGID( buffer->in_pos) ) - { - comp_index = IN_COMPONENT( buffer->in_pos ); - if ( comp_index >= lat->ComponentCount ) - return HB_Err_Not_Covered; - } - else - comp_index = lat->ComponentCount - 1; - - cr = &lat->ComponentRecord[comp_index]; - lig_anchor = &cr->LigatureAnchor[class]; - - error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(), - &x_mark_value, &y_mark_value ); - if ( error ) - return error; - error = Get_Anchor( gpi, lig_anchor, IN_GLYPH( j ), - &x_lig_value, &y_lig_value ); - if ( error ) - return error; - - /* anchor points are not cumulative */ - - o = POSITION( buffer->in_pos ); - - o->x_pos = x_lig_value - x_mark_value; - o->y_pos = y_lig_value - y_mark_value; - o->x_advance = 0; - o->y_advance = 0; - o->back = i; - - (buffer->in_pos)++; - - return HB_Err_Ok; -} - - -/* LookupType 6 */ - -/* Mark2Array */ - -static HB_Error Load_Mark2Array( HB_Mark2Array* m2a, - HB_UShort num_classes, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort m, n, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Mark2Record *m2r; - HB_Anchor *m2an, *m2ans; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = m2a->Mark2Count = GET_UShort(); - - FORGET_Frame(); - - m2a->Mark2Record = NULL; - - if ( ALLOC_ARRAY( m2a->Mark2Record, count, HB_Mark2Record ) ) - return error; - - m2r = m2a->Mark2Record; - - m2ans = NULL; - - if ( ALLOC_ARRAY( m2ans, count * num_classes, HB_Anchor ) ) - goto Fail; - - for ( m = 0; m < count; m++ ) - { - m2an = m2r[m].Mark2Anchor = m2ans + m * num_classes; - - for ( n = 0; n < num_classes; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if (new_offset == base_offset) { - /* Anchor table not provided. Skip loading. - * Some versions of FreeSans hit this. */ - m2an[n].PosFormat = 0; - continue; - } - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Anchor( &m2an[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - } - - return HB_Err_Ok; - -Fail: - FREE( m2ans ); - FREE( m2r ); - return error; -} - - -static void Free_Mark2Array( HB_Mark2Array* m2a, - HB_UShort num_classes ) -{ - HB_Mark2Record *m2r; - HB_Anchor *m2ans; - - HB_UNUSED(num_classes); - - if ( m2a->Mark2Record ) - { - m2r = m2a->Mark2Record; - - if ( m2a->Mark2Count ) - { - m2ans = m2r[0].Mark2Anchor; - FREE( m2ans ); - } - - FREE( m2r ); - } -} - - -/* MarkMarkPosFormat1 */ - -static HB_Error Load_MarkMarkPos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_MarkMarkPos* mmp = &st->markmark; - - HB_UInt cur_offset, new_offset, base_offset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - mmp->PosFormat = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &mmp->Mark1Coverage, - stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &mmp->Mark2Coverage, - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 4L ) ) - goto Fail2; - - mmp->ClassCount = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount, - stream ) ) != HB_Err_Ok ) - goto Fail1; - - return HB_Err_Ok; - -Fail1: - Free_MarkArray( &mmp->Mark1Array ); - -Fail2: - _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage ); - -Fail3: - _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage ); - return error; -} - - -static void Free_MarkMarkPos( HB_GPOS_SubTable* st) -{ - HB_MarkMarkPos* mmp = &st->markmark; - - Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount ); - Free_MarkArray( &mmp->Mark1Array ); - _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage ); - _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage ); -} - - -static HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort i, j, mark1_index, mark2_index, property, class; - HB_Fixed x_mark1_value, y_mark1_value, - x_mark2_value, y_mark2_value; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - HB_MarkMarkPos* mmp = &st->markmark; - - HB_MarkArray* ma1; - HB_Mark2Array* ma2; - HB_Mark2Record* m2r; - HB_Anchor* mark1_anchor; - HB_Anchor* mark2_anchor; - - HB_Position o; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - return HB_Err_Not_Covered; - - if ( flags & HB_LOOKUP_FLAG_IGNORE_MARKS ) - return HB_Err_Not_Covered; - - if ( CHECK_Property( gpos->gdef, IN_CURITEM(), - flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &mmp->Mark1Coverage, IN_CURGLYPH(), - &mark1_index ); - if ( error ) - return error; - - /* now we search backwards for a suitable mark glyph until a non-mark - glyph */ - - if ( buffer->in_pos == 0 ) - return HB_Err_Not_Covered; - - i = 1; - j = buffer->in_pos - 1; - while ( i <= buffer->in_pos ) - { - error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ), - &property ); - if ( error ) - return error; - - if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) - return HB_Err_Not_Covered; - - if ( flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) - { - if ( property == (flags & 0xFF00) ) - break; - } - else - break; - - i++; - j--; - } - - if ( i > buffer->in_pos ) - return HB_Err_Not_Covered; - - error = _HB_OPEN_Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ), - &mark2_index ); - if ( error ) - return error; - - ma1 = &mmp->Mark1Array; - - if ( mark1_index >= ma1->MarkCount ) - return ERR(HB_Err_Invalid_SubTable); - - class = ma1->MarkRecord[mark1_index].Class; - mark1_anchor = &ma1->MarkRecord[mark1_index].MarkAnchor; - - if ( class >= mmp->ClassCount ) - return ERR(HB_Err_Invalid_SubTable); - - ma2 = &mmp->Mark2Array; - - if ( mark2_index >= ma2->Mark2Count ) - return ERR(HB_Err_Invalid_SubTable); - - m2r = &ma2->Mark2Record[mark2_index]; - mark2_anchor = &m2r->Mark2Anchor[class]; - - error = Get_Anchor( gpi, mark1_anchor, IN_CURGLYPH(), - &x_mark1_value, &y_mark1_value ); - if ( error ) - return error; - error = Get_Anchor( gpi, mark2_anchor, IN_GLYPH( j ), - &x_mark2_value, &y_mark2_value ); - if ( error ) - return error; - - /* anchor points are not cumulative */ - - o = POSITION( buffer->in_pos ); - - o->x_pos = x_mark2_value - x_mark1_value; - o->y_pos = y_mark2_value - y_mark1_value; - o->x_advance = 0; - o->y_advance = 0; - o->back = 1; - - (buffer->in_pos)++; - - return HB_Err_Ok; -} - - -/* Do the actual positioning for a context positioning (either format - 7 or 8). This is only called after we've determined that the stream - matches the subrule. */ - -static HB_Error Do_ContextPos( GPOS_Instance* gpi, - HB_UShort GlyphCount, - HB_UShort PosCount, - HB_PosLookupRecord* pos, - HB_Buffer buffer, - int nesting_level ) -{ - HB_Error error; - HB_UInt i, old_pos; - - - i = 0; - - while ( i < GlyphCount ) - { - if ( PosCount && i == pos->SequenceIndex ) - { - old_pos = buffer->in_pos; - - /* Do a positioning */ - - error = GPOS_Do_Glyph_Lookup( gpi, pos->LookupListIndex, buffer, - GlyphCount, nesting_level ); - - if ( error ) - return error; - - pos++; - PosCount--; - i += buffer->in_pos - old_pos; - } - else - { - i++; - (buffer->in_pos)++; - } - } - - return HB_Err_Ok; -} - - -/* LookupType 7 */ - -/* PosRule */ - -static HB_Error Load_PosRule( HB_PosRule* pr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* i; - - HB_PosLookupRecord* plr; - - - if ( ACCESS_Frame( 4L ) ) - return error; - - pr->GlyphCount = GET_UShort(); - pr->PosCount = GET_UShort(); - - FORGET_Frame(); - - pr->Input = NULL; - - count = pr->GlyphCount - 1; /* only GlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( pr->Input, count, HB_UShort ) ) - return error; - - i = pr->Input; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - i[n] = GET_UShort(); - - FORGET_Frame(); - - pr->PosLookupRecord = NULL; - - count = pr->PosCount; - - if ( ALLOC_ARRAY( pr->PosLookupRecord, count, HB_PosLookupRecord ) ) - goto Fail2; - - plr = pr->PosLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - plr[n].SequenceIndex = GET_UShort(); - plr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( plr ); - -Fail2: - FREE( i ); - return error; -} - - -static void Free_PosRule( HB_PosRule* pr ) -{ - FREE( pr->PosLookupRecord ); - FREE( pr->Input ); -} - - -/* PosRuleSet */ - -static HB_Error Load_PosRuleSet( HB_PosRuleSet* prs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_PosRule* pr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = prs->PosRuleCount = GET_UShort(); - - FORGET_Frame(); - - prs->PosRule = NULL; - - if ( ALLOC_ARRAY( prs->PosRule, count, HB_PosRule ) ) - return error; - - pr = prs->PosRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_PosRule( &pr[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_PosRule( &pr[m] ); - - FREE( pr ); - return error; -} - - -static void Free_PosRuleSet( HB_PosRuleSet* prs ) -{ - HB_UShort n, count; - - HB_PosRule* pr; - - - if ( prs->PosRule ) - { - count = prs->PosRuleCount; - pr = prs->PosRule; - - for ( n = 0; n < count; n++ ) - Free_PosRule( &pr[n] ); - - FREE( pr ); - } -} - - -/* ContextPosFormat1 */ - -static HB_Error Load_ContextPos1( HB_ContextPosFormat1* cpf1, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_PosRuleSet* prs; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &cpf1->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = cpf1->PosRuleSetCount = GET_UShort(); - - FORGET_Frame(); - - cpf1->PosRuleSet = NULL; - - if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, HB_PosRuleSet ) ) - goto Fail2; - - prs = cpf1->PosRuleSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_PosRuleSet( &prs[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_PosRuleSet( &prs[m] ); - - FREE( prs ); - -Fail2: - _HB_OPEN_Free_Coverage( &cpf1->Coverage ); - return error; -} - - -static void Free_ContextPos1( HB_ContextPosFormat1* cpf1 ) -{ - HB_UShort n, count; - - HB_PosRuleSet* prs; - - - if ( cpf1->PosRuleSet ) - { - count = cpf1->PosRuleSetCount; - prs = cpf1->PosRuleSet; - - for ( n = 0; n < count; n++ ) - Free_PosRuleSet( &prs[n] ); - - FREE( prs ); - } - - _HB_OPEN_Free_Coverage( &cpf1->Coverage ); -} - - -/* PosClassRule */ - -static HB_Error Load_PosClassRule( HB_ContextPosFormat2* cpf2, - HB_PosClassRule* pcr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_UShort* c; - HB_PosLookupRecord* plr; - - - if ( ACCESS_Frame( 4L ) ) - return error; - - pcr->GlyphCount = GET_UShort(); - pcr->PosCount = GET_UShort(); - - FORGET_Frame(); - - if ( pcr->GlyphCount > cpf2->MaxContextLength ) - cpf2->MaxContextLength = pcr->GlyphCount; - - pcr->Class = NULL; - - count = pcr->GlyphCount - 1; /* only GlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( pcr->Class, count, HB_UShort ) ) - return error; - - c = pcr->Class; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - c[n] = GET_UShort(); - - FORGET_Frame(); - - pcr->PosLookupRecord = NULL; - - count = pcr->PosCount; - - if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, HB_PosLookupRecord ) ) - goto Fail2; - - plr = pcr->PosLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - plr[n].SequenceIndex = GET_UShort(); - plr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( plr ); - -Fail2: - FREE( c ); - return error; -} - - -static void Free_PosClassRule( HB_PosClassRule* pcr ) -{ - FREE( pcr->PosLookupRecord ); - FREE( pcr->Class ); -} - - -/* PosClassSet */ - -static HB_Error Load_PosClassSet( HB_ContextPosFormat2* cpf2, - HB_PosClassSet* pcs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_PosClassRule* pcr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = pcs->PosClassRuleCount = GET_UShort(); - - FORGET_Frame(); - - pcs->PosClassRule = NULL; - - if ( ALLOC_ARRAY( pcs->PosClassRule, count, HB_PosClassRule ) ) - return error; - - pcr = pcs->PosClassRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_PosClassRule( cpf2, &pcr[n], - stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_PosClassRule( &pcr[m] ); - - FREE( pcr ); - return error; -} - - -static void Free_PosClassSet( HB_PosClassSet* pcs ) -{ - HB_UShort n, count; - - HB_PosClassRule* pcr; - - - if ( pcs->PosClassRule ) - { - count = pcs->PosClassRuleCount; - pcr = pcs->PosClassRule; - - for ( n = 0; n < count; n++ ) - Free_PosClassRule( &pcr[n] ); - - FREE( pcr ); - } -} - - -/* ContextPosFormat2 */ - -static HB_Error Load_ContextPos2( HB_ContextPosFormat2* cpf2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_PosClassSet* pcs; - - - base_offset = FILE_Pos() - 2; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &cpf2->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 4L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - /* `PosClassSetCount' is the upper limit for class values, thus we - read it now to make an additional safety check. */ - - count = cpf2->PosClassSetCount = GET_UShort(); - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_ClassDefinition( &cpf2->ClassDef, count, - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - cpf2->PosClassSet = NULL; - cpf2->MaxContextLength = 0; - - if ( ALLOC_ARRAY( cpf2->PosClassSet, count, HB_PosClassSet ) ) - goto Fail2; - - pcs = cpf2->PosClassSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if ( new_offset != base_offset ) /* not a NULL offset */ - { - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_PosClassSet( cpf2, &pcs[n], - stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - else - { - /* we create a PosClassSet table with no entries */ - - cpf2->PosClassSet[n].PosClassRuleCount = 0; - cpf2->PosClassSet[n].PosClassRule = NULL; - } - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; n++ ) - Free_PosClassSet( &pcs[m] ); - - FREE( pcs ); - -Fail2: - _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef ); - -Fail3: - _HB_OPEN_Free_Coverage( &cpf2->Coverage ); - return error; -} - - -static void Free_ContextPos2( HB_ContextPosFormat2* cpf2 ) -{ - HB_UShort n, count; - - HB_PosClassSet* pcs; - - - if ( cpf2->PosClassSet ) - { - count = cpf2->PosClassSetCount; - pcs = cpf2->PosClassSet; - - for ( n = 0; n < count; n++ ) - Free_PosClassSet( &pcs[n] ); - - FREE( pcs ); - } - - _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef ); - _HB_OPEN_Free_Coverage( &cpf2->Coverage ); -} - - -/* ContextPosFormat3 */ - -static HB_Error Load_ContextPos3( HB_ContextPosFormat3* cpf3, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Coverage* c; - HB_PosLookupRecord* plr; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 4L ) ) - return error; - - cpf3->GlyphCount = GET_UShort(); - cpf3->PosCount = GET_UShort(); - - FORGET_Frame(); - - cpf3->Coverage = NULL; - - count = cpf3->GlyphCount; - - if ( ALLOC_ARRAY( cpf3->Coverage, count, HB_Coverage ) ) - return error; - - c = cpf3->Coverage; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - - cpf3->PosLookupRecord = NULL; - - count = cpf3->PosCount; - - if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, HB_PosLookupRecord ) ) - goto Fail2; - - plr = cpf3->PosLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - plr[n].SequenceIndex = GET_UShort(); - plr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( plr ); - -Fail2: - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - return error; -} - - -static void Free_ContextPos3( HB_ContextPosFormat3* cpf3 ) -{ - HB_UShort n, count; - - HB_Coverage* c; - - - FREE( cpf3->PosLookupRecord ); - - if ( cpf3->Coverage ) - { - count = cpf3->GlyphCount; - c = cpf3->Coverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } -} - - -/* ContextPos */ - -static HB_Error Load_ContextPos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_ContextPos* cp = &st->context; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - cp->PosFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( cp->PosFormat ) - { - case 1: - return Load_ContextPos1( &cp->cpf.cpf1, stream ); - - case 2: - return Load_ContextPos2( &cp->cpf.cpf2, stream ); - - case 3: - return Load_ContextPos3( &cp->cpf.cpf3, stream ); - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - -static void Free_ContextPos( HB_GPOS_SubTable* st ) -{ - HB_ContextPos* cp = &st->context; - - switch ( cp->PosFormat ) - { - case 1: Free_ContextPos1( &cp->cpf.cpf1 ); break; - case 2: Free_ContextPos2( &cp->cpf.cpf2 ); break; - case 3: Free_ContextPos3( &cp->cpf.cpf3 ); break; - default: break; - } -} - - -static HB_Error Lookup_ContextPos1( GPOS_Instance* gpi, - HB_ContextPosFormat1* cpf1, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_UShort i, j, k, numpr; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - - HB_PosRule* pr; - HB_GDEFHeader* gdef; - - - gdef = gpos->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &cpf1->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - pr = cpf1->PosRuleSet[index].PosRule; - numpr = cpf1->PosRuleSet[index].PosRuleCount; - - for ( k = 0; k < numpr; k++ ) - { - if ( context_length != 0xFFFF && context_length < pr[k].GlyphCount ) - goto next_posrule; - - if ( buffer->in_pos + pr[k].GlyphCount > buffer->in_length ) - goto next_posrule; /* context is too long */ - - for ( i = 1, j = buffer->in_pos + 1; i < pr[k].GlyphCount; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + pr[k].GlyphCount - i == (HB_Int)buffer->in_length ) - goto next_posrule; - j++; - } - - if ( IN_GLYPH( j ) != pr[k].Input[i - 1] ) - goto next_posrule; - } - - return Do_ContextPos( gpi, pr[k].GlyphCount, - pr[k].PosCount, pr[k].PosLookupRecord, - buffer, - nesting_level ); - - next_posrule: - ; - } - - return HB_Err_Not_Covered; -} - - -static HB_Error Lookup_ContextPos2( GPOS_Instance* gpi, - HB_ContextPosFormat2* cpf2, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_Error error; - HB_UShort i, j, k, known_classes; - - HB_UShort* classes; - HB_UShort* cl; - HB_GPOSHeader* gpos = gpi->gpos; - - HB_PosClassSet* pcs; - HB_PosClassRule* pr; - HB_GDEFHeader* gdef; - - - gdef = gpos->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - /* Note: The coverage table in format 2 doesn't give an index into - anything. It just lets us know whether or not we need to - do any lookup at all. */ - - error = _HB_OPEN_Coverage_Index( &cpf2->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - if (cpf2->MaxContextLength < 1) - return HB_Err_Not_Covered; - - if ( ALLOC_ARRAY( classes, cpf2->MaxContextLength, HB_UShort ) ) - return error; - - error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_CURGLYPH(), - &classes[0], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End; - known_classes = 0; - - pcs = &cpf2->PosClassSet[classes[0]]; - if ( !pcs ) - { - error = ERR(HB_Err_Invalid_SubTable); - goto End; - } - - for ( k = 0; k < pcs->PosClassRuleCount; k++ ) - { - pr = &pcs->PosClassRule[k]; - - if ( context_length != 0xFFFF && context_length < pr->GlyphCount ) - goto next_posclassrule; - - if ( buffer->in_pos + pr->GlyphCount > buffer->in_length ) - goto next_posclassrule; /* context is too long */ - - cl = pr->Class; - - /* Start at 1 because [0] is implied */ - - for ( i = 1, j = buffer->in_pos + 1; i < pr->GlyphCount; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End; - - if ( j + pr->GlyphCount - i == (HB_Int)buffer->in_length ) - goto next_posclassrule; - j++; - } - - if ( i > known_classes ) - { - /* Keeps us from having to do this for each rule */ - - error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End; - known_classes = i; - } - - if ( cl[i - 1] != classes[i] ) - goto next_posclassrule; - } - - error = Do_ContextPos( gpi, pr->GlyphCount, - pr->PosCount, pr->PosLookupRecord, - buffer, - nesting_level ); - goto End; - - next_posclassrule: - ; - } - - error = HB_Err_Not_Covered; - -End: - FREE( classes ); - return error; -} - - -static HB_Error Lookup_ContextPos3( GPOS_Instance* gpi, - HB_ContextPosFormat3* cpf3, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_Error error; - HB_UShort index, i, j, property; - HB_GPOSHeader* gpos = gpi->gpos; - - HB_Coverage* c; - HB_GDEFHeader* gdef; - - - gdef = gpos->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount ) - return HB_Err_Not_Covered; - - if ( buffer->in_pos + cpf3->GlyphCount > buffer->in_length ) - return HB_Err_Not_Covered; /* context is too long */ - - c = cpf3->Coverage; - - for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + cpf3->GlyphCount - i == (HB_Int)buffer->in_length ) - return HB_Err_Not_Covered; - j++; - } - - error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - - return Do_ContextPos( gpi, cpf3->GlyphCount, - cpf3->PosCount, cpf3->PosLookupRecord, - buffer, - nesting_level ); -} - - -static HB_Error Lookup_ContextPos( GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_ContextPos* cp = &st->context; - - switch ( cp->PosFormat ) - { - case 1: - return Lookup_ContextPos1( gpi, &cp->cpf.cpf1, buffer, - flags, context_length, nesting_level ); - - case 2: - return Lookup_ContextPos2( gpi, &cp->cpf.cpf2, buffer, - flags, context_length, nesting_level ); - - case 3: - return Lookup_ContextPos3( gpi, &cp->cpf.cpf3, buffer, - flags, context_length, nesting_level ); - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - -/* LookupType 8 */ - -/* ChainPosRule */ - -static HB_Error Load_ChainPosRule( HB_ChainPosRule* cpr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* b; - HB_UShort* i; - HB_UShort* l; - - HB_PosLookupRecord* plr; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - cpr->BacktrackGlyphCount = GET_UShort(); - - FORGET_Frame(); - - cpr->Backtrack = NULL; - - count = cpr->BacktrackGlyphCount; - - if ( ALLOC_ARRAY( cpr->Backtrack, count, HB_UShort ) ) - return error; - - b = cpr->Backtrack; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail4; - - for ( n = 0; n < count; n++ ) - b[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - cpr->InputGlyphCount = GET_UShort(); - - FORGET_Frame(); - - cpr->Input = NULL; - - count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( cpr->Input, count, HB_UShort ) ) - goto Fail4; - - i = cpr->Input; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail3; - - for ( n = 0; n < count; n++ ) - i[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - cpr->LookaheadGlyphCount = GET_UShort(); - - FORGET_Frame(); - - cpr->Lookahead = NULL; - - count = cpr->LookaheadGlyphCount; - - if ( ALLOC_ARRAY( cpr->Lookahead, count, HB_UShort ) ) - goto Fail3; - - l = cpr->Lookahead; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - l[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - cpr->PosCount = GET_UShort(); - - FORGET_Frame(); - - cpr->PosLookupRecord = NULL; - - count = cpr->PosCount; - - if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, HB_PosLookupRecord ) ) - goto Fail2; - - plr = cpr->PosLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - plr[n].SequenceIndex = GET_UShort(); - plr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( plr ); - -Fail2: - FREE( l ); - -Fail3: - FREE( i ); - -Fail4: - FREE( b ); - return error; -} - - -static void Free_ChainPosRule( HB_ChainPosRule* cpr ) -{ - FREE( cpr->PosLookupRecord ); - FREE( cpr->Lookahead ); - FREE( cpr->Input ); - FREE( cpr->Backtrack ); -} - - -/* ChainPosRuleSet */ - -static HB_Error Load_ChainPosRuleSet( HB_ChainPosRuleSet* cprs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ChainPosRule* cpr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = cprs->ChainPosRuleCount = GET_UShort(); - - FORGET_Frame(); - - cprs->ChainPosRule = NULL; - - if ( ALLOC_ARRAY( cprs->ChainPosRule, count, HB_ChainPosRule ) ) - return error; - - cpr = cprs->ChainPosRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainPosRule( &cpr[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_ChainPosRule( &cpr[m] ); - - FREE( cpr ); - return error; -} - - -static void Free_ChainPosRuleSet( HB_ChainPosRuleSet* cprs ) -{ - HB_UShort n, count; - - HB_ChainPosRule* cpr; - - - if ( cprs->ChainPosRule ) - { - count = cprs->ChainPosRuleCount; - cpr = cprs->ChainPosRule; - - for ( n = 0; n < count; n++ ) - Free_ChainPosRule( &cpr[n] ); - - FREE( cpr ); - } -} - - -/* ChainContextPosFormat1 */ - -static HB_Error Load_ChainContextPos1( HB_ChainContextPosFormat1* ccpf1, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ChainPosRuleSet* cprs; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &ccpf1->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = ccpf1->ChainPosRuleSetCount = GET_UShort(); - - FORGET_Frame(); - - ccpf1->ChainPosRuleSet = NULL; - - if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, HB_ChainPosRuleSet ) ) - goto Fail2; - - cprs = ccpf1->ChainPosRuleSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainPosRuleSet( &cprs[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_ChainPosRuleSet( &cprs[m] ); - - FREE( cprs ); - -Fail2: - _HB_OPEN_Free_Coverage( &ccpf1->Coverage ); - return error; -} - - -static void Free_ChainContextPos1( HB_ChainContextPosFormat1* ccpf1 ) -{ - HB_UShort n, count; - - HB_ChainPosRuleSet* cprs; - - - if ( ccpf1->ChainPosRuleSet ) - { - count = ccpf1->ChainPosRuleSetCount; - cprs = ccpf1->ChainPosRuleSet; - - for ( n = 0; n < count; n++ ) - Free_ChainPosRuleSet( &cprs[n] ); - - FREE( cprs ); - } - - _HB_OPEN_Free_Coverage( &ccpf1->Coverage ); -} - - -/* ChainPosClassRule */ - -static HB_Error Load_ChainPosClassRule( - HB_ChainContextPosFormat2* ccpf2, - HB_ChainPosClassRule* cpcr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_UShort* b; - HB_UShort* i; - HB_UShort* l; - HB_PosLookupRecord* plr; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - cpcr->BacktrackGlyphCount = GET_UShort(); - - FORGET_Frame(); - - if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength ) - ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount; - - cpcr->Backtrack = NULL; - - count = cpcr->BacktrackGlyphCount; - - if ( ALLOC_ARRAY( cpcr->Backtrack, count, HB_UShort ) ) - return error; - - b = cpcr->Backtrack; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail4; - - for ( n = 0; n < count; n++ ) - b[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - cpcr->InputGlyphCount = GET_UShort(); - - if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength ) - ccpf2->MaxInputLength = cpcr->InputGlyphCount; - - FORGET_Frame(); - - cpcr->Input = NULL; - - count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( cpcr->Input, count, HB_UShort ) ) - goto Fail4; - - i = cpcr->Input; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail3; - - for ( n = 0; n < count; n++ ) - i[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - cpcr->LookaheadGlyphCount = GET_UShort(); - - FORGET_Frame(); - - if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength ) - ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount; - - cpcr->Lookahead = NULL; - - count = cpcr->LookaheadGlyphCount; - - if ( ALLOC_ARRAY( cpcr->Lookahead, count, HB_UShort ) ) - goto Fail3; - - l = cpcr->Lookahead; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - l[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - cpcr->PosCount = GET_UShort(); - - FORGET_Frame(); - - cpcr->PosLookupRecord = NULL; - - count = cpcr->PosCount; - - if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, HB_PosLookupRecord ) ) - goto Fail2; - - plr = cpcr->PosLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - plr[n].SequenceIndex = GET_UShort(); - plr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( plr ); - -Fail2: - FREE( l ); - -Fail3: - FREE( i ); - -Fail4: - FREE( b ); - return error; -} - - -static void Free_ChainPosClassRule( HB_ChainPosClassRule* cpcr ) -{ - FREE( cpcr->PosLookupRecord ); - FREE( cpcr->Lookahead ); - FREE( cpcr->Input ); - FREE( cpcr->Backtrack ); -} - - -/* PosClassSet */ - -static HB_Error Load_ChainPosClassSet( - HB_ChainContextPosFormat2* ccpf2, - HB_ChainPosClassSet* cpcs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ChainPosClassRule* cpcr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = cpcs->ChainPosClassRuleCount = GET_UShort(); - - FORGET_Frame(); - - cpcs->ChainPosClassRule = NULL; - - if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count, - HB_ChainPosClassRule ) ) - return error; - - cpcr = cpcs->ChainPosClassRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n], - stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_ChainPosClassRule( &cpcr[m] ); - - FREE( cpcr ); - return error; -} - - -static void Free_ChainPosClassSet( HB_ChainPosClassSet* cpcs ) -{ - HB_UShort n, count; - - HB_ChainPosClassRule* cpcr; - - - if ( cpcs->ChainPosClassRule ) - { - count = cpcs->ChainPosClassRuleCount; - cpcr = cpcs->ChainPosClassRule; - - for ( n = 0; n < count; n++ ) - Free_ChainPosClassRule( &cpcr[n] ); - - FREE( cpcr ); - } -} - - -/* ChainContextPosFormat2 */ - -static HB_Error Load_ChainContextPos2( HB_ChainContextPosFormat2* ccpf2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - HB_UInt backtrack_offset, input_offset, lookahead_offset; - - HB_ChainPosClassSet* cpcs; - - - base_offset = FILE_Pos() - 2; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &ccpf2->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 8L ) ) - goto Fail5; - - backtrack_offset = GET_UShort(); - input_offset = GET_UShort(); - lookahead_offset = GET_UShort(); - - /* `ChainPosClassSetCount' is the upper limit for input class values, - thus we read it now to make an additional safety check. No limit - is known or needed for the other two class definitions */ - - count = ccpf2->ChainPosClassSetCount = GET_UShort(); - - FORGET_Frame(); - - if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->BacktrackClassDef, 65535, - backtrack_offset, base_offset, - stream ) ) != HB_Err_Ok ) - goto Fail5; - if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->InputClassDef, count, - input_offset, base_offset, - stream ) ) != HB_Err_Ok ) - goto Fail4; - if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->LookaheadClassDef, 65535, - lookahead_offset, base_offset, - stream ) ) != HB_Err_Ok ) - goto Fail3; - - ccpf2->ChainPosClassSet = NULL; - ccpf2->MaxBacktrackLength = 0; - ccpf2->MaxInputLength = 0; - ccpf2->MaxLookaheadLength = 0; - - if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, HB_ChainPosClassSet ) ) - goto Fail2; - - cpcs = ccpf2->ChainPosClassSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if ( new_offset != base_offset ) /* not a NULL offset */ - { - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n], - stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - else - { - /* we create a ChainPosClassSet table with no entries */ - - ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0; - ccpf2->ChainPosClassSet[n].ChainPosClassRule = NULL; - } - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_ChainPosClassSet( &cpcs[m] ); - - FREE( cpcs ); - -Fail2: - _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef ); - -Fail3: - _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef ); - -Fail4: - _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef ); - -Fail5: - _HB_OPEN_Free_Coverage( &ccpf2->Coverage ); - return error; -} - - -static void Free_ChainContextPos2( HB_ChainContextPosFormat2* ccpf2 ) -{ - HB_UShort n, count; - - HB_ChainPosClassSet* cpcs; - - - if ( ccpf2->ChainPosClassSet ) - { - count = ccpf2->ChainPosClassSetCount; - cpcs = ccpf2->ChainPosClassSet; - - for ( n = 0; n < count; n++ ) - Free_ChainPosClassSet( &cpcs[n] ); - - FREE( cpcs ); - } - - _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef ); - _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef ); - _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef ); - - _HB_OPEN_Free_Coverage( &ccpf2->Coverage ); -} - - -/* ChainContextPosFormat3 */ - -static HB_Error Load_ChainContextPos3( HB_ChainContextPosFormat3* ccpf3, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, nb, ni, nl, m, count; - HB_UShort backtrack_count, input_count, lookahead_count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Coverage* b; - HB_Coverage* i; - HB_Coverage* l; - HB_PosLookupRecord* plr; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 2L ) ) - return error; - - ccpf3->BacktrackGlyphCount = GET_UShort(); - - FORGET_Frame(); - - ccpf3->BacktrackCoverage = NULL; - - backtrack_count = ccpf3->BacktrackGlyphCount; - - if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count, - HB_Coverage ) ) - return error; - - b = ccpf3->BacktrackCoverage; - - for ( nb = 0; nb < backtrack_count; nb++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok ) - goto Fail4; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - ccpf3->InputGlyphCount = GET_UShort(); - - FORGET_Frame(); - - ccpf3->InputCoverage = NULL; - - input_count = ccpf3->InputGlyphCount; - - if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, HB_Coverage ) ) - goto Fail4; - - i = ccpf3->InputCoverage; - - for ( ni = 0; ni < input_count; ni++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - ccpf3->LookaheadGlyphCount = GET_UShort(); - - FORGET_Frame(); - - ccpf3->LookaheadCoverage = NULL; - - lookahead_count = ccpf3->LookaheadGlyphCount; - - if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count, - HB_Coverage ) ) - goto Fail3; - - l = ccpf3->LookaheadCoverage; - - for ( nl = 0; nl < lookahead_count; nl++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - ccpf3->PosCount = GET_UShort(); - - FORGET_Frame(); - - ccpf3->PosLookupRecord = NULL; - - count = ccpf3->PosCount; - - if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, HB_PosLookupRecord ) ) - goto Fail2; - - plr = ccpf3->PosLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - plr[n].SequenceIndex = GET_UShort(); - plr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( plr ); - -Fail2: - for ( m = 0; m < nl; m++ ) - _HB_OPEN_Free_Coverage( &l[m] ); - - FREE( l ); - -Fail3: - for ( m = 0; m < ni; m++ ) - _HB_OPEN_Free_Coverage( &i[m] ); - - FREE( i ); - -Fail4: - for ( m = 0; m < nb; m++ ) - _HB_OPEN_Free_Coverage( &b[m] ); - - FREE( b ); - return error; -} - - -static void Free_ChainContextPos3( HB_ChainContextPosFormat3* ccpf3 ) -{ - HB_UShort n, count; - - HB_Coverage* c; - - - FREE( ccpf3->PosLookupRecord ); - - if ( ccpf3->LookaheadCoverage ) - { - count = ccpf3->LookaheadGlyphCount; - c = ccpf3->LookaheadCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } - - if ( ccpf3->InputCoverage ) - { - count = ccpf3->InputGlyphCount; - c = ccpf3->InputCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } - - if ( ccpf3->BacktrackCoverage ) - { - count = ccpf3->BacktrackGlyphCount; - c = ccpf3->BacktrackCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } -} - - -/* ChainContextPos */ - -static HB_Error Load_ChainContextPos( HB_GPOS_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_ChainContextPos* ccp = &st->chain; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - ccp->PosFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( ccp->PosFormat ) - { - case 1: - return Load_ChainContextPos1( &ccp->ccpf.ccpf1, stream ); - - case 2: - return Load_ChainContextPos2( &ccp->ccpf.ccpf2, stream ); - - case 3: - return Load_ChainContextPos3( &ccp->ccpf.ccpf3, stream ); - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - -static void Free_ChainContextPos( HB_GPOS_SubTable* st ) -{ - HB_ChainContextPos* ccp = &st->chain; - - switch ( ccp->PosFormat ) - { - case 1: Free_ChainContextPos1( &ccp->ccpf.ccpf1 ); break; - case 2: Free_ChainContextPos2( &ccp->ccpf.ccpf2 ); break; - case 3: Free_ChainContextPos3( &ccp->ccpf.ccpf3 ); break; - default: break; - } -} - - -static HB_Error Lookup_ChainContextPos1( - GPOS_Instance* gpi, - HB_ChainContextPosFormat1* ccpf1, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_UShort i, j, k, num_cpr; - HB_UShort bgc, igc, lgc; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - - HB_ChainPosRule* cpr; - HB_ChainPosRule curr_cpr; - HB_GDEFHeader* gdef; - - - gdef = gpos->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &ccpf1->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - cpr = ccpf1->ChainPosRuleSet[index].ChainPosRule; - num_cpr = ccpf1->ChainPosRuleSet[index].ChainPosRuleCount; - - for ( k = 0; k < num_cpr; k++ ) - { - curr_cpr = cpr[k]; - bgc = curr_cpr.BacktrackGlyphCount; - igc = curr_cpr.InputGlyphCount; - lgc = curr_cpr.LookaheadGlyphCount; - - if ( context_length != 0xFFFF && context_length < igc ) - goto next_chainposrule; - - /* check whether context is too long; it is a first guess only */ - - if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length ) - goto next_chainposrule; - - if ( bgc ) - { - /* Since we don't know in advance the number of glyphs to inspect, - we search backwards for matches in the backtrack glyph array */ - - for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + 1 == bgc - i ) - goto next_chainposrule; - j--; - } - - /* In OpenType 1.3, it is undefined whether the offsets of - backtrack glyphs is in logical order or not. Version 1.4 - will clarify this: - - Logical order - a b c d e f g h i j - i - Input offsets - 0 1 - Backtrack offsets - 3 2 1 0 - Lookahead offsets - 0 1 2 3 */ - - if ( IN_GLYPH( j ) != curr_cpr.Backtrack[i] ) - goto next_chainposrule; - } - } - - /* Start at 1 because [0] is implied */ - - for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) - goto next_chainposrule; - j++; - } - - if ( IN_GLYPH( j ) != curr_cpr.Input[i - 1] ) - goto next_chainposrule; - } - - /* we are starting to check for lookahead glyphs right after the - last context glyph */ - - for ( i = 0; i < lgc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + lgc - i == (HB_Int)buffer->in_length ) - goto next_chainposrule; - j++; - } - - if ( IN_GLYPH( j ) != curr_cpr.Lookahead[i] ) - goto next_chainposrule; - } - - return Do_ContextPos( gpi, igc, - curr_cpr.PosCount, - curr_cpr.PosLookupRecord, - buffer, - nesting_level ); - - next_chainposrule: - ; - } - - return HB_Err_Not_Covered; -} - - -static HB_Error Lookup_ChainContextPos2( - GPOS_Instance* gpi, - HB_ChainContextPosFormat2* ccpf2, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_Error error; - HB_UShort i, j, k; - HB_UShort bgc, igc, lgc; - HB_UShort known_backtrack_classes, - known_input_classes, - known_lookahead_classes; - - HB_UShort* backtrack_classes; - HB_UShort* input_classes; - HB_UShort* lookahead_classes; - - HB_UShort* bc; - HB_UShort* ic; - HB_UShort* lc; - HB_GPOSHeader* gpos = gpi->gpos; - - HB_ChainPosClassSet* cpcs; - HB_ChainPosClassRule cpcr; - HB_GDEFHeader* gdef; - - - gdef = gpos->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - /* Note: The coverage table in format 2 doesn't give an index into - anything. It just lets us know whether or not we need to - do any lookup at all. */ - - error = _HB_OPEN_Coverage_Index( &ccpf2->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - if (ccpf2->MaxInputLength < 1) - return HB_Err_Not_Covered; - - if ( ALLOC_ARRAY( backtrack_classes, ccpf2->MaxBacktrackLength, HB_UShort ) ) - return error; - known_backtrack_classes = 0; - - if ( ALLOC_ARRAY( input_classes, ccpf2->MaxInputLength, HB_UShort ) ) - goto End3; - known_input_classes = 1; - - if ( ALLOC_ARRAY( lookahead_classes, ccpf2->MaxLookaheadLength, HB_UShort ) ) - goto End2; - known_lookahead_classes = 0; - - error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_CURGLYPH(), - &input_classes[0], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - cpcs = &ccpf2->ChainPosClassSet[input_classes[0]]; - if ( !cpcs ) - { - error = ERR(HB_Err_Invalid_SubTable); - goto End1; - } - - for ( k = 0; k < cpcs->ChainPosClassRuleCount; k++ ) - { - cpcr = cpcs->ChainPosClassRule[k]; - bgc = cpcr.BacktrackGlyphCount; - igc = cpcr.InputGlyphCount; - lgc = cpcr.LookaheadGlyphCount; - - if ( context_length != 0xFFFF && context_length < igc ) - goto next_chainposclassrule; - - /* check whether context is too long; it is a first guess only */ - - if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length ) - goto next_chainposclassrule; - - if ( bgc ) - { - /* Since we don't know in advance the number of glyphs to inspect, - we search backwards for matches in the backtrack glyph array. - Note that `known_backtrack_classes' starts at index 0. */ - - bc = cpcr.Backtrack; - - for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - if ( j + 1 == bgc - i ) - goto next_chainposclassrule; - j++; - } - - if ( i >= known_backtrack_classes ) - { - /* Keeps us from having to do this for each rule */ - - error = _HB_OPEN_Get_Class( &ccpf2->BacktrackClassDef, IN_GLYPH( j ), - &backtrack_classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - known_backtrack_classes = i; - } - - if ( bc[i] != backtrack_classes[i] ) - goto next_chainposclassrule; - } - } - - ic = cpcr.Input; - - /* Start at 1 because [0] is implied */ - - for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) - goto next_chainposclassrule; - j++; - } - - if ( i >= known_input_classes ) - { - error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_GLYPH( j ), - &input_classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - known_input_classes = i; - } - - if ( ic[i - 1] != input_classes[i] ) - goto next_chainposclassrule; - } - - /* we are starting to check for lookahead glyphs right after the - last context glyph */ - - lc = cpcr.Lookahead; - - for ( i = 0; i < lgc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - if ( j + lgc - i == (HB_Int)buffer->in_length ) - goto next_chainposclassrule; - j++; - } - - if ( i >= known_lookahead_classes ) - { - error = _HB_OPEN_Get_Class( &ccpf2->LookaheadClassDef, IN_GLYPH( j ), - &lookahead_classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - known_lookahead_classes = i; - } - - if ( lc[i] != lookahead_classes[i] ) - goto next_chainposclassrule; - } - - error = Do_ContextPos( gpi, igc, - cpcr.PosCount, - cpcr.PosLookupRecord, - buffer, - nesting_level ); - goto End1; - - next_chainposclassrule: - ; - } - - error = HB_Err_Not_Covered; - -End1: - FREE( lookahead_classes ); - -End2: - FREE( input_classes ); - -End3: - FREE( backtrack_classes ); - return error; -} - - -static HB_Error Lookup_ChainContextPos3( - GPOS_Instance* gpi, - HB_ChainContextPosFormat3* ccpf3, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, i, j, property; - HB_UShort bgc, igc, lgc; - HB_Error error; - HB_GPOSHeader* gpos = gpi->gpos; - - HB_Coverage* bc; - HB_Coverage* ic; - HB_Coverage* lc; - HB_GDEFHeader* gdef; - - - gdef = gpos->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - bgc = ccpf3->BacktrackGlyphCount; - igc = ccpf3->InputGlyphCount; - lgc = ccpf3->LookaheadGlyphCount; - - if ( context_length != 0xFFFF && context_length < igc ) - return HB_Err_Not_Covered; - - /* check whether context is too long; it is a first guess only */ - - if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length ) - return HB_Err_Not_Covered; - - if ( bgc ) - { - /* Since we don't know in advance the number of glyphs to inspect, - we search backwards for matches in the backtrack glyph array */ - - bc = ccpf3->BacktrackCoverage; - - for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + 1 == bgc - i ) - return HB_Err_Not_Covered; - j--; - } - - error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - } - - ic = ccpf3->InputCoverage; - - for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ ) - { - /* We already called CHECK_Property for IN_GLYPH ( buffer->in_pos ) */ - while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) - return HB_Err_Not_Covered; - j++; - } - - error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - - /* we are starting to check for lookahead glyphs right after the - last context glyph */ - - lc = ccpf3->LookaheadCoverage; - - for ( i = 0; i < lgc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + lgc - i == (HB_Int)buffer->in_length ) - return HB_Err_Not_Covered; - j++; - } - - error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - - return Do_ContextPos( gpi, igc, - ccpf3->PosCount, - ccpf3->PosLookupRecord, - buffer, - nesting_level ); -} - - -static HB_Error Lookup_ChainContextPos( - GPOS_Instance* gpi, - HB_GPOS_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_ChainContextPos* ccp = &st->chain; - - switch ( ccp->PosFormat ) - { - case 1: - return Lookup_ChainContextPos1( gpi, &ccp->ccpf.ccpf1, buffer, - flags, context_length, - nesting_level ); - - case 2: - return Lookup_ChainContextPos2( gpi, &ccp->ccpf.ccpf2, buffer, - flags, context_length, - nesting_level ); - - case 3: - return Lookup_ChainContextPos3( gpi, &ccp->ccpf.ccpf3, buffer, - flags, context_length, - nesting_level ); - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - - -/*********** - * GPOS API - ***********/ - - - -HB_Error HB_GPOS_Select_Script( HB_GPOSHeader* gpos, - HB_UInt script_tag, - HB_UShort* script_index ) -{ - HB_UShort n; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - - - if ( !gpos || !script_index ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gpos->ScriptList; - sr = sl->ScriptRecord; - - for ( n = 0; n < sl->ScriptCount; n++ ) - if ( script_tag == sr[n].ScriptTag ) - { - *script_index = n; - - return HB_Err_Ok; - } - - return HB_Err_Not_Covered; -} - - - -HB_Error HB_GPOS_Select_Language( HB_GPOSHeader* gpos, - HB_UInt language_tag, - HB_UShort script_index, - HB_UShort* language_index, - HB_UShort* req_feature_index ) -{ - HB_UShort n; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - - - if ( !gpos || !language_index || !req_feature_index ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gpos->ScriptList; - sr = sl->ScriptRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - for ( n = 0; n < s->LangSysCount; n++ ) - if ( language_tag == lsr[n].LangSysTag ) - { - *language_index = n; - *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; - - return HB_Err_Ok; - } - - return HB_Err_Not_Covered; -} - - -/* selecting 0xFFFF for language_index asks for the values of the - default language (DefaultLangSys) */ - - -HB_Error HB_GPOS_Select_Feature( HB_GPOSHeader* gpos, - HB_UInt feature_tag, - HB_UShort script_index, - HB_UShort language_index, - HB_UShort* feature_index ) -{ - HB_UShort n; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - HB_LangSys* ls; - HB_UShort* fi; - - HB_FeatureList* fl; - HB_FeatureRecord* fr; - - - if ( !gpos || !feature_index ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gpos->ScriptList; - sr = sl->ScriptRecord; - - fl = &gpos->FeatureList; - fr = fl->FeatureRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - if ( language_index == 0xFFFF ) - ls = &s->DefaultLangSys; - else - { - if ( language_index >= s->LangSysCount ) - return ERR(HB_Err_Invalid_Argument); - - ls = &lsr[language_index].LangSys; - } - - fi = ls->FeatureIndex; - - for ( n = 0; n < ls->FeatureCount; n++ ) - { - if ( fi[n] >= fl->FeatureCount ) - return ERR(HB_Err_Invalid_SubTable_Format); - - if ( feature_tag == fr[fi[n]].FeatureTag ) - { - *feature_index = fi[n]; - - return HB_Err_Ok; - } - } - - return HB_Err_Not_Covered; -} - - -/* The next three functions return a null-terminated list */ - - -HB_Error HB_GPOS_Query_Scripts( HB_GPOSHeader* gpos, - HB_UInt** script_tag_list ) -{ - HB_Error error; - HB_UShort n; - HB_UInt* stl; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - - - if ( !gpos || !script_tag_list ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gpos->ScriptList; - sr = sl->ScriptRecord; - - if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) ) - return error; - - for ( n = 0; n < sl->ScriptCount; n++ ) - stl[n] = sr[n].ScriptTag; - stl[n] = 0; - - *script_tag_list = stl; - - return HB_Err_Ok; -} - - - -HB_Error HB_GPOS_Query_Languages( HB_GPOSHeader* gpos, - HB_UShort script_index, - HB_UInt** language_tag_list ) -{ - HB_Error error; - HB_UShort n; - HB_UInt* ltl; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - - - if ( !gpos || !language_tag_list ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gpos->ScriptList; - sr = sl->ScriptRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) ) - return error; - - for ( n = 0; n < s->LangSysCount; n++ ) - ltl[n] = lsr[n].LangSysTag; - ltl[n] = 0; - - *language_tag_list = ltl; - - return HB_Err_Ok; -} - - -/* selecting 0xFFFF for language_index asks for the values of the - default language (DefaultLangSys) */ - - -HB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos, - HB_UShort script_index, - HB_UShort language_index, - HB_UInt** feature_tag_list ) -{ - HB_UShort n; - HB_Error error; - HB_UInt* ftl; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - HB_LangSys* ls; - HB_UShort* fi; - - HB_FeatureList* fl; - HB_FeatureRecord* fr; - - - if ( !gpos || !feature_tag_list ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gpos->ScriptList; - sr = sl->ScriptRecord; - - fl = &gpos->FeatureList; - fr = fl->FeatureRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - if ( language_index == 0xFFFF ) - ls = &s->DefaultLangSys; - else - { - if ( language_index >= s->LangSysCount ) - return ERR(HB_Err_Invalid_Argument); - - ls = &lsr[language_index].LangSys; - } - - fi = ls->FeatureIndex; - - if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) ) - return error; - - for ( n = 0; n < ls->FeatureCount; n++ ) - { - if ( fi[n] >= fl->FeatureCount ) - { - FREE( ftl ); - return ERR(HB_Err_Invalid_SubTable_Format); - } - ftl[n] = fr[fi[n]].FeatureTag; - } - ftl[n] = 0; - - *feature_tag_list = ftl; - - return HB_Err_Ok; -} - - -/* Do an individual subtable lookup. Returns HB_Err_Ok if positioning - has been done, or HB_Err_Not_Covered if not. */ -static HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi, - HB_UShort lookup_index, - HB_Buffer buffer, - HB_UShort context_length, - int nesting_level ) -{ - HB_Error error = HB_Err_Not_Covered; - HB_UShort i, flags, lookup_count; - HB_GPOSHeader* gpos = gpi->gpos; - HB_Lookup* lo; - int lookup_type; - - - nesting_level++; - - if ( nesting_level > HB_MAX_NESTING_LEVEL ) - return ERR(HB_Err_Not_Covered); /* ERR() call intended */ - - lookup_count = gpos->LookupList.LookupCount; - if (lookup_index >= lookup_count) - return error; - - lo = &gpos->LookupList.Lookup[lookup_index]; - flags = lo->LookupFlag; - lookup_type = lo->LookupType; - - for ( i = 0; i < lo->SubTableCount; i++ ) - { - HB_GPOS_SubTable *st = &lo->SubTable[i].st.gpos; - - switch (lookup_type) { - case HB_GPOS_LOOKUP_SINGLE: - error = Lookup_SinglePos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - case HB_GPOS_LOOKUP_PAIR: - error = Lookup_PairPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - case HB_GPOS_LOOKUP_CURSIVE: - error = Lookup_CursivePos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - case HB_GPOS_LOOKUP_MARKBASE: - error = Lookup_MarkBasePos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - case HB_GPOS_LOOKUP_MARKLIG: - error = Lookup_MarkLigPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - case HB_GPOS_LOOKUP_MARKMARK: - error = Lookup_MarkMarkPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - case HB_GPOS_LOOKUP_CONTEXT: - error = Lookup_ContextPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - case HB_GPOS_LOOKUP_CHAIN: - error = Lookup_ChainContextPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; - /*case HB_GPOS_LOOKUP_EXTENSION: - error = Lookup_ExtensionPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;*/ - default: - error = HB_Err_Not_Covered; - } - - /* Check whether we have a successful positioning or an error other - than HB_Err_Not_Covered */ - if ( error != HB_Err_Not_Covered ) - return error; - } - - return HB_Err_Not_Covered; -} - - -HB_INTERNAL HB_Error -_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st, - HB_Stream stream, - HB_UShort lookup_type ) -{ - switch ( lookup_type ) { - case HB_GPOS_LOOKUP_SINGLE: return Load_SinglePos ( st, stream ); - case HB_GPOS_LOOKUP_PAIR: return Load_PairPos ( st, stream ); - case HB_GPOS_LOOKUP_CURSIVE: return Load_CursivePos ( st, stream ); - case HB_GPOS_LOOKUP_MARKBASE: return Load_MarkBasePos ( st, stream ); - case HB_GPOS_LOOKUP_MARKLIG: return Load_MarkLigPos ( st, stream ); - case HB_GPOS_LOOKUP_MARKMARK: return Load_MarkMarkPos ( st, stream ); - case HB_GPOS_LOOKUP_CONTEXT: return Load_ContextPos ( st, stream ); - case HB_GPOS_LOOKUP_CHAIN: return Load_ChainContextPos ( st, stream ); - /*case HB_GPOS_LOOKUP_EXTENSION: return Load_ExtensionPos ( st, stream );*/ - default: return ERR(HB_Err_Invalid_SubTable_Format); - } -} - - -HB_INTERNAL void -_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st, - HB_UShort lookup_type ) -{ - switch ( lookup_type ) { - case HB_GPOS_LOOKUP_SINGLE: Free_SinglePos ( st ); return; - case HB_GPOS_LOOKUP_PAIR: Free_PairPos ( st ); return; - case HB_GPOS_LOOKUP_CURSIVE: Free_CursivePos ( st ); return; - case HB_GPOS_LOOKUP_MARKBASE: Free_MarkBasePos ( st ); return; - case HB_GPOS_LOOKUP_MARKLIG: Free_MarkLigPos ( st ); return; - case HB_GPOS_LOOKUP_MARKMARK: Free_MarkMarkPos ( st ); return; - case HB_GPOS_LOOKUP_CONTEXT: Free_ContextPos ( st ); return; - case HB_GPOS_LOOKUP_CHAIN: Free_ChainContextPos ( st ); return; - /*case HB_GPOS_LOOKUP_EXTENSION: Free_ExtensionPos ( st ); return;*/ - default: return; - } -} - - -/* apply one lookup to the input string object */ - -static HB_Error GPOS_Do_String_Lookup( GPOS_Instance* gpi, - HB_UShort lookup_index, - HB_Buffer buffer ) -{ - HB_Error error, retError = HB_Err_Not_Covered; - HB_GPOSHeader* gpos = gpi->gpos; - - HB_UInt* properties = gpos->LookupList.Properties; - - const int nesting_level = 0; - /* 0xFFFF indicates that we don't have a context length yet */ - const HB_UShort context_length = 0xFFFF; - - - gpi->last = 0xFFFF; /* no last valid glyph for cursive pos. */ - - buffer->in_pos = 0; - while ( buffer->in_pos < buffer->in_length ) - { - if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] ) - { - /* Note that the connection between mark and base glyphs hold - exactly one (string) lookup. For example, it would be possible - that in the first lookup, mark glyph X is attached to base - glyph A, and in the next lookup it is attached to base glyph B. - It is up to the font designer to provide meaningful lookups and - lookup order. */ - - error = GPOS_Do_Glyph_Lookup( gpi, lookup_index, buffer, context_length, nesting_level ); - if ( error && error != HB_Err_Not_Covered ) - return error; - } - else - { - /* Contrary to properties defined in GDEF, user-defined properties - will always stop a possible cursive positioning. */ - gpi->last = 0xFFFF; - - error = HB_Err_Not_Covered; - } - - if ( error == HB_Err_Not_Covered ) - (buffer->in_pos)++; - else - retError = error; - } - - return retError; -} - - -static HB_Error Position_CursiveChain ( HB_Buffer buffer ) -{ - HB_UInt i, j; - HB_Position positions = buffer->positions; - - /* First handle all left-to-right connections */ - for (j = 0; j < buffer->in_length; j++) - { - if (positions[j].cursive_chain > 0) - positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos; - } - - /* Then handle all right-to-left connections */ - for (i = buffer->in_length; i > 0; i--) - { - j = i - 1; - - if (positions[j].cursive_chain < 0) - positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos; - } - - return HB_Err_Ok; -} - - -HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos, - HB_UShort feature_index, - HB_UInt property ) -{ - HB_UShort i; - - HB_Feature feature; - HB_UInt* properties; - HB_UShort* index; - HB_UShort lookup_count; - - /* Each feature can only be added once */ - - if ( !gpos || - feature_index >= gpos->FeatureList.FeatureCount || - gpos->FeatureList.ApplyCount == gpos->FeatureList.FeatureCount ) - return ERR(HB_Err_Invalid_Argument); - - gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index; - - properties = gpos->LookupList.Properties; - - feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; - index = feature.LookupListIndex; - lookup_count = gpos->LookupList.LookupCount; - - for ( i = 0; i < feature.LookupListCount; i++ ) - { - HB_UShort lookup_index = index[i]; - if (lookup_index < lookup_count) - properties[lookup_index] |= property; - } - - return HB_Err_Ok; -} - - - -HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos ) -{ - HB_UShort i; - - HB_UInt* properties; - - - if ( !gpos ) - return ERR(HB_Err_Invalid_Argument); - - gpos->FeatureList.ApplyCount = 0; - - properties = gpos->LookupList.Properties; - - for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) - properties[i] = 0; - - return HB_Err_Ok; -} - -#ifdef HB_SUPPORT_MULTIPLE_MASTER -HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos, - HB_MMFunction mmfunc, - void* data ) -{ - if ( !gpos ) - return ERR(HB_Err_Invalid_Argument); - - gpos->mmfunc = mmfunc; - gpos->data = data; - - return HB_Err_Ok; -} -#endif - -/* If `dvi' is TRUE, glyph contour points for anchor points and device - tables are ignored -- you will get device independent values. */ - - -HB_Error HB_GPOS_Apply_String( HB_Font font, - HB_GPOSHeader* gpos, - HB_UShort load_flags, - HB_Buffer buffer, - HB_Bool dvi, - HB_Bool r2l ) -{ - HB_Error error, retError = HB_Err_Not_Covered; - GPOS_Instance gpi; - int i, j, lookup_count, num_features; - - if ( !font || !gpos || !buffer ) - return ERR(HB_Err_Invalid_Argument); - - if ( buffer->in_length == 0 ) - return HB_Err_Not_Covered; - - gpi.font = font; - gpi.gpos = gpos; - gpi.load_flags = load_flags; - gpi.r2l = r2l; - gpi.dvi = dvi; - - lookup_count = gpos->LookupList.LookupCount; - num_features = gpos->FeatureList.ApplyCount; - - if ( num_features ) - { - error = _hb_buffer_clear_positions( buffer ); - if ( error ) - return error; - } - - for ( i = 0; i < num_features; i++ ) - { - HB_UShort feature_index = gpos->FeatureList.ApplyOrder[i]; - HB_Feature feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; - - for ( j = 0; j < feature.LookupListCount; j++ ) - { - HB_UShort lookup_index = feature.LookupListIndex[j]; - - /* Skip nonexistant lookups */ - if (lookup_index >= lookup_count) - continue; - - error = GPOS_Do_String_Lookup( &gpi, lookup_index, buffer ); - if ( error ) - { - if ( error != HB_Err_Not_Covered ) - return error; - } - else - retError = error; - } - } - - if ( num_features ) - { - error = Position_CursiveChain ( buffer ); - if ( error ) - return error; - } - - return retError; -} - -/* END */ diff --git a/src/hb-old/harfbuzz-gpos.h b/src/hb-old/harfbuzz-gpos.h deleted file mode 100644 index 92bff84..0000000 --- a/src/hb-old/harfbuzz-gpos.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GPOS_H -#define HARFBUZZ_GPOS_H - -#include "harfbuzz-gdef.h" -#include "harfbuzz-buffer.h" - -HB_BEGIN_HEADER - - -/* Lookup types for glyph positioning */ - -#define HB_GPOS_LOOKUP_SINGLE 1 -#define HB_GPOS_LOOKUP_PAIR 2 -#define HB_GPOS_LOOKUP_CURSIVE 3 -#define HB_GPOS_LOOKUP_MARKBASE 4 -#define HB_GPOS_LOOKUP_MARKLIG 5 -#define HB_GPOS_LOOKUP_MARKMARK 6 -#define HB_GPOS_LOOKUP_CONTEXT 7 -#define HB_GPOS_LOOKUP_CHAIN 8 -#define HB_GPOS_LOOKUP_EXTENSION 9 - -#ifdef HB_SUPPORT_MULTIPLE_MASTER -/* A pointer to a function which accesses the PostScript interpreter. - Multiple Master fonts need this interface to convert a metric ID - (as stored in an OpenType font version 1.2 or higher) `metric_id' - into a metric value (returned in `metric_value'). - - `data' points to the user-defined structure specified during a - call to HB_GPOS_Register_MM_Function(). - - `metric_value' must be returned as a scaled value (but shouldn't - be rounded). */ - -typedef HB_Error (*HB_MMFunction)(HB_Font font, - HB_UShort metric_id, - HB_Fixed* metric_value, - void* data ); -#endif - - -struct HB_GPOSHeader_ -{ - HB_16Dot16 Version; - - HB_ScriptList ScriptList; - HB_FeatureList FeatureList; - HB_LookupList LookupList; - - HB_GDEFHeader* gdef; - -#ifdef HB_SUPPORT_MULTIPLE_MASTER - /* this is OpenType 1.2 -- Multiple Master fonts need this - callback function to get various metric values from the - PostScript interpreter. */ - - HB_MMFunction mmfunc; - void* data; -#endif -}; - -typedef struct HB_GPOSHeader_ HB_GPOSHeader; -typedef HB_GPOSHeader* HB_GPOS; - - -HB_Error HB_Load_GPOS_Table( HB_Stream stream, - HB_GPOSHeader** gpos, - HB_GDEFHeader* gdef, - HB_Stream gdefStream ); - - -HB_Error HB_Done_GPOS_Table( HB_GPOSHeader* gpos ); - - -HB_Error HB_GPOS_Select_Script( HB_GPOSHeader* gpos, - HB_UInt script_tag, - HB_UShort* script_index ); - -HB_Error HB_GPOS_Select_Language( HB_GPOSHeader* gpos, - HB_UInt language_tag, - HB_UShort script_index, - HB_UShort* language_index, - HB_UShort* req_feature_index ); - -HB_Error HB_GPOS_Select_Feature( HB_GPOSHeader* gpos, - HB_UInt feature_tag, - HB_UShort script_index, - HB_UShort language_index, - HB_UShort* feature_index ); - - -HB_Error HB_GPOS_Query_Scripts( HB_GPOSHeader* gpos, - HB_UInt** script_tag_list ); - -HB_Error HB_GPOS_Query_Languages( HB_GPOSHeader* gpos, - HB_UShort script_index, - HB_UInt** language_tag_list ); - -HB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos, - HB_UShort script_index, - HB_UShort language_index, - HB_UInt** feature_tag_list ); - - -HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos, - HB_UShort feature_index, - HB_UInt property ); - -HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos ); - - -#ifdef HB_SUPPORT_MULTIPLE_MASTER -HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos, - HB_MMFunction mmfunc, - void* data ); -#endif - -/* If `dvi' is TRUE, glyph contour points for anchor points and device - tables are ignored -- you will get device independent values. */ - - -HB_Error HB_GPOS_Apply_String( HB_Font font, - HB_GPOSHeader* gpos, - HB_UShort load_flags, - HB_Buffer buffer, - HB_Bool dvi, - HB_Bool r2l ); - -HB_END_HEADER - -#endif /* HARFBUZZ_GPOS_H */ diff --git a/src/hb-old/harfbuzz-greek.c b/src/hb-old/harfbuzz-greek.c deleted file mode 100644 index 2e9b858..0000000 --- a/src/hb-old/harfbuzz-greek.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" -#include <assert.h> - -#ifndef NO_OPENTYPE -static const HB_OpenTypeFeature greek_features[] = { - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty }, - { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty }, - {0, 0} -}; -#endif - -/* - Greek decompositions -*/ - - -typedef struct _hb_greek_decomposition { - HB_UChar16 composed; - HB_UChar16 base; -} hb_greek_decomposition; - -static const hb_greek_decomposition decompose_0x300[] = { - { 0x1FBA, 0x0391 }, - { 0x1FC8, 0x0395 }, - { 0x1FCA, 0x0397 }, - { 0x1FDA, 0x0399 }, - { 0x1FF8, 0x039F }, - { 0x1FEA, 0x03A5 }, - { 0x1FFA, 0x03A9 }, - { 0x1F70, 0x03B1 }, - { 0x1F72, 0x03B5 }, - { 0x1F74, 0x03B7 }, - { 0x1F76, 0x03B9 }, - { 0x1F78, 0x03BF }, - { 0x1F7A, 0x03C5 }, - { 0x1F7C, 0x03C9 }, - { 0x1FD2, 0x03CA }, - { 0x1FE2, 0x03CB }, - { 0x1F02, 0x1F00 }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x300(HB_UChar16 base) -{ - if ((base ^ 0x1f00) < 0x100) { - if (base <= 0x1f69 && !(base & 0x6)) - return base + 2; - if (base == 0x1fbf) - return 0x1fcd; - if (base == 0x1ffe) - return 0x1fdd; - return 0; - } - { - const hb_greek_decomposition *d = decompose_0x300; - while (d->base && d->base != base) - ++d; - return d->composed; - } -} - -static const hb_greek_decomposition decompose_0x301[] = { - { 0x0386, 0x0391 }, - { 0x0388, 0x0395 }, - { 0x0389, 0x0397 }, - { 0x038A, 0x0399 }, - { 0x038C, 0x039F }, - { 0x038E, 0x03A5 }, - { 0x038F, 0x03A9 }, - { 0x03AC, 0x03B1 }, - { 0x03AD, 0x03B5 }, - { 0x03AE, 0x03B7 }, - { 0x03AF, 0x03B9 }, - { 0x03CC, 0x03BF }, - { 0x03CD, 0x03C5 }, - { 0x03CE, 0x03C9 }, - { 0x0390, 0x03CA }, - { 0x03B0, 0x03CB }, - { 0x03D3, 0x03D2 }, - { 0, 0 } -}; - - -static HB_UChar16 compose_0x301(HB_UChar16 base) -{ - if ((base ^ 0x1f00) < 0x100) { - if (base <= 0x1f69 && !(base & 0x6)) - return base + 4; - if (base == 0x1fbf) - return 0x1fce; - if (base == 0x1ffe) - return 0x1fde; - } - { - const hb_greek_decomposition *d = decompose_0x301; - while (d->base && d->base != base) - ++d; - return d->composed; - } -} - -static const hb_greek_decomposition decompose_0x304[] = { - { 0x1FB9, 0x0391 }, - { 0x1FD9, 0x0399 }, - { 0x1FE9, 0x03A5 }, - { 0x1FB1, 0x03B1 }, - { 0x1FD1, 0x03B9 }, - { 0x1FE1, 0x03C5 }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x304(HB_UChar16 base) -{ - const hb_greek_decomposition *d = decompose_0x304; - while (d->base && d->base != base) - ++d; - return d->composed; -} - -static const hb_greek_decomposition decompose_0x306[] = { - { 0x1FB8, 0x0391 }, - { 0x1FD8, 0x0399 }, - { 0x1FE8, 0x03A5 }, - { 0x1FB0, 0x03B1 }, - { 0x1FD0, 0x03B9 }, - { 0x1FE0, 0x03C5 }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x306(HB_UChar16 base) -{ - const hb_greek_decomposition *d = decompose_0x306; - while (d->base && d->base != base) - ++d; - return d->composed; -} - -static const hb_greek_decomposition decompose_0x308[] = { - { 0x03AA, 0x0399 }, - { 0x03AB, 0x03A5 }, - { 0x03CA, 0x03B9 }, - { 0x03CB, 0x03C5 }, - { 0x03D4, 0x03D2 }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x308(HB_UChar16 base) -{ - const hb_greek_decomposition *d = decompose_0x308; - while (d->base && d->base != base) - ++d; - return d->composed; -} - - -static const hb_greek_decomposition decompose_0x313[] = { - { 0x1F08, 0x0391 }, - { 0x1F18, 0x0395 }, - { 0x1F28, 0x0397 }, - { 0x1F38, 0x0399 }, - { 0x1F48, 0x039F }, - { 0x1F68, 0x03A9 }, - { 0x1F00, 0x03B1 }, - { 0x1F10, 0x03B5 }, - { 0x1F20, 0x03B7 }, - { 0x1F30, 0x03B9 }, - { 0x1F40, 0x03BF }, - { 0x1FE4, 0x03C1 }, - { 0x1F50, 0x03C5 }, - { 0x1F60, 0x03C9 }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x313(HB_UChar16 base) -{ - const hb_greek_decomposition *d = decompose_0x313; - while (d->base && d->base != base) - ++d; - return d->composed; -} - -static const hb_greek_decomposition decompose_0x314[] = { - { 0x1F09, 0x0391 }, - { 0x1F19, 0x0395 }, - { 0x1F29, 0x0397 }, - { 0x1F39, 0x0399 }, - { 0x1F49, 0x039F }, - { 0x1FEC, 0x03A1 }, - { 0x1F59, 0x03A5 }, - { 0x1F69, 0x03A9 }, - { 0x1F01, 0x03B1 }, - { 0x1F11, 0x03B5 }, - { 0x1F21, 0x03B7 }, - { 0x1F31, 0x03B9 }, - { 0x1F41, 0x03BF }, - { 0x1FE5, 0x03C1 }, - { 0x1F51, 0x03C5 }, - { 0x1F61, 0x03C9 }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x314(HB_UChar16 base) -{ - const hb_greek_decomposition *d = decompose_0x314; - while (d->base && d->base != base) - ++d; - return d->composed; -} - -static const hb_greek_decomposition decompose_0x342[] = { - { 0x1FB6, 0x03B1 }, - { 0x1FC6, 0x03B7 }, - { 0x1FD6, 0x03B9 }, - { 0x1FE6, 0x03C5 }, - { 0x1FF6, 0x03C9 }, - { 0x1FD7, 0x03CA }, - { 0x1FE7, 0x03CB }, - { 0x1F06, 0x1F00 }, - { 0x1F07, 0x1F01 }, - { 0x1F0E, 0x1F08 }, - { 0x1F0F, 0x1F09 }, - { 0x1F26, 0x1F20 }, - { 0x1F27, 0x1F21 }, - { 0x1F2E, 0x1F28 }, - { 0x1F2F, 0x1F29 }, - { 0x1F36, 0x1F30 }, - { 0x1F37, 0x1F31 }, - { 0x1F3E, 0x1F38 }, - { 0x1F3F, 0x1F39 }, - { 0x1F56, 0x1F50 }, - { 0x1F57, 0x1F51 }, - { 0x1F5F, 0x1F59 }, - { 0x1F66, 0x1F60 }, - { 0x1F67, 0x1F61 }, - { 0x1F6E, 0x1F68 }, - { 0x1F6F, 0x1F69 }, - { 0x1FCF, 0x1FBF }, - { 0x1FDF, 0x1FFE }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x342(HB_UChar16 base) -{ - const hb_greek_decomposition *d = decompose_0x342; - while (d->base && d->base != base) - ++d; - return d->composed; -} - -static const hb_greek_decomposition decompose_0x345[] = { - { 0x1FBC, 0x0391 }, - { 0x1FCC, 0x0397 }, - { 0x1FFC, 0x03A9 }, - { 0x1FB4, 0x03AC }, - { 0x1FC4, 0x03AE }, - { 0x1FB3, 0x03B1 }, - { 0x1FC3, 0x03B7 }, - { 0x1FF3, 0x03C9 }, - { 0x1FF4, 0x03CE }, - { 0x1F80, 0x1F00 }, - { 0x1F81, 0x1F01 }, - { 0x1F82, 0x1F02 }, - { 0x1F83, 0x1F03 }, - { 0x1F84, 0x1F04 }, - { 0x1F85, 0x1F05 }, - { 0x1F86, 0x1F06 }, - { 0x1F87, 0x1F07 }, - { 0x1F88, 0x1F08 }, - { 0x1F89, 0x1F09 }, - { 0x1F8A, 0x1F0A }, - { 0x1F8B, 0x1F0B }, - { 0x1F8C, 0x1F0C }, - { 0x1F8D, 0x1F0D }, - { 0x1F8E, 0x1F0E }, - { 0x1F8F, 0x1F0F }, - { 0x1F90, 0x1F20 }, - { 0x1F91, 0x1F21 }, - { 0x1F92, 0x1F22 }, - { 0x1F93, 0x1F23 }, - { 0x1F94, 0x1F24 }, - { 0x1F95, 0x1F25 }, - { 0x1F96, 0x1F26 }, - { 0x1F97, 0x1F27 }, - { 0x1F98, 0x1F28 }, - { 0x1F99, 0x1F29 }, - { 0x1F9A, 0x1F2A }, - { 0x1F9B, 0x1F2B }, - { 0x1F9C, 0x1F2C }, - { 0x1F9D, 0x1F2D }, - { 0x1F9E, 0x1F2E }, - { 0x1F9F, 0x1F2F }, - { 0x1FA0, 0x1F60 }, - { 0x1FA1, 0x1F61 }, - { 0x1FA2, 0x1F62 }, - { 0x1FA3, 0x1F63 }, - { 0x1FA4, 0x1F64 }, - { 0x1FA5, 0x1F65 }, - { 0x1FA6, 0x1F66 }, - { 0x1FA7, 0x1F67 }, - { 0x1FA8, 0x1F68 }, - { 0x1FA9, 0x1F69 }, - { 0x1FAA, 0x1F6A }, - { 0x1FAB, 0x1F6B }, - { 0x1FAC, 0x1F6C }, - { 0x1FAD, 0x1F6D }, - { 0x1FAE, 0x1F6E }, - { 0x1FAF, 0x1F6F }, - { 0x1FB2, 0x1F70 }, - { 0x1FC2, 0x1F74 }, - { 0x1FF2, 0x1F7C }, - { 0x1FB7, 0x1FB6 }, - { 0x1FC7, 0x1FC6 }, - { 0x1FF7, 0x1FF6 }, - { 0, 0 } -}; - -static HB_UChar16 compose_0x345(HB_UChar16 base) -{ - const hb_greek_decomposition *d = decompose_0x345; - while (d->base && d->base != base) - ++d; - return d->composed; -} - -/* - Greek shaping. Heuristic positioning can't render polytonic greek correctly. We're a lot - better off mapping greek chars with diacritics to the characters in the extended greek - region in Unicode if possible. -*/ -HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item) -{ - const int availableGlyphs = shaper_item->num_glyphs; - const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos; - unsigned short *logClusters = shaper_item->log_clusters; - HB_GlyphAttributes *attributes = shaper_item->attributes; - - HB_Bool haveGlyphs; - int slen = 1; - int cluster_start = 0; - hb_uint32 i; - - HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length); - - assert(shaper_item->item.script == HB_Script_Greek); - - *shapedChars = *uc; - logClusters[0] = 0; - - for (i = 1; i < shaper_item->item.length; ++i) { - hb_uint16 base = shapedChars[slen-1]; - hb_uint16 shaped = 0; - if (uc[i] == 0x300) - shaped = compose_0x300(base); - else if (uc[i] == 0x301) - shaped = compose_0x301(base); - else if (uc[i] == 0x304) - shaped = compose_0x304(base); - else if (uc[i] == 0x306) - shaped = compose_0x306(base); - else if (uc[i] == 0x308) - shaped = compose_0x308(base); - else if (uc[i] == 0x313) - shaped = compose_0x313(base); - else if (uc[i] == 0x314) - shaped = compose_0x314(base); - else if (uc[i] == 0x342) - shaped = compose_0x342(base); - else if (uc[i] == 0x345) - shaped = compose_0x345(base); - - if (shaped) { - if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) { - shapedChars[slen-1] = shaped; - } else { - shaped = 0; - } - } - - if (!shaped) { - HB_CharCategory category; - int cmb; - shapedChars[slen] = uc[i]; - HB_GetUnicodeCharProperties(uc[i], &category, &cmb); - if (category != HB_Mark_NonSpacing) { - attributes[slen].clusterStart = TRUE; - attributes[slen].mark = FALSE; - attributes[slen].combiningClass = 0; - attributes[slen].dontPrint = HB_IsControlChar(uc[i]); - cluster_start = slen; - } else { - attributes[slen].clusterStart = FALSE; - attributes[slen].mark = TRUE; - attributes[slen].combiningClass = cmb; - } - ++slen; - } - logClusters[i] = cluster_start; - } - - haveGlyphs = shaper_item->font->klass - ->convertStringToGlyphIndices(shaper_item->font, - shapedChars, slen, - shaper_item->glyphs, &shaper_item->num_glyphs, - shaper_item->item.bidiLevel % 2); - - HB_FREE_STACKARRAY(shapedChars); - - if (!haveGlyphs) - return FALSE; - -#ifndef NO_OPENTYPE - if (HB_SelectScript(shaper_item, greek_features)) { - HB_OpenTypeShape(shaper_item, /*properties*/0); - return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE); - } -#endif - HB_HeuristicPosition(shaper_item); - - return TRUE; -} - diff --git a/src/hb-old/harfbuzz-gsub-private.h b/src/hb-old/harfbuzz-gsub-private.h deleted file mode 100644 index 7eb329e..0000000 --- a/src/hb-old/harfbuzz-gsub-private.h +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GSUB_PRIVATE_H -#define HARFBUZZ_GSUB_PRIVATE_H - -#include "harfbuzz-impl.h" -#include "harfbuzz-stream-private.h" -#include "harfbuzz-gsub.h" - -HB_BEGIN_HEADER - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -typedef union HB_GSUB_SubTable_ HB_GSUB_SubTable; - -/* LookupType 1 */ - -struct HB_SingleSubstFormat1_ -{ - HB_Short DeltaGlyphID; /* constant added to get - substitution glyph index */ -}; - -typedef struct HB_SingleSubstFormat1_ HB_SingleSubstFormat1; - - -struct HB_SingleSubstFormat2_ -{ - HB_UShort* Substitute; /* array of substitute glyph IDs */ - HB_UShort GlyphCount; /* number of glyph IDs in - Substitute array */ -}; - -typedef struct HB_SingleSubstFormat2_ HB_SingleSubstFormat2; - - -struct HB_SingleSubst_ -{ - union - { - HB_SingleSubstFormat1 ssf1; - HB_SingleSubstFormat2 ssf2; - } ssf; - - HB_Coverage Coverage; /* Coverage table */ - HB_Byte SubstFormat; /* 1 or 2 */ -}; - -typedef struct HB_SingleSubst_ HB_SingleSubst; - - -/* LookupType 2 */ - -struct HB_Sequence_ -{ - HB_UShort* Substitute; /* string of glyph IDs to - substitute */ - HB_UShort GlyphCount; /* number of glyph IDs in the - Substitute array */ -}; - -typedef struct HB_Sequence_ HB_Sequence; - - -struct HB_MultipleSubst_ -{ - HB_Sequence* Sequence; /* array of Sequence tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort SubstFormat; /* always 1 */ - HB_UShort SequenceCount; /* number of Sequence tables */ -}; - -typedef struct HB_MultipleSubst_ HB_MultipleSubst; - - -/* LookupType 3 */ - -struct HB_AlternateSet_ -{ - HB_UShort* Alternate; /* array of alternate glyph IDs */ - HB_UShort GlyphCount; /* number of glyph IDs in the - Alternate array */ -}; - -typedef struct HB_AlternateSet_ HB_AlternateSet; - - -struct HB_AlternateSubst_ -{ - HB_AlternateSet* AlternateSet; /* array of AlternateSet tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort SubstFormat; /* always 1 */ - HB_UShort AlternateSetCount; - /* number of AlternateSet tables */ -}; - -typedef struct HB_AlternateSubst_ HB_AlternateSubst; - - -/* LookupType 4 */ - -struct HB_Ligature_ -{ - HB_UShort* Component; /* array of component glyph IDs */ - HB_UShort LigGlyph; /* glyphID of ligature - to substitute */ - HB_UShort ComponentCount; /* number of components in ligature */ -}; - -typedef struct HB_Ligature_ HB_Ligature; - - -struct HB_LigatureSet_ -{ - HB_Ligature* Ligature; /* array of Ligature tables */ - HB_UShort LigatureCount; /* number of Ligature tables */ -}; - -typedef struct HB_LigatureSet_ HB_LigatureSet; - - -struct HB_LigatureSubst_ -{ - HB_LigatureSet* LigatureSet; /* array of LigatureSet tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort SubstFormat; /* always 1 */ - HB_UShort LigatureSetCount; /* number of LigatureSet tables */ -}; - -typedef struct HB_LigatureSubst_ HB_LigatureSubst; - - -/* needed by both lookup type 5 and 6 */ - -struct HB_SubstLookupRecord_ -{ - HB_UShort SequenceIndex; /* index into current - glyph sequence */ - HB_UShort LookupListIndex; /* Lookup to apply to that pos. */ -}; - -typedef struct HB_SubstLookupRecord_ HB_SubstLookupRecord; - - -/* LookupType 5 */ - -struct HB_SubRule_ -{ - HB_UShort* Input; /* array of input glyph IDs */ - HB_SubstLookupRecord* SubstLookupRecord; - /* array of SubstLookupRecord - tables */ - HB_UShort GlyphCount; /* total number of input glyphs */ - HB_UShort SubstCount; /* number of SubstLookupRecord - tables */ -}; - -typedef struct HB_SubRule_ HB_SubRule; - - -struct HB_SubRuleSet_ -{ - HB_SubRule* SubRule; /* array of SubRule tables */ - HB_UShort SubRuleCount; /* number of SubRule tables */ -}; - -typedef struct HB_SubRuleSet_ HB_SubRuleSet; - - -struct HB_ContextSubstFormat1_ -{ - HB_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort SubRuleSetCount; /* number of SubRuleSet tables */ -}; - -typedef struct HB_ContextSubstFormat1_ HB_ContextSubstFormat1; - - -struct HB_SubClassRule_ -{ - HB_UShort* Class; /* array of classes */ - HB_SubstLookupRecord* SubstLookupRecord; - /* array of SubstLookupRecord - tables */ - HB_UShort GlyphCount; /* total number of context classes */ - HB_UShort SubstCount; /* number of SubstLookupRecord - tables */ -}; - -typedef struct HB_SubClassRule_ HB_SubClassRule; - - -struct HB_SubClassSet_ -{ - HB_SubClassRule* SubClassRule; /* array of SubClassRule tables */ - HB_UShort SubClassRuleCount; - /* number of SubClassRule tables */ -}; - -typedef struct HB_SubClassSet_ HB_SubClassSet; - - -/* The `MaxContextLength' field is not defined in the TTO specification - but simplifies the implementation of this format. It holds the - maximal context length used in the context rules. */ - -struct HB_ContextSubstFormat2_ -{ - HB_SubClassSet* SubClassSet; /* array of SubClassSet tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_ClassDefinition ClassDef; /* ClassDef table */ - HB_UShort SubClassSetCount; - /* number of SubClassSet tables */ - HB_UShort MaxContextLength; - /* maximal context length */ -}; - -typedef struct HB_ContextSubstFormat2_ HB_ContextSubstFormat2; - - -struct HB_ContextSubstFormat3_ -{ - HB_Coverage* Coverage; /* array of Coverage tables */ - HB_SubstLookupRecord* SubstLookupRecord; - /* array of substitution lookups */ - HB_UShort GlyphCount; /* number of input glyphs */ - HB_UShort SubstCount; /* number of SubstLookupRecords */ -}; - -typedef struct HB_ContextSubstFormat3_ HB_ContextSubstFormat3; - - -struct HB_ContextSubst_ -{ - union - { - HB_ContextSubstFormat1 csf1; - HB_ContextSubstFormat2 csf2; - HB_ContextSubstFormat3 csf3; - } csf; - - HB_Byte SubstFormat; /* 1, 2, or 3 */ -}; - -typedef struct HB_ContextSubst_ HB_ContextSubst; - - -/* LookupType 6 */ - -struct HB_ChainSubRule_ -{ - HB_UShort* Backtrack; /* array of backtrack glyph IDs */ - HB_UShort* Input; /* array of input glyph IDs */ - HB_UShort* Lookahead; /* array of lookahead glyph IDs */ - HB_SubstLookupRecord* SubstLookupRecord; - /* array of SubstLookupRecords */ - HB_UShort BacktrackGlyphCount; - /* total number of backtrack glyphs */ - HB_UShort InputGlyphCount; - /* total number of input glyphs */ - HB_UShort LookaheadGlyphCount; - /* total number of lookahead glyphs */ - HB_UShort SubstCount; /* number of SubstLookupRecords */ -}; - -typedef struct HB_ChainSubRule_ HB_ChainSubRule; - - -struct HB_ChainSubRuleSet_ -{ - HB_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */ - HB_UShort ChainSubRuleCount; - /* number of ChainSubRule tables */ -}; - -typedef struct HB_ChainSubRuleSet_ HB_ChainSubRuleSet; - - -struct HB_ChainContextSubstFormat1_ -{ - HB_ChainSubRuleSet* ChainSubRuleSet; - /* array of ChainSubRuleSet tables */ - HB_Coverage Coverage; /* Coverage table */ - HB_UShort ChainSubRuleSetCount; - /* number of ChainSubRuleSet tables */ -}; - -typedef struct HB_ChainContextSubstFormat1_ HB_ChainContextSubstFormat1; - - -struct HB_ChainSubClassRule_ -{ - HB_UShort* Backtrack; /* array of backtrack classes */ - HB_UShort* Input; /* array of context classes */ - HB_UShort* Lookahead; /* array of lookahead classes */ - HB_SubstLookupRecord* SubstLookupRecord; - /* array of substitution lookups */ - HB_UShort BacktrackGlyphCount; - /* total number of backtrack - classes */ - HB_UShort InputGlyphCount; - /* total number of context classes */ - HB_UShort LookaheadGlyphCount; - /* total number of lookahead - classes */ - HB_UShort SubstCount; /* number of SubstLookupRecords */ -}; - -typedef struct HB_ChainSubClassRule_ HB_ChainSubClassRule; - - -struct HB_ChainSubClassSet_ -{ - HB_ChainSubClassRule* ChainSubClassRule; - /* array of ChainSubClassRule - tables */ - HB_UShort ChainSubClassRuleCount; - /* number of ChainSubClassRule - tables */ -}; - -typedef struct HB_ChainSubClassSet_ HB_ChainSubClassSet; - - -/* The `MaxXXXLength' fields are not defined in the TTO specification - but simplifies the implementation of this format. It holds the - maximal context length used in the specific context rules. */ - -struct HB_ChainContextSubstFormat2_ -{ - HB_ChainSubClassSet* ChainSubClassSet; - /* array of ChainSubClassSet - tables */ - HB_Coverage Coverage; /* Coverage table */ - - HB_ClassDefinition BacktrackClassDef; - /* BacktrackClassDef table */ - HB_ClassDefinition InputClassDef; - /* InputClassDef table */ - HB_ClassDefinition LookaheadClassDef; - /* LookaheadClassDef table */ - - HB_UShort ChainSubClassSetCount; - /* number of ChainSubClassSet - tables */ - HB_UShort MaxBacktrackLength; - /* maximal backtrack length */ - HB_UShort MaxLookaheadLength; - /* maximal lookahead length */ - HB_UShort MaxInputLength; - /* maximal input length */ -}; - -typedef struct HB_ChainContextSubstFormat2_ HB_ChainContextSubstFormat2; - - -struct HB_ChainContextSubstFormat3_ -{ - HB_Coverage* BacktrackCoverage; - /* array of backtrack Coverage - tables */ - HB_Coverage* InputCoverage; - /* array of input coverage - tables */ - HB_Coverage* LookaheadCoverage; - /* array of lookahead coverage - tables */ - HB_SubstLookupRecord* SubstLookupRecord; - /* array of substitution lookups */ - HB_UShort BacktrackGlyphCount; - /* number of backtrack glyphs */ - HB_UShort InputGlyphCount; - /* number of input glyphs */ - HB_UShort LookaheadGlyphCount; - /* number of lookahead glyphs */ - HB_UShort SubstCount; /* number of SubstLookupRecords */ -}; - -typedef struct HB_ChainContextSubstFormat3_ HB_ChainContextSubstFormat3; - - -struct HB_ChainContextSubst_ -{ - union - { - HB_ChainContextSubstFormat1 ccsf1; - HB_ChainContextSubstFormat2 ccsf2; - HB_ChainContextSubstFormat3 ccsf3; - } ccsf; - - HB_Byte SubstFormat; /* 1, 2, or 3 */ -}; - -typedef struct HB_ChainContextSubst_ HB_ChainContextSubst; - - -#if 0 -/* LookupType 7 */ -struct HB_ExtensionSubst_ -{ - HB_GSUB_SubTable *subtable; /* referenced subtable */ - HB_UShort SubstFormat; /* always 1 */ - HB_UShort LookuptType; /* lookup-type of referenced subtable */ -}; - -typedef struct HB_ExtensionSubst_ HB_ExtensionSubst; -#endif - - -/* LookupType 8 */ -struct HB_ReverseChainContextSubst_ -{ - HB_Coverage* LookaheadCoverage; /* array of lookahead Coverage - tables */ - HB_UShort* Substitute; /* array of substitute Glyph ID */ - HB_Coverage* BacktrackCoverage; /* array of backtrack Coverage - tables */ - HB_Coverage Coverage; /* coverage table for input glyphs */ - HB_UShort SubstFormat; /* always 1 */ - HB_UShort BacktrackGlyphCount; /* number of backtrack glyphs */ - HB_UShort LookaheadGlyphCount; /* number of lookahead glyphs */ - HB_UShort GlyphCount; /* number of Glyph IDs */ -}; - -typedef struct HB_ReverseChainContextSubst_ HB_ReverseChainContextSubst; - - -union HB_GSUB_SubTable_ -{ - HB_SingleSubst single; - HB_MultipleSubst multiple; - HB_AlternateSubst alternate; - HB_LigatureSubst ligature; - HB_ContextSubst context; - HB_ChainContextSubst chain; - HB_ReverseChainContextSubst reverse; -}; - - - - -HB_INTERNAL HB_Error -_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st, - HB_Stream stream, - HB_UShort lookup_type ); - -HB_INTERNAL void -_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st, - HB_UShort lookup_type ); - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -HB_END_HEADER - -#endif /* HARFBUZZ_GSUB_PRIVATE_H */ diff --git a/src/hb-old/harfbuzz-gsub.c b/src/hb-old/harfbuzz-gsub.c deleted file mode 100644 index ceb7034..0000000 --- a/src/hb-old/harfbuzz-gsub.c +++ /dev/null @@ -1,4329 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * Copyright (C) 2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 - */ - -#include "harfbuzz-impl.h" -#include "harfbuzz-gsub-private.h" -#include "harfbuzz-open-private.h" -#include "harfbuzz-gdef-private.h" - -static HB_Error GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub, - HB_UShort lookup_index, - HB_Buffer buffer, - HB_UShort context_length, - int nesting_level ); - - - -/********************** - * Auxiliary functions - **********************/ - - - -HB_Error HB_Load_GSUB_Table( HB_Stream stream, - HB_GSUBHeader** retptr, - HB_GDEFHeader* gdef, - HB_Stream gdefStream ) -{ - HB_Error error; - HB_UInt cur_offset, new_offset, base_offset; - - HB_GSUBHeader* gsub; - - if ( !retptr ) - return ERR(HB_Err_Invalid_Argument); - - if ( GOTO_Table( TTAG_GSUB ) ) - return error; - - base_offset = FILE_Pos(); - - if ( ALLOC ( gsub, sizeof( *gsub ) ) ) - return error; - - - /* skip version */ - - if ( FILE_Seek( base_offset + 4L ) || - ACCESS_Frame( 2L ) ) - goto Fail4; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_ScriptList( &gsub->ScriptList, - stream ) ) != HB_Err_Ok ) - goto Fail4; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_FeatureList( &gsub->FeatureList, - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_LookupList( &gsub->LookupList, - stream, HB_Type_GSUB ) ) != HB_Err_Ok ) - goto Fail2; - - gsub->gdef = gdef; /* can be NULL */ - - if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream, - gsub->LookupList.Lookup, - gsub->LookupList.LookupCount ) ) ) - goto Fail1; - - *retptr = gsub; - - return HB_Err_Ok; - -Fail1: - _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB ); - -Fail2: - _HB_OPEN_Free_FeatureList( &gsub->FeatureList ); - -Fail3: - _HB_OPEN_Free_ScriptList( &gsub->ScriptList ); - -Fail4: - FREE ( gsub ); - - - return error; -} - - -HB_Error HB_Done_GSUB_Table( HB_GSUBHeader* gsub ) -{ - _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB ); - _HB_OPEN_Free_FeatureList( &gsub->FeatureList ); - _HB_OPEN_Free_ScriptList( &gsub->ScriptList ); - - FREE( gsub ); - - return HB_Err_Ok; -} - -/***************************** - * SubTable related functions - *****************************/ - - -/* LookupType 1 */ - -/* SingleSubstFormat1 */ -/* SingleSubstFormat2 */ - -static HB_Error Load_SingleSubst( HB_GSUB_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_SingleSubst* ss = &st->single; - - HB_UShort n, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_UShort* s; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - ss->SubstFormat = GET_UShort(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &ss->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - switch ( ss->SubstFormat ) - { - case 1: - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - ss->ssf.ssf1.DeltaGlyphID = GET_UShort(); - - FORGET_Frame(); - - break; - - case 2: - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = ss->ssf.ssf2.GlyphCount = GET_UShort(); - - FORGET_Frame(); - - ss->ssf.ssf2.Substitute = NULL; - - if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, HB_UShort ) ) - goto Fail2; - - s = ss->ssf.ssf2.Substitute; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - s[n] = GET_UShort(); - - FORGET_Frame(); - - break; - - default: - return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; - -Fail1: - FREE( s ); - -Fail2: - _HB_OPEN_Free_Coverage( &ss->Coverage ); - return error; -} - - -static void Free_SingleSubst( HB_GSUB_SubTable* st ) -{ - HB_SingleSubst* ss = &st->single; - - switch ( ss->SubstFormat ) - { - case 1: - break; - - case 2: - FREE( ss->ssf.ssf2.Substitute ); - break; - - default: - break; - } - - _HB_OPEN_Free_Coverage( &ss->Coverage ); -} - - -static HB_Error Lookup_SingleSubst( HB_GSUBHeader* gsub, - HB_GSUB_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, value, property; - HB_Error error; - HB_SingleSubst* ss = &st->single; - HB_GDEFHeader* gdef = gsub->gdef; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - return HB_Err_Not_Covered; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &ss->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - switch ( ss->SubstFormat ) - { - case 1: - value = ( IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF; - if ( REPLACE_Glyph( buffer, value, nesting_level ) ) - return error; - break; - - case 2: - if ( index >= ss->ssf.ssf2.GlyphCount ) - return ERR(HB_Err_Invalid_SubTable); - value = ss->ssf.ssf2.Substitute[index]; - if ( REPLACE_Glyph( buffer, value, nesting_level ) ) - return error; - break; - - default: - return ERR(HB_Err_Invalid_SubTable); - } - - if ( gdef && gdef->NewGlyphClasses ) - { - /* we inherit the old glyph class to the substituted glyph */ - - error = _HB_GDEF_Add_Glyph_Property( gdef, value, property ); - if ( error && error != HB_Err_Not_Covered ) - return error; - } - - return HB_Err_Ok; -} - - -/* LookupType 2 */ - -/* Sequence */ - -static HB_Error Load_Sequence( HB_Sequence* s, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* sub; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = s->GlyphCount = GET_UShort(); - - FORGET_Frame(); - - s->Substitute = NULL; - - if ( count ) - { - if ( ALLOC_ARRAY( s->Substitute, count, HB_UShort ) ) - return error; - - sub = s->Substitute; - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( sub ); - return error; - } - - for ( n = 0; n < count; n++ ) - sub[n] = GET_UShort(); - - FORGET_Frame(); - } - - return HB_Err_Ok; -} - - -static void Free_Sequence( HB_Sequence* s ) -{ - FREE( s->Substitute ); -} - - -/* MultipleSubstFormat1 */ - -static HB_Error Load_MultipleSubst( HB_GSUB_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_MultipleSubst* ms = &st->multiple; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Sequence* s; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - ms->SubstFormat = GET_UShort(); /* should be 1 */ - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &ms->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = ms->SequenceCount = GET_UShort(); - - FORGET_Frame(); - - ms->Sequence = NULL; - - if ( ALLOC_ARRAY( ms->Sequence, count, HB_Sequence ) ) - goto Fail2; - - s = ms->Sequence; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Sequence( &s[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_Sequence( &s[m] ); - - FREE( s ); - -Fail2: - _HB_OPEN_Free_Coverage( &ms->Coverage ); - return error; -} - - -static void Free_MultipleSubst( HB_GSUB_SubTable* st ) -{ - HB_UShort n, count; - HB_MultipleSubst* ms = &st->multiple; - - HB_Sequence* s; - - - if ( ms->Sequence ) - { - count = ms->SequenceCount; - s = ms->Sequence; - - for ( n = 0; n < count; n++ ) - Free_Sequence( &s[n] ); - - FREE( s ); - } - - _HB_OPEN_Free_Coverage( &ms->Coverage ); -} - - -static HB_Error Lookup_MultipleSubst( HB_GSUBHeader* gsub, - HB_GSUB_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_Error error; - HB_UShort index, property, n, count; - HB_UShort*s; - HB_MultipleSubst* ms = &st->multiple; - HB_GDEFHeader* gdef = gsub->gdef; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - return HB_Err_Not_Covered; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &ms->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - if ( index >= ms->SequenceCount ) - return ERR(HB_Err_Invalid_SubTable); - - count = ms->Sequence[index].GlyphCount; - s = ms->Sequence[index].Substitute; - - if ( ADD_String( buffer, 1, count, s, 0xFFFF, 0xFFFF ) ) - return error; - - if ( gdef && gdef->NewGlyphClasses ) - { - /* this is a guess only ... */ - - if ( property == HB_GDEF_LIGATURE ) - property = HB_GDEF_BASE_GLYPH; - - for ( n = 0; n < count; n++ ) - { - error = _HB_GDEF_Add_Glyph_Property( gdef, s[n], property ); - if ( error && error != HB_Err_Not_Covered ) - return error; - } - } - - return HB_Err_Ok; -} - - -/* LookupType 3 */ - -/* AlternateSet */ - -static HB_Error Load_AlternateSet( HB_AlternateSet* as, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* a; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = as->GlyphCount = GET_UShort(); - - FORGET_Frame(); - - as->Alternate = NULL; - - if ( ALLOC_ARRAY( as->Alternate, count, HB_UShort ) ) - return error; - - a = as->Alternate; - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( a ); - return error; - } - - for ( n = 0; n < count; n++ ) - a[n] = GET_UShort(); - - FORGET_Frame(); - - return HB_Err_Ok; -} - - -static void Free_AlternateSet( HB_AlternateSet* as ) -{ - FREE( as->Alternate ); -} - - -/* AlternateSubstFormat1 */ - -static HB_Error Load_AlternateSubst( HB_GSUB_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_AlternateSubst* as = &st->alternate; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_AlternateSet* aset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - as->SubstFormat = GET_UShort(); /* should be 1 */ - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &as->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = as->AlternateSetCount = GET_UShort(); - - FORGET_Frame(); - - as->AlternateSet = NULL; - - if ( ALLOC_ARRAY( as->AlternateSet, count, HB_AlternateSet ) ) - goto Fail2; - - aset = as->AlternateSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_AlternateSet( &aset[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_AlternateSet( &aset[m] ); - - FREE( aset ); - -Fail2: - _HB_OPEN_Free_Coverage( &as->Coverage ); - return error; -} - - -static void Free_AlternateSubst( HB_GSUB_SubTable* st ) -{ - HB_UShort n, count; - HB_AlternateSubst* as = &st->alternate; - - HB_AlternateSet* aset; - - - if ( as->AlternateSet ) - { - count = as->AlternateSetCount; - aset = as->AlternateSet; - - for ( n = 0; n < count; n++ ) - Free_AlternateSet( &aset[n] ); - - FREE( aset ); - } - - _HB_OPEN_Free_Coverage( &as->Coverage ); -} - - -static HB_Error Lookup_AlternateSubst( HB_GSUBHeader* gsub, - HB_GSUB_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_Error error; - HB_UShort index, value, alt_index, property; - HB_AlternateSubst* as = &st->alternate; - HB_GDEFHeader* gdef = gsub->gdef; - HB_AlternateSet aset; - - HB_UNUSED(nesting_level); - - if ( context_length != 0xFFFF && context_length < 1 ) - return HB_Err_Not_Covered; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &as->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - aset = as->AlternateSet[index]; - - /* we use a user-defined callback function to get the alternate index */ - - if ( gsub->altfunc ) - alt_index = (gsub->altfunc)( buffer->out_pos, IN_CURGLYPH(), - aset.GlyphCount, aset.Alternate, - gsub->data ); - else - alt_index = 0; - - value = aset.Alternate[alt_index]; - if ( REPLACE_Glyph( buffer, value, nesting_level ) ) - return error; - - if ( gdef && gdef->NewGlyphClasses ) - { - /* we inherit the old glyph class to the substituted glyph */ - - error = _HB_GDEF_Add_Glyph_Property( gdef, value, property ); - if ( error && error != HB_Err_Not_Covered ) - return error; - } - - return HB_Err_Ok; -} - - -/* LookupType 4 */ - -/* Ligature */ - -static HB_Error Load_Ligature( HB_Ligature* l, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* c; - - - if ( ACCESS_Frame( 4L ) ) - return error; - - l->LigGlyph = GET_UShort(); - l->ComponentCount = GET_UShort(); - - FORGET_Frame(); - - l->Component = NULL; - - count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */ - - if ( ALLOC_ARRAY( l->Component, count, HB_UShort ) ) - return error; - - c = l->Component; - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( c ); - return error; - } - - for ( n = 0; n < count; n++ ) - c[n] = GET_UShort(); - - FORGET_Frame(); - - return HB_Err_Ok; -} - - -static void Free_Ligature( HB_Ligature* l ) -{ - FREE( l->Component ); -} - - -/* LigatureSet */ - -static HB_Error Load_LigatureSet( HB_LigatureSet* ls, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Ligature* l; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = ls->LigatureCount = GET_UShort(); - - FORGET_Frame(); - - ls->Ligature = NULL; - - if ( ALLOC_ARRAY( ls->Ligature, count, HB_Ligature ) ) - return error; - - l = ls->Ligature; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Ligature( &l[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_Ligature( &l[m] ); - - FREE( l ); - return error; -} - - -static void Free_LigatureSet( HB_LigatureSet* ls ) -{ - HB_UShort n, count; - - HB_Ligature* l; - - - if ( ls->Ligature ) - { - count = ls->LigatureCount; - l = ls->Ligature; - - for ( n = 0; n < count; n++ ) - Free_Ligature( &l[n] ); - - FREE( l ); - } -} - - -/* LigatureSubstFormat1 */ - -static HB_Error Load_LigatureSubst( HB_GSUB_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_LigatureSubst* ls = &st->ligature; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_LigatureSet* lset; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 4L ) ) - return error; - - ls->SubstFormat = GET_UShort(); /* should be 1 */ - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &ls->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = ls->LigatureSetCount = GET_UShort(); - - FORGET_Frame(); - - ls->LigatureSet = NULL; - - if ( ALLOC_ARRAY( ls->LigatureSet, count, HB_LigatureSet ) ) - goto Fail2; - - lset = ls->LigatureSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_LigatureSet( &lset[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_LigatureSet( &lset[m] ); - - FREE( lset ); - -Fail2: - _HB_OPEN_Free_Coverage( &ls->Coverage ); - return error; -} - - -static void Free_LigatureSubst( HB_GSUB_SubTable* st ) -{ - HB_UShort n, count; - HB_LigatureSubst* ls = &st->ligature; - - HB_LigatureSet* lset; - - - if ( ls->LigatureSet ) - { - count = ls->LigatureSetCount; - lset = ls->LigatureSet; - - for ( n = 0; n < count; n++ ) - Free_LigatureSet( &lset[n] ); - - FREE( lset ); - } - - _HB_OPEN_Free_Coverage( &ls->Coverage ); -} - - -static HB_Error Lookup_LigatureSubst( HB_GSUBHeader* gsub, - HB_GSUB_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_Error error; - HB_UShort numlig, i, j, is_mark, first_is_mark = FALSE; - HB_UShort* c; - HB_LigatureSubst* ls = &st->ligature; - HB_GDEFHeader* gdef = gsub->gdef; - - HB_Ligature* lig; - - HB_UNUSED(nesting_level); - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - if ( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) - first_is_mark = TRUE; - - error = _HB_OPEN_Coverage_Index( &ls->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - if ( index >= ls->LigatureSetCount ) - return ERR(HB_Err_Invalid_SubTable); - - lig = ls->LigatureSet[index].Ligature; - - for ( numlig = ls->LigatureSet[index].LigatureCount; - numlig; - numlig--, lig++ ) - { - if ( buffer->in_pos + lig->ComponentCount > buffer->in_length ) - goto next_ligature; /* Not enough glyphs in input */ - - c = lig->Component; - - is_mark = first_is_mark; - - if ( context_length != 0xFFFF && context_length < lig->ComponentCount ) - break; - - for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + lig->ComponentCount - i == (HB_Int)buffer->in_length ) - goto next_ligature; - j++; - } - - if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) - is_mark = FALSE; - - if ( IN_GLYPH( j ) != c[i - 1] ) - goto next_ligature; - } - - if ( gdef && gdef->NewGlyphClasses ) - { - /* this is just a guess ... */ - - error = _HB_GDEF_Add_Glyph_Property( gdef, lig->LigGlyph, - is_mark ? HB_GDEF_MARK : HB_GDEF_LIGATURE ); - if ( error && error != HB_Err_Not_Covered ) - return error; - } - - if ( j == buffer->in_pos + i ) /* No input glyphs skipped */ - { - /* We don't use a new ligature ID if there are no skipped - glyphs and the ligature already has an ID. */ - - if ( IN_LIGID( buffer->in_pos ) ) - { - if ( ADD_String( buffer, i, 1, &lig->LigGlyph, - 0xFFFF, 0xFFFF ) ) - return error; - } - else - { - HB_UShort ligID = _hb_buffer_allocate_ligid( buffer ); - if ( ADD_String( buffer, i, 1, &lig->LigGlyph, - 0xFFFF, ligID ) ) - return error; - } - } - else - { - HB_UShort ligID = _hb_buffer_allocate_ligid( buffer ); - if ( ADD_Glyph( buffer, lig->LigGlyph, 0xFFFF, ligID ) ) - return error; - - /* Now we must do a second loop to copy the skipped glyphs to - `out' and assign component values to it. We start with the - glyph after the first component. Glyphs between component - i and i+1 belong to component i. Together with the ligID - value it is later possible to check whether a specific - component value really belongs to a given ligature. */ - - for ( i = 0; i < lig->ComponentCount - 1; i++ ) - { - while ( CHECK_Property( gdef, IN_CURITEM(), - flags, &property ) ) - if ( ADD_Glyph( buffer, IN_CURGLYPH(), i, ligID ) ) - return error; - - (buffer->in_pos)++; - } - } - - return HB_Err_Ok; - - next_ligature: - ; - } - - return HB_Err_Not_Covered; -} - - -/* Do the actual substitution for a context substitution (either format - 5 or 6). This is only called after we've determined that the input - matches the subrule. */ - -static HB_Error Do_ContextSubst( HB_GSUBHeader* gsub, - HB_UShort GlyphCount, - HB_UShort SubstCount, - HB_SubstLookupRecord* subst, - HB_Buffer buffer, - int nesting_level ) -{ - HB_Error error; - HB_UInt i, old_pos; - - - i = 0; - - while ( i < GlyphCount ) - { - if ( SubstCount && i == subst->SequenceIndex ) - { - old_pos = buffer->in_pos; - - /* Do a substitution */ - - error = GSUB_Do_Glyph_Lookup( gsub, subst->LookupListIndex, buffer, - GlyphCount, nesting_level ); - - subst++; - SubstCount--; - i += buffer->in_pos - old_pos; - - if ( error == HB_Err_Not_Covered ) - { - if ( COPY_Glyph( buffer ) ) - return error; - i++; - } - else if ( error ) - return error; - } - else - { - /* No substitution for this index */ - - if ( COPY_Glyph( buffer ) ) - return error; - i++; - } - } - - return HB_Err_Ok; -} - - -/* LookupType 5 */ - -/* SubRule */ - -static HB_Error Load_SubRule( HB_SubRule* sr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* i; - - HB_SubstLookupRecord* slr; - - - if ( ACCESS_Frame( 4L ) ) - return error; - - sr->GlyphCount = GET_UShort(); - sr->SubstCount = GET_UShort(); - - FORGET_Frame(); - - sr->Input = NULL; - - count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( sr->Input, count, HB_UShort ) ) - return error; - - i = sr->Input; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - i[n] = GET_UShort(); - - FORGET_Frame(); - - sr->SubstLookupRecord = NULL; - - count = sr->SubstCount; - - if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, HB_SubstLookupRecord ) ) - goto Fail2; - - slr = sr->SubstLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - slr[n].SequenceIndex = GET_UShort(); - slr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( slr ); - -Fail2: - FREE( i ); - return error; -} - - -static void Free_SubRule( HB_SubRule* sr ) -{ - FREE( sr->SubstLookupRecord ); - FREE( sr->Input ); -} - - -/* SubRuleSet */ - -static HB_Error Load_SubRuleSet( HB_SubRuleSet* srs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_SubRule* sr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = srs->SubRuleCount = GET_UShort(); - - FORGET_Frame(); - - srs->SubRule = NULL; - - if ( ALLOC_ARRAY( srs->SubRule, count, HB_SubRule ) ) - return error; - - sr = srs->SubRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_SubRule( &sr[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_SubRule( &sr[m] ); - - FREE( sr ); - return error; -} - - -static void Free_SubRuleSet( HB_SubRuleSet* srs ) -{ - HB_UShort n, count; - - HB_SubRule* sr; - - - if ( srs->SubRule ) - { - count = srs->SubRuleCount; - sr = srs->SubRule; - - for ( n = 0; n < count; n++ ) - Free_SubRule( &sr[n] ); - - FREE( sr ); - } -} - - -/* ContextSubstFormat1 */ - -static HB_Error Load_ContextSubst1( HB_ContextSubstFormat1* csf1, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_SubRuleSet* srs; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &csf1->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = csf1->SubRuleSetCount = GET_UShort(); - - FORGET_Frame(); - - csf1->SubRuleSet = NULL; - - if ( ALLOC_ARRAY( csf1->SubRuleSet, count, HB_SubRuleSet ) ) - goto Fail2; - - srs = csf1->SubRuleSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_SubRuleSet( &srs[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_SubRuleSet( &srs[m] ); - - FREE( srs ); - -Fail2: - _HB_OPEN_Free_Coverage( &csf1->Coverage ); - return error; -} - - -static void Free_ContextSubst1( HB_ContextSubstFormat1* csf1 ) -{ - HB_UShort n, count; - - HB_SubRuleSet* srs; - - - if ( csf1->SubRuleSet ) - { - count = csf1->SubRuleSetCount; - srs = csf1->SubRuleSet; - - for ( n = 0; n < count; n++ ) - Free_SubRuleSet( &srs[n] ); - - FREE( srs ); - } - - _HB_OPEN_Free_Coverage( &csf1->Coverage ); -} - - -/* SubClassRule */ - -static HB_Error Load_SubClassRule( HB_ContextSubstFormat2* csf2, - HB_SubClassRule* scr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_UShort* c; - HB_SubstLookupRecord* slr; - - - if ( ACCESS_Frame( 4L ) ) - return error; - - scr->GlyphCount = GET_UShort(); - scr->SubstCount = GET_UShort(); - - if ( scr->GlyphCount > csf2->MaxContextLength ) - csf2->MaxContextLength = scr->GlyphCount; - - FORGET_Frame(); - - scr->Class = NULL; - - count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( scr->Class, count, HB_UShort ) ) - return error; - - c = scr->Class; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - c[n] = GET_UShort(); - - FORGET_Frame(); - - scr->SubstLookupRecord = NULL; - - count = scr->SubstCount; - - if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, HB_SubstLookupRecord ) ) - goto Fail2; - - slr = scr->SubstLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - slr[n].SequenceIndex = GET_UShort(); - slr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( slr ); - -Fail2: - FREE( c ); - return error; -} - - -static void Free_SubClassRule( HB_SubClassRule* scr ) -{ - FREE( scr->SubstLookupRecord ); - FREE( scr->Class ); -} - - -/* SubClassSet */ - -static HB_Error Load_SubClassSet( HB_ContextSubstFormat2* csf2, - HB_SubClassSet* scs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_SubClassRule* scr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = scs->SubClassRuleCount = GET_UShort(); - - FORGET_Frame(); - - scs->SubClassRule = NULL; - - if ( ALLOC_ARRAY( scs->SubClassRule, count, HB_SubClassRule ) ) - return error; - - scr = scs->SubClassRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_SubClassRule( csf2, &scr[n], - stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_SubClassRule( &scr[m] ); - - FREE( scr ); - return error; -} - - -static void Free_SubClassSet( HB_SubClassSet* scs ) -{ - HB_UShort n, count; - - HB_SubClassRule* scr; - - - if ( scs->SubClassRule ) - { - count = scs->SubClassRuleCount; - scr = scs->SubClassRule; - - for ( n = 0; n < count; n++ ) - Free_SubClassRule( &scr[n] ); - - FREE( scr ); - } -} - - -/* ContextSubstFormat2 */ - -static HB_Error Load_ContextSubst2( HB_ContextSubstFormat2* csf2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_SubClassSet* scs; - - - base_offset = FILE_Pos() - 2; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &csf2->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 4L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - /* `SubClassSetCount' is the upper limit for class values, thus we - read it now to make an additional safety check. */ - - count = csf2->SubClassSetCount = GET_UShort(); - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_ClassDefinition( &csf2->ClassDef, count, - stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - - csf2->SubClassSet = NULL; - csf2->MaxContextLength = 0; - - if ( ALLOC_ARRAY( csf2->SubClassSet, count, HB_SubClassSet ) ) - goto Fail2; - - scs = csf2->SubClassSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if ( new_offset != base_offset ) /* not a NULL offset */ - { - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_SubClassSet( csf2, &scs[n], - stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - else - { - /* we create a SubClassSet table with no entries */ - - csf2->SubClassSet[n].SubClassRuleCount = 0; - csf2->SubClassSet[n].SubClassRule = NULL; - } - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_SubClassSet( &scs[m] ); - - FREE( scs ); - -Fail2: - _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef ); - -Fail3: - _HB_OPEN_Free_Coverage( &csf2->Coverage ); - return error; -} - - -static void Free_ContextSubst2( HB_ContextSubstFormat2* csf2 ) -{ - HB_UShort n, count; - - HB_SubClassSet* scs; - - - if ( csf2->SubClassSet ) - { - count = csf2->SubClassSetCount; - scs = csf2->SubClassSet; - - for ( n = 0; n < count; n++ ) - Free_SubClassSet( &scs[n] ); - - FREE( scs ); - } - - _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef ); - _HB_OPEN_Free_Coverage( &csf2->Coverage ); -} - - -/* ContextSubstFormat3 */ - -static HB_Error Load_ContextSubst3( HB_ContextSubstFormat3* csf3, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Coverage* c; - HB_SubstLookupRecord* slr; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 4L ) ) - return error; - - csf3->GlyphCount = GET_UShort(); - csf3->SubstCount = GET_UShort(); - - FORGET_Frame(); - - csf3->Coverage = NULL; - - count = csf3->GlyphCount; - - if ( ALLOC_ARRAY( csf3->Coverage, count, HB_Coverage ) ) - return error; - - c = csf3->Coverage; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - - csf3->SubstLookupRecord = NULL; - - count = csf3->SubstCount; - - if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count, - HB_SubstLookupRecord ) ) - goto Fail2; - - slr = csf3->SubstLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - slr[n].SequenceIndex = GET_UShort(); - slr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( slr ); - -Fail2: - for ( m = 0; m < n; m++ ) - _HB_OPEN_Free_Coverage( &c[m] ); - - FREE( c ); - return error; -} - - -static void Free_ContextSubst3( HB_ContextSubstFormat3* csf3 ) -{ - HB_UShort n, count; - - HB_Coverage* c; - - - FREE( csf3->SubstLookupRecord ); - - if ( csf3->Coverage ) - { - count = csf3->GlyphCount; - c = csf3->Coverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } -} - - -/* ContextSubst */ - -static HB_Error Load_ContextSubst( HB_GSUB_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_ContextSubst* cs = &st->context; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - cs->SubstFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( cs->SubstFormat ) - { - case 1: return Load_ContextSubst1( &cs->csf.csf1, stream ); - case 2: return Load_ContextSubst2( &cs->csf.csf2, stream ); - case 3: return Load_ContextSubst3( &cs->csf.csf3, stream ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - -static void Free_ContextSubst( HB_GSUB_SubTable* st ) -{ - HB_ContextSubst* cs = &st->context; - - switch ( cs->SubstFormat ) - { - case 1: Free_ContextSubst1( &cs->csf.csf1 ); break; - case 2: Free_ContextSubst2( &cs->csf.csf2 ); break; - case 3: Free_ContextSubst3( &cs->csf.csf3 ); break; - default: break; - } -} - - -static HB_Error Lookup_ContextSubst1( HB_GSUBHeader* gsub, - HB_ContextSubstFormat1* csf1, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_UShort i, j, k, numsr; - HB_Error error; - - HB_SubRule* sr; - HB_GDEFHeader* gdef; - - - gdef = gsub->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - sr = csf1->SubRuleSet[index].SubRule; - numsr = csf1->SubRuleSet[index].SubRuleCount; - - for ( k = 0; k < numsr; k++ ) - { - if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount ) - goto next_subrule; - - if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length ) - goto next_subrule; /* context is too long */ - - for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + sr[k].GlyphCount - i == (HB_Int)buffer->in_length ) - goto next_subrule; - j++; - } - - if ( IN_GLYPH( j ) != sr[k].Input[i - 1] ) - goto next_subrule; - } - - return Do_ContextSubst( gsub, sr[k].GlyphCount, - sr[k].SubstCount, sr[k].SubstLookupRecord, - buffer, - nesting_level ); - next_subrule: - ; - } - - return HB_Err_Not_Covered; -} - - -static HB_Error Lookup_ContextSubst2( HB_GSUBHeader* gsub, - HB_ContextSubstFormat2* csf2, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_Error error; - HB_UShort i, j, k, known_classes; - - HB_UShort* classes; - HB_UShort* cl; - - HB_SubClassSet* scs; - HB_SubClassRule* sr; - HB_GDEFHeader* gdef; - - - gdef = gsub->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - /* Note: The coverage table in format 2 doesn't give an index into - anything. It just lets us know whether or not we need to - do any lookup at all. */ - - error = _HB_OPEN_Coverage_Index( &csf2->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - if (csf2->MaxContextLength < 1) - return HB_Err_Not_Covered; - - if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, HB_UShort ) ) - return error; - - error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_CURGLYPH(), - &classes[0], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End; - known_classes = 0; - - scs = &csf2->SubClassSet[classes[0]]; - if ( !scs ) - { - error = ERR(HB_Err_Invalid_SubTable); - goto End; - } - - for ( k = 0; k < scs->SubClassRuleCount; k++ ) - { - sr = &scs->SubClassRule[k]; - - if ( context_length != 0xFFFF && context_length < sr->GlyphCount ) - goto next_subclassrule; - - if ( buffer->in_pos + sr->GlyphCount > buffer->in_length ) - goto next_subclassrule; /* context is too long */ - - cl = sr->Class; - - /* Start at 1 because [0] is implied */ - - for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End; - - if ( j + sr->GlyphCount - i < (HB_Int)buffer->in_length ) - goto next_subclassrule; - j++; - } - - if ( i > known_classes ) - { - /* Keeps us from having to do this for each rule */ - - error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End; - known_classes = i; - } - - if ( cl[i - 1] != classes[i] ) - goto next_subclassrule; - } - - error = Do_ContextSubst( gsub, sr->GlyphCount, - sr->SubstCount, sr->SubstLookupRecord, - buffer, - nesting_level ); - goto End; - - next_subclassrule: - ; - } - - error = HB_Err_Not_Covered; - -End: - FREE( classes ); - return error; -} - - -static HB_Error Lookup_ContextSubst3( HB_GSUBHeader* gsub, - HB_ContextSubstFormat3* csf3, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_Error error; - HB_UShort index, i, j, property; - - HB_Coverage* c; - HB_GDEFHeader* gdef; - - - gdef = gsub->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - if ( context_length != 0xFFFF && context_length < csf3->GlyphCount ) - return HB_Err_Not_Covered; - - if ( buffer->in_pos + csf3->GlyphCount > buffer->in_length ) - return HB_Err_Not_Covered; /* context is too long */ - - c = csf3->Coverage; - - for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + csf3->GlyphCount - i == (HB_Int)buffer->in_length ) - return HB_Err_Not_Covered; - j++; - } - - error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - - return Do_ContextSubst( gsub, csf3->GlyphCount, - csf3->SubstCount, csf3->SubstLookupRecord, - buffer, - nesting_level ); -} - - -static HB_Error Lookup_ContextSubst( HB_GSUBHeader* gsub, - HB_GSUB_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_ContextSubst* cs = &st->context; - - switch ( cs->SubstFormat ) - { - case 1: return Lookup_ContextSubst1( gsub, &cs->csf.csf1, buffer, flags, context_length, nesting_level ); - case 2: return Lookup_ContextSubst2( gsub, &cs->csf.csf2, buffer, flags, context_length, nesting_level ); - case 3: return Lookup_ContextSubst3( gsub, &cs->csf.csf3, buffer, flags, context_length, nesting_level ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - -/* LookupType 6 */ - -/* ChainSubRule */ - -static HB_Error Load_ChainSubRule( HB_ChainSubRule* csr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - HB_UShort* b; - HB_UShort* i; - HB_UShort* l; - - HB_SubstLookupRecord* slr; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - csr->BacktrackGlyphCount = GET_UShort(); - - FORGET_Frame(); - - csr->Backtrack = NULL; - - count = csr->BacktrackGlyphCount; - - if ( ALLOC_ARRAY( csr->Backtrack, count, HB_UShort ) ) - return error; - - b = csr->Backtrack; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail4; - - for ( n = 0; n < count; n++ ) - b[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - csr->InputGlyphCount = GET_UShort(); - - FORGET_Frame(); - - csr->Input = NULL; - - count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( csr->Input, count, HB_UShort ) ) - goto Fail4; - - i = csr->Input; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail3; - - for ( n = 0; n < count; n++ ) - i[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - csr->LookaheadGlyphCount = GET_UShort(); - - FORGET_Frame(); - - csr->Lookahead = NULL; - - count = csr->LookaheadGlyphCount; - - if ( ALLOC_ARRAY( csr->Lookahead, count, HB_UShort ) ) - goto Fail3; - - l = csr->Lookahead; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - l[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - csr->SubstCount = GET_UShort(); - - FORGET_Frame(); - - csr->SubstLookupRecord = NULL; - - count = csr->SubstCount; - - if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, HB_SubstLookupRecord ) ) - goto Fail2; - - slr = csr->SubstLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - slr[n].SequenceIndex = GET_UShort(); - slr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( slr ); - -Fail2: - FREE( l ); - -Fail3: - FREE( i ); - -Fail4: - FREE( b ); - return error; -} - - -static void Free_ChainSubRule( HB_ChainSubRule* csr ) -{ - FREE( csr->SubstLookupRecord ); - FREE( csr->Lookahead ); - FREE( csr->Input ); - FREE( csr->Backtrack ); -} - - -/* ChainSubRuleSet */ - -static HB_Error Load_ChainSubRuleSet( HB_ChainSubRuleSet* csrs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ChainSubRule* csr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = csrs->ChainSubRuleCount = GET_UShort(); - - FORGET_Frame(); - - csrs->ChainSubRule = NULL; - - if ( ALLOC_ARRAY( csrs->ChainSubRule, count, HB_ChainSubRule ) ) - return error; - - csr = csrs->ChainSubRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainSubRule( &csr[n], stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_ChainSubRule( &csr[m] ); - - FREE( csr ); - return error; -} - - -static void Free_ChainSubRuleSet( HB_ChainSubRuleSet* csrs ) -{ - HB_UShort n, count; - - HB_ChainSubRule* csr; - - - if ( csrs->ChainSubRule ) - { - count = csrs->ChainSubRuleCount; - csr = csrs->ChainSubRule; - - for ( n = 0; n < count; n++ ) - Free_ChainSubRule( &csr[n] ); - - FREE( csr ); - } -} - - -/* ChainContextSubstFormat1 */ - -static HB_Error Load_ChainContextSubst1( - HB_ChainContextSubstFormat1* ccsf1, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ChainSubRuleSet* csrs; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &ccsf1->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = ccsf1->ChainSubRuleSetCount = GET_UShort(); - - FORGET_Frame(); - - ccsf1->ChainSubRuleSet = NULL; - - if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, HB_ChainSubRuleSet ) ) - goto Fail2; - - csrs = ccsf1->ChainSubRuleSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainSubRuleSet( &csrs[n], stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_ChainSubRuleSet( &csrs[m] ); - - FREE( csrs ); - -Fail2: - _HB_OPEN_Free_Coverage( &ccsf1->Coverage ); - return error; -} - - -static void Free_ChainContextSubst1( HB_ChainContextSubstFormat1* ccsf1 ) -{ - HB_UShort n, count; - - HB_ChainSubRuleSet* csrs; - - - if ( ccsf1->ChainSubRuleSet ) - { - count = ccsf1->ChainSubRuleSetCount; - csrs = ccsf1->ChainSubRuleSet; - - for ( n = 0; n < count; n++ ) - Free_ChainSubRuleSet( &csrs[n] ); - - FREE( csrs ); - } - - _HB_OPEN_Free_Coverage( &ccsf1->Coverage ); -} - - -/* ChainSubClassRule */ - -static HB_Error Load_ChainSubClassRule( - HB_ChainContextSubstFormat2* ccsf2, - HB_ChainSubClassRule* cscr, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_UShort* b; - HB_UShort* i; - HB_UShort* l; - HB_SubstLookupRecord* slr; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - cscr->BacktrackGlyphCount = GET_UShort(); - - FORGET_Frame(); - - if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength ) - ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount; - - cscr->Backtrack = NULL; - - count = cscr->BacktrackGlyphCount; - - if ( ALLOC_ARRAY( cscr->Backtrack, count, HB_UShort ) ) - return error; - - b = cscr->Backtrack; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail4; - - for ( n = 0; n < count; n++ ) - b[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - cscr->InputGlyphCount = GET_UShort(); - - FORGET_Frame(); - - if ( cscr->InputGlyphCount > ccsf2->MaxInputLength ) - ccsf2->MaxInputLength = cscr->InputGlyphCount; - - cscr->Input = NULL; - - count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ - - if ( ALLOC_ARRAY( cscr->Input, count, HB_UShort ) ) - goto Fail4; - - i = cscr->Input; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail3; - - for ( n = 0; n < count; n++ ) - i[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - cscr->LookaheadGlyphCount = GET_UShort(); - - FORGET_Frame(); - - if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength ) - ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount; - - cscr->Lookahead = NULL; - - count = cscr->LookaheadGlyphCount; - - if ( ALLOC_ARRAY( cscr->Lookahead, count, HB_UShort ) ) - goto Fail3; - - l = cscr->Lookahead; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail2; - - for ( n = 0; n < count; n++ ) - l[n] = GET_UShort(); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - cscr->SubstCount = GET_UShort(); - - FORGET_Frame(); - - cscr->SubstLookupRecord = NULL; - - count = cscr->SubstCount; - - if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count, - HB_SubstLookupRecord ) ) - goto Fail2; - - slr = cscr->SubstLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - slr[n].SequenceIndex = GET_UShort(); - slr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( slr ); - -Fail2: - FREE( l ); - -Fail3: - FREE( i ); - -Fail4: - FREE( b ); - return error; -} - - -static void Free_ChainSubClassRule( HB_ChainSubClassRule* cscr ) -{ - FREE( cscr->SubstLookupRecord ); - FREE( cscr->Lookahead ); - FREE( cscr->Input ); - FREE( cscr->Backtrack ); -} - - -/* SubClassSet */ - -static HB_Error Load_ChainSubClassSet( - HB_ChainContextSubstFormat2* ccsf2, - HB_ChainSubClassSet* cscs, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ChainSubClassRule* cscr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = cscs->ChainSubClassRuleCount = GET_UShort(); - - FORGET_Frame(); - - cscs->ChainSubClassRule = NULL; - - if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count, - HB_ChainSubClassRule ) ) - return error; - - cscr = cscs->ChainSubClassRule; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainSubClassRule( ccsf2, &cscr[n], - stream ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_ChainSubClassRule( &cscr[m] ); - - FREE( cscr ); - return error; -} - - -static void Free_ChainSubClassSet( HB_ChainSubClassSet* cscs ) -{ - HB_UShort n, count; - - HB_ChainSubClassRule* cscr; - - - if ( cscs->ChainSubClassRule ) - { - count = cscs->ChainSubClassRuleCount; - cscr = cscs->ChainSubClassRule; - - for ( n = 0; n < count; n++ ) - Free_ChainSubClassRule( &cscr[n] ); - - FREE( cscr ); - } -} - - -/* ChainContextSubstFormat2 */ - -static HB_Error Load_ChainContextSubst2( - HB_ChainContextSubstFormat2* ccsf2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n = 0, m, count; - HB_UInt cur_offset, new_offset, base_offset; - HB_UInt backtrack_offset, input_offset, lookahead_offset; - - HB_ChainSubClassSet* cscs; - - - base_offset = FILE_Pos() - 2; - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &ccsf2->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - if ( ACCESS_Frame( 8L ) ) - goto Fail5; - - backtrack_offset = GET_UShort(); - input_offset = GET_UShort(); - lookahead_offset = GET_UShort(); - - /* `ChainSubClassSetCount' is the upper limit for input class values, - thus we read it now to make an additional safety check. No limit - is known or needed for the other two class definitions */ - - count = ccsf2->ChainSubClassSetCount = GET_UShort(); - - FORGET_Frame(); - - if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535, - backtrack_offset, base_offset, - stream ) ) != HB_Err_Ok ) - goto Fail5; - - if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count, - input_offset, base_offset, - stream ) ) != HB_Err_Ok ) - goto Fail4; - if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535, - lookahead_offset, base_offset, - stream ) ) != HB_Err_Ok ) - goto Fail3; - - ccsf2->ChainSubClassSet = NULL; - ccsf2->MaxBacktrackLength = 0; - ccsf2->MaxInputLength = 0; - ccsf2->MaxLookaheadLength = 0; - - if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, HB_ChainSubClassSet ) ) - goto Fail2; - - cscs = ccsf2->ChainSubClassSet; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if ( new_offset != base_offset ) /* not a NULL offset */ - { - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_ChainSubClassSet( ccsf2, &cscs[n], - stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - else - { - /* we create a ChainSubClassSet table with no entries */ - - ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0; - ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL; - } - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_ChainSubClassSet( &cscs[m] ); - - FREE( cscs ); - -Fail2: - _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef ); - -Fail3: - _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef ); - -Fail4: - _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef ); - -Fail5: - _HB_OPEN_Free_Coverage( &ccsf2->Coverage ); - return error; -} - - -static void Free_ChainContextSubst2( HB_ChainContextSubstFormat2* ccsf2 ) -{ - HB_UShort n, count; - - HB_ChainSubClassSet* cscs; - - - if ( ccsf2->ChainSubClassSet ) - { - count = ccsf2->ChainSubClassSetCount; - cscs = ccsf2->ChainSubClassSet; - - for ( n = 0; n < count; n++ ) - Free_ChainSubClassSet( &cscs[n] ); - - FREE( cscs ); - } - - _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef ); - _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef ); - _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef ); - - _HB_OPEN_Free_Coverage( &ccsf2->Coverage ); -} - - -/* ChainContextSubstFormat3 */ - -static HB_Error Load_ChainContextSubst3( - HB_ChainContextSubstFormat3* ccsf3, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, nb = 0, ni =0, nl = 0, m, count; - HB_UShort backtrack_count, input_count, lookahead_count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Coverage* b; - HB_Coverage* i; - HB_Coverage* l; - HB_SubstLookupRecord* slr; - - - base_offset = FILE_Pos() - 2L; - - if ( ACCESS_Frame( 2L ) ) - return error; - - ccsf3->BacktrackGlyphCount = GET_UShort(); - - FORGET_Frame(); - - ccsf3->BacktrackCoverage = NULL; - - backtrack_count = ccsf3->BacktrackGlyphCount; - - if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count, - HB_Coverage ) ) - return error; - - b = ccsf3->BacktrackCoverage; - - for ( nb = 0; nb < backtrack_count; nb++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok ) - goto Fail4; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - ccsf3->InputGlyphCount = GET_UShort(); - - FORGET_Frame(); - - ccsf3->InputCoverage = NULL; - - input_count = ccsf3->InputGlyphCount; - - if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, HB_Coverage ) ) - goto Fail4; - - i = ccsf3->InputCoverage; - - for ( ni = 0; ni < input_count; ni++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - ccsf3->LookaheadGlyphCount = GET_UShort(); - - FORGET_Frame(); - - ccsf3->LookaheadCoverage = NULL; - - lookahead_count = ccsf3->LookaheadGlyphCount; - - if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count, - HB_Coverage ) ) - goto Fail3; - - l = ccsf3->LookaheadCoverage; - - for ( nl = 0; nl < lookahead_count; nl++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - ccsf3->SubstCount = GET_UShort(); - - FORGET_Frame(); - - ccsf3->SubstLookupRecord = NULL; - - count = ccsf3->SubstCount; - - if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count, - HB_SubstLookupRecord ) ) - goto Fail2; - - slr = ccsf3->SubstLookupRecord; - - if ( ACCESS_Frame( count * 4L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - { - slr[n].SequenceIndex = GET_UShort(); - slr[n].LookupListIndex = GET_UShort(); - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( slr ); - -Fail2: - for ( m = 0; m < nl; m++ ) - _HB_OPEN_Free_Coverage( &l[m] ); - - FREE( l ); - -Fail3: - for ( m = 0; m < ni; m++ ) - _HB_OPEN_Free_Coverage( &i[m] ); - - FREE( i ); - -Fail4: - for ( m = 0; m < nb; m++ ) - _HB_OPEN_Free_Coverage( &b[m] ); - - FREE( b ); - return error; -} - - -static void Free_ChainContextSubst3( HB_ChainContextSubstFormat3* ccsf3 ) -{ - HB_UShort n, count; - - HB_Coverage* c; - - - FREE( ccsf3->SubstLookupRecord ); - - if ( ccsf3->LookaheadCoverage ) - { - count = ccsf3->LookaheadGlyphCount; - c = ccsf3->LookaheadCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } - - if ( ccsf3->InputCoverage ) - { - count = ccsf3->InputGlyphCount; - c = ccsf3->InputCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } - - if ( ccsf3->BacktrackCoverage ) - { - count = ccsf3->BacktrackGlyphCount; - c = ccsf3->BacktrackCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } -} - - -/* ChainContextSubst */ - -static HB_Error Load_ChainContextSubst( HB_GSUB_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_ChainContextSubst* ccs = &st->chain; - - if ( ACCESS_Frame( 2L ) ) - return error; - - ccs->SubstFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( ccs->SubstFormat ) { - case 1: return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream ); - case 2: return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream ); - case 3: return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - -static void Free_ChainContextSubst( HB_GSUB_SubTable* st ) -{ - HB_ChainContextSubst* ccs = &st->chain; - - switch ( ccs->SubstFormat ) { - case 1: Free_ChainContextSubst1( &ccs->ccsf.ccsf1 ); break; - case 2: Free_ChainContextSubst2( &ccs->ccsf.ccsf2 ); break; - case 3: Free_ChainContextSubst3( &ccs->ccsf.ccsf3 ); break; - default: break; - } -} - - -static HB_Error Lookup_ChainContextSubst1( HB_GSUBHeader* gsub, - HB_ChainContextSubstFormat1* ccsf1, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_UShort i, j, k, num_csr; - HB_UShort bgc, igc, lgc; - HB_Error error; - - HB_ChainSubRule* csr; - HB_ChainSubRule curr_csr; - HB_GDEFHeader* gdef; - - - gdef = gsub->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - error = _HB_OPEN_Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - csr = ccsf1->ChainSubRuleSet[index].ChainSubRule; - num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount; - - for ( k = 0; k < num_csr; k++ ) - { - curr_csr = csr[k]; - bgc = curr_csr.BacktrackGlyphCount; - igc = curr_csr.InputGlyphCount; - lgc = curr_csr.LookaheadGlyphCount; - - if ( context_length != 0xFFFF && context_length < igc ) - goto next_chainsubrule; - - /* check whether context is too long; it is a first guess only */ - - if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length ) - goto next_chainsubrule; - - if ( bgc ) - { - /* since we don't know in advance the number of glyphs to inspect, - we search backwards for matches in the backtrack glyph array */ - - for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- ) - { - while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + 1 == bgc - i ) - goto next_chainsubrule; - j--; - } - - /* In OpenType 1.3, it is undefined whether the offsets of - backtrack glyphs is in logical order or not. Version 1.4 - will clarify this: - - Logical order - a b c d e f g h i j - i - Input offsets - 0 1 - Backtrack offsets - 3 2 1 0 - Lookahead offsets - 0 1 2 3 */ - - if ( OUT_GLYPH( j ) != curr_csr.Backtrack[i] ) - goto next_chainsubrule; - } - } - - /* Start at 1 because [0] is implied */ - - for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) - goto next_chainsubrule; - j++; - } - - if ( IN_GLYPH( j ) != curr_csr.Input[i - 1] ) - goto next_chainsubrule; - } - - /* we are starting to check for lookahead glyphs right after the - last context glyph */ - - for ( i = 0; i < lgc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + lgc - i == (HB_Int)buffer->in_length ) - goto next_chainsubrule; - j++; - } - - if ( IN_GLYPH( j ) != curr_csr.Lookahead[i] ) - goto next_chainsubrule; - } - - return Do_ContextSubst( gsub, igc, - curr_csr.SubstCount, - curr_csr.SubstLookupRecord, - buffer, - nesting_level ); - - next_chainsubrule: - ; - } - - return HB_Err_Not_Covered; -} - - -static HB_Error Lookup_ChainContextSubst2( HB_GSUBHeader* gsub, - HB_ChainContextSubstFormat2* ccsf2, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, property; - HB_Error error; - HB_UShort i, j, k; - HB_UShort bgc, igc, lgc; - HB_UShort known_backtrack_classes, - known_input_classes, - known_lookahead_classes; - - HB_UShort* backtrack_classes; - HB_UShort* input_classes; - HB_UShort* lookahead_classes; - - HB_UShort* bc; - HB_UShort* ic; - HB_UShort* lc; - - HB_ChainSubClassSet* cscs; - HB_ChainSubClassRule ccsr; - HB_GDEFHeader* gdef; - - - gdef = gsub->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - /* Note: The coverage table in format 2 doesn't give an index into - anything. It just lets us know whether or not we need to - do any lookup at all. */ - - error = _HB_OPEN_Coverage_Index( &ccsf2->Coverage, IN_CURGLYPH(), &index ); - if ( error ) - return error; - - if (ccsf2->MaxInputLength < 1) - return HB_Err_Not_Covered; - - if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, HB_UShort ) ) - return error; - known_backtrack_classes = 0; - - if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, HB_UShort ) ) - goto End3; - known_input_classes = 1; - - if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, HB_UShort ) ) - goto End2; - known_lookahead_classes = 0; - - error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_CURGLYPH(), - &input_classes[0], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - cscs = &ccsf2->ChainSubClassSet[input_classes[0]]; - if ( !cscs ) - { - error = ERR(HB_Err_Invalid_SubTable); - goto End1; - } - - for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ ) - { - ccsr = cscs->ChainSubClassRule[k]; - bgc = ccsr.BacktrackGlyphCount; - igc = ccsr.InputGlyphCount; - lgc = ccsr.LookaheadGlyphCount; - - if ( context_length != 0xFFFF && context_length < igc ) - goto next_chainsubclassrule; - - /* check whether context is too long; it is a first guess only */ - - if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length ) - goto next_chainsubclassrule; - - if ( bgc ) - { - /* Since we don't know in advance the number of glyphs to inspect, - we search backwards for matches in the backtrack glyph array. - Note that `known_backtrack_classes' starts at index 0. */ - - bc = ccsr.Backtrack; - - for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- ) - { - while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - if ( j + 1 == bgc - i ) - goto next_chainsubclassrule; - j--; - } - - if ( i >= known_backtrack_classes ) - { - /* Keeps us from having to do this for each rule */ - - error = _HB_OPEN_Get_Class( &ccsf2->BacktrackClassDef, OUT_GLYPH( j ), - &backtrack_classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - known_backtrack_classes = i; - } - - if ( bc[i] != backtrack_classes[i] ) - goto next_chainsubclassrule; - } - } - - ic = ccsr.Input; - - /* Start at 1 because [0] is implied */ - - for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) - goto next_chainsubclassrule; - j++; - } - - if ( i >= known_input_classes ) - { - error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_GLYPH( j ), - &input_classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - known_input_classes = i; - } - - if ( ic[i - 1] != input_classes[i] ) - goto next_chainsubclassrule; - } - - /* we are starting to check for lookahead glyphs right after the - last context glyph */ - - lc = ccsr.Lookahead; - - for ( i = 0; i < lgc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - goto End1; - - if ( j + lgc - i == (HB_Int)buffer->in_length ) - goto next_chainsubclassrule; - j++; - } - - if ( i >= known_lookahead_classes ) - { - error = _HB_OPEN_Get_Class( &ccsf2->LookaheadClassDef, IN_GLYPH( j ), - &lookahead_classes[i], NULL ); - if ( error && error != HB_Err_Not_Covered ) - goto End1; - known_lookahead_classes = i; - } - - if ( lc[i] != lookahead_classes[i] ) - goto next_chainsubclassrule; - } - - error = Do_ContextSubst( gsub, igc, - ccsr.SubstCount, - ccsr.SubstLookupRecord, - buffer, - nesting_level ); - goto End1; - - next_chainsubclassrule: - ; - } - - error = HB_Err_Not_Covered; - -End1: - FREE( lookahead_classes ); - -End2: - FREE( input_classes ); - -End3: - FREE( backtrack_classes ); - return error; -} - - -static HB_Error Lookup_ChainContextSubst3( HB_GSUBHeader* gsub, - HB_ChainContextSubstFormat3* ccsf3, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, i, j, property; - HB_UShort bgc, igc, lgc; - HB_Error error; - - HB_Coverage* bc; - HB_Coverage* ic; - HB_Coverage* lc; - HB_GDEFHeader* gdef; - - - gdef = gsub->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - bgc = ccsf3->BacktrackGlyphCount; - igc = ccsf3->InputGlyphCount; - lgc = ccsf3->LookaheadGlyphCount; - - if ( context_length != 0xFFFF && context_length < igc ) - return HB_Err_Not_Covered; - - /* check whether context is too long; it is a first guess only */ - - if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length ) - return HB_Err_Not_Covered; - - if ( bgc ) - { - /* Since we don't know in advance the number of glyphs to inspect, - we search backwards for matches in the backtrack glyph array */ - - bc = ccsf3->BacktrackCoverage; - - for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- ) - { - while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + 1 == bgc - i ) - return HB_Err_Not_Covered; - j--; - } - - error = _HB_OPEN_Coverage_Index( &bc[i], OUT_GLYPH( j ), &index ); - if ( error ) - return error; - } - } - - ic = ccsf3->InputCoverage; - - for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ ) - { - /* We already called CHECK_Property for IN_GLYPH( buffer->in_pos ) */ - while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) - return HB_Err_Not_Covered; - j++; - } - - error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - - /* we are starting for lookahead glyphs right after the last context - glyph */ - - lc = ccsf3->LookaheadCoverage; - - for ( i = 0; i < lgc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + lgc - i == (HB_Int)buffer->in_length ) - return HB_Err_Not_Covered; - j++; - } - - error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - - return Do_ContextSubst( gsub, igc, - ccsf3->SubstCount, - ccsf3->SubstLookupRecord, - buffer, - nesting_level ); -} - - -static HB_Error Lookup_ChainContextSubst( HB_GSUBHeader* gsub, - HB_GSUB_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_ChainContextSubst* ccs = &st->chain; - - switch ( ccs->SubstFormat ) { - case 1: return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, buffer, flags, context_length, nesting_level ); - case 2: return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, buffer, flags, context_length, nesting_level ); - case 3: return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, buffer, flags, context_length, nesting_level ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - } -} - - -static HB_Error Load_ReverseChainContextSubst( HB_GSUB_SubTable* st, - HB_Stream stream ) -{ - HB_Error error; - HB_ReverseChainContextSubst* rccs = &st->reverse; - - HB_UShort m, count; - - HB_UShort nb = 0, nl = 0, n; - HB_UShort backtrack_count, lookahead_count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Coverage* b; - HB_Coverage* l; - HB_UShort* sub; - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - rccs->SubstFormat = GET_UShort(); - - if ( rccs->SubstFormat != 1 ) - return ERR(HB_Err_Invalid_SubTable_Format); - - FORGET_Frame(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &rccs->Coverage, stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - - - if ( ACCESS_Frame( 2L ) ) - goto Fail4; - - rccs->BacktrackGlyphCount = GET_UShort(); - - FORGET_Frame(); - - rccs->BacktrackCoverage = NULL; - - backtrack_count = rccs->BacktrackGlyphCount; - - if ( ALLOC_ARRAY( rccs->BacktrackCoverage, backtrack_count, - HB_Coverage ) ) - goto Fail4; - - b = rccs->BacktrackCoverage; - - for ( nb = 0; nb < backtrack_count; nb++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok ) - goto Fail3; - (void)FILE_Seek( cur_offset ); - } - - - if ( ACCESS_Frame( 2L ) ) - goto Fail3; - - rccs->LookaheadGlyphCount = GET_UShort(); - - FORGET_Frame(); - - rccs->LookaheadCoverage = NULL; - - lookahead_count = rccs->LookaheadGlyphCount; - - if ( ALLOC_ARRAY( rccs->LookaheadCoverage, lookahead_count, - HB_Coverage ) ) - goto Fail3; - - l = rccs->LookaheadCoverage; - - for ( nl = 0; nl < lookahead_count; nl++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok ) - goto Fail2; - (void)FILE_Seek( cur_offset ); - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - rccs->GlyphCount = GET_UShort(); - - FORGET_Frame(); - - rccs->Substitute = NULL; - - count = rccs->GlyphCount; - - if ( ALLOC_ARRAY( rccs->Substitute, count, - HB_UShort ) ) - goto Fail2; - - sub = rccs->Substitute; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail1; - - for ( n = 0; n < count; n++ ) - sub[n] = GET_UShort(); - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail1: - FREE( sub ); - -Fail2: - for ( m = 0; m < nl; m++ ) - _HB_OPEN_Free_Coverage( &l[m] ); - - FREE( l ); - -Fail3: - for ( m = 0; m < nb; m++ ) - _HB_OPEN_Free_Coverage( &b[m] ); - - FREE( b ); - -Fail4: - _HB_OPEN_Free_Coverage( &rccs->Coverage ); - return error; -} - - -static void Free_ReverseChainContextSubst( HB_GSUB_SubTable* st ) -{ - HB_UShort n, count; - HB_ReverseChainContextSubst* rccs = &st->reverse; - - HB_Coverage* c; - - _HB_OPEN_Free_Coverage( &rccs->Coverage ); - - if ( rccs->LookaheadCoverage ) - { - count = rccs->LookaheadGlyphCount; - c = rccs->LookaheadCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } - - if ( rccs->BacktrackCoverage ) - { - count = rccs->BacktrackGlyphCount; - c = rccs->BacktrackCoverage; - - for ( n = 0; n < count; n++ ) - _HB_OPEN_Free_Coverage( &c[n] ); - - FREE( c ); - } - - FREE ( rccs->Substitute ); -} - - -static HB_Error Lookup_ReverseChainContextSubst( HB_GSUBHeader* gsub, - HB_GSUB_SubTable* st, - HB_Buffer buffer, - HB_UShort flags, - HB_UShort context_length, - int nesting_level ) -{ - HB_UShort index, input_index, i, j, property; - HB_UShort bgc, lgc; - HB_Error error; - - HB_ReverseChainContextSubst* rccs = &st->reverse; - HB_Coverage* bc; - HB_Coverage* lc; - HB_GDEFHeader* gdef; - - if ( nesting_level != 1 || context_length != 0xFFFF ) - return HB_Err_Not_Covered; - - gdef = gsub->gdef; - - if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) - return error; - - bgc = rccs->BacktrackGlyphCount; - lgc = rccs->LookaheadGlyphCount; - - /* check whether context is too long; it is a first guess only */ - - if ( bgc > buffer->in_pos || buffer->in_pos + 1 + lgc > buffer->in_length ) - return HB_Err_Not_Covered; - - if ( bgc ) - { - /* Since we don't know in advance the number of glyphs to inspect, - we search backwards for matches in the backtrack glyph array */ - - bc = rccs->BacktrackCoverage; - - for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + 1 == bgc - i ) - return HB_Err_Not_Covered; - j--; - } - - error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - } - - j = buffer->in_pos; - - error = _HB_OPEN_Coverage_Index( &rccs->Coverage, IN_GLYPH( j ), &input_index ); - if ( error ) - return error; - - lc = rccs->LookaheadCoverage; - - for ( i = 0, j = buffer->in_pos + 1; i < lgc; i++, j++ ) - { - while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) - { - if ( error && error != HB_Err_Not_Covered ) - return error; - - if ( j + lgc - i == (HB_Int)buffer->in_length ) - return HB_Err_Not_Covered; - j++; - } - - error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index ); - if ( error ) - return error; - } - - IN_CURGLYPH() = rccs->Substitute[input_index]; - buffer->in_pos--; /* Reverse! */ - - return error; -} - - - -/*********** - * GSUB API - ***********/ - - - -HB_Error HB_GSUB_Select_Script( HB_GSUBHeader* gsub, - HB_UInt script_tag, - HB_UShort* script_index ) -{ - HB_UShort n; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - - - if ( !gsub || !script_index ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gsub->ScriptList; - sr = sl->ScriptRecord; - - for ( n = 0; n < sl->ScriptCount; n++ ) - if ( script_tag == sr[n].ScriptTag ) - { - *script_index = n; - - return HB_Err_Ok; - } - - return HB_Err_Not_Covered; -} - - - -HB_Error HB_GSUB_Select_Language( HB_GSUBHeader* gsub, - HB_UInt language_tag, - HB_UShort script_index, - HB_UShort* language_index, - HB_UShort* req_feature_index ) -{ - HB_UShort n; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - - - if ( !gsub || !language_index || !req_feature_index ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gsub->ScriptList; - sr = sl->ScriptRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - for ( n = 0; n < s->LangSysCount; n++ ) - if ( language_tag == lsr[n].LangSysTag ) - { - *language_index = n; - *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; - - return HB_Err_Ok; - } - - return HB_Err_Not_Covered; -} - - -/* selecting 0xFFFF for language_index asks for the values of the - default language (DefaultLangSys) */ - - -HB_Error HB_GSUB_Select_Feature( HB_GSUBHeader* gsub, - HB_UInt feature_tag, - HB_UShort script_index, - HB_UShort language_index, - HB_UShort* feature_index ) -{ - HB_UShort n; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - HB_LangSys* ls; - HB_UShort* fi; - - HB_FeatureList* fl; - HB_FeatureRecord* fr; - - - if ( !gsub || !feature_index ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gsub->ScriptList; - sr = sl->ScriptRecord; - - fl = &gsub->FeatureList; - fr = fl->FeatureRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - if ( language_index == 0xFFFF ) - ls = &s->DefaultLangSys; - else - { - if ( language_index >= s->LangSysCount ) - return ERR(HB_Err_Invalid_Argument); - - ls = &lsr[language_index].LangSys; - } - - fi = ls->FeatureIndex; - - for ( n = 0; n < ls->FeatureCount; n++ ) - { - if ( fi[n] >= fl->FeatureCount ) - return ERR(HB_Err_Invalid_SubTable_Format); - - if ( feature_tag == fr[fi[n]].FeatureTag ) - { - *feature_index = fi[n]; - - return HB_Err_Ok; - } - } - - return HB_Err_Not_Covered; -} - - -/* The next three functions return a null-terminated list */ - - -HB_Error HB_GSUB_Query_Scripts( HB_GSUBHeader* gsub, - HB_UInt** script_tag_list ) -{ - HB_UShort n; - HB_Error error; - HB_UInt* stl; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - - - if ( !gsub || !script_tag_list ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gsub->ScriptList; - sr = sl->ScriptRecord; - - if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) ) - return error; - - for ( n = 0; n < sl->ScriptCount; n++ ) - stl[n] = sr[n].ScriptTag; - stl[n] = 0; - - *script_tag_list = stl; - - return HB_Err_Ok; -} - - - -HB_Error HB_GSUB_Query_Languages( HB_GSUBHeader* gsub, - HB_UShort script_index, - HB_UInt** language_tag_list ) -{ - HB_UShort n; - HB_Error error; - HB_UInt* ltl; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - - - if ( !gsub || !language_tag_list ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gsub->ScriptList; - sr = sl->ScriptRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) ) - return error; - - for ( n = 0; n < s->LangSysCount; n++ ) - ltl[n] = lsr[n].LangSysTag; - ltl[n] = 0; - - *language_tag_list = ltl; - - return HB_Err_Ok; -} - - -/* selecting 0xFFFF for language_index asks for the values of the - default language (DefaultLangSys) */ - - -HB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub, - HB_UShort script_index, - HB_UShort language_index, - HB_UInt** feature_tag_list ) -{ - HB_UShort n; - HB_Error error; - HB_UInt* ftl; - - HB_ScriptList* sl; - HB_ScriptRecord* sr; - HB_ScriptTable* s; - HB_LangSysRecord* lsr; - HB_LangSys* ls; - HB_UShort* fi; - - HB_FeatureList* fl; - HB_FeatureRecord* fr; - - - if ( !gsub || !feature_tag_list ) - return ERR(HB_Err_Invalid_Argument); - - sl = &gsub->ScriptList; - sr = sl->ScriptRecord; - - fl = &gsub->FeatureList; - fr = fl->FeatureRecord; - - if ( script_index >= sl->ScriptCount ) - return ERR(HB_Err_Invalid_Argument); - - s = &sr[script_index].Script; - lsr = s->LangSysRecord; - - if ( language_index == 0xFFFF ) - ls = &s->DefaultLangSys; - else - { - if ( language_index >= s->LangSysCount ) - return ERR(HB_Err_Invalid_Argument); - - ls = &lsr[language_index].LangSys; - } - - fi = ls->FeatureIndex; - - if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) ) - return error; - - for ( n = 0; n < ls->FeatureCount; n++ ) - { - if ( fi[n] >= fl->FeatureCount ) - { - FREE( ftl ); - return ERR(HB_Err_Invalid_SubTable_Format); - } - ftl[n] = fr[fi[n]].FeatureTag; - } - ftl[n] = 0; - - *feature_tag_list = ftl; - - return HB_Err_Ok; -} - - -/* Do an individual subtable lookup. Returns HB_Err_Ok if substitution - has been done, or HB_Err_Not_Covered if not. */ -static HB_Error GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub, - HB_UShort lookup_index, - HB_Buffer buffer, - HB_UShort context_length, - int nesting_level ) -{ - HB_Error error = HB_Err_Not_Covered; - HB_UShort i, flags, lookup_count; - HB_Lookup* lo; - int lookup_type; - - nesting_level++; - - if ( nesting_level > HB_MAX_NESTING_LEVEL ) - return ERR(HB_Err_Not_Covered); /* ERR() call intended */ - - lookup_count = gsub->LookupList.LookupCount; - if (lookup_index >= lookup_count) - return error; - - lo = &gsub->LookupList.Lookup[lookup_index]; - flags = lo->LookupFlag; - lookup_type = lo->LookupType; - - for ( i = 0; i < lo->SubTableCount; i++ ) - { - HB_GSUB_SubTable *st = &lo->SubTable[i].st.gsub; - - switch (lookup_type) { - case HB_GSUB_LOOKUP_SINGLE: - error = Lookup_SingleSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; - case HB_GSUB_LOOKUP_MULTIPLE: - error = Lookup_MultipleSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; - case HB_GSUB_LOOKUP_ALTERNATE: - error = Lookup_AlternateSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; - case HB_GSUB_LOOKUP_LIGATURE: - error = Lookup_LigatureSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; - case HB_GSUB_LOOKUP_CONTEXT: - error = Lookup_ContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; - case HB_GSUB_LOOKUP_CHAIN: - error = Lookup_ChainContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; - /*case HB_GSUB_LOOKUP_EXTENSION: - error = Lookup_ExtensionSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;*/ - case HB_GSUB_LOOKUP_REVERSE_CHAIN: - error = Lookup_ReverseChainContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; - default: - error = HB_Err_Not_Covered; - }; - - /* Check whether we have a successful substitution or an error other - than HB_Err_Not_Covered */ - if ( error != HB_Err_Not_Covered ) - return error; - } - - return HB_Err_Not_Covered; -} - - -HB_INTERNAL HB_Error -_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st, - HB_Stream stream, - HB_UShort lookup_type ) -{ - switch (lookup_type) { - case HB_GSUB_LOOKUP_SINGLE: return Load_SingleSubst ( st, stream ); - case HB_GSUB_LOOKUP_MULTIPLE: return Load_MultipleSubst ( st, stream ); - case HB_GSUB_LOOKUP_ALTERNATE: return Load_AlternateSubst ( st, stream ); - case HB_GSUB_LOOKUP_LIGATURE: return Load_LigatureSubst ( st, stream ); - case HB_GSUB_LOOKUP_CONTEXT: return Load_ContextSubst ( st, stream ); - case HB_GSUB_LOOKUP_CHAIN: return Load_ChainContextSubst ( st, stream ); - /*case HB_GSUB_LOOKUP_EXTENSION: return Load_ExtensionSubst ( st, stream );*/ - case HB_GSUB_LOOKUP_REVERSE_CHAIN: return Load_ReverseChainContextSubst ( st, stream ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - }; -} - - -HB_INTERNAL void -_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st, - HB_UShort lookup_type ) -{ - switch ( lookup_type ) { - case HB_GSUB_LOOKUP_SINGLE: Free_SingleSubst ( st ); return; - case HB_GSUB_LOOKUP_MULTIPLE: Free_MultipleSubst ( st ); return; - case HB_GSUB_LOOKUP_ALTERNATE: Free_AlternateSubst ( st ); return; - case HB_GSUB_LOOKUP_LIGATURE: Free_LigatureSubst ( st ); return; - case HB_GSUB_LOOKUP_CONTEXT: Free_ContextSubst ( st ); return; - case HB_GSUB_LOOKUP_CHAIN: Free_ChainContextSubst ( st ); return; - /*case HB_GSUB_LOOKUP_EXTENSION: Free_ExtensionSubst ( st ); return;*/ - case HB_GSUB_LOOKUP_REVERSE_CHAIN: Free_ReverseChainContextSubst ( st ); return; - default: return; - }; -} - - - -/* apply one lookup to the input string object */ - -static HB_Error GSUB_Do_String_Lookup( HB_GSUBHeader* gsub, - HB_UShort lookup_index, - HB_Buffer buffer ) -{ - HB_Error error, retError = HB_Err_Not_Covered; - - HB_UInt* properties = gsub->LookupList.Properties; - int lookup_type = gsub->LookupList.Lookup[lookup_index].LookupType; - - const int nesting_level = 0; - /* 0xFFFF indicates that we don't have a context length yet */ - const HB_UShort context_length = 0xFFFF; - - switch (lookup_type) { - - case HB_GSUB_LOOKUP_SINGLE: - case HB_GSUB_LOOKUP_MULTIPLE: - case HB_GSUB_LOOKUP_ALTERNATE: - case HB_GSUB_LOOKUP_LIGATURE: - case HB_GSUB_LOOKUP_CONTEXT: - case HB_GSUB_LOOKUP_CHAIN: - /* in/out forward substitution (implemented lazy) */ - - _hb_buffer_clear_output ( buffer ); - buffer->in_pos = 0; - while ( buffer->in_pos < buffer->in_length ) - { - if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] ) - { - error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level ); - if ( error ) - { - if ( error != HB_Err_Not_Covered ) - return error; - } - else - retError = error; - } - else - error = HB_Err_Not_Covered; - - if ( error == HB_Err_Not_Covered ) - if ( COPY_Glyph ( buffer ) ) - return error; - } - /* we shouldn't swap if error occurred. - * - * also don't swap if nothing changed (ie HB_Err_Not_Covered). - * shouldn't matter in that case though. - */ - if ( retError == HB_Err_Ok ) - _hb_buffer_swap( buffer ); - - return retError; - - case HB_GSUB_LOOKUP_REVERSE_CHAIN: - /* in-place backward substitution */ - - buffer->in_pos = buffer->in_length - 1; - do - { - if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] ) - { - error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level ); - if ( error ) - { - if ( error != HB_Err_Not_Covered ) - return error; - } - else - retError = error; - } - else - error = HB_Err_Not_Covered; - - if ( error == HB_Err_Not_Covered ) - buffer->in_pos--; - } - while ((HB_Int) buffer->in_pos >= 0); - - return retError; - - /*case HB_GSUB_LOOKUP_EXTENSION:*/ - default: - return retError; - }; -} - - -HB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub, - HB_UShort feature_index, - HB_UInt property ) -{ - HB_UShort i; - - HB_Feature feature; - HB_UInt* properties; - HB_UShort* index; - HB_UShort lookup_count; - - /* Each feature can only be added once */ - - if ( !gsub || - feature_index >= gsub->FeatureList.FeatureCount || - gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount ) - return ERR(HB_Err_Invalid_Argument); - - gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index; - - properties = gsub->LookupList.Properties; - - feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; - index = feature.LookupListIndex; - lookup_count = gsub->LookupList.LookupCount; - - for ( i = 0; i < feature.LookupListCount; i++ ) - { - HB_UShort lookup_index = index[i]; - if (lookup_index < lookup_count) - properties[lookup_index] |= property; - } - - return HB_Err_Ok; -} - - - -HB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub ) -{ - HB_UShort i; - - HB_UInt* properties; - - - if ( !gsub ) - return ERR(HB_Err_Invalid_Argument); - - gsub->FeatureList.ApplyCount = 0; - - properties = gsub->LookupList.Properties; - - for ( i = 0; i < gsub->LookupList.LookupCount; i++ ) - properties[i] = 0; - - return HB_Err_Ok; -} - - - -HB_Error HB_GSUB_Register_Alternate_Function( HB_GSUBHeader* gsub, - HB_AltFunction altfunc, - void* data ) -{ - if ( !gsub ) - return ERR(HB_Err_Invalid_Argument); - - gsub->altfunc = altfunc; - gsub->data = data; - - return HB_Err_Ok; -} - -/* returns error if one happened, otherwise returns HB_Err_Not_Covered if no - * feature were applied, or HB_Err_Ok otherwise. - */ -HB_Error HB_GSUB_Apply_String( HB_GSUBHeader* gsub, - HB_Buffer buffer ) -{ - HB_Error error, retError = HB_Err_Not_Covered; - int i, j, lookup_count, num_features; - - if ( !gsub || - !buffer) - return ERR(HB_Err_Invalid_Argument); - - if ( buffer->in_length == 0 ) - return retError; - - lookup_count = gsub->LookupList.LookupCount; - num_features = gsub->FeatureList.ApplyCount; - - for ( i = 0; i < num_features; i++) - { - HB_UShort feature_index = gsub->FeatureList.ApplyOrder[i]; - HB_Feature feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; - - for ( j = 0; j < feature.LookupListCount; j++ ) - { - HB_UShort lookup_index = feature.LookupListIndex[j]; - - /* Skip nonexistant lookups */ - if (lookup_index >= lookup_count) - continue; - - error = GSUB_Do_String_Lookup( gsub, lookup_index, buffer ); - if ( error ) - { - if ( error != HB_Err_Not_Covered ) - return error; - } - else - retError = error; - } - } - - error = retError; - - return error; -} - - -/* END */ diff --git a/src/hb-old/harfbuzz-gsub.h b/src/hb-old/harfbuzz-gsub.h deleted file mode 100644 index b00df44..0000000 --- a/src/hb-old/harfbuzz-gsub.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GSUB_H -#define HARFBUZZ_GSUB_H - -#include "harfbuzz-gdef.h" -#include "harfbuzz-buffer.h" - -HB_BEGIN_HEADER - - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -/* Lookup types for glyph substitution */ - -#define HB_GSUB_LOOKUP_SINGLE 1 -#define HB_GSUB_LOOKUP_MULTIPLE 2 -#define HB_GSUB_LOOKUP_ALTERNATE 3 -#define HB_GSUB_LOOKUP_LIGATURE 4 -#define HB_GSUB_LOOKUP_CONTEXT 5 -#define HB_GSUB_LOOKUP_CHAIN 6 -#define HB_GSUB_LOOKUP_EXTENSION 7 -#define HB_GSUB_LOOKUP_REVERSE_CHAIN 8 - - -/* A pointer to a function which selects the alternate glyph. `pos' is - the position of the glyph with index `glyphID', `num_alternates' - gives the number of alternates in the `alternates' array. `data' - points to the user-defined structure specified during a call to - HB_GSUB_Register_Alternate_Function(). The function must return an - index into the `alternates' array. */ - -typedef HB_UShort (*HB_AltFunction)(HB_UInt pos, - HB_UShort glyphID, - HB_UShort num_alternates, - HB_UShort* alternates, - void* data ); - - -struct HB_GSUBHeader_ -{ - HB_GDEFHeader* gdef; - - /* the next two fields are used for an alternate substitution callback - function to select the proper alternate glyph. */ - - void* data; - HB_AltFunction altfunc; - - HB_UInt offset; - - HB_16Dot16 Version; - - HB_ScriptList ScriptList; - HB_FeatureList FeatureList; - HB_LookupList LookupList; -}; - -typedef struct HB_GSUBHeader_ HB_GSUBHeader; -typedef HB_GSUBHeader* HB_GSUB; - - -HB_Error HB_Load_GSUB_Table( HB_Stream stream, - HB_GSUBHeader** gsub, - HB_GDEFHeader* gdef, - HB_Stream gdefStream ); - - -HB_Error HB_Done_GSUB_Table( HB_GSUBHeader* gsub ); - - -HB_Error HB_GSUB_Select_Script( HB_GSUBHeader* gsub, - HB_UInt script_tag, - HB_UShort* script_index ); - -HB_Error HB_GSUB_Select_Language( HB_GSUBHeader* gsub, - HB_UInt language_tag, - HB_UShort script_index, - HB_UShort* language_index, - HB_UShort* req_feature_index ); - -HB_Error HB_GSUB_Select_Feature( HB_GSUBHeader* gsub, - HB_UInt feature_tag, - HB_UShort script_index, - HB_UShort language_index, - HB_UShort* feature_index ); - - -HB_Error HB_GSUB_Query_Scripts( HB_GSUBHeader* gsub, - HB_UInt** script_tag_list ); - -HB_Error HB_GSUB_Query_Languages( HB_GSUBHeader* gsub, - HB_UShort script_index, - HB_UInt** language_tag_list ); - -HB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub, - HB_UShort script_index, - HB_UShort language_index, - HB_UInt** feature_tag_list ); - - -HB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub, - HB_UShort feature_index, - HB_UInt property ); - -HB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub ); - - -HB_Error HB_GSUB_Register_Alternate_Function( HB_GSUBHeader* gsub, - HB_AltFunction altfunc, - void* data ); - - -HB_Error HB_GSUB_Apply_String( HB_GSUBHeader* gsub, - HB_Buffer buffer ); - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -HB_END_HEADER - -#endif /* HARFBUZZ_GSUB_H */ diff --git a/src/hb-old/harfbuzz-hangul.c b/src/hb-old/harfbuzz-hangul.c deleted file mode 100644 index 6f89ed6..0000000 --- a/src/hb-old/harfbuzz-hangul.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" - -#include <assert.h> - -/* -// Hangul is a syllable based script. Unicode reserves a large range -// for precomposed hangul, where syllables are already precomposed to -// their final glyph shape. In addition, a so called jamo range is -// defined, that can be used to express old Hangul. Modern hangul -// syllables can also be expressed as jamo, and should be composed -// into syllables. The operation is rather simple and mathematical. - -// Every hangul jamo is classified as being either a Leading consonant -// (L), and intermediat Vowel (V) or a trailing consonant (T). Modern -// hangul syllables (the ones in the precomposed area can be of type -// LV or LVT. -// -// Syllable breaks do _not_ occur between: -// -// L L, V or precomposed -// V, LV V, T -// LVT, T T -// -// A standard syllable is of the form L+V+T*. The above rules allow -// nonstandard syllables L*V*T*. To transform them into standard -// syllables fill characters L_f and V_f can be inserted. -*/ - -enum { - Hangul_SBase = 0xac00, - Hangul_LBase = 0x1100, - Hangul_VBase = 0x1161, - Hangul_TBase = 0x11a7, - Hangul_SCount = 11172, - Hangul_LCount = 19, - Hangul_VCount = 21, - Hangul_TCount = 28, - Hangul_NCount = 21*28 -}; - -#define hangul_isPrecomposed(uc) \ - (uc >= Hangul_SBase && uc < Hangul_SBase + Hangul_SCount) - -#define hangul_isLV(uc) \ - ((uc - Hangul_SBase) % Hangul_TCount == 0) - -typedef enum { - L, - V, - T, - LV, - LVT, - X -} HangulType; - -static HangulType hangul_type(unsigned short uc) { - if (uc > Hangul_SBase && uc < Hangul_SBase + Hangul_SCount) - return hangul_isLV(uc) ? LV : LVT; - if (uc < Hangul_LBase || uc > 0x11ff) - return X; - if (uc < Hangul_VBase) - return L; - if (uc < Hangul_TBase) - return V; - return T; -} - -static int hangul_nextSyllableBoundary(const HB_UChar16 *s, int start, int end) -{ - const HB_UChar16 *uc = s + start; - - HangulType state = hangul_type(*uc); - int pos = 1; - - while (pos < end - start) { - HangulType newState = hangul_type(uc[pos]); - switch(newState) { - case X: - goto finish; - case L: - case V: - case T: - if (state > newState) - goto finish; - state = newState; - break; - case LV: - if (state > L) - goto finish; - state = V; - break; - case LVT: - if (state > L) - goto finish; - state = T; - } - ++pos; - } - - finish: - return start+pos; -} - -#ifndef NO_OPENTYPE -static const HB_OpenTypeFeature hangul_features [] = { - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('l', 'j', 'm', 'o'), CcmpProperty }, - { HB_MAKE_TAG('v', 'j', 'm', 'o'), CcmpProperty }, - { HB_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty }, - { 0, 0 } -}; -#endif - -static HB_Bool hangul_shape_syllable(HB_ShaperItem *item, HB_Bool openType) -{ - const HB_UChar16 *ch = item->string + item->item.pos; - int len = item->item.length; -#ifndef NO_OPENTYPE - const int availableGlyphs = item->num_glyphs; -#endif - - int i; - HB_UChar16 composed = 0; - /* see if we can compose the syllable into a modern hangul */ - if (item->item.length == 2) { - int LIndex = ch[0] - Hangul_LBase; - int VIndex = ch[1] - Hangul_VBase; - if (LIndex >= 0 && LIndex < Hangul_LCount && - VIndex >= 0 && VIndex < Hangul_VCount) - composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + Hangul_SBase; - } else if (item->item.length == 3) { - int LIndex = ch[0] - Hangul_LBase; - int VIndex = ch[1] - Hangul_VBase; - int TIndex = ch[2] - Hangul_TBase; - if (LIndex >= 0 && LIndex < Hangul_LCount && - VIndex >= 0 && VIndex < Hangul_VCount && - TIndex >= 0 && TIndex < Hangul_TCount) - composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + TIndex + Hangul_SBase; - } - - - - /* if we have a modern hangul use the composed form */ - if (composed) { - ch = &composed; - len = 1; - } - - if (!item->font->klass->convertStringToGlyphIndices(item->font, - ch, len, - item->glyphs, &item->num_glyphs, - item->item.bidiLevel % 2)) - return FALSE; - for (i = 0; i < len; i++) { - item->attributes[i].mark = FALSE; - item->attributes[i].clusterStart = FALSE; - item->attributes[i].justification = 0; - item->attributes[i].zeroWidth = FALSE; - /*IDEBUG(" %d: %4x", i, ch[i].unicode()); */ - } - -#ifndef NO_OPENTYPE - if (!composed && openType) { - HB_Bool positioned; - - HB_STACKARRAY(unsigned short, logClusters, len); - for (i = 0; i < len; ++i) - logClusters[i] = i; - item->log_clusters = logClusters; - - HB_OpenTypeShape(item, /*properties*/0); - - positioned = HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE); - - HB_FREE_STACKARRAY(logClusters); - - if (!positioned) - return FALSE; - } else { - HB_HeuristicPosition(item); - } -#endif - - item->attributes[0].clusterStart = TRUE; - return TRUE; -} - -HB_Bool HB_HangulShape(HB_ShaperItem *item) -{ - const HB_UChar16 *uc = item->string + item->item.pos; - HB_Bool allPrecomposed = TRUE; - int i; - - assert(item->item.script == HB_Script_Hangul); - - for (i = 0; i < (int)item->item.length; ++i) { - if (!hangul_isPrecomposed(uc[i])) { - allPrecomposed = FALSE; - break; - } - } - - if (!allPrecomposed) { - HB_Bool openType = FALSE; - unsigned short *logClusters = item->log_clusters; - HB_ShaperItem syllable; - int first_glyph = 0; - int sstart = item->item.pos; - int end = sstart + item->item.length; - -#ifndef NO_OPENTYPE - openType = HB_SelectScript(item, hangul_features); -#endif - syllable = *item; - - while (sstart < end) { - int send = hangul_nextSyllableBoundary(item->string, sstart, end); - - syllable.item.pos = sstart; - syllable.item.length = send-sstart; - syllable.glyphs = item->glyphs + first_glyph; - syllable.attributes = item->attributes + first_glyph; - syllable.offsets = item->offsets + first_glyph; - syllable.advances = item->advances + first_glyph; - syllable.num_glyphs = item->num_glyphs - first_glyph; - if (!hangul_shape_syllable(&syllable, openType)) { - item->num_glyphs += syllable.num_glyphs; - return FALSE; - } - /* fix logcluster array */ - for (i = sstart; i < send; ++i) - logClusters[i-item->item.pos] = first_glyph; - sstart = send; - first_glyph += syllable.num_glyphs; - } - item->num_glyphs = first_glyph; - return TRUE; - } - - return HB_BasicShape(item); -} - - diff --git a/src/hb-old/harfbuzz-hebrew.c b/src/hb-old/harfbuzz-hebrew.c deleted file mode 100644 index b5431a5..0000000 --- a/src/hb-old/harfbuzz-hebrew.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" -#include <assert.h> - -/* -// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly -// ligatures one does not want in modern Hebrew (as lam-alef ligatures). -*/ -#ifndef NO_OPENTYPE -static const HB_OpenTypeFeature hebrew_features[] = { - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - {0, 0} -}; -#endif - -/* Hebrew shaping. In the non opentype case we try to use the - presentation forms specified for Hebrew. Especially for the - ligatures with Dagesh this gives much better results than we could - achieve manually. -*/ -HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item) -{ - enum { - Dagesh = 0x5bc, - ShinDot = 0x5c1, - SinDot = 0x5c2, - Patah = 0x5b7, - Qamats = 0x5b8, - Holam = 0x5b9, - Rafe = 0x5bf - }; - - assert(shaper_item->item.script == HB_Script_Hebrew); - -#ifndef NO_OPENTYPE - if (HB_SelectScript(shaper_item, hebrew_features)) { - - const int availableGlyphs = shaper_item->num_glyphs; - if (!HB_ConvertStringToGlyphIndices(shaper_item)) - return FALSE; - - HB_HeuristicSetGlyphAttributes(shaper_item); - HB_OpenTypeShape(shaper_item, /*properties*/0); - return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE); - } -#endif - - { - const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos; - unsigned short *logClusters = shaper_item->log_clusters; - HB_GlyphAttributes *attributes = shaper_item->attributes; - - HB_Bool haveGlyphs; - int slen = 1; - int cluster_start = 0; - hb_uint32 i; - - HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length); - *shapedChars = *uc; - logClusters[0] = 0; - - for (i = 1; i < shaper_item->item.length; ++i) { - hb_uint16 base = shapedChars[cluster_start]; - hb_uint16 shaped = 0; - HB_Bool invalid = FALSE; - if (uc[i] == Dagesh) { - if (base >= 0x5d0 - && base <= 0x5ea - && base != 0x5d7 - && base != 0x5dd - && base != 0x5df - && base != 0x5e2 - && base != 0x5e5) { - shaped = base - 0x5d0 + 0xfb30; - } else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) { - shaped = base + 2; - } else { - invalid = TRUE; - } - } else if (uc[i] == ShinDot) { - if (base == 0x05e9) - shaped = 0xfb2a; - else if (base == 0xfb49) - shaped = 0xfb2c; - else - invalid = TRUE; - } else if (uc[i] == SinDot) { - if (base == 0x05e9) - shaped = 0xfb2b; - else if (base == 0xfb49) - shaped = 0xfb2d; - else - invalid = TRUE; - } else if (uc[i] == Patah) { - if (base == 0x5d0) - shaped = 0xfb2e; - } else if (uc[i] == Qamats) { - if (base == 0x5d0) - shaped = 0xfb2f; - } else if (uc[i] == Holam) { - if (base == 0x5d5) - shaped = 0xfb4b; - } else if (uc[i] == Rafe) { - if (base == 0x5d1) - shaped = 0xfb4c; - else if (base == 0x5db) - shaped = 0xfb4d; - else if (base == 0x5e4) - shaped = 0xfb4e; - } - - if (invalid) { - shapedChars[slen] = 0x25cc; - attributes[slen].clusterStart = TRUE; - attributes[slen].mark = FALSE; - attributes[slen].combiningClass = 0; - cluster_start = slen; - ++slen; - } - if (shaped) { - if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) { - shapedChars[cluster_start] = shaped; - } else - shaped = 0; - } - if (!shaped) { - HB_CharCategory category; - int cmb; - shapedChars[slen] = uc[i]; - HB_GetUnicodeCharProperties(uc[i], &category, &cmb); - if (category != HB_Mark_NonSpacing) { - attributes[slen].clusterStart = TRUE; - attributes[slen].mark = FALSE; - attributes[slen].combiningClass = 0; - attributes[slen].dontPrint = HB_IsControlChar(uc[i]); - cluster_start = slen; - } else { - attributes[slen].clusterStart = FALSE; - attributes[slen].mark = TRUE; - attributes[slen].combiningClass = cmb; - } - ++slen; - } - logClusters[i] = cluster_start; - } - - haveGlyphs = shaper_item->font->klass - ->convertStringToGlyphIndices(shaper_item->font, - shapedChars, slen, - shaper_item->glyphs, &shaper_item->num_glyphs, - shaper_item->item.bidiLevel % 2); - - HB_FREE_STACKARRAY(shapedChars); - - if (!haveGlyphs) - return FALSE; - - HB_HeuristicPosition(shaper_item); - } - - return TRUE; -} - diff --git a/src/hb-old/harfbuzz-impl.c b/src/hb-old/harfbuzz-impl.c deleted file mode 100644 index ddbf36b..0000000 --- a/src/hb-old/harfbuzz-impl.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 - */ - -#include "harfbuzz-impl.h" - - -HB_INTERNAL HB_Pointer -_hb_alloc(size_t size, - HB_Error *perror ) -{ - HB_Error error = (HB_Error)0; - HB_Pointer block = NULL; - - if ( size > 0 ) - { - block = calloc( 1, size ); - if ( !block ) - error = ERR(HB_Err_Out_Of_Memory); - } - - *perror = error; - return block; -} - - -HB_INTERNAL HB_Pointer -_hb_realloc(HB_Pointer block, - size_t new_size, - HB_Error *perror ) -{ - HB_Pointer block2 = NULL; - HB_Error error = (HB_Error)0; - - block2 = realloc( block, new_size ); - if ( block2 == NULL && new_size != 0 ) - error = ERR(HB_Err_Out_Of_Memory); - - if ( !error ) - block = block2; - - *perror = error; - return block; -} - - -HB_INTERNAL void -_hb_free( HB_Pointer block ) -{ - if ( block ) - free( block ); -} - - -/* helper func to set a breakpoint on */ -HB_INTERNAL HB_Error -_hb_err (HB_Error code) -{ - return code; -} diff --git a/src/hb-old/harfbuzz-impl.h b/src/hb-old/harfbuzz-impl.h deleted file mode 100644 index 3f370b6..0000000 --- a/src/hb-old/harfbuzz-impl.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_IMPL_H -#define HARFBUZZ_IMPL_H - -#include "harfbuzz-global.h" - -#include <stdlib.h> - -HB_BEGIN_HEADER - -#ifndef HB_INTERNAL -# ifndef __MINGW32__ -# define HB_INTERNAL __attribute__((__visibility__("hidden"))) -# else -# define HB_INTERNAL -# endif -#endif - -#ifndef NULL -# define NULL ((void *)0) -#endif - -#ifndef FALSE -# define FALSE 0 -#endif - -#ifndef TRUE -# define TRUE 1 -#endif - -#ifndef TTAG_GDEF -# define TTAG_GDEF HB_MAKE_TAG( 'G', 'D', 'E', 'F' ) -#endif -#ifndef TTAG_GPOS -# define TTAG_GPOS HB_MAKE_TAG( 'G', 'P', 'O', 'S' ) -#endif -#ifndef TTAG_GSUB -# define TTAG_GSUB HB_MAKE_TAG( 'G', 'S', 'U', 'B' ) -#endif - -#ifndef HB_UNUSED -# define HB_UNUSED(arg) ((arg) = (arg)) -#endif - -#define HB_LIKELY(cond) (cond) -#define HB_UNLIKELY(cond) (cond) - -#define ARRAY_LEN(Array) ((int)(sizeof (Array) / sizeof (Array)[0])) - - - -#define HB_IsHighSurrogate(ucs) \ - (((ucs) & 0xfc00) == 0xd800) - -#define HB_IsLowSurrogate(ucs) \ - (((ucs) & 0xfc00) == 0xdc00) - -#define HB_SurrogateToUcs4(high, low) \ - (((HB_UChar32)(high))<<10) + (low) - 0x35fdc00; - - - - - -#define ALLOC(_ptr,_size) \ - ( (_ptr) = _hb_alloc( _size, &error ), error != 0 ) - -#define REALLOC(_ptr,_newsz) \ - ( (_ptr) = _hb_realloc( (_ptr), (_newsz), &error ), error != 0 ) - -#define FREE(_ptr) \ - do { \ - if ( (_ptr) ) \ - { \ - _hb_free( _ptr ); \ - _ptr = NULL; \ - } \ - } while (0) - -#define ALLOC_ARRAY(_ptr,_count,_type) \ - ALLOC(_ptr,(_count)*sizeof(_type)) - -#define REALLOC_ARRAY(_ptr,_newcnt,_type) \ - REALLOC(_ptr,(_newcnt)*sizeof(_type)) - -#define MEM_Copy(dest,source,count) memcpy( (char*)(dest), (const char*)(source), (size_t)(count) ) - -#define ERR(err) _hb_err (err) - - -HB_INTERNAL HB_Pointer -_hb_alloc( size_t size, - HB_Error *perror_ ); - -HB_INTERNAL HB_Pointer -_hb_realloc( HB_Pointer block, - size_t new_size, - HB_Error *perror_ ); - -HB_INTERNAL void -_hb_free( HB_Pointer block ); - - -/* helper func to set a breakpoint on */ -HB_INTERNAL HB_Error -_hb_err (HB_Error code); - - -HB_END_HEADER - -#endif /* HARFBUZZ_IMPL_H */ diff --git a/src/hb-old/harfbuzz-indic.cpp b/src/hb-old/harfbuzz-indic.cpp deleted file mode 100644 index 17e97e0..0000000 --- a/src/hb-old/harfbuzz-indic.cpp +++ /dev/null @@ -1,1868 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" - -#include <assert.h> -#include <stdio.h> - -#define FLAG(x) (1 << (x)) - -static HB_Bool isLetter(HB_UChar16 ucs) -{ - const int test = FLAG(HB_Letter_Uppercase) | - FLAG(HB_Letter_Lowercase) | - FLAG(HB_Letter_Titlecase) | - FLAG(HB_Letter_Modifier) | - FLAG(HB_Letter_Other); - return !!(FLAG(HB_GetUnicodeCharCategory(ucs)) & test); -} - -static HB_Bool isMark(HB_UChar16 ucs) -{ - const int test = FLAG(HB_Mark_NonSpacing) | - FLAG(HB_Mark_SpacingCombining) | - FLAG(HB_Mark_Enclosing); - return !!(FLAG(HB_GetUnicodeCharCategory(ucs)) & test); -} - -enum Form { - Invalid = 0x0, - UnknownForm = Invalid, - Consonant, - Nukta, - Halant, - Matra, - VowelMark, - StressMark, - IndependentVowel, - LengthMark, - Control, - Other -}; - -static const unsigned char indicForms[0xe00-0x900] = { - // Devangari - Invalid, VowelMark, VowelMark, VowelMark, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Nukta, Other, Matra, Matra, - - Matra, Matra, Matra, Matra, - Matra, Matra, Matra, Matra, - Matra, Matra, Matra, Matra, - Matra, Halant, UnknownForm, UnknownForm, - - Other, StressMark, StressMark, StressMark, - StressMark, UnknownForm, UnknownForm, UnknownForm, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - IndependentVowel, IndependentVowel, VowelMark, VowelMark, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Consonant, - Consonant, Consonant /* ??? */, Consonant, Consonant, - - // Bengali - Invalid, VowelMark, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, Invalid, Invalid, IndependentVowel, - - IndependentVowel, Invalid, Invalid, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Invalid, Consonant, Invalid, - Invalid, Invalid, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Nukta, Other, Matra, Matra, - - Matra, Matra, Matra, Matra, - Matra, Invalid, Invalid, Matra, - Matra, Invalid, Invalid, Matra, - Matra, Halant, Consonant, UnknownForm, - - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, VowelMark, - Invalid, Invalid, Invalid, Invalid, - Consonant, Consonant, Invalid, Consonant, - - IndependentVowel, IndependentVowel, VowelMark, VowelMark, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Consonant, Consonant, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - // Gurmukhi - Invalid, VowelMark, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, Invalid, - Invalid, Invalid, Invalid, IndependentVowel, - - IndependentVowel, Invalid, Invalid, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Invalid, Consonant, Consonant, - Invalid, Consonant, Consonant, Invalid, - Consonant, Consonant, UnknownForm, UnknownForm, - Nukta, Other, Matra, Matra, - - Matra, Matra, Matra, Invalid, - Invalid, Invalid, Invalid, Matra, - Matra, Invalid, Invalid, Matra, - Matra, Halant, UnknownForm, UnknownForm, - - Invalid, Invalid, Invalid, Invalid, - Invalid, UnknownForm, UnknownForm, UnknownForm, - Invalid, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Invalid, - - Other, Other, Invalid, Invalid, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - StressMark, StressMark, Consonant, Consonant, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - // Gujarati - Invalid, VowelMark, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, Invalid, IndependentVowel, - - IndependentVowel, IndependentVowel, Invalid, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Invalid, Consonant, Consonant, - Invalid, Consonant, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Nukta, Other, Matra, Matra, - - Matra, Matra, Matra, Matra, - Matra, Matra, Invalid, Matra, - Matra, Matra, Invalid, Matra, - Matra, Halant, UnknownForm, UnknownForm, - - Other, UnknownForm, UnknownForm, UnknownForm, - UnknownForm, UnknownForm, UnknownForm, UnknownForm, - UnknownForm, UnknownForm, UnknownForm, UnknownForm, - UnknownForm, UnknownForm, UnknownForm, UnknownForm, - - IndependentVowel, IndependentVowel, VowelMark, VowelMark, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - // Oriya - Invalid, VowelMark, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, Invalid, Invalid, IndependentVowel, - - IndependentVowel, Invalid, Invalid, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Invalid, Consonant, Consonant, - Invalid, Consonant, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Nukta, Other, Matra, Matra, - - Matra, Matra, Matra, Matra, - Invalid, Invalid, Invalid, Matra, - Matra, Invalid, Invalid, Matra, - Matra, Halant, UnknownForm, UnknownForm, - - Other, Invalid, Invalid, Invalid, - Invalid, UnknownForm, LengthMark, LengthMark, - Invalid, Invalid, Invalid, Invalid, - Consonant, Consonant, Invalid, Consonant, - - IndependentVowel, IndependentVowel, Invalid, Invalid, - Invalid, Invalid, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Other, Consonant, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - //Tamil - Invalid, Invalid, VowelMark, Other, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, Invalid, - Invalid, Invalid, IndependentVowel, IndependentVowel, - - IndependentVowel, Invalid, IndependentVowel, IndependentVowel, - IndependentVowel, Consonant, Invalid, Invalid, - Invalid, Consonant, Consonant, Invalid, - Consonant, Invalid, Consonant, Consonant, - - Invalid, Invalid, Invalid, Consonant, - Consonant, Invalid, Invalid, Invalid, - Consonant, Consonant, Consonant, Invalid, - Invalid, Invalid, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Invalid, Invalid, Matra, Matra, - - Matra, Matra, Matra, Invalid, - Invalid, Invalid, Matra, Matra, - Matra, Invalid, Matra, Matra, - Matra, Halant, Invalid, Invalid, - - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, LengthMark, - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, Invalid, - - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - // Telugu - Invalid, VowelMark, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, Invalid, IndependentVowel, IndependentVowel, - - IndependentVowel, Invalid, IndependentVowel, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Invalid, Consonant, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Invalid, Invalid, Matra, Matra, - - Matra, Matra, Matra, Matra, - Matra, Invalid, Matra, Matra, - Matra, Invalid, Matra, Matra, - Matra, Halant, Invalid, Invalid, - - Invalid, Invalid, Invalid, Invalid, - Invalid, LengthMark, Matra, Invalid, - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, Invalid, - - IndependentVowel, IndependentVowel, Invalid, Invalid, - Invalid, Invalid, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - // Kannada - Invalid, Invalid, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, Invalid, IndependentVowel, IndependentVowel, - - IndependentVowel, Invalid, IndependentVowel, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Invalid, Consonant, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Nukta, Other, Matra, Matra, - - Matra, Matra, Matra, Matra, - Matra, Invalid, Matra, Matra, - Matra, Invalid, Matra, Matra, - Matra, Halant, Invalid, Invalid, - - Invalid, Invalid, Invalid, Invalid, - Invalid, LengthMark, LengthMark, Invalid, - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Consonant, Invalid, - - IndependentVowel, IndependentVowel, VowelMark, VowelMark, - Invalid, Invalid, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - // Malayalam - Invalid, Invalid, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, Invalid, IndependentVowel, IndependentVowel, - - IndependentVowel, Invalid, IndependentVowel, IndependentVowel, - IndependentVowel, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, UnknownForm, UnknownForm, - Invalid, Invalid, Matra, Matra, - - Matra, Matra, Matra, Matra, - Invalid, Invalid, Matra, Matra, - Matra, Invalid, Matra, Matra, - Matra, Halant, Invalid, Invalid, - - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, Matra, - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, Invalid, - - IndependentVowel, IndependentVowel, Invalid, Invalid, - Invalid, Invalid, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, - - // Sinhala - Invalid, Invalid, VowelMark, VowelMark, - Invalid, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - - IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, - IndependentVowel, IndependentVowel, IndependentVowel, Invalid, - Invalid, Invalid, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - - Consonant, Consonant, Invalid, Consonant, - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Consonant, - Invalid, Consonant, Invalid, Invalid, - - Consonant, Consonant, Consonant, Consonant, - Consonant, Consonant, Consonant, Invalid, - Invalid, Invalid, Halant, Invalid, - Invalid, Invalid, Invalid, Matra, - - Matra, Matra, Matra, Matra, - Matra, Invalid, Matra, Invalid, - Matra, Matra, Matra, Matra, - Matra, Matra, Matra, Matra, - - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, Invalid, - Invalid, Invalid, Invalid, Invalid, - - Invalid, Invalid, Matra, Matra, - Other, Other, Other, Other, - Other, Other, Other, Other, - Other, Other, Other, Other, -}; - -enum Position { - None, - Pre, - Above, - Below, - Post, - Split, - Base, - Reph, - Vattu, - Inherit -}; - -static const unsigned char indicPosition[0xe00-0x900] = { - // Devanagari - None, Above, Above, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - Below, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, Post, Pre, - - Post, Below, Below, Below, - Below, Above, Above, Above, - Above, Post, Post, Post, - Post, None, None, None, - - None, Above, Below, Above, - Above, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, Below, Below, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Bengali - None, Above, Post, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - Below, None, None, Post, - - Below, None, None, None, - None, None, None, None, - None, None, None, None, - Below, None, Post, Pre, - - Post, Below, Below, Below, - Below, None, None, Pre, - Pre, None, None, Split, - Split, Below, None, None, - - None, None, None, None, - None, None, None, Post, - None, None, None, None, - None, None, None, None, - - None, None, Below, Below, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - Below, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Gurmukhi - None, Above, Above, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, Post, - - Below, None, None, None, - None, Below, None, None, - None, Below, None, None, - Below, None, Post, Pre, - - Post, Below, Below, None, - None, None, None, Above, - Above, None, None, Above, - Above, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - Above, Above, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Gujarati - None, Above, Above, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - Below, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, Post, Pre, - - Post, Below, Below, Below, - Below, Above, None, Above, - Above, Post, None, Post, - Post, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, Below, Below, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Oriya - None, Above, Post, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - Below, None, None, None, - Below, None, None, None, - Below, Below, Below, Post, - - Below, None, Below, Below, - None, None, None, None, - None, None, None, None, - None, None, Post, Above, - - Post, Below, Below, Below, - None, None, None, Pre, - Split, None, None, Split, - Split, None, None, None, - - None, None, None, None, - None, None, Above, Post, - None, None, None, None, - None, None, None, Post, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, Below, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Tamil - None, None, Above, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, Post, Post, - - Above, Below, Below, None, - None, None, Pre, Pre, - Pre, None, Split, Split, - Split, Halant, None, None, - - None, None, None, None, - None, None, None, Post, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Telugu - None, Post, Post, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, Below, Below, Below, - Below, Below, Below, Below, - Below, Below, Below, Below, - - Below, Below, Below, Below, - Below, Below, Below, Below, - Below, None, Below, Below, - Below, Below, Below, Below, - - Below, None, Below, Below, - None, Below, Below, Below, - Below, Below, None, None, - None, None, Post, Above, - - Above, Post, Post, Post, - Post, None, Above, Above, - Split, None, Post, Above, - Above, Halant, None, None, - - None, None, None, None, - None, Above, Below, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Kannada - None, None, Post, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, Below, Below, Below, - Below, Below, Below, Below, - Below, Below, Below, Below, - - Below, Below, Below, Below, - Below, Below, Below, Below, - Below, Below, Below, Below, - Below, Below, Below, Below, - - Below, None, Below, Below, - None, Below, Below, Below, - Below, Below, None, None, - None, None, Post, Above, - - Split, Post, Post, Post, - Post, None, Above, Split, - Split, None, Split, Split, - Above, Halant, None, None, - - None, None, None, None, - None, Post, Post, None, - None, None, None, None, - None, None, Below, None, - - None, None, Below, Below, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Malayalam - None, None, Post, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, Post, - - Post, None, Below, None, - None, Post, None, None, - None, None, None, None, - None, None, Post, Post, - - Post, Post, Post, Post, - None, None, Pre, Pre, - Pre, None, Split, Split, - Split, Halant, None, None, - - None, None, None, None, - None, None, None, Post, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - // Sinhala - None, None, Post, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, Post, - - Post, Post, Above, Above, - Below, None, Below, None, - Post, Pre, Split, Pre, - Split, Split, Split, Post, - - None, None, None, None, - None, None, None, None, - None, None, None, None, - None, None, None, None, - - None, None, Post, Post, - None, None, None, None, - None, None, None, None, - None, None, None, None -}; - -static inline Form form(unsigned short uc) { - if (uc < 0x900 || uc > 0xdff) { - if (uc == 0x25cc) - return Consonant; - if (uc == 0x200c || uc == 0x200d) - return Control; - return Other; - } - return (Form)indicForms[uc-0x900]; -} - -static inline Position indic_position(unsigned short uc) { - if (uc < 0x900 || uc > 0xdff) - return None; - return (Position) indicPosition[uc-0x900]; -} - - -enum IndicScriptProperties { - HasReph = 0x01, - HasSplit = 0x02 -}; - -const hb_uint8 scriptProperties[10] = { - // Devanagari, - HasReph, - // Bengali, - HasReph|HasSplit, - // Gurmukhi, - 0, - // Gujarati, - HasReph, - // Oriya, - HasReph|HasSplit, - // Tamil, - HasSplit, - // Telugu, - HasSplit, - // Kannada, - HasSplit|HasReph, - // Malayalam, - HasSplit, - // Sinhala, - HasSplit -}; - -struct IndicOrdering { - Form form; - Position position; -}; - -static const IndicOrdering devanagari_order [] = { - { Consonant, Below }, - { Matra, Below }, - { VowelMark, Below }, - { StressMark, Below }, - { Matra, Above }, - { Matra, Post }, - { Consonant, Reph }, - { VowelMark, Above }, - { StressMark, Above }, - { VowelMark, Post }, - { (Form)0, None } -}; - -static const IndicOrdering bengali_order [] = { - { Consonant, Below }, - { Matra, Below }, - { Matra, Above }, - { Consonant, Reph }, - { VowelMark, Above }, - { Consonant, Post }, - { Matra, Post }, - { VowelMark, Post }, - { (Form)0, None } -}; - -static const IndicOrdering gurmukhi_order [] = { - { Consonant, Below }, - { Matra, Below }, - { Matra, Above }, - { Consonant, Post }, - { Matra, Post }, - { VowelMark, Above }, - { (Form)0, None } -}; - -static const IndicOrdering tamil_order [] = { - { Matra, Above }, - { Matra, Post }, - { VowelMark, Post }, - { (Form)0, None } -}; - -static const IndicOrdering telugu_order [] = { - { Matra, Above }, - { Matra, Below }, - { Matra, Post }, - { Consonant, Below }, - { Consonant, Post }, - { VowelMark, Post }, - { (Form)0, None } -}; - -static const IndicOrdering kannada_order [] = { - { Matra, Above }, - { Matra, Post }, - { Consonant, Below }, - { Consonant, Post }, - { LengthMark, Post }, - { Consonant, Reph }, - { VowelMark, Post }, - { (Form)0, None } -}; - -static const IndicOrdering malayalam_order [] = { - { Consonant, Below }, - { Matra, Below }, - { Consonant, Reph }, - { Consonant, Post }, - { Matra, Post }, - { VowelMark, Post }, - { (Form)0, None } -}; - -static const IndicOrdering sinhala_order [] = { - { Matra, Below }, - { Matra, Above }, - { Matra, Post }, - { VowelMark, Post }, - { (Form)0, None } -}; - -static const IndicOrdering * const indic_order[] = { - devanagari_order, // Devanagari - bengali_order, // Bengali - gurmukhi_order, // Gurmukhi - devanagari_order, // Gujarati - bengali_order, // Oriya - tamil_order, // Tamil - telugu_order, // Telugu - kannada_order, // Kannada - malayalam_order, // Malayalam - sinhala_order // Sinhala -}; - - - -// vowel matras that have to be split into two parts. -static const unsigned short split_matras[] = { - // matra, split1, split2, split3 - - // bengalis - 0x9cb, 0x9c7, 0x9be, 0x0, - 0x9cc, 0x9c7, 0x9d7, 0x0, - // oriya - 0xb48, 0xb47, 0xb56, 0x0, - 0xb4b, 0xb47, 0xb3e, 0x0, - 0xb4c, 0xb47, 0xb57, 0x0, - // tamil - 0xbca, 0xbc6, 0xbbe, 0x0, - 0xbcb, 0xbc7, 0xbbe, 0x0, - 0xbcc, 0xbc6, 0xbd7, 0x0, - // telugu - 0xc48, 0xc46, 0xc56, 0x0, - // kannada - 0xcc0, 0xcbf, 0xcd5, 0x0, - 0xcc7, 0xcc6, 0xcd5, 0x0, - 0xcc8, 0xcc6, 0xcd6, 0x0, - 0xcca, 0xcc6, 0xcc2, 0x0, - 0xccb, 0xcc6, 0xcc2, 0xcd5, - // malayalam - 0xd4a, 0xd46, 0xd3e, 0x0, - 0xd4b, 0xd47, 0xd3e, 0x0, - 0xd4c, 0xd46, 0xd57, 0x0, - // sinhala - 0xdda, 0xdd9, 0xdca, 0x0, - 0xddc, 0xdd9, 0xdcf, 0x0, - 0xddd, 0xdd9, 0xdcf, 0xdca, - 0xdde, 0xdd9, 0xddf, 0x0, - 0xffff -}; - -static inline void splitMatra(unsigned short *reordered, int matra, int &len) -{ - unsigned short matra_uc = reordered[matra]; - //qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]); - - const unsigned short *split = split_matras; - while (split[0] < matra_uc) - split += 4; - - assert(*split == matra_uc); - ++split; - - int added_chars = split[2] == 0x0 ? 1 : 2; - - memmove(reordered + matra + added_chars, reordered + matra, (len-matra)*sizeof(unsigned short)); - reordered[matra] = split[0]; - reordered[matra+1] = split[1]; - if(added_chars == 2) - reordered[matra+2] = split[2]; - len += added_chars; -} - -#ifndef NO_OPENTYPE -static const HB_OpenTypeFeature indic_features[] = { - { HB_MAKE_TAG('l', 'o', 'c', 'a'), LocaProperty }, - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, - { HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty }, - { HB_MAKE_TAG('a', 'k', 'h', 'n'), AkhantProperty }, - { HB_MAKE_TAG('r', 'p', 'h', 'f'), RephProperty }, - { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty }, - { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty }, - { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty }, - { HB_MAKE_TAG('c', 'j', 'c', 't'), ConjunctFormProperty }, - { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty }, - { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty }, - { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty }, - { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty }, - { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty }, - { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty }, - { HB_MAKE_TAG('c', 'a', 'l', 't'), IndicCaltProperty }, - { 0, 0 } -}; -#endif - -// #define INDIC_DEBUG -#ifdef INDIC_DEBUG -#define IDEBUG hb_debug -#include <stdarg.h> - -static void hb_debug(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); // use variable arg list - vfprintf(stderr, msg, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -#else -#define IDEBUG if(0) printf -#endif - -#if 0 //def INDIC_DEBUG -static QString propertiesToString(int properties) -{ - QString res; - properties = ~properties; - if (properties & LocaProperty) - res += "Loca "; - if (properties & CcmpProperty) - res += "Ccmp "; - if (properties & InitProperty) - res += "Init "; - if (properties & NuktaProperty) - res += "Nukta "; - if (properties & AkhantProperty) - res += "Akhant "; - if (properties & RephProperty) - res += "Reph "; - if (properties & PreFormProperty) - res += "PreForm "; - if (properties & BelowFormProperty) - res += "BelowForm "; - if (properties & AboveFormProperty) - res += "AboveForm "; - if (properties & HalfFormProperty) - res += "HalfForm "; - if (properties & PostFormProperty) - res += "PostForm "; - if (properties & ConjunctFormProperty) - res += "PostForm "; - if (properties & VattuProperty) - res += "Vattu "; - if (properties & PreSubstProperty) - res += "PreSubst "; - if (properties & BelowSubstProperty) - res += "BelowSubst "; - if (properties & AboveSubstProperty) - res += "AboveSubst "; - if (properties & PostSubstProperty) - res += "PostSubst "; - if (properties & HalantProperty) - res += "Halant "; - if (properties & CligProperty) - res += "Clig "; - if (properties & IndicCaltProperty) - res += "Calt "; - return res; -} -#endif - -static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool invalid) -{ - HB_Script script = item->item.script; - assert(script >= HB_Script_Devanagari && script <= HB_Script_Sinhala); - const unsigned short script_base = 0x0900 + 0x80*(script-HB_Script_Devanagari); - const unsigned short ra = script_base + 0x30; - const unsigned short halant = script_base + 0x4d; - const unsigned short nukta = script_base + 0x3c; - bool control = false; - - int len = (int)item->item.length; - IDEBUG(">>>>> indic shape: from=%d, len=%d invalid=%d", item->item.pos, item->item.length, invalid); - - if ((int)item->num_glyphs < len+4) { - item->num_glyphs = len+4; - return false; - } - - HB_STACKARRAY(HB_UChar16, reordered, len + 4); - HB_STACKARRAY(hb_uint8, position, len + 4); - - unsigned char properties = scriptProperties[script-HB_Script_Devanagari]; - - if (invalid) { - *reordered = 0x25cc; - memcpy(reordered+1, item->string + item->item.pos, len*sizeof(HB_UChar16)); - len++; - } else { - memcpy(reordered, item->string + item->item.pos, len*sizeof(HB_UChar16)); - } - if (reordered[len-1] == 0x200c) // zero width non joiner - len--; - - int i; - int base = 0; - int reph = -1; - -#ifdef INDIC_DEBUG - IDEBUG("original:"); - for (i = 0; i < len; i++) { - IDEBUG(" %d: %4x", i, reordered[i]); - } -#endif - - if (len != 1) { - HB_UChar16 *uc = reordered; - bool beginsWithRa = false; - - // Rule 1: find base consonant - // - // The shaping engine finds the base consonant of the - // syllable, using the following algorithm: starting from the - // end of the syllable, move backwards until a consonant is - // found that does not have a below-base or post-base form - // (post-base forms have to follow below-base forms), or - // arrive at the first consonant. The consonant stopped at - // will be the base. - // - // * If the syllable starts with Ra + H (in a script that has - // 'Reph'), Ra is excluded from candidates for base - // consonants. - // - // * In Kannada and Telugu, the base consonant cannot be - // farther than 3 consonants from the end of the syllable. - // #### replace the HasReph property by testing if the feature exists in the font! - if (form(*uc) == Consonant || (script == HB_Script_Bengali && form(*uc) == IndependentVowel)) { - if ((properties & HasReph) && (len > 2) && - (*uc == ra || *uc == 0x9f0) && *(uc+1) == halant) - beginsWithRa = true; - - if (beginsWithRa && form(*(uc+2)) == Control) - beginsWithRa = false; - - base = (beginsWithRa ? 2 : 0); - IDEBUG(" length = %d, beginsWithRa = %d, base=%d", len, beginsWithRa, base); - - int lastConsonant = 0; - int matra = -1; - // we remember: - // * the last consonant since we need it for rule 2 - // * the matras position for rule 3 and 4 - - // figure out possible base glyphs - memset(position, 0, len); - if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) { - bool vattu = false; - for (i = base; i < len; ++i) { - position[i] = form(uc[i]); - if (position[i] == Consonant) { - lastConsonant = i; - vattu = (!vattu && uc[i] == ra); - if (vattu) { - IDEBUG("excluding vattu glyph at %d from base candidates", i); - position[i] = Vattu; - } - } else if (position[i] == Matra) { - matra = i; - } - } - } else { - for (i = base; i < len; ++i) { - position[i] = form(uc[i]); - if (position[i] == Consonant) - lastConsonant = i; - else if (matra < 0 && position[i] == Matra) - matra = i; - } - } - int skipped = 0; - Position pos = Post; - for (i = len-1; i >= base; i--) { - if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada)) - continue; - - if (i < len-1 && position[i] == Control && position[i+1] == Consonant) { - base = i+1; - break; - } - - Position charPosition = indic_position(uc[i]); - if (pos == Post && charPosition == Post) { - pos = Post; - } else if ((pos == Post || pos == Below) && charPosition == Below) { - if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) - base = i; - pos = Below; - } else { - base = i; - break; - } - if (skipped == 2 && (script == HB_Script_Kannada || script == HB_Script_Telugu)) { - base = i; - break; - } - ++skipped; - } - - IDEBUG(" base consonant at %d skipped=%d, lastConsonant=%d", base, skipped, lastConsonant); - - // Rule 2: - // - // If the base consonant is not the last one, Uniscribe - // moves the halant from the base consonant to the last - // one. - if (lastConsonant > base) { - int halantPos = 0; - if (uc[base+1] == halant) - halantPos = base + 1; - else if (uc[base+1] == nukta && uc[base+2] == halant) - halantPos = base + 2; - if (halantPos > 0) { - IDEBUG(" moving halant from %d to %d!", base+1, lastConsonant); - for (i = halantPos; i < lastConsonant; i++) - uc[i] = uc[i+1]; - uc[lastConsonant] = halant; - } - } - - // Rule 3: - // - // If the syllable starts with Ra + H, Uniscribe moves - // this combination so that it follows either: - - // * the post-base 'matra' (if any) or the base consonant - // (in scripts that show similarity to Devanagari, i.e., - // Devanagari, Gujarati, Bengali) - // * the base consonant (other scripts) - // * the end of the syllable (Kannada) - - Position matra_position = None; - if (matra > 0) - matra_position = indic_position(uc[matra]); - IDEBUG(" matra at %d with form %d, base=%d", matra, matra_position, base); - - if (beginsWithRa && base != 0) { - int toPos = base+1; - if (toPos < len && uc[toPos] == nukta) - toPos++; - if (toPos < len && uc[toPos] == halant) - toPos++; - if (toPos < len && uc[toPos] == 0x200d) - toPos++; - if (toPos < len-1 && uc[toPos] == ra && uc[toPos+1] == halant) - toPos += 2; - if (script == HB_Script_Devanagari || script == HB_Script_Gujarati || script == HB_Script_Bengali) { - if (matra_position == Post || matra_position == Split) { - toPos = matra+1; - matra -= 2; - } - } else if (script == HB_Script_Kannada) { - toPos = len; - matra -= 2; - } - - IDEBUG("moving leading ra+halant to position %d", toPos); - for (i = 2; i < toPos; i++) - uc[i-2] = uc[i]; - uc[toPos-2] = ra; - uc[toPos-1] = halant; - base -= 2; - if (properties & HasReph) - reph = toPos-2; - } - - // Rule 4: - - // Uniscribe splits two- or three-part matras into their - // parts. This splitting is a character-to-character - // operation). - // - // Uniscribe describes some moving operations for these - // matras here. For shaping however all pre matras need - // to be at the beginning of the syllable, so we just move - // them there now. - if (matra_position == Split) { - splitMatra(uc, matra, len); - // Handle three-part matras (0xccb in Kannada) - matra_position = indic_position(uc[matra]); - } - - if (matra_position == Pre) { - unsigned short m = uc[matra]; - while (matra--) - uc[matra+1] = uc[matra]; - uc[0] = m; - base++; - } - } - - // Rule 5: - // - // Uniscribe classifies consonants and 'matra' parts as - // pre-base, above-base (Reph), below-base or post-base. This - // classification exists on the character code level and is - // language-dependent, not font-dependent. - for (i = 0; i < base; ++i) - position[i] = Pre; - position[base] = Base; - for (i = base+1; i < len; ++i) { - position[i] = indic_position(uc[i]); - // #### replace by adjusting table - if (uc[i] == nukta || uc[i] == halant) - position[i] = Inherit; - } - if (reph > 0) { - // recalculate reph, it might have changed. - for (i = base+1; i < len; ++i) - if (uc[i] == ra) - reph = i; - position[reph] = Reph; - position[reph+1] = Inherit; - } - - // all reordering happens now to the chars after the base - int fixed = base+1; - if (fixed < len && uc[fixed] == nukta) - fixed++; - if (fixed < len && uc[fixed] == halant) - fixed++; - if (fixed < len && uc[fixed] == 0x200d) - fixed++; - -#ifdef INDIC_DEBUG - for (i = fixed; i < len; ++i) - IDEBUG("position[%d] = %d, form=%d uc=%x", i, position[i], form(uc[i]), uc[i]); -#endif - // we continuosly position the matras and vowel marks and increase the fixed - // until we reached the end. - const IndicOrdering *finalOrder = indic_order[script-HB_Script_Devanagari]; - - IDEBUG(" reordering pass:"); - IDEBUG(" base=%d fixed=%d", base, fixed); - int toMove = 0; - while (finalOrder[toMove].form && fixed < len-1) { - IDEBUG(" fixed = %d, toMove=%d, moving form %d with pos %d", fixed, toMove, finalOrder[toMove].form, finalOrder[toMove].position); - for (i = fixed; i < len; i++) { -// IDEBUG() << " i=" << i << "uc=" << hex << uc[i] << "form=" << form(uc[i]) -// << "position=" << position[i]; - if (form(uc[i]) == finalOrder[toMove].form && - position[i] == finalOrder[toMove].position) { - // need to move this glyph - int to = fixed; - if (i < len-1 && position[i+1] == Inherit) { - IDEBUG(" moving two chars from %d to %d", i, to); - unsigned short ch = uc[i]; - unsigned short ch2 = uc[i+1]; - unsigned char pos = position[i]; - for (int j = i+1; j > to+1; j--) { - uc[j] = uc[j-2]; - position[j] = position[j-2]; - } - uc[to] = ch; - uc[to+1] = ch2; - position[to] = pos; - position[to+1] = pos; - fixed += 2; - } else { - IDEBUG(" moving one char from %d to %d", i, to); - unsigned short ch = uc[i]; - unsigned char pos = position[i]; - for (int j = i; j > to; j--) { - uc[j] = uc[j-1]; - position[j] = position[j-1]; - } - uc[to] = ch; - position[to] = pos; - fixed++; - } - } - } - toMove++; - } - - } - - if (reph > 0) { - // recalculate reph, it might have changed. - for (i = base+1; i < len; ++i) - if (reordered[i] == ra) - reph = i; - } - -#ifndef NO_OPENTYPE - const int availableGlyphs = item->num_glyphs; -#endif - if (!item->font->klass->convertStringToGlyphIndices(item->font, - reordered, len, - item->glyphs, &item->num_glyphs, - item->item.bidiLevel % 2)) - goto error; - - - IDEBUG(" base=%d, reph=%d", base, reph); - IDEBUG("reordered:"); - for (i = 0; i < len; i++) { - item->attributes[i].mark = false; - item->attributes[i].clusterStart = false; - item->attributes[i].justification = 0; - item->attributes[i].zeroWidth = false; - IDEBUG(" %d: %4x", i, reordered[i]); - } - - // now we have the syllable in the right order, and can start running it through open type. - - for (i = 0; i < len; ++i) - control |= (form(reordered[i]) == Control); - -#ifndef NO_OPENTYPE - if (openType) { - - // we need to keep track of where the base glyph is for some - // scripts and use the cluster feature for this. This - // also means we have to correct the logCluster output from - // the open type engine manually afterwards. for indic this - // is rather simple, as all chars just point to the first - // glyph in the syllable. - HB_STACKARRAY(unsigned short, clusters, len); - HB_STACKARRAY(unsigned int, properties, len); - - for (i = 0; i < len; ++i) - clusters[i] = i; - - // features we should always apply - for (i = 0; i < len; ++i) - properties[i] = ~(LocaProperty - | CcmpProperty - | NuktaProperty - | VattuProperty - | ConjunctFormProperty - | PreSubstProperty - | BelowSubstProperty - | AboveSubstProperty - | PostSubstProperty - | HalantProperty - | IndicCaltProperty - | PositioningProperties); - - // Loca always applies - // Ccmp always applies - // Init - if (item->item.pos == 0 - || !(isLetter(item->string[item->item.pos-1]) || isMark(item->string[item->item.pos-1]))) - properties[0] &= ~InitProperty; - - // Nukta always applies - // Akhant - for (i = 0; i <= base; ++i) - properties[i] &= ~AkhantProperty; - // Reph - if (reph >= 0) { - properties[reph] &= ~RephProperty; - properties[reph+1] &= ~RephProperty; - } - // BelowForm - for (i = base+1; i < len; ++i) - properties[i] &= ~BelowFormProperty; - - if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) { - // vattu glyphs need this aswell - bool vattu = false; - for (i = base-2; i > 1; --i) { - if (form(reordered[i]) == Consonant) { - vattu = (!vattu && reordered[i] == ra); - if (vattu) { - IDEBUG("forming vattu ligature at %d", i); - properties[i] &= ~BelowFormProperty; - properties[i+1] &= ~BelowFormProperty; - } - } - } - } - // HalfFormProperty - for (i = 0; i < base; ++i) - properties[i] &= ~HalfFormProperty; - if (control) { - for (i = 2; i < len; ++i) { - if (reordered[i] == 0x200d /* ZWJ */) { - properties[i-1] &= ~HalfFormProperty; - properties[i-2] &= ~HalfFormProperty; - } else if (reordered[i] == 0x200c /* ZWNJ */) { - properties[i-1] &= ~HalfFormProperty; - properties[i-2] &= ~HalfFormProperty; - } - } - } - // PostFormProperty - for (i = base+1; i < len; ++i) - properties[i] &= ~PostFormProperty; - // vattu always applies - // pres always applies - // blws always applies - // abvs always applies - // psts always applies - // halant always applies - // calt always applies - -#ifdef INDIC_DEBUG -// { -// IDEBUG("OT properties:"); -// for (int i = 0; i < len; ++i) -// qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data()); -// } -#endif - - // initialize - item->log_clusters = clusters; - HB_OpenTypeShape(item, properties); - - int newLen = item->face->buffer->in_length; - HB_GlyphItem otl_glyphs = item->face->buffer->in_string; - - // move the left matra back to its correct position in malayalam and tamil - if ((script == HB_Script_Malayalam || script == HB_Script_Tamil) && (form(reordered[0]) == Matra)) { -// qDebug("reordering matra, len=%d", newLen); - // need to find the base in the shaped string and move the matra there - int basePos = 0; - while (basePos < newLen && (int)otl_glyphs[basePos].cluster <= base) - basePos++; - --basePos; - if (basePos < newLen && basePos > 1) { -// qDebug("moving prebase matra to position %d in syllable newlen=%d", basePos, newLen); - HB_GlyphItemRec m = otl_glyphs[0]; - --basePos; - for (i = 0; i < basePos; ++i) - otl_glyphs[i] = otl_glyphs[i+1]; - otl_glyphs[basePos] = m; - } - } - - HB_Bool positioned = HB_OpenTypePosition(item, availableGlyphs, false); - - HB_FREE_STACKARRAY(clusters); - HB_FREE_STACKARRAY(properties); - - if (!positioned) - goto error; - - if (control) { - IDEBUG("found a control char in the syllable"); - hb_uint32 i = 0, j = 0; - while (i < item->num_glyphs) { - if (form(reordered[otl_glyphs[i].cluster]) == Control) { - ++i; - if (i >= item->num_glyphs) - break; - } - item->glyphs[j] = item->glyphs[i]; - item->attributes[j] = item->attributes[i]; - item->offsets[j] = item->offsets[i]; - item->advances[j] = item->advances[i]; - ++i; - ++j; - } - item->num_glyphs = j; - } - - } else { - HB_HeuristicPosition(item); - } -#endif // NO_OPENTYPE - item->attributes[0].clusterStart = true; - - HB_FREE_STACKARRAY(reordered); - HB_FREE_STACKARRAY(position); - - IDEBUG("<<<<<<"); - return true; - -error: - HB_FREE_STACKARRAY(reordered); - HB_FREE_STACKARRAY(position); - return false; -} - -/* syllables are of the form: - - (Consonant Nukta? Halant)* Consonant Matra? VowelMark? StressMark? - (Consonant Nukta? Halant)* Consonant Halant - IndependentVowel VowelMark? StressMark? - - We return syllable boundaries on invalid combinations aswell -*/ -static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int start, int end, bool *invalid) -{ - *invalid = false; - IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", start, end); - const HB_UChar16 *uc = s+start; - - int pos = 0; - Form state = form(uc[pos]); - IDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos]); - pos++; - - if (state != Consonant && state != IndependentVowel) { - if (state != Other) - *invalid = true; - goto finish; - } - - while (pos < end - start) { - Form newState = form(uc[pos]); - IDEBUG("state[%d]=%d (uc=%4x)", pos, newState, uc[pos]); - switch(newState) { - case Control: - newState = state; - if (state == Halant && uc[pos] == 0x200d /* ZWJ */) - break; - // the control character should be the last char in the item - ++pos; - goto finish; - case Consonant: - if (state == Halant && (script != HB_Script_Sinhala || uc[pos-1] == 0x200d /* ZWJ */)) - break; - goto finish; - case Halant: - if (state == Nukta || state == Consonant) - break; - // Bengali has a special exception allowing the combination Vowel_A/E + Halant + Ya - if (script == HB_Script_Bengali && pos == 1 && - (uc[0] == 0x0985 || uc[0] == 0x098f)) - break; - // Sinhala uses the Halant as a component of certain matras. Allow these, but keep the state on Matra. - if (script == HB_Script_Sinhala && state == Matra) { - ++pos; - continue; - } - if (script == HB_Script_Malayalam && state == Matra && uc[pos-1] == 0x0d41) { - ++pos; - continue; - } - goto finish; - case Nukta: - if (state == Consonant) - break; - goto finish; - case StressMark: - if (state == VowelMark) - break; - // fall through - case VowelMark: - if (state == Matra || state == LengthMark || state == IndependentVowel) - break; - // fall through - case Matra: - if (state == Consonant || state == Nukta) - break; - if (state == Matra) { - // ### needs proper testing for correct two/three part matras - break; - } - // ### not sure if this is correct. If it is, does it apply only to Bengali or should - // it work for all Indic languages? - // the combination Independent_A + Vowel Sign AA is allowed. - if (script == HB_Script_Bengali && uc[pos] == 0x9be && uc[pos-1] == 0x985) - break; - if (script == HB_Script_Tamil && state == Matra) { - if (uc[pos-1] == 0x0bc6 && - (uc[pos] == 0xbbe || uc[pos] == 0xbd7)) - break; - if (uc[pos-1] == 0x0bc7 && uc[pos] == 0xbbe) - break; - } - goto finish; - - case LengthMark: - if (state == Matra) { - // ### needs proper testing for correct two/three part matras - break; - } - case IndependentVowel: - case Invalid: - case Other: - goto finish; - } - state = newState; - pos++; - } - finish: - return pos+start; -} - -HB_Bool HB_IndicShape(HB_ShaperItem *item) -{ - assert(item->item.script >= HB_Script_Devanagari && item->item.script <= HB_Script_Sinhala); - - HB_Bool openType = false; -#ifndef NO_OPENTYPE - openType = HB_SelectScript(item, indic_features); -#endif - unsigned short *logClusters = item->log_clusters; - - HB_ShaperItem syllable = *item; - int first_glyph = 0; - - int sstart = item->item.pos; - int end = sstart + item->item.length; - IDEBUG("indic_shape: from %d length %d", item->item.pos, item->item.length); - while (sstart < end) { - bool invalid; - int send = indic_nextSyllableBoundary(item->item.script, item->string, sstart, end, &invalid); - IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, - invalid ? "true" : "false"); - syllable.item.pos = sstart; - syllable.item.length = send-sstart; - syllable.glyphs = item->glyphs + first_glyph; - syllable.attributes = item->attributes + first_glyph; - syllable.offsets = item->offsets + first_glyph; - syllable.advances = item->advances + first_glyph; - syllable.num_glyphs = item->num_glyphs - first_glyph; - if (!indic_shape_syllable(openType, &syllable, invalid)) { - IDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs); - item->num_glyphs += syllable.num_glyphs; - return false; - } - // fix logcluster array - IDEBUG("syllable:"); - hb_uint32 g; - for (g = first_glyph; g < first_glyph + syllable.num_glyphs; ++g) - IDEBUG(" %d -> glyph %x", g, item->glyphs[g]); - IDEBUG(" logclusters:"); - int i; - for (i = sstart; i < send; ++i) { - IDEBUG(" %d -> glyph %d", i, first_glyph); - logClusters[i-item->item.pos] = first_glyph; - } - sstart = send; - first_glyph += syllable.num_glyphs; - } - item->num_glyphs = first_glyph; - return true; -} diff --git a/src/hb-old/harfbuzz-khmer.c b/src/hb-old/harfbuzz-khmer.c deleted file mode 100644 index 150cbc1..0000000 --- a/src/hb-old/harfbuzz-khmer.c +++ /dev/null @@ -1,642 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" - -#include <assert.h> -#include <stdio.h> - -/* -// Vocabulary -// Base -> A consonant or an independent vowel in its full (not subscript) form. It is the -// center of the syllable, it can be surrounded by coeng (subscript) consonants, vowels, -// split vowels, signs... but there is only one base in a syllable, it has to be coded as -// the first character of the syllable. -// split vowel --> vowel that has two parts placed separately (e.g. Before and after the consonant). -// Khmer language has five of them. Khmer split vowels either have one part before the -// base and one after the base or they have a part before the base and a part above the base. -// The first part of all Khmer split vowels is the same character, identical to -// the glyph of Khmer dependent vowel SRA EI -// coeng --> modifier used in Khmer to construct coeng (subscript) consonants -// Differently than indian languages, the coeng modifies the consonant that follows it, -// not the one preceding it Each consonant has two forms, the base form and the subscript form -// the base form is the normal one (using the consonants code-point), the subscript form is -// displayed when the combination coeng + consonant is encountered. -// Consonant of type 1 -> A consonant which has subscript for that only occupies space under a base consonant -// Consonant of type 2.-> Its subscript form occupies space under and before the base (only one, RO) -// Consonant of Type 3 -> Its subscript form occupies space under and after the base (KHO, CHHO, THHO, BA, YO, SA) -// Consonant shifter -> Khmer has to series of consonants. The same dependent vowel has different sounds -// if it is attached to a consonant of the first series or a consonant of the second series -// Most consonants have an equivalent in the other series, but some of theme exist only in -// one series (for example SA). If we want to use the consonant SA with a vowel sound that -// can only be done with a vowel sound that corresponds to a vowel accompanying a consonant -// of the other series, then we need to use a consonant shifter: TRIISAP or MUSIKATOAN -// x17C9 y x17CA. TRIISAP changes a first series consonant to second series sound and -// MUSIKATOAN a second series consonant to have a first series vowel sound. -// Consonant shifter are both normally supercript marks, but, when they are followed by a -// superscript, they change shape and take the form of subscript dependent vowel SRA U. -// If they are in the same syllable as a coeng consonant, Unicode 3.0 says that they -// should be typed before the coeng. Unicode 4.0 breaks the standard and says that it should -// be placed after the coeng consonant. -// Dependent vowel -> In khmer dependent vowels can be placed above, below, before or after the base -// Each vowel has its own position. Only one vowel per syllable is allowed. -// Signs -> Khmer has above signs and post signs. Only one above sign and/or one post sign are -// Allowed in a syllable. -// -// -// order is important here! This order must be the same that is found in each horizontal -// line in the statetable for Khmer (see khmerStateTable) . -*/ -enum KhmerCharClassValues { - CC_RESERVED = 0, - CC_CONSONANT = 1, /* Consonant of type 1 or independent vowel */ - CC_CONSONANT2 = 2, /* Consonant of type 2 */ - CC_CONSONANT3 = 3, /* Consonant of type 3 */ - CC_ZERO_WIDTH_NJ_MARK = 4, /* Zero Width non joiner character (0x200C) */ - CC_CONSONANT_SHIFTER = 5, - CC_ROBAT = 6, /* Khmer special diacritic accent -treated differently in state table */ - CC_COENG = 7, /* Subscript consonant combining character */ - CC_DEPENDENT_VOWEL = 8, - CC_SIGN_ABOVE = 9, - CC_SIGN_AFTER = 10, - CC_ZERO_WIDTH_J_MARK = 11, /* Zero width joiner character */ - CC_COUNT = 12 /* This is the number of character classes */ -}; - - -enum KhmerCharClassFlags { - CF_CLASS_MASK = 0x0000FFFF, - - CF_CONSONANT = 0x01000000, /* flag to speed up comparing */ - CF_SPLIT_VOWEL = 0x02000000, /* flag for a split vowel -> the first part is added in front of the syllable */ - CF_DOTTED_CIRCLE = 0x04000000, /* add a dotted circle if a character with this flag is the first in a syllable */ - CF_COENG = 0x08000000, /* flag to speed up comparing */ - CF_SHIFTER = 0x10000000, /* flag to speed up comparing */ - CF_ABOVE_VOWEL = 0x20000000, /* flag to speed up comparing */ - - /* position flags */ - CF_POS_BEFORE = 0x00080000, - CF_POS_BELOW = 0x00040000, - CF_POS_ABOVE = 0x00020000, - CF_POS_AFTER = 0x00010000, - CF_POS_MASK = 0x000f0000 -}; - - -/* Characters that get referred to by name */ -enum KhmerChar { - C_SIGN_ZWNJ = 0x200C, - C_SIGN_ZWJ = 0x200D, - C_RO = 0x179A, - C_VOWEL_AA = 0x17B6, - C_SIGN_NIKAHIT = 0x17C6, - C_VOWEL_E = 0x17C1, - C_COENG = 0x17D2 -}; - - -/* -// simple classes, they are used in the statetable (in this file) to control the length of a syllable -// they are also used to know where a character should be placed (location in reference to the base character) -// and also to know if a character, when independently displayed, should be displayed with a dotted-circle to -// indicate error in syllable construction -*/ -enum { - _xx = CC_RESERVED, - _sa = CC_SIGN_ABOVE | CF_DOTTED_CIRCLE | CF_POS_ABOVE, - _sp = CC_SIGN_AFTER | CF_DOTTED_CIRCLE| CF_POS_AFTER, - _c1 = CC_CONSONANT | CF_CONSONANT, - _c2 = CC_CONSONANT2 | CF_CONSONANT, - _c3 = CC_CONSONANT3 | CF_CONSONANT, - _rb = CC_ROBAT | CF_POS_ABOVE | CF_DOTTED_CIRCLE, - _cs = CC_CONSONANT_SHIFTER | CF_DOTTED_CIRCLE | CF_SHIFTER, - _dl = CC_DEPENDENT_VOWEL | CF_POS_BEFORE | CF_DOTTED_CIRCLE, - _db = CC_DEPENDENT_VOWEL | CF_POS_BELOW | CF_DOTTED_CIRCLE, - _da = CC_DEPENDENT_VOWEL | CF_POS_ABOVE | CF_DOTTED_CIRCLE | CF_ABOVE_VOWEL, - _dr = CC_DEPENDENT_VOWEL | CF_POS_AFTER | CF_DOTTED_CIRCLE, - _co = CC_COENG | CF_COENG | CF_DOTTED_CIRCLE, - - /* split vowel */ - _va = _da | CF_SPLIT_VOWEL, - _vr = _dr | CF_SPLIT_VOWEL -}; - - -/* -// Character class: a character class value -// ORed with character class flags. -*/ -typedef unsigned long KhmerCharClass; - - -/* -// Character class tables -// _xx character does not combine into syllable, such as numbers, puntuation marks, non-Khmer signs... -// _sa Sign placed above the base -// _sp Sign placed after the base -// _c1 Consonant of type 1 or independent vowel (independent vowels behave as type 1 consonants) -// _c2 Consonant of type 2 (only RO) -// _c3 Consonant of type 3 -// _rb Khmer sign robat u17CC. combining mark for subscript consonants -// _cd Consonant-shifter -// _dl Dependent vowel placed before the base (left of the base) -// _db Dependent vowel placed below the base -// _da Dependent vowel placed above the base -// _dr Dependent vowel placed behind the base (right of the base) -// _co Khmer combining mark COENG u17D2, combines with the consonant or independent vowel following -// it to create a subscript consonant or independent vowel -// _va Khmer split vowel in which the first part is before the base and the second one above the base -// _vr Khmer split vowel in which the first part is before the base and the second one behind (right of) the base -*/ -static const KhmerCharClass khmerCharClasses[] = { - _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, /* 1780 - 178F */ - _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c2, _c1, _c1, _c1, _c3, _c3, /* 1790 - 179F */ - _c1, _c3, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, /* 17A0 - 17AF */ - _c1, _c1, _c1, _c1, _dr, _dr, _dr, _da, _da, _da, _da, _db, _db, _db, _va, _vr, /* 17B0 - 17BF */ - _vr, _dl, _dl, _dl, _vr, _vr, _sa, _sp, _sp, _cs, _cs, _sa, _rb, _sa, _sa, _sa, /* 17C0 - 17CF */ - _sa, _sa, _co, _sa, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _sa, _xx, _xx /* 17D0 - 17DF */ -}; - -/* this enum must reflect the range of khmerCharClasses */ -enum KhmerCharClassesRange { - KhmerFirstChar = 0x1780, - KhmerLastChar = 0x17df -}; - -/* -// Below we define how a character in the input string is either in the khmerCharClasses table -// (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear -// within the syllable, but are not in the table) we also get their type back, or an unknown object -// in which case we get _xx (CC_RESERVED) back -*/ -static KhmerCharClass getKhmerCharClass(HB_UChar16 uc) -{ - if (uc == C_SIGN_ZWJ) { - return CC_ZERO_WIDTH_J_MARK; - } - - if (uc == C_SIGN_ZWNJ) { - return CC_ZERO_WIDTH_NJ_MARK; - } - - if (uc < KhmerFirstChar || uc > KhmerLastChar) { - return CC_RESERVED; - } - - return khmerCharClasses[uc - KhmerFirstChar]; -} - - -/* -// The stateTable is used to calculate the end (the length) of a well -// formed Khmer Syllable. -// -// Each horizontal line is ordered exactly the same way as the values in KhmerClassTable -// CharClassValues. This coincidence of values allows the follow up of the table. -// -// Each line corresponds to a state, which does not necessarily need to be a type -// of component... for example, state 2 is a base, with is always a first character -// in the syllable, but the state could be produced a consonant of any type when -// it is the first character that is analysed (in ground state). -// -// Differentiating 3 types of consonants is necessary in order to -// forbid the use of certain combinations, such as having a second -// coeng after a coeng RO, -// The inexistent possibility of having a type 3 after another type 3 is permitted, -// eliminating it would very much complicate the table, and it does not create typing -// problems, as the case above. -// -// The table is quite complex, in order to limit the number of coeng consonants -// to 2 (by means of the table). -// -// There a peculiarity, as far as Unicode is concerned: -// - The consonant-shifter is considered in two possible different -// locations, the one considered in Unicode 3.0 and the one considered in -// Unicode 4.0. (there is a backwards compatibility problem in this standard). -// -// -// xx independent character, such as a number, punctuation sign or non-khmer char -// -// c1 Khmer consonant of type 1 or an independent vowel -// that is, a letter in which the subscript for is only under the -// base, not taking any space to the right or to the left -// -// c2 Khmer consonant of type 2, the coeng form takes space under -// and to the left of the base (only RO is of this type) -// -// c3 Khmer consonant of type 3. Its subscript form takes space under -// and to the right of the base. -// -// cs Khmer consonant shifter -// -// rb Khmer robat -// -// co coeng character (u17D2) -// -// dv dependent vowel (including split vowels, they are treated in the same way). -// even if dv is not defined above, the component that is really tested for is -// KhmerClassTable::CC_DEPENDENT_VOWEL, which is common to all dependent vowels -// -// zwj Zero Width joiner -// -// zwnj Zero width non joiner -// -// sa above sign -// -// sp post sign -// -// there are lines with equal content but for an easier understanding -// (and maybe change in the future) we did not join them -*/ -static const signed char khmerStateTable[][CC_COUNT] = -{ - /* xx c1 c2 c3 zwnj cs rb co dv sa sp zwj */ - { 1, 2, 2, 2, 1, 1, 1, 6, 1, 1, 1, 2}, /* 0 - ground state */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 1 - exit state (or sign to the right of the syllable) */ - {-1, -1, -1, -1, 3, 4, 5, 6, 16, 17, 1, -1}, /* 2 - Base consonant */ - {-1, -1, -1, -1, -1, 4, -1, -1, 16, -1, -1, -1}, /* 3 - First ZWNJ before a register shifter It can only be followed by a shifter or a vowel */ - {-1, -1, -1, -1, 15, -1, -1, 6, 16, 17, 1, 14}, /* 4 - First register shifter */ - {-1, -1, -1, -1, -1, -1, -1, -1, 20, -1, 1, -1}, /* 5 - Robat */ - {-1, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, /* 6 - First Coeng */ - {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 7 - First consonant of type 1 after coeng */ - {-1, -1, -1, -1, 12, 13, -1, -1, 16, 17, 1, 14}, /* 8 - First consonant of type 2 after coeng */ - {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 9 - First consonant or type 3 after ceong */ - {-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, /* 10 - Second Coeng (no register shifter before) */ - {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 11 - Second coeng consonant (or ind. vowel) no register shifter before */ - {-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, /* 12 - Second ZWNJ before a register shifter */ - {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 13 - Second register shifter */ - {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 14 - ZWJ before vowel */ - {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 15 - ZWNJ before vowel */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, /* 16 - dependent vowel */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, /* 17 - sign above */ - {-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, /* 18 - ZWJ after vowel */ - {-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19 - Third coeng */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, /* 20 - dependent vowel after a Robat */ -}; - - -/* #define KHMER_DEBUG */ -#ifdef KHMER_DEBUG -#define KHDEBUG qDebug -#else -#define KHDEBUG if(0) printf -#endif - -/* -// Given an input string of characters and a location in which to start looking -// calculate, using the state table, which one is the last character of the syllable -// that starts in the starting position. -*/ -static int khmer_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid) -{ - const HB_UChar16 *uc = s + start; - int state = 0; - int pos = start; - *invalid = FALSE; - - while (pos < end) { - KhmerCharClass charClass = getKhmerCharClass(*uc); - if (pos == start) { - *invalid = (charClass > 0) && ! (charClass & CF_CONSONANT); - } - state = khmerStateTable[state][charClass & CF_CLASS_MASK]; - - KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state, - charClass, *uc ); - - if (state < 0) { - break; - } - ++uc; - ++pos; - } - return pos; -} - -#ifndef NO_OPENTYPE -static const HB_OpenTypeFeature khmer_features[] = { - { HB_MAKE_TAG( 'p', 'r', 'e', 'f' ), PreFormProperty }, - { HB_MAKE_TAG( 'b', 'l', 'w', 'f' ), BelowFormProperty }, - { HB_MAKE_TAG( 'a', 'b', 'v', 'f' ), AboveFormProperty }, - { HB_MAKE_TAG( 'p', 's', 't', 'f' ), PostFormProperty }, - { HB_MAKE_TAG( 'p', 'r', 'e', 's' ), PreSubstProperty }, - { HB_MAKE_TAG( 'b', 'l', 'w', 's' ), BelowSubstProperty }, - { HB_MAKE_TAG( 'a', 'b', 'v', 's' ), AboveSubstProperty }, - { HB_MAKE_TAG( 'p', 's', 't', 's' ), PostSubstProperty }, - { HB_MAKE_TAG( 'c', 'l', 'i', 'g' ), CligProperty }, - { 0, 0 } -}; -#endif - - -static HB_Bool khmer_shape_syllable(HB_Bool openType, HB_ShaperItem *item) -{ -/* KHDEBUG("syllable from %d len %d, str='%s'", item->from, item->length, - item->string->mid(item->from, item->length).toUtf8().data()); */ - - int len = 0; - int syllableEnd = item->item.pos + item->item.length; - unsigned short reordered[16]; - unsigned char properties[16]; - enum { - AboveForm = 0x01, - PreForm = 0x02, - PostForm = 0x04, - BelowForm = 0x08 - }; -#ifndef NO_OPENTYPE - const int availableGlyphs = item->num_glyphs; -#endif - int coengRo; - int i; - - /* according to the specs this is the max length one can get - ### the real value should be smaller */ - assert(item->item.length < 13); - - memset(properties, 0, 16*sizeof(unsigned char)); - -#ifdef KHMER_DEBUG - qDebug("original:"); - for (int i = from; i < syllableEnd; i++) { - qDebug(" %d: %4x", i, string[i]); - } -#endif - - /* - // write a pre vowel or the pre part of a split vowel first - // and look out for coeng + ro. RO is the only vowel of type 2, and - // therefore the only one that requires saving space before the base. - */ - coengRo = -1; /* There is no Coeng Ro, if found this value will change */ - for (i = item->item.pos; i < syllableEnd; i += 1) { - KhmerCharClass charClass = getKhmerCharClass(item->string[i]); - - /* if a split vowel, write the pre part. In Khmer the pre part - is the same for all split vowels, same glyph as pre vowel C_VOWEL_E */ - if (charClass & CF_SPLIT_VOWEL) { - reordered[len] = C_VOWEL_E; - properties[len] = PreForm; - ++len; - break; /* there can be only one vowel */ - } - /* if a vowel with pos before write it out */ - if (charClass & CF_POS_BEFORE) { - reordered[len] = item->string[i]; - properties[len] = PreForm; - ++len; - break; /* there can be only one vowel */ - } - /* look for coeng + ro and remember position - works because coeng + ro is always in front of a vowel (if there is a vowel) - and because CC_CONSONANT2 is enough to identify it, as it is the only consonant - with this flag */ - if ( (charClass & CF_COENG) && (i + 1 < syllableEnd) && - ( (getKhmerCharClass(item->string[i+1]) & CF_CLASS_MASK) == CC_CONSONANT2) ) { - coengRo = i; - } - } - - /* write coeng + ro if found */ - if (coengRo > -1) { - reordered[len] = C_COENG; - properties[len] = PreForm; - ++len; - reordered[len] = C_RO; - properties[len] = PreForm; - ++len; - } - - /* - shall we add a dotted circle? - If in the position in which the base should be (first char in the string) there is - a character that has the Dotted circle flag (a character that cannot be a base) - then write a dotted circle */ - if (getKhmerCharClass(item->string[item->item.pos]) & CF_DOTTED_CIRCLE) { - reordered[len] = C_DOTTED_CIRCLE; - ++len; - } - - /* copy what is left to the output, skipping before vowels and - coeng Ro if they are present */ - for (i = item->item.pos; i < syllableEnd; i += 1) { - HB_UChar16 uc = item->string[i]; - KhmerCharClass charClass = getKhmerCharClass(uc); - - /* skip a before vowel, it was already processed */ - if (charClass & CF_POS_BEFORE) { - continue; - } - - /* skip coeng + ro, it was already processed */ - if (i == coengRo) { - i += 1; - continue; - } - - switch (charClass & CF_POS_MASK) - { - case CF_POS_ABOVE : - reordered[len] = uc; - properties[len] = AboveForm; - ++len; - break; - - case CF_POS_AFTER : - reordered[len] = uc; - properties[len] = PostForm; - ++len; - break; - - case CF_POS_BELOW : - reordered[len] = uc; - properties[len] = BelowForm; - ++len; - break; - - default: - /* assign the correct flags to a coeng consonant - Consonants of type 3 are taged as Post forms and those type 1 as below forms */ - if ( (charClass & CF_COENG) && i + 1 < syllableEnd ) { - unsigned char property = (getKhmerCharClass(item->string[i+1]) & CF_CLASS_MASK) == CC_CONSONANT3 ? - PostForm : BelowForm; - reordered[len] = uc; - properties[len] = property; - ++len; - i += 1; - reordered[len] = item->string[i]; - properties[len] = property; - ++len; - break; - } - - /* if a shifter is followed by an above vowel change the shifter to below form, - an above vowel can have two possible positions i + 1 or i + 3 - (position i+1 corresponds to unicode 3, position i+3 to Unicode 4) - and there is an extra rule for C_VOWEL_AA + C_SIGN_NIKAHIT also for two - different positions, right after the shifter or after a vowel (Unicode 4) */ - if ( (charClass & CF_SHIFTER) && (i + 1 < syllableEnd) ) { - if (getKhmerCharClass(item->string[i+1]) & CF_ABOVE_VOWEL ) { - reordered[len] = uc; - properties[len] = BelowForm; - ++len; - break; - } - if (i + 2 < syllableEnd && - (item->string[i+1] == C_VOWEL_AA) && - (item->string[i+2] == C_SIGN_NIKAHIT) ) - { - reordered[len] = uc; - properties[len] = BelowForm; - ++len; - break; - } - if (i + 3 < syllableEnd && (getKhmerCharClass(item->string[i+3]) & CF_ABOVE_VOWEL) ) { - reordered[len] = uc; - properties[len] = BelowForm; - ++len; - break; - } - if (i + 4 < syllableEnd && - (item->string[i+3] == C_VOWEL_AA) && - (item->string[i+4] == C_SIGN_NIKAHIT) ) - { - reordered[len] = uc; - properties[len] = BelowForm; - ++len; - break; - } - } - - /* default - any other characters */ - reordered[len] = uc; - ++len; - break; - } /* switch */ - } /* for */ - - if (!item->font->klass->convertStringToGlyphIndices(item->font, - reordered, len, - item->glyphs, &item->num_glyphs, - item->item.bidiLevel % 2)) - return FALSE; - - - KHDEBUG("after shaping: len=%d", len); - for (i = 0; i < len; i++) { - item->attributes[i].mark = FALSE; - item->attributes[i].clusterStart = FALSE; - item->attributes[i].justification = 0; - item->attributes[i].zeroWidth = FALSE; - KHDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]); - } - - /* now we have the syllable in the right order, and can start running it through open type. */ - -#ifndef NO_OPENTYPE - if (openType) { - hb_uint32 where[16]; - for (i = 0; i < len; ++i) { - where[i] = ~(PreSubstProperty - | BelowSubstProperty - | AboveSubstProperty - | PostSubstProperty - | CligProperty - | PositioningProperties); - if (properties[i] == PreForm) - where[i] &= ~PreFormProperty; - else if (properties[i] == BelowForm) - where[i] &= ~BelowFormProperty; - else if (properties[i] == AboveForm) - where[i] &= ~AboveFormProperty; - else if (properties[i] == PostForm) - where[i] &= ~PostFormProperty; - } - - HB_OpenTypeShape(item, where); - if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE)) - return FALSE; - } else -#endif - { - KHDEBUG("Not using openType"); - HB_HeuristicPosition(item); - } - - item->attributes[0].clusterStart = TRUE; - return TRUE; -} - -HB_Bool HB_KhmerShape(HB_ShaperItem *item) -{ - HB_Bool openType = FALSE; - unsigned short *logClusters = item->log_clusters; - int i; - - HB_ShaperItem syllable = *item; - int first_glyph = 0; - - int sstart = item->item.pos; - int end = sstart + item->item.length; - - assert(item->item.script == HB_Script_Khmer); - -#ifndef NO_OPENTYPE - openType = HB_SelectScript(item, khmer_features); -#endif - - KHDEBUG("khmer_shape: from %d length %d", item->item.pos, item->item.length); - while (sstart < end) { - HB_Bool invalid; - int send = khmer_nextSyllableBoundary(item->string, sstart, end, &invalid); - KHDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, - invalid ? "TRUE" : "FALSE"); - syllable.item.pos = sstart; - syllable.item.length = send-sstart; - syllable.glyphs = item->glyphs + first_glyph; - syllable.attributes = item->attributes + first_glyph; - syllable.offsets = item->offsets + first_glyph; - syllable.advances = item->advances + first_glyph; - syllable.num_glyphs = item->num_glyphs - first_glyph; - if (!khmer_shape_syllable(openType, &syllable)) { - KHDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs); - item->num_glyphs += syllable.num_glyphs; - return FALSE; - } - /* fix logcluster array */ - KHDEBUG("syllable:"); - for (i = first_glyph; i < first_glyph + (int)syllable.num_glyphs; ++i) - KHDEBUG(" %d -> glyph %x", i, item->glyphs[i]); - KHDEBUG(" logclusters:"); - for (i = sstart; i < send; ++i) { - KHDEBUG(" %d -> glyph %d", i, first_glyph); - logClusters[i-item->item.pos] = first_glyph; - } - sstart = send; - first_glyph += syllable.num_glyphs; - } - item->num_glyphs = first_glyph; - return TRUE; -} diff --git a/src/hb-old/harfbuzz-myanmar.c b/src/hb-old/harfbuzz-myanmar.c deleted file mode 100644 index 51ec14b..0000000 --- a/src/hb-old/harfbuzz-myanmar.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" - -#include <assert.h> -#include <stdio.h> - -enum MymrCharClassValues -{ - Mymr_CC_RESERVED = 0, - Mymr_CC_CONSONANT = 1, /* Consonant of type 1, that has subscript form */ - Mymr_CC_CONSONANT2 = 2, /* Consonant of type 2, that has no subscript form */ - Mymr_CC_NGA = 3, /* Consonant NGA */ - Mymr_CC_YA = 4, /* Consonant YA */ - Mymr_CC_RA = 5, /* Consonant RA */ - Mymr_CC_WA = 6, /* Consonant WA */ - Mymr_CC_HA = 7, /* Consonant HA */ - Mymr_CC_IND_VOWEL = 8, /* Independent vowel */ - Mymr_CC_ZERO_WIDTH_NJ_MARK = 9, /* Zero Width non joiner character (0x200C) */ - Mymr_CC_VIRAMA = 10, /* Subscript consonant combining character */ - Mymr_CC_PRE_VOWEL = 11, /* Dependent vowel, prebase (Vowel e) */ - Mymr_CC_BELOW_VOWEL = 12, /* Dependent vowel, prebase (Vowel u, uu) */ - Mymr_CC_ABOVE_VOWEL = 13, /* Dependent vowel, prebase (Vowel i, ii, ai) */ - Mymr_CC_POST_VOWEL = 14, /* Dependent vowel, prebase (Vowel aa) */ - Mymr_CC_SIGN_ABOVE = 15, - Mymr_CC_SIGN_BELOW = 16, - Mymr_CC_SIGN_AFTER = 17, - Mymr_CC_ZERO_WIDTH_J_MARK = 18, /* Zero width joiner character */ - Mymr_CC_COUNT = 19 /* This is the number of character classes */ -}; - -enum MymrCharClassFlags -{ - Mymr_CF_CLASS_MASK = 0x0000FFFF, - - Mymr_CF_CONSONANT = 0x01000000, /* flag to speed up comparing */ - Mymr_CF_MEDIAL = 0x02000000, /* flag to speed up comparing */ - Mymr_CF_IND_VOWEL = 0x04000000, /* flag to speed up comparing */ - Mymr_CF_DEP_VOWEL = 0x08000000, /* flag to speed up comparing */ - Mymr_CF_DOTTED_CIRCLE = 0x10000000, /* add a dotted circle if a character with this flag is the first in a syllable */ - Mymr_CF_VIRAMA = 0x20000000, /* flag to speed up comparing */ - - /* position flags */ - Mymr_CF_POS_BEFORE = 0x00080000, - Mymr_CF_POS_BELOW = 0x00040000, - Mymr_CF_POS_ABOVE = 0x00020000, - Mymr_CF_POS_AFTER = 0x00010000, - Mymr_CF_POS_MASK = 0x000f0000, - - Mymr_CF_AFTER_KINZI = 0x00100000 -}; - -/* Characters that get refrered to by name */ -enum MymrChar -{ - Mymr_C_SIGN_ZWNJ = 0x200C, - Mymr_C_SIGN_ZWJ = 0x200D, - Mymr_C_DOTTED_CIRCLE = 0x25CC, - Mymr_C_RA = 0x101B, - Mymr_C_YA = 0x101A, - Mymr_C_NGA = 0x1004, - Mymr_C_VOWEL_E = 0x1031, - Mymr_C_VIRAMA = 0x1039 -}; - -enum -{ - Mymr_xx = Mymr_CC_RESERVED, - Mymr_c1 = Mymr_CC_CONSONANT | Mymr_CF_CONSONANT | Mymr_CF_POS_BELOW, - Mymr_c2 = Mymr_CC_CONSONANT2 | Mymr_CF_CONSONANT, - Mymr_ng = Mymr_CC_NGA | Mymr_CF_CONSONANT | Mymr_CF_POS_ABOVE, - Mymr_ya = Mymr_CC_YA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_AFTER | Mymr_CF_AFTER_KINZI, - Mymr_ra = Mymr_CC_RA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BEFORE, - Mymr_wa = Mymr_CC_WA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW, - Mymr_ha = Mymr_CC_HA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW, - Mymr_id = Mymr_CC_IND_VOWEL | Mymr_CF_IND_VOWEL, - Mymr_vi = Mymr_CC_VIRAMA | Mymr_CF_VIRAMA | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE, - Mymr_dl = Mymr_CC_PRE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BEFORE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI, - Mymr_db = Mymr_CC_BELOW_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI, - Mymr_da = Mymr_CC_ABOVE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI, - Mymr_dr = Mymr_CC_POST_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI, - Mymr_sa = Mymr_CC_SIGN_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_ABOVE | Mymr_CF_AFTER_KINZI, - Mymr_sb = Mymr_CC_SIGN_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_BELOW | Mymr_CF_AFTER_KINZI, - Mymr_sp = Mymr_CC_SIGN_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI -}; - - -typedef int MymrCharClass; - - -static const MymrCharClass mymrCharClasses[] = -{ - Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_ng, Mymr_c1, Mymr_c1, Mymr_c1, - Mymr_c1, Mymr_c1, Mymr_c2, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, /* 1000 - 100F */ - Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, - Mymr_c1, Mymr_c1, Mymr_ya, Mymr_ra, Mymr_c1, Mymr_wa, Mymr_c1, Mymr_ha, /* 1010 - 101F */ - Mymr_c2, Mymr_c2, Mymr_xx, Mymr_id, Mymr_id, Mymr_id, Mymr_id, Mymr_id, - Mymr_xx, Mymr_id, Mymr_id, Mymr_xx, Mymr_dr, Mymr_da, Mymr_da, Mymr_db, /* 1020 - 102F */ - Mymr_db, Mymr_dl, Mymr_da, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_sa, Mymr_sb, - Mymr_sp, Mymr_vi, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1030 - 103F */ - Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, - Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1040 - 104F */ - Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, - Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1050 - 105F */ -}; - -static MymrCharClass -getMyanmarCharClass (HB_UChar16 ch) -{ - if (ch == Mymr_C_SIGN_ZWJ) - return Mymr_CC_ZERO_WIDTH_J_MARK; - - if (ch == Mymr_C_SIGN_ZWNJ) - return Mymr_CC_ZERO_WIDTH_NJ_MARK; - - if (ch < 0x1000 || ch > 0x105f) - return Mymr_CC_RESERVED; - - return mymrCharClasses[ch - 0x1000]; -} - -static const signed char mymrStateTable[][Mymr_CC_COUNT] = -{ -/* xx c1, c2 ng ya ra wa ha id zwnj vi dl db da dr sa sb sp zwj */ - { 1, 4, 4, 2, 4, 4, 4, 4, 24, 1, 27, 17, 18, 19, 20, 21, 1, 1, 4}, /* 0 - ground state */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 1 - exit state (or sp to the right of the syllable) */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 17, 18, 19, 20, 21, -1, -1, 4}, /* 2 - NGA */ - {-1, 4, 4, 4, 4, 4, 4, 4, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 3 - Virama after NGA */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 17, 18, 19, 20, 21, 1, 1, -1}, /* 4 - Base consonant */ - {-2, 6, -2, -2, 7, 8, 9, 10, -2, 23, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 5 - First virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 17, 18, 19, 20, 21, -1, -1, -1}, /* 6 - c1 after virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /* 7 - ya after virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /* 8 - ra after virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /* 9 - wa after virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 10 - ha after virama */ - {-1, -1, -1, -1, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 11 - Virama after NGA+zwj */ - {-2, -2, -2, -2, -2, -2, 13, 14, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 12 - Second virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 18, 19, 20, 21, -1, -1, -1}, /* 13 - wa after virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 14 - ha after virama */ - {-2, -2, -2, -2, -2, -2, -2, 16, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 15 - Third virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 16 - ha after virama */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 21, 1, 1, -1}, /* 17 - dl, Dependent vowel e */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, 21, 1, 1, -1}, /* 18 - db, Dependent vowel u,uu */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1}, /* 19 - da, Dependent vowel i,ii,ai */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, 1, 1, -1}, /* 20 - dr, Dependent vowel aa */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1}, /* 21 - sa, Sign anusvara */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 22 - atha */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1}, /* 23 - zwnj for atha */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, /* 24 - Independent vowel */ - {-2, -2, -2, -2, 26, 26, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 25 - Virama after subscript consonant */ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, 1, -1}, /* 26 - ra/ya after subscript consonant + virama */ - {-1, 6, -1, -1, 7, 8, 9, 10, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 - Virama after ground state */ -/* exit state -2 is for invalid order of medials and combination of invalids - with virama where virama should treat as start of next syllable - */ -}; - - - -/*#define MYANMAR_DEBUG */ -#ifdef MYANMAR_DEBUG -#define MMDEBUG qDebug -#else -#define MMDEBUG if(0) printf -#endif - -/* -// Given an input string of characters and a location in which to start looking -// calculate, using the state table, which one is the last character of the syllable -// that starts in the starting position. -*/ -static int myanmar_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid) -{ - const HB_UChar16 *uc = s + start; - int state = 0; - int pos = start; - *invalid = FALSE; - - while (pos < end) { - MymrCharClass charClass = getMyanmarCharClass(*uc); - state = mymrStateTable[state][charClass & Mymr_CF_CLASS_MASK]; - if (pos == start) - *invalid = (HB_Bool)(charClass & Mymr_CF_DOTTED_CIRCLE); - - MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", pos - start, state, charClass, *uc); - - if (state < 0) { - if (state < -1) - --pos; - break; - } - ++uc; - ++pos; - } - return pos; -} - -#ifndef NO_OPENTYPE -/* ###### might have to change order of above and below forms and substitutions, - but according to Unicode below comes before above */ -static const HB_OpenTypeFeature myanmar_features[] = { - { HB_MAKE_TAG('p', 'r', 'e', 'f'), PreFormProperty }, - { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty }, - { HB_MAKE_TAG('a', 'b', 'v', 'f'), AboveFormProperty }, - { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty }, - { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty }, - { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty }, - { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty }, - { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty }, - { HB_MAKE_TAG('r', 'l', 'i', 'g'), CligProperty }, /* Myanmar1 uses this instead of the other features */ - { 0, 0 } -}; -#endif - - -/* -// Visual order before shaping should be: -// -// [Vowel Mark E] -// [Virama + Medial Ra] -// [Base] -// [Virama + Consonant] -// [Nga + Virama] (Kinzi) ### should probably come before post forms (medial ya) -// [Vowels] -// [Marks] -// -// This means that we can keep the logical order apart from having to -// move the pre vowel, medial ra and kinzi -*/ - -static HB_Bool myanmar_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid) -{ - /* -// MMDEBUG("\nsyllable from %d len %d, str='%s'", item->item.pos, item->item.length, -// item->string->mid(item->from, item->length).toUtf8().data()); - */ - -#ifndef NO_OPENTYPE - const int availableGlyphs = item->num_glyphs; -#endif - const HB_UChar16 *uc = item->string + item->item.pos; - int vowel_e = -1; - int kinzi = -1; - int medial_ra = -1; - int base = -1; - int i; - int len = 0; - unsigned short reordered[32]; - unsigned char properties[32]; - enum { - AboveForm = 0x01, - PreForm = 0x02, - PostForm = 0x04, - BelowForm = 0x08 - }; - HB_Bool lastWasVirama = FALSE; - int basePos = -1; - - memset(properties, 0, 32*sizeof(unsigned char)); - - /* according to the table the max length of a syllable should be around 14 chars */ - assert(item->item.length < 32); - -#ifdef MYANMAR_DEBUG - printf("original:"); - for (i = 0; i < (int)item->item.length; i++) { - printf(" %d: %4x", i, uc[i]); - } -#endif - for (i = 0; i < (int)item->item.length; ++i) { - HB_UChar16 chr = uc[i]; - - if (chr == Mymr_C_VOWEL_E) { - vowel_e = i; - continue; - } - if (i == 0 - && chr == Mymr_C_NGA - && i + 2 < (int)item->item.length - && uc[i+1] == Mymr_C_VIRAMA) { - int mc = getMyanmarCharClass(uc[i+2]); - /*MMDEBUG("maybe kinzi: mc=%x", mc);*/ - if ((mc & Mymr_CF_CONSONANT) == Mymr_CF_CONSONANT) { - kinzi = i; - continue; - } - } - if (base >= 0 - && chr == Mymr_C_VIRAMA - && i + 1 < (int)item->item.length - && uc[i+1] == Mymr_C_RA) { - medial_ra = i; - continue; - } - if (base < 0) - base = i; - } - - MMDEBUG("\n base=%d, vowel_e=%d, kinzi=%d, medial_ra=%d", base, vowel_e, kinzi, medial_ra); - /* write vowel_e if found */ - if (vowel_e >= 0) { - reordered[0] = Mymr_C_VOWEL_E; - len = 1; - } - /* write medial_ra */ - if (medial_ra >= 0) { - reordered[len] = Mymr_C_VIRAMA; - reordered[len+1] = Mymr_C_RA; - properties[len] = PreForm; - properties[len+1] = PreForm; - len += 2; - } - - /* shall we add a dotted circle? - If in the position in which the base should be (first char in the string) there is - a character that has the Dotted circle flag (a character that cannot be a base) - then write a dotted circle */ - if (invalid) { - reordered[len] = C_DOTTED_CIRCLE; - ++len; - } - - /* copy the rest of the syllable to the output, inserting the kinzi - at the correct place */ - for (i = 0; i < (int)item->item.length; ++i) { - hb_uint16 chr = uc[i]; - MymrCharClass cc; - if (i == vowel_e) - continue; - if (i == medial_ra || i == kinzi) { - ++i; - continue; - } - - cc = getMyanmarCharClass(uc[i]); - if (kinzi >= 0 && i > base && (cc & Mymr_CF_AFTER_KINZI)) { - reordered[len] = Mymr_C_NGA; - reordered[len+1] = Mymr_C_VIRAMA; - if (len > 0) - properties[len-1] = AboveForm; - properties[len] = AboveForm; - len += 2; - kinzi = -1; - } - - if (lastWasVirama) { - int prop = 0; - switch(cc & Mymr_CF_POS_MASK) { - case Mymr_CF_POS_BEFORE: - prop = PreForm; - break; - case Mymr_CF_POS_BELOW: - prop = BelowForm; - break; - case Mymr_CF_POS_ABOVE: - prop = AboveForm; - break; - case Mymr_CF_POS_AFTER: - prop = PostForm; - break; - default: - break; - } - properties[len-1] = prop; - properties[len] = prop; - if(basePos >= 0 && basePos == len-2) - properties[len-2] = prop; - } - lastWasVirama = (chr == Mymr_C_VIRAMA); - if(i == base) - basePos = len; - - if ((chr != Mymr_C_SIGN_ZWNJ && chr != Mymr_C_SIGN_ZWJ) || !len) { - reordered[len] = chr; - ++len; - } - } - if (kinzi >= 0) { - reordered[len] = Mymr_C_NGA; - reordered[len+1] = Mymr_C_VIRAMA; - properties[len] = AboveForm; - properties[len+1] = AboveForm; - len += 2; - } - - if (!item->font->klass->convertStringToGlyphIndices(item->font, - reordered, len, - item->glyphs, &item->num_glyphs, - item->item.bidiLevel % 2)) - return FALSE; - - MMDEBUG("after shaping: len=%d", len); - for (i = 0; i < len; i++) { - item->attributes[i].mark = FALSE; - item->attributes[i].clusterStart = FALSE; - item->attributes[i].justification = 0; - item->attributes[i].zeroWidth = FALSE; - MMDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]); - } - - /* now we have the syllable in the right order, and can start running it through open type. */ - -#ifndef NO_OPENTYPE - if (openType) { - hb_uint32 where[32]; - - for (i = 0; i < len; ++i) { - where[i] = ~(PreSubstProperty - | BelowSubstProperty - | AboveSubstProperty - | PostSubstProperty - | CligProperty - | PositioningProperties); - if (properties[i] & PreForm) - where[i] &= ~PreFormProperty; - if (properties[i] & BelowForm) - where[i] &= ~BelowFormProperty; - if (properties[i] & AboveForm) - where[i] &= ~AboveFormProperty; - if (properties[i] & PostForm) - where[i] &= ~PostFormProperty; - } - - HB_OpenTypeShape(item, where); - if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE)) - return FALSE; - } else -#endif - { - MMDEBUG("Not using openType"); - HB_HeuristicPosition(item); - } - - item->attributes[0].clusterStart = TRUE; - return TRUE; -} - -HB_Bool HB_MyanmarShape(HB_ShaperItem *item) -{ - HB_Bool openType = FALSE; - unsigned short *logClusters = item->log_clusters; - - HB_ShaperItem syllable = *item; - int first_glyph = 0; - - int sstart = item->item.pos; - int end = sstart + item->item.length; - int i = 0; - - assert(item->item.script == HB_Script_Myanmar); -#ifndef NO_OPENTYPE - openType = HB_SelectScript(item, myanmar_features); -#endif - - MMDEBUG("myanmar_shape: from %d length %d", item->item.pos, item->item.length); - while (sstart < end) { - HB_Bool invalid; - int send = myanmar_nextSyllableBoundary(item->string, sstart, end, &invalid); - MMDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, - invalid ? "TRUE" : "FALSE"); - syllable.item.pos = sstart; - syllable.item.length = send-sstart; - syllable.glyphs = item->glyphs + first_glyph; - syllable.attributes = item->attributes + first_glyph; - syllable.advances = item->advances + first_glyph; - syllable.offsets = item->offsets + first_glyph; - syllable.num_glyphs = item->num_glyphs - first_glyph; - if (!myanmar_shape_syllable(openType, &syllable, invalid)) { - MMDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs); - item->num_glyphs += syllable.num_glyphs; - return FALSE; - } - - /* fix logcluster array */ - MMDEBUG("syllable:"); - for (i = first_glyph; i < first_glyph + (int)syllable.num_glyphs; ++i) - MMDEBUG(" %d -> glyph %x", i, item->glyphs[i]); - MMDEBUG(" logclusters:"); - for (i = sstart; i < send; ++i) { - MMDEBUG(" %d -> glyph %d", i, first_glyph); - logClusters[i-item->item.pos] = first_glyph; - } - sstart = send; - first_glyph += syllable.num_glyphs; - } - item->num_glyphs = first_glyph; - return TRUE; -} diff --git a/src/hb-old/harfbuzz-open-private.h b/src/hb-old/harfbuzz-open-private.h deleted file mode 100644 index f1ca278..0000000 --- a/src/hb-old/harfbuzz-open-private.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_OPEN_PRIVATE_H -#define HARFBUZZ_OPEN_PRIVATE_H - -#include "harfbuzz-impl.h" -#include "harfbuzz-open.h" -#include "harfbuzz-gsub-private.h" -#include "harfbuzz-gpos-private.h" - -HB_BEGIN_HEADER - - -struct HB_SubTable_ -{ - union - { - HB_GSUB_SubTable gsub; - HB_GPOS_SubTable gpos; - } st; -}; - - -HB_INTERNAL HB_Error -_HB_OPEN_Load_ScriptList( HB_ScriptList* sl, - HB_Stream input ); -HB_INTERNAL HB_Error -_HB_OPEN_Load_FeatureList( HB_FeatureList* fl, - HB_Stream input ); -HB_INTERNAL HB_Error -_HB_OPEN_Load_LookupList( HB_LookupList* ll, - HB_Stream input, - HB_Type type ); - -HB_INTERNAL HB_Error -_HB_OPEN_Load_Coverage( HB_Coverage* c, - HB_Stream input ); -HB_INTERNAL HB_Error -_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd, - HB_UShort limit, - HB_Stream input ); -HB_INTERNAL HB_Error -_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd, - HB_UShort limit, - HB_UInt class_offset, - HB_UInt base_offset, - HB_Stream input ); -HB_INTERNAL HB_Error -_HB_OPEN_Load_Device( HB_Device** d, - HB_Stream input ); - -HB_INTERNAL void _HB_OPEN_Free_ScriptList( HB_ScriptList* sl ); -HB_INTERNAL void _HB_OPEN_Free_FeatureList( HB_FeatureList* fl ); -HB_INTERNAL void _HB_OPEN_Free_LookupList( HB_LookupList* ll, - HB_Type type ); - -HB_INTERNAL void _HB_OPEN_Free_Coverage( HB_Coverage* c ); -HB_INTERNAL void _HB_OPEN_Free_ClassDefinition( HB_ClassDefinition* cd ); -HB_INTERNAL void _HB_OPEN_Free_Device( HB_Device* d ); - - - -HB_INTERNAL HB_Error -_HB_OPEN_Coverage_Index( HB_Coverage* c, - HB_UShort glyphID, - HB_UShort* index ); -HB_INTERNAL HB_Error -_HB_OPEN_Get_Class( HB_ClassDefinition* cd, - HB_UShort glyphID, - HB_UShort* klass, - HB_UShort* index ); -HB_INTERNAL HB_Error -_HB_OPEN_Get_Device( HB_Device* d, - HB_UShort size, - HB_Short* value ); - -HB_END_HEADER - -#endif /* HARFBUZZ_OPEN_PRIVATE_H */ diff --git a/src/hb-old/harfbuzz-open.c b/src/hb-old/harfbuzz-open.c deleted file mode 100644 index f12f5b7..0000000 --- a/src/hb-old/harfbuzz-open.c +++ /dev/null @@ -1,1433 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-impl.h" -#include "harfbuzz-open-private.h" - - -/*************************** - * Script related functions - ***************************/ - - -/* LangSys */ - -static HB_Error Load_LangSys( HB_LangSys* ls, - HB_Stream stream ) -{ - HB_Error error; - HB_UShort n, count; - HB_UShort* fi; - - - if ( ACCESS_Frame( 6L ) ) - return error; - - ls->LookupOrderOffset = GET_UShort(); /* should be 0 */ - ls->ReqFeatureIndex = GET_UShort(); - count = ls->FeatureCount = GET_UShort(); - - FORGET_Frame(); - - ls->FeatureIndex = NULL; - - if ( ALLOC_ARRAY( ls->FeatureIndex, count, HB_UShort ) ) - return error; - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( ls->FeatureIndex ); - return error; - } - - fi = ls->FeatureIndex; - - for ( n = 0; n < count; n++ ) - fi[n] = GET_UShort(); - - FORGET_Frame(); - - return HB_Err_Ok; -} - - -static void Free_LangSys( HB_LangSys* ls ) -{ - FREE( ls->FeatureIndex ); -} - - -/* Script */ - -static HB_Error Load_Script( HB_ScriptTable* s, - HB_Stream stream ) -{ - HB_Error error; - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_LangSysRecord* lsr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - if ( new_offset != base_offset ) /* not a NULL offset */ - { - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_LangSys( &s->DefaultLangSys, - stream ) ) != HB_Err_Ok ) - return error; - (void)FILE_Seek( cur_offset ); - } - else - { - /* we create a DefaultLangSys table with no entries */ - - s->DefaultLangSys.LookupOrderOffset = 0; - s->DefaultLangSys.ReqFeatureIndex = 0xFFFF; - s->DefaultLangSys.FeatureCount = 0; - s->DefaultLangSys.FeatureIndex = NULL; - } - - if ( ACCESS_Frame( 2L ) ) - goto Fail2; - - count = s->LangSysCount = GET_UShort(); - - /* safety check; otherwise the official handling of TrueType Open - fonts won't work */ - - if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 ) - { - error = HB_Err_Not_Covered; - goto Fail2; - } - - FORGET_Frame(); - - s->LangSysRecord = NULL; - - if ( ALLOC_ARRAY( s->LangSysRecord, count, HB_LangSysRecord ) ) - goto Fail2; - - lsr = s->LangSysRecord; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 6L ) ) - goto Fail1; - - lsr[n].LangSysTag = GET_ULong(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_LangSys( &lsr[m].LangSys ); - - FREE( s->LangSysRecord ); - -Fail2: - Free_LangSys( &s->DefaultLangSys ); - return error; -} - - -static void Free_Script( HB_ScriptTable* s ) -{ - HB_UShort n, count; - - HB_LangSysRecord* lsr; - - - Free_LangSys( &s->DefaultLangSys ); - - if ( s->LangSysRecord ) - { - count = s->LangSysCount; - lsr = s->LangSysRecord; - - for ( n = 0; n < count; n++ ) - Free_LangSys( &lsr[n].LangSys ); - - FREE( lsr ); - } -} - - -/* ScriptList */ - -HB_INTERNAL HB_Error -_HB_OPEN_Load_ScriptList( HB_ScriptList* sl, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, script_count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_ScriptRecord* sr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - script_count = GET_UShort(); - - FORGET_Frame(); - - sl->ScriptRecord = NULL; - - if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, HB_ScriptRecord ) ) - return error; - - sr = sl->ScriptRecord; - - sl->ScriptCount= 0; - for ( n = 0; n < script_count; n++ ) - { - if ( ACCESS_Frame( 6L ) ) - goto Fail; - - sr[sl->ScriptCount].ScriptTag = GET_ULong(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - - if ( FILE_Seek( new_offset ) ) - goto Fail; - - error = Load_Script( &sr[sl->ScriptCount].Script, stream ); - if ( error == HB_Err_Ok ) - sl->ScriptCount += 1; - else if ( error != HB_Err_Not_Covered ) - goto Fail; - - (void)FILE_Seek( cur_offset ); - } - - /* Empty tables are harmless and generated by fontforge. - * See http://bugzilla.gnome.org/show_bug.cgi?id=347073 - */ -#if 0 - if ( sl->ScriptCount == 0 ) - { - error = ERR(HB_Err_Invalid_SubTable); - goto Fail; - } -#endif - - return HB_Err_Ok; - -Fail: - for ( n = 0; n < sl->ScriptCount; n++ ) - Free_Script( &sr[n].Script ); - - FREE( sl->ScriptRecord ); - return error; -} - - -HB_INTERNAL void -_HB_OPEN_Free_ScriptList( HB_ScriptList* sl ) -{ - HB_UShort n, count; - - HB_ScriptRecord* sr; - - - if ( sl->ScriptRecord ) - { - count = sl->ScriptCount; - sr = sl->ScriptRecord; - - for ( n = 0; n < count; n++ ) - Free_Script( &sr[n].Script ); - - FREE( sr ); - } -} - - - -/********************************* - * Feature List related functions - *********************************/ - - -/* Feature */ - -static HB_Error Load_Feature( HB_Feature* f, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_UShort* lli; - - - if ( ACCESS_Frame( 4L ) ) - return error; - - f->FeatureParams = GET_UShort(); /* should be 0 */ - count = f->LookupListCount = GET_UShort(); - - FORGET_Frame(); - - f->LookupListIndex = NULL; - - if ( ALLOC_ARRAY( f->LookupListIndex, count, HB_UShort ) ) - return error; - - lli = f->LookupListIndex; - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( f->LookupListIndex ); - return error; - } - - for ( n = 0; n < count; n++ ) - lli[n] = GET_UShort(); - - FORGET_Frame(); - - return HB_Err_Ok; -} - - -static void Free_Feature( HB_Feature* f ) -{ - FREE( f->LookupListIndex ); -} - - -/* FeatureList */ - -HB_INTERNAL HB_Error -_HB_OPEN_Load_FeatureList( HB_FeatureList* fl, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_FeatureRecord* fr; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = fl->FeatureCount = GET_UShort(); - - FORGET_Frame(); - - fl->FeatureRecord = NULL; - - if ( ALLOC_ARRAY( fl->FeatureRecord, count, HB_FeatureRecord ) ) - return error; - if ( ALLOC_ARRAY( fl->ApplyOrder, count, HB_UShort ) ) - goto Fail2; - - fl->ApplyCount = 0; - - fr = fl->FeatureRecord; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 6L ) ) - goto Fail1; - - fr[n].FeatureTag = GET_ULong(); - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Feature( &fr[n].Feature, stream ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - for ( m = 0; m < n; m++ ) - Free_Feature( &fr[m].Feature ); - - FREE( fl->ApplyOrder ); - -Fail2: - FREE( fl->FeatureRecord ); - - return error; -} - - -HB_INTERNAL void -_HB_OPEN_Free_FeatureList( HB_FeatureList* fl ) -{ - HB_UShort n, count; - - HB_FeatureRecord* fr; - - - if ( fl->FeatureRecord ) - { - count = fl->FeatureCount; - fr = fl->FeatureRecord; - - for ( n = 0; n < count; n++ ) - Free_Feature( &fr[n].Feature ); - - FREE( fr ); - } - - FREE( fl->ApplyOrder ); -} - - - -/******************************** - * Lookup List related functions - ********************************/ - -/* the subroutines of the following two functions are defined in - ftxgsub.c and ftxgpos.c respectively */ - - -/* SubTable */ - -static HB_Error Load_SubTable( HB_SubTable* st, - HB_Stream stream, - HB_Type table_type, - HB_UShort lookup_type ) -{ - if ( table_type == HB_Type_GSUB ) - return _HB_GSUB_Load_SubTable ( &st->st.gsub, stream, lookup_type ); - else - return _HB_GPOS_Load_SubTable ( &st->st.gpos, stream, lookup_type ); -} - - -static void Free_SubTable( HB_SubTable* st, - HB_Type table_type, - HB_UShort lookup_type ) -{ - if ( table_type == HB_Type_GSUB ) - _HB_GSUB_Free_SubTable ( &st->st.gsub, lookup_type ); - else - _HB_GPOS_Free_SubTable ( &st->st.gpos, lookup_type ); -} - - -/* Lookup */ - -static HB_Error Load_Lookup( HB_Lookup* l, - HB_Stream stream, - HB_Type type ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_SubTable* st; - - HB_Bool is_extension = FALSE; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 6L ) ) - return error; - - l->LookupType = GET_UShort(); - l->LookupFlag = GET_UShort(); - count = l->SubTableCount = GET_UShort(); - - FORGET_Frame(); - - l->SubTable = NULL; - - if ( ALLOC_ARRAY( l->SubTable, count, HB_SubTable ) ) - return error; - - st = l->SubTable; - - if ( ( type == HB_Type_GSUB && l->LookupType == HB_GSUB_LOOKUP_EXTENSION ) || - ( type == HB_Type_GPOS && l->LookupType == HB_GPOS_LOOKUP_EXTENSION ) ) - is_extension = TRUE; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - - if ( is_extension ) - { - if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) ) - goto Fail; - - if (GET_UShort() != 1) /* format should be 1 */ - goto Fail; - - l->LookupType = GET_UShort(); - new_offset += GET_ULong(); - - FORGET_Frame(); - } - - if ( FILE_Seek( new_offset ) || - ( error = Load_SubTable( &st[n], stream, - type, l->LookupType ) ) != HB_Err_Ok ) - goto Fail; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail: - for ( m = 0; m < n; m++ ) - Free_SubTable( &st[m], type, l->LookupType ); - - FREE( l->SubTable ); - return error; -} - - -static void Free_Lookup( HB_Lookup* l, - HB_Type type) -{ - HB_UShort n, count; - - HB_SubTable* st; - - - if ( l->SubTable ) - { - count = l->SubTableCount; - st = l->SubTable; - - for ( n = 0; n < count; n++ ) - Free_SubTable( &st[n], type, l->LookupType ); - - FREE( st ); - } -} - - -/* LookupList */ - -HB_INTERNAL HB_Error -_HB_OPEN_Load_LookupList( HB_LookupList* ll, - HB_Stream stream, - HB_Type type ) -{ - HB_Error error; - - HB_UShort n, m, count; - HB_UInt cur_offset, new_offset, base_offset; - - HB_Lookup* l; - - - base_offset = FILE_Pos(); - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = ll->LookupCount = GET_UShort(); - - FORGET_Frame(); - - ll->Lookup = NULL; - - if ( ALLOC_ARRAY( ll->Lookup, count, HB_Lookup ) ) - return error; - if ( ALLOC_ARRAY( ll->Properties, count, HB_UInt ) ) - goto Fail2; - - l = ll->Lookup; - - for ( n = 0; n < count; n++ ) - { - if ( ACCESS_Frame( 2L ) ) - goto Fail1; - - new_offset = GET_UShort() + base_offset; - - FORGET_Frame(); - - cur_offset = FILE_Pos(); - if ( FILE_Seek( new_offset ) || - ( error = Load_Lookup( &l[n], stream, type ) ) != HB_Err_Ok ) - goto Fail1; - (void)FILE_Seek( cur_offset ); - } - - return HB_Err_Ok; - -Fail1: - FREE( ll->Properties ); - - for ( m = 0; m < n; m++ ) - Free_Lookup( &l[m], type ); - -Fail2: - FREE( ll->Lookup ); - return error; -} - - -HB_INTERNAL void -_HB_OPEN_Free_LookupList( HB_LookupList* ll, - HB_Type type ) -{ - HB_UShort n, count; - - HB_Lookup* l; - - - FREE( ll->Properties ); - - if ( ll->Lookup ) - { - count = ll->LookupCount; - l = ll->Lookup; - - for ( n = 0; n < count; n++ ) - Free_Lookup( &l[n], type ); - - FREE( l ); - } -} - - - -/***************************** - * Coverage related functions - *****************************/ - - -/* CoverageFormat1 */ - -static HB_Error Load_Coverage1( HB_CoverageFormat1* cf1, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_UShort* ga; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = cf1->GlyphCount = GET_UShort(); - - FORGET_Frame(); - - cf1->GlyphArray = NULL; - - if ( ALLOC_ARRAY( cf1->GlyphArray, count, HB_UShort ) ) - return error; - - ga = cf1->GlyphArray; - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( cf1->GlyphArray ); - return error; - } - - for ( n = 0; n < count; n++ ) - ga[n] = GET_UShort(); - - FORGET_Frame(); - - return HB_Err_Ok; -} - - -static void Free_Coverage1( HB_CoverageFormat1* cf1) -{ - FREE( cf1->GlyphArray ); -} - - -/* CoverageFormat2 */ - -static HB_Error Load_Coverage2( HB_CoverageFormat2* cf2, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_RangeRecord* rr; - - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = cf2->RangeCount = GET_UShort(); - - FORGET_Frame(); - - cf2->RangeRecord = NULL; - - if ( ALLOC_ARRAY( cf2->RangeRecord, count, HB_RangeRecord ) ) - return error; - - rr = cf2->RangeRecord; - - if ( ACCESS_Frame( count * 6L ) ) - goto Fail; - - for ( n = 0; n < count; n++ ) - { - rr[n].Start = GET_UShort(); - rr[n].End = GET_UShort(); - rr[n].StartCoverageIndex = GET_UShort(); - - /* sanity check; we are limited to 16bit integers */ - if ( rr[n].Start > rr[n].End || - ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >= - 0x10000L ) - { - error = ERR(HB_Err_Invalid_SubTable); - goto Fail; - } - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail: - FREE( cf2->RangeRecord ); - return error; -} - - -static void Free_Coverage2( HB_CoverageFormat2* cf2 ) -{ - FREE( cf2->RangeRecord ); -} - - -HB_INTERNAL HB_Error -_HB_OPEN_Load_Coverage( HB_Coverage* c, - HB_Stream stream ) -{ - HB_Error error; - - if ( ACCESS_Frame( 2L ) ) - return error; - - c->CoverageFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( c->CoverageFormat ) - { - case 1: return Load_Coverage1( &c->cf.cf1, stream ); - case 2: return Load_Coverage2( &c->cf.cf2, stream ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - -HB_INTERNAL void -_HB_OPEN_Free_Coverage( HB_Coverage* c ) -{ - switch ( c->CoverageFormat ) - { - case 1: Free_Coverage1( &c->cf.cf1 ); break; - case 2: Free_Coverage2( &c->cf.cf2 ); break; - default: break; - } -} - - -static HB_Error Coverage_Index1( HB_CoverageFormat1* cf1, - HB_UShort glyphID, - HB_UShort* index ) -{ - HB_UShort min, max, new_min, new_max, middle; - - HB_UShort* array = cf1->GlyphArray; - - - /* binary search */ - - if ( cf1->GlyphCount == 0 ) - return HB_Err_Not_Covered; - - new_min = 0; - new_max = cf1->GlyphCount - 1; - - do - { - min = new_min; - max = new_max; - - /* we use (min + max) / 2 = max - (max - min) / 2 to avoid - overflow and rounding errors */ - - middle = max - ( ( max - min ) >> 1 ); - - if ( glyphID == array[middle] ) - { - *index = middle; - return HB_Err_Ok; - } - else if ( glyphID < array[middle] ) - { - if ( middle == min ) - break; - new_max = middle - 1; - } - else - { - if ( middle == max ) - break; - new_min = middle + 1; - } - } while ( min < max ); - - return HB_Err_Not_Covered; -} - - -static HB_Error Coverage_Index2( HB_CoverageFormat2* cf2, - HB_UShort glyphID, - HB_UShort* index ) -{ - HB_UShort min, max, new_min, new_max, middle; - - HB_RangeRecord* rr = cf2->RangeRecord; - - - /* binary search */ - - if ( cf2->RangeCount == 0 ) - return HB_Err_Not_Covered; - - new_min = 0; - new_max = cf2->RangeCount - 1; - - do - { - min = new_min; - max = new_max; - - /* we use (min + max) / 2 = max - (max - min) / 2 to avoid - overflow and rounding errors */ - - middle = max - ( ( max - min ) >> 1 ); - - if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End ) - { - *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start; - return HB_Err_Ok; - } - else if ( glyphID < rr[middle].Start ) - { - if ( middle == min ) - break; - new_max = middle - 1; - } - else - { - if ( middle == max ) - break; - new_min = middle + 1; - } - } while ( min < max ); - - return HB_Err_Not_Covered; -} - - -HB_INTERNAL HB_Error -_HB_OPEN_Coverage_Index( HB_Coverage* c, - HB_UShort glyphID, - HB_UShort* index ) -{ - switch ( c->CoverageFormat ) - { - case 1: return Coverage_Index1( &c->cf.cf1, glyphID, index ); - case 2: return Coverage_Index2( &c->cf.cf2, glyphID, index ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - - -/************************************* - * Class Definition related functions - *************************************/ - - -/* ClassDefFormat1 */ - -static HB_Error Load_ClassDef1( HB_ClassDefinition* cd, - HB_UShort limit, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_UShort* cva; - - HB_ClassDefFormat1* cdf1; - - - cdf1 = &cd->cd.cd1; - - if ( ACCESS_Frame( 4L ) ) - return error; - - cdf1->StartGlyph = GET_UShort(); - count = cdf1->GlyphCount = GET_UShort(); - - FORGET_Frame(); - - /* sanity check; we are limited to 16bit integers */ - - if ( cdf1->StartGlyph + (long)count >= 0x10000L ) - return ERR(HB_Err_Invalid_SubTable); - - cdf1->ClassValueArray = NULL; - - if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, HB_UShort ) ) - return error; - - cva = cdf1->ClassValueArray; - - if ( ACCESS_Frame( count * 2L ) ) - goto Fail; - - for ( n = 0; n < count; n++ ) - { - cva[n] = GET_UShort(); - if ( cva[n] >= limit ) - { - error = ERR(HB_Err_Invalid_SubTable); - goto Fail; - } - } - - FORGET_Frame(); - - return HB_Err_Ok; - -Fail: - FREE( cva ); - - return error; -} - - -static void Free_ClassDef1( HB_ClassDefFormat1* cdf1 ) -{ - FREE( cdf1->ClassValueArray ); -} - - -/* ClassDefFormat2 */ - -static HB_Error Load_ClassDef2( HB_ClassDefinition* cd, - HB_UShort limit, - HB_Stream stream ) -{ - HB_Error error; - - HB_UShort n, count; - - HB_ClassRangeRecord* crr; - - HB_ClassDefFormat2* cdf2; - - - cdf2 = &cd->cd.cd2; - - if ( ACCESS_Frame( 2L ) ) - return error; - - count = GET_UShort(); - cdf2->ClassRangeCount = 0; /* zero for now. we fill with the number of good entries later */ - - FORGET_Frame(); - - cdf2->ClassRangeRecord = NULL; - - if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, HB_ClassRangeRecord ) ) - return error; - - crr = cdf2->ClassRangeRecord; - - if ( ACCESS_Frame( count * 6L ) ) - goto Fail; - - for ( n = 0; n < count; n++ ) - { - crr[n].Start = GET_UShort(); - crr[n].End = GET_UShort(); - crr[n].Class = GET_UShort(); - - /* sanity check */ - - if ( crr[n].Start > crr[n].End || - crr[n].Class >= limit ) - { - /* XXX - * Corrupt entry. Skip it. - * This is hit by Nafees Nastaliq font for example - */ - n--; - count--; - } - } - - FORGET_Frame(); - - cdf2->ClassRangeCount = count; - - return HB_Err_Ok; - -Fail: - FREE( crr ); - - return error; -} - - -static void Free_ClassDef2( HB_ClassDefFormat2* cdf2 ) -{ - FREE( cdf2->ClassRangeRecord ); -} - - -/* ClassDefinition */ - -HB_INTERNAL HB_Error -_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd, - HB_UShort limit, - HB_Stream stream ) -{ - HB_Error error; - - if ( ACCESS_Frame( 2L ) ) - return error; - - cd->ClassFormat = GET_UShort(); - - FORGET_Frame(); - - switch ( cd->ClassFormat ) - { - case 1: error = Load_ClassDef1( cd, limit, stream ); break; - case 2: error = Load_ClassDef2( cd, limit, stream ); break; - default: error = ERR(HB_Err_Invalid_SubTable_Format); break; - } - - if ( error ) - return error; - - cd->loaded = TRUE; - - return HB_Err_Ok; -} - - -static HB_Error -_HB_OPEN_Load_EmptyClassDefinition( HB_ClassDefinition* cd ) -{ - HB_Error error; - - cd->ClassFormat = 1; /* Meaningless */ - - if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, HB_UShort ) ) - return error; - - cd->loaded = TRUE; - - return HB_Err_Ok; -} - -HB_INTERNAL HB_Error -_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd, - HB_UShort limit, - HB_UInt class_offset, - HB_UInt base_offset, - HB_Stream stream ) -{ - HB_Error error; - HB_UInt cur_offset; - - cur_offset = FILE_Pos(); - - if ( class_offset ) - { - if ( !FILE_Seek( class_offset + base_offset ) ) - error = _HB_OPEN_Load_ClassDefinition( cd, limit, stream ); - } - else - error = _HB_OPEN_Load_EmptyClassDefinition ( cd ); - - if (error == HB_Err_Ok) - (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */ - - return error; -} - -HB_INTERNAL void -_HB_OPEN_Free_ClassDefinition( HB_ClassDefinition* cd ) -{ - if ( !cd->loaded ) - return; - - switch ( cd->ClassFormat ) - { - case 1: Free_ClassDef1( &cd->cd.cd1 ); break; - case 2: Free_ClassDef2( &cd->cd.cd2 ); break; - default: break; - } -} - - -static HB_Error Get_Class1( HB_ClassDefFormat1* cdf1, - HB_UShort glyphID, - HB_UShort* klass, - HB_UShort* index ) -{ - HB_UShort* cva = cdf1->ClassValueArray; - - - if ( index ) - *index = 0; - - if ( glyphID >= cdf1->StartGlyph && - glyphID < cdf1->StartGlyph + cdf1->GlyphCount ) - { - *klass = cva[glyphID - cdf1->StartGlyph]; - return HB_Err_Ok; - } - else - { - *klass = 0; - return HB_Err_Not_Covered; - } -} - - -/* we need the index value of the last searched class range record - in case of failure for constructed GDEF tables */ - -static HB_Error Get_Class2( HB_ClassDefFormat2* cdf2, - HB_UShort glyphID, - HB_UShort* klass, - HB_UShort* index ) -{ - HB_Error error = HB_Err_Ok; - HB_UShort min, max, new_min, new_max, middle; - - HB_ClassRangeRecord* crr = cdf2->ClassRangeRecord; - - - /* binary search */ - - if ( cdf2->ClassRangeCount == 0 ) - { - *klass = 0; - if ( index ) - *index = 0; - - return HB_Err_Not_Covered; - } - - new_min = 0; - new_max = cdf2->ClassRangeCount - 1; - - do - { - min = new_min; - max = new_max; - - /* we use (min + max) / 2 = max - (max - min) / 2 to avoid - overflow and rounding errors */ - - middle = max - ( ( max - min ) >> 1 ); - - if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End ) - { - *klass = crr[middle].Class; - error = HB_Err_Ok; - break; - } - else if ( glyphID < crr[middle].Start ) - { - if ( middle == min ) - { - *klass = 0; - error = HB_Err_Not_Covered; - break; - } - new_max = middle - 1; - } - else - { - if ( middle == max ) - { - *klass = 0; - error = HB_Err_Not_Covered; - break; - } - new_min = middle + 1; - } - } while ( min < max ); - - if ( index ) - *index = middle; - - return error; -} - - -HB_INTERNAL HB_Error -_HB_OPEN_Get_Class( HB_ClassDefinition* cd, - HB_UShort glyphID, - HB_UShort* klass, - HB_UShort* index ) -{ - switch ( cd->ClassFormat ) - { - case 1: return Get_Class1( &cd->cd.cd1, glyphID, klass, index ); - case 2: return Get_Class2( &cd->cd.cd2, glyphID, klass, index ); - default: return ERR(HB_Err_Invalid_SubTable_Format); - } - - return HB_Err_Ok; /* never reached */ -} - - - -/*************************** - * Device related functions - ***************************/ - - -HB_INTERNAL HB_Error -_HB_OPEN_Load_Device( HB_Device** device, - HB_Stream stream ) -{ - HB_Device* d; - HB_Error error; - - HB_UShort n, count; - - HB_UShort* dv; - - - if ( ACCESS_Frame( 6L ) ) - return error; - - if ( ALLOC( *device, sizeof(HB_Device)) ) - { - *device = 0; - return error; - } - - d = *device; - - d->StartSize = GET_UShort(); - d->EndSize = GET_UShort(); - d->DeltaFormat = GET_UShort(); - - FORGET_Frame(); - - d->DeltaValue = NULL; - - if ( d->StartSize > d->EndSize || - d->DeltaFormat == 0 || d->DeltaFormat > 3 ) - { - /* XXX - * I've seen fontforge generate DeltaFormat == 0. - * Just return Ok and let the NULL DeltaValue disable - * this table. - */ - return HB_Err_Ok; - } - - count = ( ( d->EndSize - d->StartSize + 1 ) >> - ( 4 - d->DeltaFormat ) ) + 1; - - if ( ALLOC_ARRAY( d->DeltaValue, count, HB_UShort ) ) - { - FREE( *device ); - *device = 0; - return error; - } - - if ( ACCESS_Frame( count * 2L ) ) - { - FREE( d->DeltaValue ); - FREE( *device ); - *device = 0; - return error; - } - - dv = d->DeltaValue; - - for ( n = 0; n < count; n++ ) - dv[n] = GET_UShort(); - - FORGET_Frame(); - - return HB_Err_Ok; -} - - -HB_INTERNAL void -_HB_OPEN_Free_Device( HB_Device* d ) -{ - if ( d ) - { - FREE( d->DeltaValue ); - FREE( d ); - } -} - - -/* Since we have the delta values stored in compressed form, we must - uncompress it now. To simplify the interface, the function always - returns a meaningful value in `value'; the error is just for - information. - | | - format = 1: 0011223344556677|8899101112131415|... - | | - byte 1 byte 2 - - 00: (byte >> 14) & mask - 11: (byte >> 12) & mask - ... - - mask = 0x0003 - | | - format = 2: 0000111122223333|4444555566667777|... - | | - byte 1 byte 2 - - 0000: (byte >> 12) & mask - 1111: (byte >> 8) & mask - ... - - mask = 0x000F - | | - format = 3: 0000000011111111|2222222233333333|... - | | - byte 1 byte 2 - - 00000000: (byte >> 8) & mask - 11111111: (byte >> 0) & mask - .... - - mask = 0x00FF */ - -HB_INTERNAL HB_Error -_HB_OPEN_Get_Device( HB_Device* d, - HB_UShort size, - HB_Short* value ) -{ - HB_UShort byte, bits, mask, s; - - if ( d && d->DeltaValue && size >= d->StartSize && size <= d->EndSize ) - { - HB_UShort f = d->DeltaFormat; - s = size - d->StartSize; - byte = d->DeltaValue[s >> ( 4 - f )]; - bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) ); - mask = 0xFFFF >> ( 16 - ( 1 << f ) ); - - *value = (HB_Short)( bits & mask ); - - /* conversion to a signed value */ - - if ( *value >= ( ( mask + 1 ) >> 1 ) ) - *value -= mask + 1; - - return HB_Err_Ok; - } - else - { - *value = 0; - return HB_Err_Not_Covered; - } -} - - -/* END */ diff --git a/src/hb-old/harfbuzz-open.h b/src/hb-old/harfbuzz-open.h deleted file mode 100644 index 4ba6cf5..0000000 --- a/src/hb-old/harfbuzz-open.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_OPEN_H -#define HARFBUZZ_OPEN_H - -#include "harfbuzz-global.h" - -HB_BEGIN_HEADER - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -/* Use this if a feature applies to all glyphs */ -#define HB_ALL_GLYPHS 0xFFFF - -#define HB_DEFAULT_LANGUAGE 0xFFFF - -#define HB_MAX_NESTING_LEVEL 100 - - -/* Script list related structures */ - -struct HB_LangSys_ -{ - HB_UShort* FeatureIndex; /* array of Feature indices */ - HB_UShort LookupOrderOffset; /* always 0 for TT Open 1.0 */ - HB_UShort ReqFeatureIndex; /* required FeatureIndex */ - HB_UShort FeatureCount; /* number of Feature indices */ -}; - -typedef struct HB_LangSys_ HB_LangSys; - - -struct HB_LangSysRecord_ -{ - HB_LangSys LangSys; /* LangSys table */ - HB_UInt LangSysTag; /* LangSysTag identifier */ -}; - -typedef struct HB_LangSysRecord_ HB_LangSysRecord; - - -struct HB_ScriptTable_ -{ - HB_LangSysRecord* LangSysRecord; /* array of LangSysRecords */ - HB_LangSys DefaultLangSys; /* DefaultLangSys table */ - HB_UShort LangSysCount; /* number of LangSysRecords */ -}; - -typedef struct HB_ScriptTable_ HB_ScriptTable; - - -struct HB_ScriptRecord_ -{ - HB_UInt ScriptTag; /* ScriptTag identifier */ - HB_ScriptTable Script; /* Script table */ -}; - -typedef struct HB_ScriptRecord_ HB_ScriptRecord; - - -struct HB_ScriptList_ -{ - HB_ScriptRecord* ScriptRecord; /* array of ScriptRecords */ - HB_UShort ScriptCount; /* number of ScriptRecords */ -}; - -typedef struct HB_ScriptList_ HB_ScriptList; - - -/* Feature list related structures */ - -struct HB_Feature_ -{ - HB_UShort* LookupListIndex; /* array of LookupList indices */ - HB_UShort FeatureParams; /* always 0 for TT Open 1.0 */ - HB_UShort LookupListCount; /* number of LookupList indices */ -}; - -typedef struct HB_Feature_ HB_Feature; - - -struct HB_FeatureRecord_ -{ - HB_UInt FeatureTag; /* FeatureTag identifier */ - HB_Feature Feature; /* Feature table */ -}; - -typedef struct HB_FeatureRecord_ HB_FeatureRecord; - - -struct HB_FeatureList_ -{ - HB_UShort* ApplyOrder; /* order to apply features */ - HB_FeatureRecord* FeatureRecord; /* array of FeatureRecords */ - HB_UShort FeatureCount; /* number of FeatureRecords */ - HB_UShort ApplyCount; /* number of elements in ApplyOrder */ -}; - -typedef struct HB_FeatureList_ HB_FeatureList; - - -/* Lookup list related structures */ - -typedef struct HB_SubTable_ HB_SubTable; - - -struct HB_Lookup_ -{ - HB_SubTable* SubTable; /* array of SubTables */ - HB_UShort LookupType; /* Lookup type */ - HB_UShort LookupFlag; /* Lookup qualifiers */ - HB_UShort SubTableCount; /* number of SubTables */ -}; - -typedef struct HB_Lookup_ HB_Lookup; - - -/* The `Properties' field is not defined in the OpenType specification but - is needed for processing lookups. If properties[n] is > 0, the - functions HB_GSUB_Apply_String() resp. HB_GPOS_Apply_String() will - process Lookup[n] for glyphs which have the specific bit not set in - the `properties' field of the input string object. */ - -struct HB_LookupList_ -{ - HB_Lookup* Lookup; /* array of Lookup records */ - HB_UInt* Properties; /* array of flags */ - HB_UShort LookupCount; /* number of Lookups */ -}; - -typedef struct HB_LookupList_ HB_LookupList; - - -/* Possible LookupFlag bit masks. `HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS' comes from the - OpenType 1.2 specification; HB_LOOKUP_FLAG_RIGHT_TO_LEFT has been (re)introduced in - OpenType 1.3 -- if set, the last glyph in a cursive attachment - sequence has to be positioned on the baseline -- regardless of the - writing direction. */ - -#define HB_LOOKUP_FLAG_RIGHT_TO_LEFT 0x0001 -#define HB_LOOKUP_FLAG_IGNORE_BASE_GLYPHS 0x0002 -#define HB_LOOKUP_FLAG_IGNORE_LIGATURES 0x0004 -#define HB_LOOKUP_FLAG_IGNORE_MARKS 0x0008 -#define HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS 0xFF00 - - -struct HB_CoverageFormat1_ -{ - HB_UShort* GlyphArray; /* array of glyph IDs */ - HB_UShort GlyphCount; /* number of glyphs in GlyphArray */ -}; - -typedef struct HB_CoverageFormat1_ HB_CoverageFormat1; - - -struct HB_RangeRecord_ -{ - HB_UShort Start; /* first glyph ID in the range */ - HB_UShort End; /* last glyph ID in the range */ - HB_UShort StartCoverageIndex; /* coverage index of first - glyph ID in the range */ -}; - -typedef struct HB_RangeRecord_ HB_RangeRecord; - - -struct HB_CoverageFormat2_ -{ - HB_RangeRecord* RangeRecord; /* array of RangeRecords */ - HB_UShort RangeCount; /* number of RangeRecords */ -}; - -typedef struct HB_CoverageFormat2_ HB_CoverageFormat2; - - -struct HB_Coverage_ -{ - HB_Byte CoverageFormat; /* 1 or 2 */ - - union - { - HB_CoverageFormat1 cf1; - HB_CoverageFormat2 cf2; - } cf; -}; - -typedef struct HB_Coverage_ HB_Coverage; - - -struct HB_ClassDefFormat1_ -{ - HB_UShort* ClassValueArray; /* array of class values */ - HB_UShort StartGlyph; /* first glyph ID of the - ClassValueArray */ - HB_UShort GlyphCount; /* size of the ClassValueArray */ -}; - -typedef struct HB_ClassDefFormat1_ HB_ClassDefFormat1; - - -struct HB_ClassRangeRecord_ -{ - HB_UShort Start; /* first glyph ID in the range */ - HB_UShort End; /* last glyph ID in the range */ - HB_UShort Class; /* applied to all glyphs in range */ -}; - -typedef struct HB_ClassRangeRecord_ HB_ClassRangeRecord; - - -struct HB_ClassDefFormat2_ -{ - HB_ClassRangeRecord* ClassRangeRecord; - /* array of ClassRangeRecords */ - HB_UShort ClassRangeCount; - /* number of ClassRangeRecords */ -}; - -typedef struct HB_ClassDefFormat2_ HB_ClassDefFormat2; - - -struct HB_ClassDefinition_ -{ - union - { - HB_ClassDefFormat1 cd1; - HB_ClassDefFormat2 cd2; - } cd; - - HB_Byte ClassFormat; /* 1 or 2 */ - HB_Bool loaded; -}; - -typedef struct HB_ClassDefinition_ HB_ClassDefinition; - - -struct HB_Device_ -{ - HB_UShort* DeltaValue; /* array of compressed data */ - HB_UShort StartSize; /* smallest size to correct */ - HB_UShort EndSize; /* largest size to correct */ - HB_Byte DeltaFormat; /* DeltaValue array data format: - 1, 2, or 3 */ -}; - -typedef struct HB_Device_ HB_Device; - - -enum HB_Type_ -{ - HB_Type_GSUB, - HB_Type_GPOS -}; - -typedef enum HB_Type_ HB_Type; - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -HB_END_HEADER - -#endif /* HARFBUZZ_OPEN_H */ diff --git a/src/hb-old/harfbuzz-shaper-private.h b/src/hb-old/harfbuzz-shaper-private.h deleted file mode 100644 index 66fad4c..0000000 --- a/src/hb-old/harfbuzz-shaper-private.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_SHAPER_PRIVATE_H -#define HARFBUZZ_SHAPER_PRIVATE_H - -HB_BEGIN_HEADER - -enum { - C_DOTTED_CIRCLE = 0x25CC -}; - -typedef enum -{ - HB_Combining_BelowLeftAttached = 200, - HB_Combining_BelowAttached = 202, - HB_Combining_BelowRightAttached = 204, - HB_Combining_LeftAttached = 208, - HB_Combining_RightAttached = 210, - HB_Combining_AboveLeftAttached = 212, - HB_Combining_AboveAttached = 214, - HB_Combining_AboveRightAttached = 216, - - HB_Combining_BelowLeft = 218, - HB_Combining_Below = 220, - HB_Combining_BelowRight = 222, - HB_Combining_Left = 224, - HB_Combining_Right = 226, - HB_Combining_AboveLeft = 228, - HB_Combining_Above = 230, - HB_Combining_AboveRight = 232, - - HB_Combining_DoubleBelow = 233, - HB_Combining_DoubleAbove = 234, - HB_Combining_IotaSubscript = 240 -} HB_CombiningClass; - -typedef enum { - LocaProperty = 0x1, - CcmpProperty = 0x2, - InitProperty = 0x4, - IsolProperty = 0x8, - FinaProperty = 0x10, - MediProperty = 0x20, - RligProperty = 0x40, - CaltProperty = 0x80, - LigaProperty = 0x100, - DligProperty = 0x200, - CswhProperty = 0x400, - MsetProperty = 0x800, - - /* used by indic and myanmar shaper */ - NuktaProperty = 0x8, - AkhantProperty = 0x10, - RephProperty = 0x20, - PreFormProperty = 0x40, - BelowFormProperty = 0x80, - AboveFormProperty = 0x100, - HalfFormProperty = 0x200, - PostFormProperty = 0x400, - ConjunctFormProperty = 0x800, - VattuProperty = 0x1000, - PreSubstProperty = 0x2000, - BelowSubstProperty = 0x4000, - AboveSubstProperty = 0x8000, - PostSubstProperty = 0x10000, - HalantProperty = 0x20000, - CligProperty = 0x40000, - IndicCaltProperty = 0x80000 - -} HB_OpenTypeProperty; - -/* return true if ok. */ -typedef HB_Bool (*HB_ShapeFunction)(HB_ShaperItem *shaper_item); - -typedef struct { - HB_ShapeFunction shape; -} HB_ScriptEngine; - -extern const HB_ScriptEngine hb_scriptEngines[]; - -extern HB_Bool HB_BasicShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_TibetanShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_ArabicShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_HangulShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_MyanmarShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_KhmerShape(HB_ShaperItem *shaper_item); -extern HB_Bool HB_IndicShape(HB_ShaperItem *shaper_item); - -typedef struct { - hb_uint32 tag; - hb_uint32 property; -} HB_OpenTypeFeature; - -#define PositioningProperties 0x80000000 - -HB_Bool HB_SelectScript(HB_ShaperItem *item, const HB_OpenTypeFeature *features); - -HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties); -HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool doLogClusters); - -void HB_HeuristicPosition(HB_ShaperItem *item); -void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item); - -#define HB_IsControlChar(uc) \ - ((uc >= 0x200b && uc <= 0x200f /* ZW Space, ZWNJ, ZWJ, LRM and RLM */) \ - || (uc >= 0x2028 && uc <= 0x202f /* LS, PS, LRE, RLE, PDF, LRO, RLO, NNBSP */) \ - || (uc >= 0x206a && uc <= 0x206f /* ISS, ASS, IAFS, AFS, NADS, NODS */)) - -HB_Bool HB_ConvertStringToGlyphIndices(HB_ShaperItem *shaper_item); - -#define HB_GetGlyphAdvances(shaper_item) \ - shaper_item->font->klass->getGlyphAdvances(shaper_item->font, \ - shaper_item->glyphs, shaper_item->num_glyphs, \ - shaper_item->advances, \ - shaper_item->face->current_flags); - -#define HB_DECLARE_STACKARRAY(Type, Name) \ - Type stack##Name[512]; \ - Type *Name = stack##Name; - -#define HB_INIT_STACKARRAY(Type, Name, Length) \ - if ((Length) >= 512) \ - Name = (Type *)malloc((Length) * sizeof(Type)); - -#define HB_STACKARRAY(Type, Name, Length) \ - HB_DECLARE_STACKARRAY(Type, Name) \ - HB_INIT_STACKARRAY(Type, Name, Length) - -#define HB_FREE_STACKARRAY(Name) \ - if (stack##Name != Name) \ - free(Name); - -HB_END_HEADER - -#endif diff --git a/src/hb-old/harfbuzz-shaper.cpp b/src/hb-old/harfbuzz-shaper.cpp deleted file mode 100644 index d1e2335..0000000 --- a/src/hb-old/harfbuzz-shaper.cpp +++ /dev/null @@ -1,994 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" - -#include "harfbuzz-stream-private.h" -#include <assert.h> -#include <stdio.h> - -#define HB_MIN(a, b) ((a) < (b) ? (a) : (b)) -#define HB_MAX(a, b) ((a) > (b) ? (a) : (b)) - -// -------------------------------------------------------------------------------------------------------------------------------------------- -// -// Basic processing -// -// -------------------------------------------------------------------------------------------------------------------------------------------- - -static inline void positionCluster(HB_ShaperItem *item, int gfrom, int glast) -{ - int nmarks = glast - gfrom; - assert(nmarks > 0); - - HB_Glyph *glyphs = item->glyphs; - HB_GlyphAttributes *attributes = item->attributes; - - HB_GlyphMetrics baseMetrics; - item->font->klass->getGlyphMetrics(item->font, glyphs[gfrom], &baseMetrics); - - if (item->item.script == HB_Script_Hebrew - && (-baseMetrics.y) > baseMetrics.height) - // we need to attach below the baseline, because of the hebrew iud. - baseMetrics.height = -baseMetrics.y; - -// qDebug("---> positionCluster: cluster from %d to %d", gfrom, glast); -// qDebug("baseInfo: %f/%f (%f/%f) off=%f/%f", baseInfo.x, baseInfo.y, baseInfo.width, baseInfo.height, baseInfo.xoff, baseInfo.yoff); - - HB_Fixed size = item->font->klass->getFontMetric(item->font, HB_FontAscent) / 10; - HB_Fixed offsetBase = HB_FIXED_CONSTANT(1) + (size - HB_FIXED_CONSTANT(4)) / 4; - if (size > HB_FIXED_CONSTANT(4)) - offsetBase += HB_FIXED_CONSTANT(4); - else - offsetBase += size; - offsetBase = -offsetBase; - //qreal offsetBase = (size - 4) / 4 + qMin<qreal>(size, 4) + 1; -// qDebug("offset = %f", offsetBase); - - bool rightToLeft = item->item.bidiLevel % 2; - - int i; - unsigned char lastCmb = 0; - HB_GlyphMetrics attachmentRect; - memset(&attachmentRect, 0, sizeof(attachmentRect)); - - for(i = 1; i <= nmarks; i++) { - HB_Glyph mark = glyphs[gfrom+i]; - HB_GlyphMetrics markMetrics; - item->font->klass->getGlyphMetrics(item->font, mark, &markMetrics); - HB_FixedPoint p; - p.x = p.y = 0; -// qDebug("markInfo: %f/%f (%f/%f) off=%f/%f", markInfo.x, markInfo.y, markInfo.width, markInfo.height, markInfo.xoff, markInfo.yoff); - - HB_Fixed offset = offsetBase; - unsigned char cmb = attributes[gfrom+i].combiningClass; - - // ### maybe the whole position determination should move down to heuristicSetGlyphAttributes. Would save some - // bits in the glyphAttributes structure. - if (cmb < 200) { - // fixed position classes. We approximate by mapping to one of the others. - // currently I added only the ones for arabic, hebrew, lao and thai. - - // for Lao and Thai marks with class 0, see below (heuristicSetGlyphAttributes) - - // add a bit more offset to arabic, a bit hacky - if (cmb >= 27 && cmb <= 36 && offset < 3) - offset +=1; - // below - if ((cmb >= 10 && cmb <= 18) || - cmb == 20 || cmb == 22 || - cmb == 29 || cmb == 32) - cmb = HB_Combining_Below; - // above - else if (cmb == 23 || cmb == 27 || cmb == 28 || - cmb == 30 || cmb == 31 || (cmb >= 33 && cmb <= 36)) - cmb = HB_Combining_Above; - //below-right - else if (cmb == 9 || cmb == 103 || cmb == 118) - cmb = HB_Combining_BelowRight; - // above-right - else if (cmb == 24 || cmb == 107 || cmb == 122) - cmb = HB_Combining_AboveRight; - else if (cmb == 25) - cmb = HB_Combining_AboveLeft; - // fixed: - // 19 21 - - } - - // combining marks of different class don't interact. Reset the rectangle. - if (cmb != lastCmb) { - //qDebug("resetting rect"); - attachmentRect = baseMetrics; - } - - switch(cmb) { - case HB_Combining_DoubleBelow: - // ### wrong in rtl context! - case HB_Combining_BelowLeft: - p.y += offset; - case HB_Combining_BelowLeftAttached: - p.x += attachmentRect.x - markMetrics.x; - p.y += (attachmentRect.y + attachmentRect.height) - markMetrics.y; - break; - case HB_Combining_Below: - p.y += offset; - case HB_Combining_BelowAttached: - p.x += attachmentRect.x - markMetrics.x; - p.y += (attachmentRect.y + attachmentRect.height) - markMetrics.y; - - p.x += (attachmentRect.width - markMetrics.width) / 2; - break; - case HB_Combining_BelowRight: - p.y += offset; - case HB_Combining_BelowRightAttached: - p.x += attachmentRect.x + attachmentRect.width - markMetrics.width - markMetrics.x; - p.y += attachmentRect.y + attachmentRect.height - markMetrics.y; - break; - case HB_Combining_Left: - p.x -= offset; - case HB_Combining_LeftAttached: - break; - case HB_Combining_Right: - p.x += offset; - case HB_Combining_RightAttached: - break; - case HB_Combining_DoubleAbove: - // ### wrong in RTL context! - case HB_Combining_AboveLeft: - p.y -= offset; - case HB_Combining_AboveLeftAttached: - p.x += attachmentRect.x - markMetrics.x; - p.y += attachmentRect.y - markMetrics.y - markMetrics.height; - break; - case HB_Combining_Above: - p.y -= offset; - case HB_Combining_AboveAttached: - p.x += attachmentRect.x - markMetrics.x; - p.y += attachmentRect.y - markMetrics.y - markMetrics.height; - - p.x += (attachmentRect.width - markMetrics.width) / 2; - break; - case HB_Combining_AboveRight: - p.y -= offset; - case HB_Combining_AboveRightAttached: - p.x += attachmentRect.x + attachmentRect.width - markMetrics.x - markMetrics.width; - p.y += attachmentRect.y - markMetrics.y - markMetrics.height; - break; - - case HB_Combining_IotaSubscript: - default: - break; - } -// qDebug("char=%x combiningClass = %d offset=%f/%f", mark, cmb, p.x(), p.y()); - markMetrics.x += p.x; - markMetrics.y += p.y; - - HB_GlyphMetrics unitedAttachmentRect = attachmentRect; - unitedAttachmentRect.x = HB_MIN(attachmentRect.x, markMetrics.x); - unitedAttachmentRect.y = HB_MIN(attachmentRect.y, markMetrics.y); - unitedAttachmentRect.width = HB_MAX(attachmentRect.x + attachmentRect.width, markMetrics.x + markMetrics.width) - unitedAttachmentRect.x; - unitedAttachmentRect.height = HB_MAX(attachmentRect.y + attachmentRect.height, markMetrics.y + markMetrics.height) - unitedAttachmentRect.y; - attachmentRect = unitedAttachmentRect; - - lastCmb = cmb; - if (rightToLeft) { - item->offsets[gfrom+i].x = p.x; - item->offsets[gfrom+i].y = p.y; - } else { - item->offsets[gfrom+i].x = p.x - baseMetrics.xOffset; - item->offsets[gfrom+i].y = p.y - baseMetrics.yOffset; - } - item->advances[gfrom+i] = 0; - } -} - -void HB_HeuristicPosition(HB_ShaperItem *item) -{ - HB_GetGlyphAdvances(item); - HB_GlyphAttributes *attributes = item->attributes; - - int cEnd = -1; - int i = item->num_glyphs; - while (i--) { - if (cEnd == -1 && attributes[i].mark) { - cEnd = i; - } else if (cEnd != -1 && !attributes[i].mark) { - positionCluster(item, i, cEnd); - cEnd = -1; - } - } -} - -// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs -// and no reordering. -// also computes logClusters heuristically -void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) -{ - const HB_UChar16 *uc = item->string + item->item.pos; - hb_uint32 length = item->item.length; - - // ### zeroWidth and justification are missing here!!!!! - - assert(item->num_glyphs <= length); - -// qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs); - HB_GlyphAttributes *attributes = item->attributes; - unsigned short *logClusters = item->log_clusters; - - hb_uint32 glyph_pos = 0; - hb_uint32 i; - for (i = 0; i < length; i++) { - if (HB_IsHighSurrogate(uc[i]) && i < length - 1 - && HB_IsLowSurrogate(uc[i + 1])) { - logClusters[i] = glyph_pos; - logClusters[++i] = glyph_pos; - } else { - logClusters[i] = glyph_pos; - } - ++glyph_pos; - } - assert(glyph_pos == item->num_glyphs); - - // first char in a run is never (treated as) a mark - int cStart = 0; - const bool symbolFont = item->face->isSymbolFont; - attributes[0].mark = false; - attributes[0].clusterStart = true; - attributes[0].dontPrint = (!symbolFont && uc[0] == 0x00ad) || HB_IsControlChar(uc[0]); - - int pos = 0; - HB_CharCategory lastCat; - int dummy; - HB_GetUnicodeCharProperties(uc[0], &lastCat, &dummy); - for (i = 1; i < length; ++i) { - if (logClusters[i] == pos) - // same glyph - continue; - ++pos; - while (pos < logClusters[i]) { - attributes[pos] = attributes[pos-1]; - ++pos; - } - // hide soft-hyphens by default - if ((!symbolFont && uc[i] == 0x00ad) || HB_IsControlChar(uc[i])) - attributes[pos].dontPrint = true; - HB_CharCategory cat; - int cmb; - HB_GetUnicodeCharProperties(uc[i], &cat, &cmb); - if (cat != HB_Mark_NonSpacing) { - attributes[pos].mark = false; - attributes[pos].clusterStart = true; - attributes[pos].combiningClass = 0; - cStart = logClusters[i]; - } else { - if (cmb == 0) { - // Fix 0 combining classes - if ((uc[pos] & 0xff00) == 0x0e00) { - // thai or lao - if (uc[pos] == 0xe31 || - uc[pos] == 0xe34 || - uc[pos] == 0xe35 || - uc[pos] == 0xe36 || - uc[pos] == 0xe37 || - uc[pos] == 0xe47 || - uc[pos] == 0xe4c || - uc[pos] == 0xe4d || - uc[pos] == 0xe4e) { - cmb = HB_Combining_AboveRight; - } else if (uc[pos] == 0xeb1 || - uc[pos] == 0xeb4 || - uc[pos] == 0xeb5 || - uc[pos] == 0xeb6 || - uc[pos] == 0xeb7 || - uc[pos] == 0xebb || - uc[pos] == 0xecc || - uc[pos] == 0xecd) { - cmb = HB_Combining_Above; - } else if (uc[pos] == 0xebc) { - cmb = HB_Combining_Below; - } - } - } - - attributes[pos].mark = true; - attributes[pos].clusterStart = false; - attributes[pos].combiningClass = cmb; - logClusters[i] = cStart; - } - // one gets an inter character justification point if the current char is not a non spacing mark. - // as then the current char belongs to the last one and one gets a space justification point - // after the space char. - if (lastCat == HB_Separator_Space) - attributes[pos-1].justification = HB_Space; - else if (cat != HB_Mark_NonSpacing) - attributes[pos-1].justification = HB_Character; - else - attributes[pos-1].justification = HB_NoJustification; - - lastCat = cat; - } - pos = logClusters[length-1]; - if (lastCat == HB_Separator_Space) - attributes[pos].justification = HB_Space; - else - attributes[pos].justification = HB_Character; -} - -#ifndef NO_OPENTYPE -static const HB_OpenTypeFeature basic_features[] = { - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty }, - { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty }, - {0, 0} -}; -#endif - -HB_Bool HB_ConvertStringToGlyphIndices(HB_ShaperItem *shaper_item) -{ - if (shaper_item->glyphIndicesPresent) { - shaper_item->num_glyphs = shaper_item->initialGlyphCount; - shaper_item->glyphIndicesPresent = false; - return true; - } - return shaper_item->font->klass - ->convertStringToGlyphIndices(shaper_item->font, - shaper_item->string + shaper_item->item.pos, shaper_item->item.length, - shaper_item->glyphs, &shaper_item->num_glyphs, - shaper_item->item.bidiLevel % 2); -} - -HB_Bool HB_BasicShape(HB_ShaperItem *shaper_item) -{ -#ifndef NO_OPENTYPE - const int availableGlyphs = shaper_item->num_glyphs; -#endif - - if (!HB_ConvertStringToGlyphIndices(shaper_item)) - return false; - - HB_HeuristicSetGlyphAttributes(shaper_item); - -#ifndef NO_OPENTYPE - if (HB_SelectScript(shaper_item, basic_features)) { - HB_OpenTypeShape(shaper_item, /*properties*/0); - return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/true); - } -#endif - - HB_HeuristicPosition(shaper_item); - return true; -} - -const HB_ScriptEngine HB_ScriptEngines[] = { - // Common - { HB_BasicShape}, - // Greek - { HB_GreekShape}, - // Cyrillic - { HB_BasicShape}, - // Armenian - { HB_BasicShape}, - // Hebrew - { HB_HebrewShape}, - // Arabic - { HB_ArabicShape}, - // Syriac - { HB_ArabicShape}, - // Thaana - { HB_BasicShape}, - // Devanagari - { HB_IndicShape}, - // Bengali - { HB_IndicShape}, - // Gurmukhi - { HB_IndicShape}, - // Gujarati - { HB_IndicShape}, - // Oriya - { HB_IndicShape}, - // Tamil - { HB_IndicShape}, - // Telugu - { HB_IndicShape}, - // Kannada - { HB_IndicShape}, - // Malayalam - { HB_IndicShape}, - // Sinhala - { HB_IndicShape}, - // Thai - { HB_BasicShape}, - // Lao - { HB_BasicShape}, - // Tibetan - { HB_TibetanShape}, - // Myanmar - { HB_MyanmarShape}, - // Georgian - { HB_BasicShape}, - // Hangul - { HB_HangulShape}, - // Ogham - { HB_BasicShape}, - // Runic - { HB_BasicShape}, - // Khmer - { HB_KhmerShape}, - // N'Ko - { HB_ArabicShape} -}; - - -static inline char *tag_to_string(HB_UInt tag) -{ - static char string[5]; - string[0] = (tag >> 24)&0xff; - string[1] = (tag >> 16)&0xff; - string[2] = (tag >> 8)&0xff; - string[3] = tag&0xff; - string[4] = 0; - return string; -} - -#ifdef OT_DEBUG -static void dump_string(HB_Buffer buffer) -{ - for (uint i = 0; i < buffer->in_length; ++i) { - qDebug(" %x: cluster=%d", buffer->in_string[i].gindex, buffer->in_string[i].cluster); - } -} -#define DEBUG printf -#else -#define DEBUG if (1) ; else printf -#endif - -#if 0 -#define DefaultLangSys 0xffff -#define DefaultScript HB_MAKE_TAG('D', 'F', 'L', 'T') -#endif - -enum { - RequiresGsub = 1, - RequiresGpos = 2 -}; - -struct OTScripts { - unsigned int tag; - int flags; -}; -static const OTScripts ot_scripts [] = { - // Common - { HB_MAKE_TAG('l', 'a', 't', 'n'), 0 }, - // Greek - { HB_MAKE_TAG('g', 'r', 'e', 'k'), 0 }, - // Cyrillic - { HB_MAKE_TAG('c', 'y', 'r', 'l'), 0 }, - // Armenian - { HB_MAKE_TAG('a', 'r', 'm', 'n'), 0 }, - // Hebrew - { HB_MAKE_TAG('h', 'e', 'b', 'r'), 1 }, - // Arabic - { HB_MAKE_TAG('a', 'r', 'a', 'b'), 1 }, - // Syriac - { HB_MAKE_TAG('s', 'y', 'r', 'c'), 1 }, - // Thaana - { HB_MAKE_TAG('t', 'h', 'a', 'a'), 1 }, - // Devanagari - { HB_MAKE_TAG('d', 'e', 'v', 'a'), 1 }, - // Bengali - { HB_MAKE_TAG('b', 'e', 'n', 'g'), 1 }, - // Gurmukhi - { HB_MAKE_TAG('g', 'u', 'r', 'u'), 1 }, - // Gujarati - { HB_MAKE_TAG('g', 'u', 'j', 'r'), 1 }, - // Oriya - { HB_MAKE_TAG('o', 'r', 'y', 'a'), 1 }, - // Tamil - { HB_MAKE_TAG('t', 'a', 'm', 'l'), 1 }, - // Telugu - { HB_MAKE_TAG('t', 'e', 'l', 'u'), 1 }, - // Kannada - { HB_MAKE_TAG('k', 'n', 'd', 'a'), 1 }, - // Malayalam - { HB_MAKE_TAG('m', 'l', 'y', 'm'), 1 }, - // Sinhala - { HB_MAKE_TAG('s', 'i', 'n', 'h'), 1 }, - // Thai - { HB_MAKE_TAG('t', 'h', 'a', 'i'), 1 }, - // Lao - { HB_MAKE_TAG('l', 'a', 'o', ' '), 1 }, - // Tibetan - { HB_MAKE_TAG('t', 'i', 'b', 't'), 1 }, - // Myanmar - { HB_MAKE_TAG('m', 'y', 'm', 'r'), 1 }, - // Georgian - { HB_MAKE_TAG('g', 'e', 'o', 'r'), 0 }, - // Hangul - { HB_MAKE_TAG('h', 'a', 'n', 'g'), 1 }, - // Ogham - { HB_MAKE_TAG('o', 'g', 'a', 'm'), 0 }, - // Runic - { HB_MAKE_TAG('r', 'u', 'n', 'r'), 0 }, - // Khmer - { HB_MAKE_TAG('k', 'h', 'm', 'r'), 1 }, - // N'Ko - { HB_MAKE_TAG('n', 'k', 'o', ' '), 1 } -}; -enum { NumOTScripts = sizeof(ot_scripts)/sizeof(OTScripts) }; - -static HB_Bool checkScript(HB_Face face, int script) -{ - assert(script < HB_ScriptCount); - - if (!face->gsub && !face->gpos) - return false; - - unsigned int tag = ot_scripts[script].tag; - int requirements = ot_scripts[script].flags; - - if (requirements & RequiresGsub) { - if (!face->gsub) - return false; - - HB_UShort script_index; - HB_Error error = HB_GSUB_Select_Script(face->gsub, tag, &script_index); - if (error) { - DEBUG("could not select script %d in GSub table: %d", (int)script, error); - error = HB_GSUB_Select_Script(face->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &script_index); - if (error) - return false; - } - } - - if (requirements & RequiresGpos) { - if (!face->gpos) - return false; - - HB_UShort script_index; - HB_Error error = HB_GPOS_Select_Script(face->gpos, script, &script_index); - if (error) { - DEBUG("could not select script in gpos table: %d", error); - error = HB_GPOS_Select_Script(face->gpos, HB_MAKE_TAG('D', 'F', 'L', 'T'), &script_index); - if (error) - return false; - } - - } - return true; -} - -static HB_Stream getTableStream(void *font, HB_GetFontTableFunc tableFunc, HB_Tag tag) -{ - HB_Error error; - HB_UInt length = 0; - HB_Stream stream = 0; - - if (!font) - return 0; - - error = tableFunc(font, tag, 0, &length); - if (error) - return 0; - stream = (HB_Stream)malloc(sizeof(HB_StreamRec)); - if (!stream) - return 0; - stream->base = (HB_Byte*)malloc(length); - if (!stream->base) { - free(stream); - return 0; - } - error = tableFunc(font, tag, stream->base, &length); - if (error) { - _hb_close_stream(stream); - return 0; - } - stream->size = length; - stream->pos = 0; - stream->cursor = NULL; - return stream; -} - -HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) -{ - HB_Face face = (HB_Face )malloc(sizeof(HB_FaceRec)); - if (!face) - return 0; - - face->isSymbolFont = false; - face->gdef = 0; - face->gpos = 0; - face->gsub = 0; - face->current_script = HB_ScriptCount; - face->current_flags = HB_ShaperFlag_Default; - face->has_opentype_kerning = false; - face->tmpAttributes = 0; - face->tmpLogClusters = 0; - face->glyphs_substituted = false; - face->buffer = 0; - - HB_Error error = HB_Err_Ok; - HB_Stream stream; - HB_Stream gdefStream; - - gdefStream = getTableStream(font, tableFunc, TTAG_GDEF); - error = HB_Err_Not_Covered; - if (!gdefStream || (error = HB_Load_GDEF_Table(gdefStream, &face->gdef))) { - //DEBUG("error loading gdef table: %d", error); - face->gdef = 0; - } - - //DEBUG() << "trying to load gsub table"; - stream = getTableStream(font, tableFunc, TTAG_GSUB); - error = HB_Err_Not_Covered; - if (!stream || (error = HB_Load_GSUB_Table(stream, &face->gsub, face->gdef, gdefStream))) { - face->gsub = 0; - if (error != HB_Err_Not_Covered) { - //DEBUG("error loading gsub table: %d", error); - } else { - //DEBUG("face doesn't have a gsub table"); - } - } - _hb_close_stream(stream); - - stream = getTableStream(font, tableFunc, TTAG_GPOS); - error = HB_Err_Not_Covered; - if (!stream || (error = HB_Load_GPOS_Table(stream, &face->gpos, face->gdef, gdefStream))) { - face->gpos = 0; - DEBUG("error loading gpos table: %d", error); - } - _hb_close_stream(stream); - - _hb_close_stream(gdefStream); - - for (unsigned int i = 0; i < HB_ScriptCount; ++i) - face->supported_scripts[i] = checkScript(face, i); - - if (HB_Buffer_new(&face->buffer) != HB_Err_Ok) { - HB_FreeFace(face); - return 0; - } - - return face; -} - -void HB_FreeFace(HB_Face face) -{ - if (!face) - return; - if (face->gpos) - HB_Done_GPOS_Table(face->gpos); - if (face->gsub) - HB_Done_GSUB_Table(face->gsub); - if (face->gdef) - HB_Done_GDEF_Table(face->gdef); - if (face->buffer) - HB_Buffer_free(face->buffer); - if (face->tmpAttributes) - free(face->tmpAttributes); - if (face->tmpLogClusters) - free(face->tmpLogClusters); - free(face); -} - -HB_Bool HB_SelectScript(HB_ShaperItem *shaper_item, const HB_OpenTypeFeature *features) -{ - HB_Script script = shaper_item->item.script; - - if (!shaper_item->face->supported_scripts[script]) - return false; - - HB_Face face = shaper_item->face; - if (face->current_script == script && face->current_flags == shaper_item->shaperFlags) - return true; - - face->current_script = script; - face->current_flags = shaper_item->shaperFlags; - - assert(script < HB_ScriptCount); - // find script in our list of supported scripts. - unsigned int tag = ot_scripts[script].tag; - - if (face->gsub && features) { -#ifdef OT_DEBUG - { - HB_FeatureList featurelist = face->gsub->FeatureList; - int numfeatures = featurelist.FeatureCount; - DEBUG("gsub table has %d features", numfeatures); - for (int i = 0; i < numfeatures; i++) { - HB_FeatureRecord *r = featurelist.FeatureRecord + i; - DEBUG(" feature '%s'", tag_to_string(r->FeatureTag)); - } - } -#endif - HB_GSUB_Clear_Features(face->gsub); - HB_UShort script_index; - HB_Error error = HB_GSUB_Select_Script(face->gsub, tag, &script_index); - if (!error) { - DEBUG("script %s has script index %d", tag_to_string(script), script_index); - while (features->tag) { - HB_UShort feature_index; - error = HB_GSUB_Select_Feature(face->gsub, features->tag, script_index, 0xffff, &feature_index); - if (!error) { - DEBUG(" adding feature %s", tag_to_string(features->tag)); - HB_GSUB_Add_Feature(face->gsub, feature_index, features->property); - } - ++features; - } - } - } - - // reset - face->has_opentype_kerning = false; - - if (face->gpos) { - HB_GPOS_Clear_Features(face->gpos); - HB_UShort script_index; - HB_Error error = HB_GPOS_Select_Script(face->gpos, tag, &script_index); - if (!error) { -#ifdef OT_DEBUG - { - HB_FeatureList featurelist = face->gpos->FeatureList; - int numfeatures = featurelist.FeatureCount; - DEBUG("gpos table has %d features", numfeatures); - for(int i = 0; i < numfeatures; i++) { - HB_FeatureRecord *r = featurelist.FeatureRecord + i; - HB_UShort feature_index; - HB_GPOS_Select_Feature(face->gpos, r->FeatureTag, script_index, 0xffff, &feature_index); - DEBUG(" feature '%s'", tag_to_string(r->FeatureTag)); - } - } -#endif - HB_UInt *feature_tag_list_buffer; - error = HB_GPOS_Query_Features(face->gpos, script_index, 0xffff, &feature_tag_list_buffer); - if (!error) { - HB_UInt *feature_tag_list = feature_tag_list_buffer; - while (*feature_tag_list) { - HB_UShort feature_index; - if (*feature_tag_list == HB_MAKE_TAG('k', 'e', 'r', 'n')) { - if (face->current_flags & HB_ShaperFlag_NoKerning) { - ++feature_tag_list; - continue; - } - face->has_opentype_kerning = true; - } - error = HB_GPOS_Select_Feature(face->gpos, *feature_tag_list, script_index, 0xffff, &feature_index); - if (!error) - HB_GPOS_Add_Feature(face->gpos, feature_index, PositioningProperties); - ++feature_tag_list; - } - FREE(feature_tag_list_buffer); - } - } - } - - return true; -} - -HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties) -{ - HB_GlyphAttributes *tmpAttributes; - unsigned int *tmpLogClusters; - - HB_Face face = item->face; - - face->length = item->num_glyphs; - - HB_Buffer_clear(face->buffer); - - tmpAttributes = (HB_GlyphAttributes *) realloc(face->tmpAttributes, face->length*sizeof(HB_GlyphAttributes)); - if (!tmpAttributes) - return false; - face->tmpAttributes = tmpAttributes; - - tmpLogClusters = (unsigned int *) realloc(face->tmpLogClusters, face->length*sizeof(unsigned int)); - if (!tmpLogClusters) - return false; - face->tmpLogClusters = tmpLogClusters; - - for (int i = 0; i < face->length; ++i) { - HB_Buffer_add_glyph(face->buffer, item->glyphs[i], properties ? properties[i] : 0, i); - face->tmpAttributes[i] = item->attributes[i]; - face->tmpLogClusters[i] = item->log_clusters[i]; - } - -#ifdef OT_DEBUG - DEBUG("-----------------------------------------"); -// DEBUG("log clusters before shaping:"); -// for (int j = 0; j < length; j++) -// DEBUG(" log[%d] = %d", j, item->log_clusters[j]); - DEBUG("original glyphs: %p", item->glyphs); - for (int i = 0; i < length; ++i) - DEBUG(" glyph=%4x", hb_buffer->in_string[i].gindex); -// dump_string(hb_buffer); -#endif - - face->glyphs_substituted = false; - if (face->gsub) { - unsigned int error = HB_GSUB_Apply_String(face->gsub, face->buffer); - if (error && error != HB_Err_Not_Covered) - return false; - face->glyphs_substituted = (error != HB_Err_Not_Covered); - } - -#ifdef OT_DEBUG -// DEBUG("log clusters before shaping:"); -// for (int j = 0; j < length; j++) -// DEBUG(" log[%d] = %d", j, item->log_clusters[j]); - DEBUG("shaped glyphs:"); - for (int i = 0; i < length; ++i) - DEBUG(" glyph=%4x", hb_buffer->in_string[i].gindex); - DEBUG("-----------------------------------------"); -// dump_string(hb_buffer); -#endif - - return true; -} - -HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool doLogClusters) -{ - HB_Face face = item->face; - - bool glyphs_positioned = false; - if (face->gpos) { - if (face->buffer->positions) - memset(face->buffer->positions, 0, face->buffer->in_length*sizeof(HB_PositionRec)); - // #### check that passing "false,false" is correct - glyphs_positioned = HB_GPOS_Apply_String(item->font, face->gpos, face->current_flags, face->buffer, false, false) != HB_Err_Not_Covered; - } - - if (!face->glyphs_substituted && !glyphs_positioned) { - HB_GetGlyphAdvances(item); - return true; // nothing to do for us - } - - // make sure we have enough space to write everything back - if (availableGlyphs < (int)face->buffer->in_length) { - item->num_glyphs = face->buffer->in_length; - return false; - } - - HB_Glyph *glyphs = item->glyphs; - HB_GlyphAttributes *attributes = item->attributes; - - for (unsigned int i = 0; i < face->buffer->in_length; ++i) { - glyphs[i] = face->buffer->in_string[i].gindex; - attributes[i] = face->tmpAttributes[face->buffer->in_string[i].cluster]; - if (i && face->buffer->in_string[i].cluster == face->buffer->in_string[i-1].cluster) - attributes[i].clusterStart = false; - } - item->num_glyphs = face->buffer->in_length; - - if (doLogClusters && face->glyphs_substituted) { - // we can't do this for indic, as we pass the stuf in syllables and it's easier to do it in the shaper. - unsigned short *logClusters = item->log_clusters; - int clusterStart = 0; - int oldCi = 0; - // #### the reconstruction of the logclusters currently does not work if the original string - // contains surrogate pairs - for (unsigned int i = 0; i < face->buffer->in_length; ++i) { - int ci = face->buffer->in_string[i].cluster; - // DEBUG(" ci[%d] = %d mark=%d, cmb=%d, cs=%d", - // i, ci, glyphAttributes[i].mark, glyphAttributes[i].combiningClass, glyphAttributes[i].clusterStart); - if (!attributes[i].mark && attributes[i].clusterStart && ci != oldCi) { - for (int j = oldCi; j < ci; j++) - logClusters[j] = clusterStart; - clusterStart = i; - oldCi = ci; - } - } - for (int j = oldCi; j < face->length; j++) - logClusters[j] = clusterStart; - } - - // calulate the advances for the shaped glyphs -// DEBUG("unpositioned: "); - - // positioning code: - if (glyphs_positioned) { - HB_GetGlyphAdvances(item); - HB_Position positions = face->buffer->positions; - HB_Fixed *advances = item->advances; - -// DEBUG("positioned glyphs:"); - for (unsigned int i = 0; i < face->buffer->in_length; i++) { -// DEBUG(" %d:\t orig advance: (%d/%d)\tadv=(%d/%d)\tpos=(%d/%d)\tback=%d\tnew_advance=%d", i, -// glyphs[i].advance.x.toInt(), glyphs[i].advance.y.toInt(), -// (int)(positions[i].x_advance >> 6), (int)(positions[i].y_advance >> 6), -// (int)(positions[i].x_pos >> 6), (int)(positions[i].y_pos >> 6), -// positions[i].back, positions[i].new_advance); - - HB_Fixed adjustment = positions[i].x_advance; - - if (!(face->current_flags & HB_ShaperFlag_UseDesignMetrics)) - adjustment = HB_FIXED_ROUND(adjustment); - - if (positions[i].new_advance) { - ; //advances[i] = adjustment; - } else { - advances[i] += adjustment; - } - - int back = 0; - HB_FixedPoint *offsets = item->offsets; - offsets[i].x = positions[i].x_pos; - offsets[i].y = positions[i].y_pos; - while (positions[i - back].back) { - back += positions[i - back].back; - offsets[i].x += positions[i - back].x_pos; - offsets[i].y += positions[i - back].y_pos; - } - offsets[i].y = -offsets[i].y; - - if (item->item.bidiLevel % 2) { - // ### may need to go back multiple glyphs like in ltr - back = positions[i].back; - while (back--) - offsets[i].x -= advances[i-back]; - } else { - back = 0; - while (positions[i - back].back) { - back += positions[i - back].back; - offsets[i].x -= advances[i-back]; - } - } -// DEBUG(" ->\tadv=%d\tpos=(%d/%d)", -// glyphs[i].advance.x.toInt(), glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt()); - } - item->kerning_applied = face->has_opentype_kerning; - } else { - HB_HeuristicPosition(item); - } - -#ifdef OT_DEBUG - if (doLogClusters) { - DEBUG("log clusters after shaping:"); - for (int j = 0; j < length; j++) - DEBUG(" log[%d] = %d", j, item->log_clusters[j]); - } - DEBUG("final glyphs:"); - for (int i = 0; i < (int)hb_buffer->in_length; ++i) - DEBUG(" glyph=%4x char_index=%d mark: %d cmp: %d, clusterStart: %d advance=%d/%d offset=%d/%d", - glyphs[i].glyph, hb_buffer->in_string[i].cluster, glyphs[i].attributes.mark, - glyphs[i].attributes.combiningClass, glyphs[i].attributes.clusterStart, - glyphs[i].advance.x.toInt(), glyphs[i].advance.y.toInt(), - glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt()); - DEBUG("-----------------------------------------"); -#endif - return true; -} - -HB_Bool HB_ShapeItem(HB_ShaperItem *shaper_item) -{ - HB_Bool result = false; - if (shaper_item->num_glyphs < shaper_item->item.length) { - shaper_item->num_glyphs = shaper_item->item.length; - return false; - } - assert(shaper_item->item.script < HB_ScriptCount); - result = HB_ScriptEngines[shaper_item->item.script].shape(shaper_item); - shaper_item->glyphIndicesPresent = false; - return result; -} diff --git a/src/hb-old/harfbuzz-shaper.h b/src/hb-old/harfbuzz-shaper.h deleted file mode 100644 index ab65004..0000000 --- a/src/hb-old/harfbuzz-shaper.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_SHAPER_H -#define HARFBUZZ_SHAPER_H - -#include "harfbuzz-global.h" -#include "harfbuzz-gdef.h" -#include "harfbuzz-gpos.h" -#include "harfbuzz-gsub.h" -#include "harfbuzz-external.h" -#include "harfbuzz-stream-private.h" - -HB_BEGIN_HEADER - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(push, 1) -#endif - -/* - using anything else than signed or unsigned for bitfields in C is non standard, - but accepted by almost all compilers. And it gives a significant reduction in - memory consumption as HB_CharAttributes and HB_GlyphAttributes will not have - a 4 byte alignment -*/ -#ifdef __xlC__ -typedef unsigned hb_bitfield; -#else -typedef hb_uint8 hb_bitfield; -#endif - -typedef enum { - HB_Script_Common, - HB_Script_Greek, - HB_Script_Cyrillic, - HB_Script_Armenian, - HB_Script_Hebrew, - HB_Script_Arabic, - HB_Script_Syriac, - HB_Script_Thaana, - HB_Script_Devanagari, - HB_Script_Bengali, - HB_Script_Gurmukhi, - HB_Script_Gujarati, - HB_Script_Oriya, - HB_Script_Tamil, - HB_Script_Telugu, - HB_Script_Kannada, - HB_Script_Malayalam, - HB_Script_Sinhala, - HB_Script_Thai, - HB_Script_Lao, - HB_Script_Tibetan, - HB_Script_Myanmar, - HB_Script_Georgian, - HB_Script_Hangul, - HB_Script_Ogham, - HB_Script_Runic, - HB_Script_Khmer, - HB_Script_Nko, - HB_Script_Inherited, - HB_ScriptCount = HB_Script_Inherited - /* - HB_Script_Latin = Common, - HB_Script_Ethiopic = Common, - HB_Script_Cherokee = Common, - HB_Script_CanadianAboriginal = Common, - HB_Script_Mongolian = Common, - HB_Script_Hiragana = Common, - HB_Script_Katakana = Common, - HB_Script_Bopomofo = Common, - HB_Script_Han = Common, - HB_Script_Yi = Common, - HB_Script_OldItalic = Common, - HB_Script_Gothic = Common, - HB_Script_Deseret = Common, - HB_Script_Tagalog = Common, - HB_Script_Hanunoo = Common, - HB_Script_Buhid = Common, - HB_Script_Tagbanwa = Common, - HB_Script_Limbu = Common, - HB_Script_TaiLe = Common, - HB_Script_LinearB = Common, - HB_Script_Ugaritic = Common, - HB_Script_Shavian = Common, - HB_Script_Osmanya = Common, - HB_Script_Cypriot = Common, - HB_Script_Braille = Common, - HB_Script_Buginese = Common, - HB_Script_Coptic = Common, - HB_Script_NewTaiLue = Common, - HB_Script_Glagolitic = Common, - HB_Script_Tifinagh = Common, - HB_Script_SylotiNagri = Common, - HB_Script_OldPersian = Common, - HB_Script_Kharoshthi = Common, - HB_Script_Balinese = Common, - HB_Script_Cuneiform = Common, - HB_Script_Phoenician = Common, - HB_Script_PhagsPa = Common, - */ -} HB_Script; - -typedef struct -{ - hb_uint32 pos; - hb_uint32 length; - HB_Script script; - hb_uint8 bidiLevel; -} HB_ScriptItem; - - -typedef enum { - HB_LeftToRight = 0, - HB_RightToLeft = 1 -} HB_StringToGlyphsFlags; - -typedef enum { - HB_ShaperFlag_Default = 0, - HB_ShaperFlag_NoKerning = 1, - HB_ShaperFlag_UseDesignMetrics = 2 -} HB_ShaperFlag; - -/* - highest value means highest priority for justification. Justification is done by first inserting kashidas - starting with the highest priority positions, then stretching spaces, afterwards extending inter char - spacing, and last spacing between arabic words. - NoJustification is for example set for arabic where no Kashida can be inserted or for diacritics. -*/ -typedef enum { - HB_NoJustification= 0, /* Justification can't be applied after this glyph */ - HB_Arabic_Space = 1, /* This glyph represents a space inside arabic text */ - HB_Character = 2, /* Inter-character justification point follows this glyph */ - HB_Space = 4, /* This glyph represents a blank outside an Arabic run */ - HB_Arabic_Normal = 7, /* Normal Middle-Of-Word glyph that connects to the right (begin) */ - HB_Arabic_Waw = 8, /* Next character is final form of Waw/Ain/Qaf/Fa */ - HB_Arabic_BaRa = 9, /* Next two chars are Ba + Ra/Ya/AlefMaksura */ - HB_Arabic_Alef = 10, /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */ - HB_Arabic_HaaDal = 11, /* Next character is final form of Haa/Dal/Taa Marbutah */ - HB_Arabic_Seen = 12, /* Initial or Medial form Of Seen/Sad */ - HB_Arabic_Kashida = 13 /* Kashida(U+640) in middle of word */ -} HB_JustificationClass; - -/* This structure is binary compatible with Uniscribe's SCRIPT_VISATTR. Would be nice to keep - * it like that. If this is a problem please tell Trolltech :) - */ -typedef struct { - hb_bitfield justification :4; /* Justification class */ - hb_bitfield clusterStart :1; /* First glyph of representation of cluster */ - hb_bitfield mark :1; /* needs to be positioned around base char */ - hb_bitfield zeroWidth :1; /* ZWJ, ZWNJ etc, with no width */ - hb_bitfield dontPrint :1; - hb_bitfield combiningClass :8; -} HB_GlyphAttributes; - -typedef struct HB_FaceRec_ { - HB_Bool isSymbolFont; - - HB_GDEF gdef; - HB_GSUB gsub; - HB_GPOS gpos; - HB_Bool supported_scripts[HB_ScriptCount]; - HB_Buffer buffer; - HB_Script current_script; - int current_flags; /* HB_ShaperFlags */ - HB_Bool has_opentype_kerning; - HB_Bool glyphs_substituted; - HB_GlyphAttributes *tmpAttributes; - unsigned int *tmpLogClusters; - int length; - int orig_nglyphs; -} HB_FaceRec; - -typedef HB_Error (*HB_GetFontTableFunc)(void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length); - -HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc); -void HB_FreeFace(HB_Face face); - -typedef struct { - HB_Fixed x, y; - HB_Fixed width, height; - HB_Fixed xOffset, yOffset; -} HB_GlyphMetrics; - -typedef enum { - HB_FontAscent -} HB_FontMetric; - -typedef struct { - HB_Bool (*convertStringToGlyphIndices)(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft); - void (*getGlyphAdvances)(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags /*HB_ShaperFlag*/); - HB_Bool (*canRender)(HB_Font font, const HB_UChar16 *string, hb_uint32 length); - /* implementation needs to make sure to load a scaled glyph, so /no/ FT_LOAD_NO_SCALE */ - HB_Error (*getPointInOutline)(HB_Font font, HB_Glyph glyph, int flags /*HB_ShaperFlag*/, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints); - void (*getGlyphMetrics)(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics); - HB_Fixed (*getFontMetric)(HB_Font font, HB_FontMetric metric); -} HB_FontClass; - -typedef struct HB_Font_ { - const HB_FontClass *klass; - - /* Metrics */ - HB_UShort x_ppem, y_ppem; - HB_16Dot16 x_scale, y_scale; - - void *userData; -} HB_FontRec; - -#ifdef HB_USE_PACKED_STRUCTS -#pragma pack(pop) -#endif - -typedef struct HB_ShaperItem_ HB_ShaperItem; - -struct HB_ShaperItem_ { - const HB_UChar16 *string; /* input: the Unicode UTF16 text to be shaped */ - hb_uint32 stringLength; /* input: the length of the input in 16-bit words */ - HB_ScriptItem item; /* input: the current run to be shaped: a run of text all in the same script that is a substring of <string> */ - HB_Font font; /* input: the font: scale, units and function pointers supplying glyph indices and metrics */ - HB_Face face; /* input: the shaper state; current script, access to the OpenType tables , etc. */ - int shaperFlags; /* input (unused) should be set to 0; intended to support flags defined in HB_ShaperFlag */ - HB_Bool glyphIndicesPresent; /* input: true if the <glyphs> array contains glyph indices ready to be shaped */ - hb_uint32 initialGlyphCount; /* input: if glyphIndicesPresent is true, the number of glyph indices in the <glyphs> array */ - - hb_uint32 num_glyphs; /* input: capacity of output arrays <glyphs>, <attributes>, <advances>, <offsets>, and <log_clusters>; */ - /* output: required capacity (may be larger than actual capacity) */ - - HB_Glyph *glyphs; /* output: <num_glyphs> indices of shaped glyphs */ - HB_GlyphAttributes *attributes; /* output: <num_glyphs> glyph attributes */ - HB_Fixed *advances; /* output: <num_glyphs> advances */ - HB_FixedPoint *offsets; /* output: <num_glyphs> offsets */ - unsigned short *log_clusters; /* output: for each output glyph, the index in the input of the start of its logical cluster */ - /* XXX the discription for log_clusters is wrong. It maps each input position to output glyph position! */ - - /* internal */ - HB_Bool kerning_applied; /* output: true if kerning was applied by the shaper */ -}; - -HB_Bool HB_ShapeItem(HB_ShaperItem *item); - -HB_END_HEADER - -#endif diff --git a/src/hb-old/harfbuzz-stream-private.h b/src/hb-old/harfbuzz-stream-private.h deleted file mode 100644 index fbd9f81..0000000 --- a/src/hb-old/harfbuzz-stream-private.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod - * - * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_STREAM_PRIVATE_H -#define HARFBUZZ_STREAM_PRIVATE_H - -#include "harfbuzz-impl.h" -#include "harfbuzz-stream.h" - -HB_BEGIN_HEADER - -HB_INTERNAL void -_hb_close_stream( HB_Stream stream ); - -HB_INTERNAL HB_Int -_hb_stream_pos( HB_Stream stream ); - -HB_INTERNAL HB_Error -_hb_stream_seek( HB_Stream stream, - HB_UInt pos ); - -HB_INTERNAL HB_Error -_hb_stream_frame_enter( HB_Stream stream, - HB_UInt size ); - -HB_INTERNAL void -_hb_stream_frame_exit( HB_Stream stream ); - -/* convenience macros */ - -#define SET_ERR(c) ( (error = (c)) != 0 ) - -#define GOTO_Table(tag) (0) -#define FILE_Pos() _hb_stream_pos( stream ) -#define FILE_Seek(pos) SET_ERR( _hb_stream_seek( stream, pos ) ) -#define ACCESS_Frame(size) SET_ERR( _hb_stream_frame_enter( stream, size ) ) -#define FORGET_Frame() _hb_stream_frame_exit( stream ) - -#define GET_Byte() (*stream->cursor++) -#define GET_Short() (stream->cursor += 2, (HB_Short)( \ - (*(((HB_Byte*)stream->cursor)-2) << 8) | \ - *(((HB_Byte*)stream->cursor)-1) \ - )) -#define GET_Long() (stream->cursor += 4, (HB_Int)( \ - (*(((HB_Byte*)stream->cursor)-4) << 24) | \ - (*(((HB_Byte*)stream->cursor)-3) << 16) | \ - (*(((HB_Byte*)stream->cursor)-2) << 8) | \ - *(((HB_Byte*)stream->cursor)-1) \ - )) - - -#define GET_Char() ((HB_Char)GET_Byte()) -#define GET_UShort() ((HB_UShort)GET_Short()) -#define GET_ULong() ((HB_UInt)GET_Long()) -#define GET_Tag4() GET_ULong() - -HB_END_HEADER - -#endif /* HARFBUZZ_STREAM_PRIVATE_H */ diff --git a/src/hb-old/harfbuzz-stream.c b/src/hb-old/harfbuzz-stream.c deleted file mode 100644 index 2d9638f..0000000 --- a/src/hb-old/harfbuzz-stream.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2005 David Turner - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2007 Red Hat, Inc. - * - * This is part of HarfBuzz, an OpenType Layout engine 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 - */ - -#include "harfbuzz-impl.h" -#include "harfbuzz-stream-private.h" -#include <stdlib.h> - -#if 0 -#include <stdio.h> -#define LOG(x) _hb_log x - -static void -_hb_log( const char* format, ... ) -{ - va_list ap; - - va_start( ap, format ); - vfprintf( stderr, format, ap ); - va_end( ap ); -} - -#else -#define LOG(x) do {} while (0) -#endif - -HB_INTERNAL void -_hb_close_stream( HB_Stream stream ) -{ - if (!stream) - return; - free(stream->base); - free(stream); -} - - -HB_INTERNAL HB_Int -_hb_stream_pos( HB_Stream stream ) -{ - LOG(( "_hb_stream_pos() -> %ld\n", stream->pos )); - return stream->pos; -} - - -HB_INTERNAL HB_Error -_hb_stream_seek( HB_Stream stream, - HB_UInt pos ) -{ - HB_Error error = (HB_Error)0; - - stream->pos = pos; - if (pos > stream->size) - error = ERR(HB_Err_Read_Error); - - LOG(( "_hb_stream_seek(%ld) -> 0x%04X\n", pos, error )); - return error; -} - - -HB_INTERNAL HB_Error -_hb_stream_frame_enter( HB_Stream stream, - HB_UInt count ) -{ - HB_Error error = HB_Err_Ok; - - /* check new position, watch for overflow */ - if (HB_UNLIKELY (stream->pos + count > stream->size || - stream->pos + count < stream->pos)) - { - error = ERR(HB_Err_Read_Error); - goto Exit; - } - - /* set cursor */ - stream->cursor = stream->base + stream->pos; - stream->pos += count; - -Exit: - LOG(( "_hb_stream_frame_enter(%ld) -> 0x%04X\n", count, error )); - return error; -} - - -HB_INTERNAL void -_hb_stream_frame_exit( HB_Stream stream ) -{ - stream->cursor = NULL; - - LOG(( "_hb_stream_frame_exit()\n" )); -} diff --git a/src/hb-old/harfbuzz-tibetan.c b/src/hb-old/harfbuzz-tibetan.c deleted file mode 100644 index 8b3e953..0000000 --- a/src/hb-old/harfbuzz-tibetan.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * - * This is part of HarfBuzz, an OpenType Layout engine library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "harfbuzz-shaper.h" -#include "harfbuzz-shaper-private.h" - -#include <assert.h> - -/* - tibetan syllables are of the form: - head position consonant - first sub-joined consonant - ....intermediate sub-joined consonants (if any) - last sub-joined consonant - sub-joined vowel (a-chung U+0F71) - standard or compound vowel sign (or 'virama' for devanagari transliteration) -*/ - -typedef enum { - TibetanOther, - TibetanHeadConsonant, - TibetanSubjoinedConsonant, - TibetanSubjoinedVowel, - TibetanVowel -} TibetanForm; - -/* this table starts at U+0f40 */ -static const unsigned char tibetanForm[0x80] = { - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, - TibetanOther, TibetanOther, TibetanOther, TibetanOther, - - TibetanOther, TibetanVowel, TibetanVowel, TibetanVowel, - TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, - TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, - TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, - - TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, - TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, - TibetanOther, TibetanOther, TibetanOther, TibetanOther, - TibetanOther, TibetanOther, TibetanOther, TibetanOther, - - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, - TibetanSubjoinedConsonant, TibetanOther, TibetanOther, TibetanOther -}; - - -#define tibetan_form(c) \ - ((c) >= 0x0f40 && (c) < 0x0fc0 ? (TibetanForm)tibetanForm[(c) - 0x0f40] : TibetanOther) - -static const HB_OpenTypeFeature tibetan_features[] = { - { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty }, - { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty }, - { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty }, - {0, 0} -}; - -static HB_Bool tibetan_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid) -{ - hb_uint32 i; - const HB_UChar16 *str = item->string + item->item.pos; - int len = item->item.length; -#ifndef NO_OPENTYPE - const int availableGlyphs = item->num_glyphs; -#endif - HB_Bool haveGlyphs; - HB_STACKARRAY(HB_UChar16, reordered, len + 4); - - if (item->num_glyphs < item->item.length + 4) { - item->num_glyphs = item->item.length + 4; - HB_FREE_STACKARRAY(reordered); - return FALSE; - } - - if (invalid) { - *reordered = 0x25cc; - memcpy(reordered+1, str, len*sizeof(HB_UChar16)); - len++; - str = reordered; - } - - haveGlyphs = item->font->klass->convertStringToGlyphIndices(item->font, - str, len, - item->glyphs, &item->num_glyphs, - item->item.bidiLevel % 2); - - HB_FREE_STACKARRAY(reordered); - - if (!haveGlyphs) - return FALSE; - - for (i = 0; i < item->item.length; i++) { - item->attributes[i].mark = FALSE; - item->attributes[i].clusterStart = FALSE; - item->attributes[i].justification = 0; - item->attributes[i].zeroWidth = FALSE; -/* IDEBUG(" %d: %4x", i, str[i]); */ - } - - /* now we have the syllable in the right order, and can start running it through open type. */ - -#ifndef NO_OPENTYPE - if (openType) { - HB_OpenTypeShape(item, /*properties*/0); - if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE)) - return FALSE; - } else { - HB_HeuristicPosition(item); - } -#endif - - item->attributes[0].clusterStart = TRUE; - return TRUE; -} - - -static int tibetan_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid) -{ - const HB_UChar16 *uc = s + start; - - int pos = 0; - TibetanForm state = tibetan_form(*uc); - -/* qDebug("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);*/ - pos++; - - if (state != TibetanHeadConsonant) { - if (state != TibetanOther) - *invalid = TRUE; - goto finish; - } - - while (pos < end - start) { - TibetanForm newState = tibetan_form(uc[pos]); - switch(newState) { - case TibetanSubjoinedConsonant: - case TibetanSubjoinedVowel: - if (state != TibetanHeadConsonant && - state != TibetanSubjoinedConsonant) - goto finish; - state = newState; - break; - case TibetanVowel: - if (state != TibetanHeadConsonant && - state != TibetanSubjoinedConsonant && - state != TibetanSubjoinedVowel) - goto finish; - break; - case TibetanOther: - case TibetanHeadConsonant: - goto finish; - } - pos++; - } - -finish: - *invalid = FALSE; - return start+pos; -} - -HB_Bool HB_TibetanShape(HB_ShaperItem *item) -{ - - HB_Bool openType = FALSE; - unsigned short *logClusters = item->log_clusters; - - HB_ShaperItem syllable = *item; - int first_glyph = 0; - - int sstart = item->item.pos; - int end = sstart + item->item.length; - - assert(item->item.script == HB_Script_Tibetan); - -#ifndef QT_NO_OPENTYPE - openType = HB_SelectScript(item, tibetan_features); -#endif - - while (sstart < end) { - HB_Bool invalid; - int i; - int send = tibetan_nextSyllableBoundary(item->string, sstart, end, &invalid); -/* IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, - invalid ? "TRUE" : "FALSE"); */ - syllable.item.pos = sstart; - syllable.item.length = send-sstart; - syllable.glyphs = item->glyphs + first_glyph; - syllable.attributes = item->attributes + first_glyph; - syllable.offsets = item->offsets + first_glyph; - syllable.advances = item->advances + first_glyph; - syllable.num_glyphs = item->num_glyphs - first_glyph; - if (!tibetan_shape_syllable(openType, &syllable, invalid)) { - item->num_glyphs += syllable.num_glyphs; - return FALSE; - } - /* fix logcluster array */ - for (i = sstart; i < send; ++i) - logClusters[i-item->item.pos] = first_glyph; - sstart = send; - first_glyph += syllable.num_glyphs; - } - item->num_glyphs = first_glyph; - return TRUE; -} diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh index 250504a..57db59d 100644 --- a/src/hb-open-file-private.hh +++ b/src/hb-open-file-private.hh @@ -110,9 +110,9 @@ typedef struct OffsetTable protected: Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ USHORT numTables; /* Number of tables. */ - USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */ - USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */ - USHORT rangeShift; /* NumTables x 16-searchRange. */ + 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); @@ -138,8 +138,8 @@ struct TTCHeaderVersion1 protected: Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion version; /* Version of the TTC Header (1.0), - * 0x00010000 */ - LongOffsetLongArrayOf<OffsetTable> + * 0x00010000u */ + ArrayOf<OffsetTo<OffsetTable, ULONG>, ULONG> table; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ public: @@ -184,7 +184,7 @@ struct TTCHeader struct { Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion version; /* Version of the TTC Header (1.0 or 2.0), - * 0x00010000 or 0x00020000 */ + * 0x00010000u or 0x00020000u */ } header; TTCHeaderVersion1 version1; } u; diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 90f2836..475187b 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -31,8 +31,6 @@ #include "hb-private.hh" -#include "hb-blob.h" - namespace OT { @@ -44,36 +42,36 @@ namespace OT { /* Cast to struct T, reference to reference */ template<typename Type, typename TObject> -inline const Type& CastR(const TObject &X) +static inline const Type& CastR(const TObject &X) { return reinterpret_cast<const Type&> (X); } template<typename Type, typename TObject> -inline Type& CastR(TObject &X) +static inline Type& CastR(TObject &X) { return reinterpret_cast<Type&> (X); } /* Cast to struct T, pointer to pointer */ template<typename Type, typename TObject> -inline const Type* CastP(const TObject *X) +static inline const Type* CastP(const TObject *X) { return reinterpret_cast<const Type*> (X); } template<typename Type, typename TObject> -inline Type* CastP(TObject *X) +static inline Type* CastP(TObject *X) { return reinterpret_cast<Type*> (X); } /* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory * location pointed to by P plus Ofs bytes. */ template<typename Type> -inline const Type& StructAtOffset(const void *P, unsigned int offset) +static inline const Type& StructAtOffset(const void *P, unsigned int offset) { return * reinterpret_cast<const Type*> ((const char *) P + offset); } template<typename Type> -inline Type& StructAtOffset(void *P, unsigned int offset) +static inline Type& StructAtOffset(void *P, unsigned int offset) { return * reinterpret_cast<Type*> ((char *) P + offset); } /* StructAfter<T>(X) returns the struct T& that is placed after X. * Works with X of variable size also. X must implement get_size() */ template<typename Type, typename TObject> -inline const Type& StructAfter(const TObject &X) +static inline const Type& StructAfter(const TObject &X) { return StructAtOffset<Type>(&X, X.get_size()); } template<typename Type, typename TObject> -inline Type& StructAfter(TObject &X) +static inline Type& StructAfter(TObject &X) { return StructAtOffset<Type>(&X, X.get_size()); } @@ -134,7 +132,7 @@ inline Type& StructAfter(TObject &X) /* Global nul-content Null pool. Enlarge as necessary. */ /* TODO This really should be a extern HB_INTERNAL and defined somewhere... */ -static const void *_NullPool[64 / sizeof (void *)]; +static const void *_NullPool[(256+8) / sizeof (void *)]; /* Generic nul-content Null objects. */ template <typename Type> @@ -147,7 +145,7 @@ static inline const Type& Null (void) { #define DEFINE_NULL_DATA(Type, data) \ static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \ template <> \ -inline const Type& Null<Type> (void) { \ +/*static*/ inline const Type& Null<Type> (void) { \ return *CastP<Type> (_Null##Type); \ } /* The following line really exists such that we end in a place needing semicolon */ \ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) @@ -171,6 +169,10 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ ""); +/* This limits sanitizing time on really broken fonts. */ +#ifndef HB_SANITIZE_MAX_EDITS +#define HB_SANITIZE_MAX_EDITS 100 +#endif struct hb_sanitize_context_t { @@ -178,7 +180,7 @@ struct hb_sanitize_context_t static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; typedef bool return_t; template <typename T> - inline return_t process (const T &obj) { return obj.sanitize (this); } + inline return_t dispatch (const T &obj) { return obj.sanitize (this); } static return_t default_return_value (void) { return true; } bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; } @@ -247,6 +249,9 @@ struct hb_sanitize_context_t inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED) { + if (this->edit_count >= HB_SANITIZE_MAX_EDITS) + return false; + const char *p = (const char *) base; this->edit_count++; @@ -261,6 +266,15 @@ struct hb_sanitize_context_t return TRACE_RETURN (this->writable); } + template <typename Type, typename ValueType> + inline bool try_set (Type *obj, const ValueType &v) { + if (this->may_edit (obj, obj->static_size)) { + obj->set (v); + return true; + } + return false; + } + mutable unsigned int debug_depth; const char *start, *end; bool writable; @@ -275,7 +289,7 @@ template <typename Type> struct Sanitizer { static hb_blob_t *sanitize (hb_blob_t *blob) { - hb_sanitize_context_t c[1] = {{0}}; + hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}}; bool sane; /* TODO is_sane() stuff */ @@ -404,7 +418,7 @@ struct hb_serialize_context_t template <typename Type> inline Type *allocate_size (unsigned int size) { - if (unlikely (this->ran_out_of_room || this->end - this->head < size)) { + if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) { this->ran_out_of_room = true; return NULL; } @@ -567,6 +581,7 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; +typedef uint8_t BYTE; /* 8-bit unsigned integer. */ typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ @@ -587,7 +602,7 @@ struct LONGDATETIME TRACE_SANITIZE (this); return TRACE_RETURN (likely (c->check_struct (this))); } - private: + protected: LONG major; ULONG minor; public: @@ -611,39 +626,38 @@ typedef USHORT GlyphID; /* Script/language-system/feature index */ struct Index : USHORT { - static const unsigned int NOT_FOUND_INDEX = 0xFFFF; + static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; }; DEFINE_NULL_DATA (Index, "\xff\xff"); -/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */ -struct Offset : USHORT +/* Offset, Null offset = 0 */ +template <typename Type=USHORT> +struct Offset : Type { inline bool is_null (void) const { return 0 == *this; } public: - DEFINE_SIZE_STATIC (2); -}; - -/* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */ -struct LongOffset : ULONG -{ - inline bool is_null (void) const { return 0 == *this; } - public: - DEFINE_SIZE_STATIC (4); + DEFINE_SIZE_STATIC (sizeof(Type)); }; /* CheckSum */ struct CheckSum : ULONG { - static uint32_t CalcTableChecksum (ULONG *Table, uint32_t Length) + /* This is reference implementation from the spec. */ + static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length) { uint32_t Sum = 0L; - ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size; + const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size; while (Table < EndPtr) Sum += *Table++; return Sum; } + + /* Note: data should be 4byte aligned and have 4byte padding at the end. */ + inline void set_for_data (const void *data, unsigned int length) + { set (CalcTableChecksum ((const ULONG *) data, length)); } + public: DEFINE_SIZE_STATIC (4); }; @@ -671,12 +685,12 @@ struct FixedVersion /* - * Template subclasses of Offset and LongOffset that do the dereferencing. + * Template subclasses of Offset that do the dereferencing. * Use: (base+offset) */ -template <typename OffsetType, typename Type> -struct GenericOffsetTo : OffsetType +template <typename Type, typename OffsetType=USHORT> +struct OffsetTo : Offset<OffsetType> { inline const Type& operator () (const void *base) const { @@ -684,11 +698,6 @@ struct GenericOffsetTo : OffsetType if (unlikely (!offset)) return Null(Type); return StructAtOffset<Type> (base, offset); } - inline Type& operator () (void *base) - { - unsigned int offset = *this; - return StructAtOffset<Type> (base, offset); - } inline Type& serialize (hb_serialize_context_t *c, void *base) { @@ -715,40 +724,25 @@ struct GenericOffsetTo : OffsetType return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); } - inline bool try_set (hb_sanitize_context_t *c, const OffsetType &v) { - if (c->may_edit (this, this->static_size)) { - this->set (v); - return true; - } - return false; - } /* Set the offset to Null */ inline bool neuter (hb_sanitize_context_t *c) { - if (c->may_edit (this, this->static_size)) { - this->set (0); /* 0 is Null offset */ - return true; - } - return false; + return c->try_set (this, 0); } + DEFINE_SIZE_STATIC (sizeof(OffsetType)); }; template <typename Base, typename OffsetType, typename Type> -inline const Type& operator + (const Base &base, const GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); } +static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); } template <typename Base, typename OffsetType, typename Type> -inline Type& operator + (Base &base, GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); } - -template <typename Type> -struct OffsetTo : GenericOffsetTo<Offset, Type> {}; - -template <typename Type> -struct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {}; +static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); } /* * Array Types */ -template <typename LenType, typename Type> -struct GenericArrayOf +/* An array with a number of elements. */ +template <typename Type, typename LenType=USHORT> +struct ArrayOf { const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const { @@ -831,6 +825,16 @@ struct GenericArrayOf return TRACE_RETURN (true); } + template <typename SearchType> + inline int lsearch (const SearchType &x) const + { + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!this->array[i].cmp (x)) + return i; + return -1; + } + private: inline bool sanitize_shallow (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); @@ -844,26 +848,10 @@ struct GenericArrayOf DEFINE_SIZE_ARRAY (sizeof (LenType), array); }; -/* An array with a USHORT number of elements. */ -template <typename Type> -struct ArrayOf : GenericArrayOf<USHORT, Type> {}; - -/* An array with a ULONG number of elements. */ -template <typename Type> -struct LongArrayOf : GenericArrayOf<ULONG, Type> {}; - /* Array of Offset's */ template <typename Type> struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; -/* Array of LongOffset's */ -template <typename Type> -struct LongOffsetArrayOf : ArrayOf<LongOffsetTo<Type> > {}; - -/* LongArray of LongOffset's */ -template <typename Type> -struct LongOffsetLongArrayOf : LongArrayOf<LongOffsetTo<Type> > {}; - /* Array of offsets relative to the beginning of the array itself. */ template <typename Type> struct OffsetListOf : OffsetArrayOf<Type> @@ -886,9 +874,8 @@ struct OffsetListOf : OffsetArrayOf<Type> }; -/* An array with a USHORT number of elements, - * starting at second element. */ -template <typename Type> +/* An array starting at second element. */ +template <typename Type, typename LenType=USHORT> struct HeadlessArrayOf { inline const Type& operator [] (unsigned int i) const @@ -935,33 +922,34 @@ struct HeadlessArrayOf return TRACE_RETURN (true); } - USHORT len; + LenType len; Type array[VAR]; public: - DEFINE_SIZE_ARRAY (sizeof (USHORT), array); + DEFINE_SIZE_ARRAY (sizeof (LenType), array); }; /* An array with sorted elements. Supports binary searching. */ -template <typename Type> -struct SortedArrayOf : ArrayOf<Type> { - +template <typename Type, typename LenType=USHORT> +struct SortedArrayOf : ArrayOf<Type, LenType> +{ template <typename SearchType> - inline int search (const SearchType &x) const { - unsigned int count = this->len; - /* Linear search is *much* faster for small counts. */ - if (likely (count < 32)) { - for (unsigned int i = 0; i < count; i++) - if (this->array[i].cmp (x) == 0) - return i; - return -1; - } else { - struct Cmp { - static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); } - }; - const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (this->array[0]), (hb_compare_func_t) Cmp::cmp); - return p ? p - this->array : -1; + inline int bsearch (const SearchType &x) const + { + /* Hand-coded bsearch here since this is in the hot inner loop. */ + int min = 0, max = (int) this->len - 1; + while (min <= max) + { + int mid = (min + max) / 2; + int c = this->array[mid].cmp (x); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + return mid; } + return -1; } }; diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh new file mode 100644 index 0000000..d531411 --- /dev/null +++ b/src/hb-ot-cmap-table.hh @@ -0,0 +1,517 @@ +/* + * 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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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 +{ + inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + { + unsigned int segCount; + const USHORT *endCount; + const USHORT *startCount; + const USHORT *idDelta; + const USHORT *idRangeOffset; + const USHORT *glyphIdArray; + unsigned int glyphIdArrayLength; + + segCount = this->segCountX2 / 2; + endCount = this->values; + startCount = endCount + segCount + 1; + idDelta = startCount + segCount; + idRangeOffset = idDelta + segCount; + glyphIdArray = idRangeOffset + segCount; + glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; + + /* Custom two-array bsearch. */ + int min = 0, max = (int) segCount - 1; + 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 = idRangeOffset[i]; + if (rangeOffset == 0) + gid = codepoint + idDelta[i]; + else + { + /* Somebody has been smoking... */ + unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount; + if (unlikely (index >= glyphIdArrayLength)) + return false; + gid = glyphIdArray[index]; + if (unlikely (!gid)) + return false; + gid += idDelta[i]; + } + + *glyph = gid & 0xFFFFu; + return true; + } + + inline bool sanitize (hb_sanitize_context_t *c) + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return TRACE_RETURN (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_RETURN (false); + } + + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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, void *base) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (c->check_struct (this) && + record.sanitize (c, this)); + } + + protected: + USHORT format; /* Format number is set to 0. */ + 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 glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph) const + { + switch (u.format) { + case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph); + default: return GLYPH_VARIANT_NOT_FOUND; + } + } + + inline bool sanitize (hb_sanitize_context_t *c) { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return TRACE_RETURN (false); + switch (u.format) { + case 0: return TRACE_RETURN (u.format0 .sanitize (c)); + case 4: return TRACE_RETURN (u.format4 .sanitize (c)); + case 6: return TRACE_RETURN (u.format6 .sanitize (c)); + case 10: return TRACE_RETURN (u.format10.sanitize (c)); + case 12: return TRACE_RETURN (u.format12.sanitize (c)); + case 13: return TRACE_RETURN (u.format13.sanitize (c)); + case 14: return TRACE_RETURN (u.format14.sanitize (c)); + default:return TRACE_RETURN (true); + } + } + + protected: + 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, void *base) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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 */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc new file mode 100644 index 0000000..c9890c5 --- /dev/null +++ b/src/hb-ot-font.cc @@ -0,0 +1,289 @@ +/* + * 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-hhea-table.hh" +#include "hb-ot-hmtx-table.hh" + + + +struct hb_ot_font_t +{ + unsigned int num_glyphs; + unsigned int num_hmetrics; + const OT::hmtx *hmtx; + hb_blob_t *hmtx_blob; + + const OT::CmapSubtable *cmap; + const OT::CmapSubtable *cmap_uvs; + hb_blob_t *cmap_blob; +}; + + +static hb_ot_font_t * +_hb_ot_font_create (hb_font_t *font) +{ + 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->num_glyphs = font->face->get_num_glyphs (); + + { + hb_blob_t *hhea_blob = OT::Sanitizer<OT::hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea)); + const OT::hhea *hhea = OT::Sanitizer<OT::hhea>::lock_instance (hhea_blob); + ot_font->num_hmetrics = hhea->numberOfHMetrics; + hb_blob_destroy (hhea_blob); + } + ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::sanitize (font->face->reference_table (HB_OT_TAG_hmtx)); + if (unlikely (!ot_font->num_hmetrics || + 2 * (ot_font->num_hmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->hmtx_blob))) + { + hb_blob_destroy (ot_font->hmtx_blob); + free (ot_font); + return NULL; + } + ot_font->hmtx = OT::Sanitizer<OT::hmtx>::lock_instance (ot_font->hmtx_blob); + + ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap)); + const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob); + const OT::CmapSubtable *subtable = NULL; + const OT::CmapSubtable *subtable_uvs = NULL; + + /* 32-bit subtables. */ + if (!subtable) subtable = cmap->find_subtable (0, 6); + if (!subtable) subtable = cmap->find_subtable (0, 4); + if (!subtable) subtable = cmap->find_subtable (3, 10); + /* 16-bit subtables. */ + if (!subtable) subtable = cmap->find_subtable (0, 3); + if (!subtable) subtable = cmap->find_subtable (3, 1); + /* Meh. */ + if (!subtable) subtable = &OT::Null(OT::CmapSubtable); + + /* UVS subtable. */ + if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5); + /* Meh. */ + if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable); + + ot_font->cmap = subtable; + ot_font->cmap_uvs = subtable_uvs; + + return ot_font; +} + +static void +_hb_ot_font_destroy (hb_ot_font_t *ot_font) +{ + hb_blob_destroy (ot_font->cmap_blob); + hb_blob_destroy (ot_font->hmtx_blob); + + free (ot_font); +} + + +static hb_bool_t +hb_ot_get_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; + + if (unlikely (variation_selector)) + { + switch (ot_font->cmap_uvs->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 ot_font->cmap->get_glyph (unicode, 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; + + if (unlikely (glyph >= ot_font->num_glyphs)) + return 0; /* Maybe better to return notdef's advance instead? */ + + if (glyph >= ot_font->num_hmetrics) + glyph = ot_font->num_hmetrics - 1; + + return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advanceWidth); +} + +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) +{ + /* TODO */ + return 0; +} + +static hb_bool_t +hb_ot_get_glyph_h_origin (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_position_t *x HB_UNUSED, + hb_position_t *y HB_UNUSED, + void *user_data HB_UNUSED) +{ + /* We always work in the horizontal coordinates. */ + return true; +} + +static hb_bool_t +hb_ot_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) +{ + /* TODO */ + return false; +} + +static hb_position_t +hb_ot_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) +{ + /* TODO */ + return 0; +} + +static hb_position_t +hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t top_glyph HB_UNUSED, + hb_codepoint_t bottom_glyph HB_UNUSED, + void *user_data HB_UNUSED) +{ + return 0; +} + +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) +{ + /* TODO */ + return false; +} + +static hb_bool_t +hb_ot_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) +{ + /* TODO */ + return false; +} + +static hb_bool_t +hb_ot_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) +{ + /* TODO */ + return false; +} + +static hb_bool_t +hb_ot_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) +{ + /* TODO */ + return false; +} + + +static hb_font_funcs_t * +_hb_ot_get_font_funcs (void) +{ + static const hb_font_funcs_t ot_ffuncs = { + HB_OBJECT_HEADER_STATIC, + + true, /* immutable */ + + { +#define HB_FONT_FUNC_IMPLEMENT(name) hb_ot_get_##name, + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + } + }; + + return const_cast<hb_font_funcs_t *> (&ot_ffuncs); +} + + +void +hb_ot_font_set_funcs (hb_font_t *font) +{ + hb_ot_font_t *ot_font = _hb_ot_font_create (font); + 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); +} diff --git a/src/hb-old/harfbuzz.h b/src/hb-ot-font.h index e91a33e..7a8c04a 100644 --- a/src/hb-old/harfbuzz.h +++ b/src/hb-ot-font.h @@ -1,8 +1,7 @@ /* - * Copyright (C) 1998-2004 David Turner and Werner Lemberg - * Copyright (C) 2006 Behdad Esfahbod + * Copyright © 2014 Google, Inc. * - * This is part of HarfBuzz, an OpenType Layout engine library. + * 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 @@ -21,18 +20,22 @@ * 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 HARFBUZZ_H -#define HARFBUZZ_H +#ifndef HB_OT_FONT_H +#define HB_OT_FONT_H + +#include "hb.h" + +HB_BEGIN_DECLS + + +void +hb_ot_font_set_funcs (hb_font_t *font); + -#include "harfbuzz-external.h" -#include "harfbuzz-global.h" -#include "harfbuzz-buffer.h" -#include "harfbuzz-gdef.h" -#include "harfbuzz-gsub.h" -#include "harfbuzz-gpos.h" -#include "harfbuzz-open.h" -#include "harfbuzz-shaper.h" +HB_END_DECLS -#endif /* HARFBUZZ_OPEN_H */ +#endif /* HB_OT_FONT_H */ diff --git a/src/hb-ot-head-table.hh b/src/hb-ot-head-table.hh index 3a94512..ec4e8c9 100644 --- a/src/hb-ot-head-table.hh +++ b/src/hb-ot-head-table.hh @@ -43,7 +43,7 @@ namespace OT { struct head { - static const hb_tag_t Tag = HB_OT_TAG_head; + static const hb_tag_t tableTag = HB_OT_TAG_head; inline unsigned int get_upem (void) const { unsigned int upem = unitsPerEm; @@ -58,12 +58,12 @@ struct head protected: FixedVersion version; /* Version of the head table--currently - * 0x00010000 for version 1.0. */ + * 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 - * 0xB1B0AFBA - sum. */ - ULONG magicNumber; /* Set to 0x5F0F3CF5. */ + * 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; diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh index 2b89c4e..d433200 100644 --- a/src/hb-ot-hhea-table.hh +++ b/src/hb-ot-hhea-table.hh @@ -42,15 +42,15 @@ namespace OT { struct hhea { - static const hb_tag_t Tag = HB_OT_TAG_hhea; + static const hb_tag_t tableTag = HB_OT_TAG_hhea; inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); } - protected: - FixedVersion version; /* 0x00010000 for version 1.0. */ + public: + FixedVersion version; /* 0x00010000u for version 1.0. */ FWORD ascender; /* Typographic ascent. <a * href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html"> * (Distance from baseline of highest diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index b94337d..e918e3b 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -50,7 +50,7 @@ struct LongHorMetric struct hmtx { - static const hb_tag_t Tag = HB_OT_TAG_hmtx; + static const hb_tag_t tableTag = HB_OT_TAG_hmtx; inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); @@ -59,7 +59,7 @@ struct hmtx return TRACE_RETURN (true); } - protected: + public: LongHorMetric longHorMetric[VAR]; /* Paired advance width and left side * bearing values for each glyph. The * value numOfHMetrics comes from diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index e6018db..abd063c 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -39,6 +39,7 @@ namespace OT { #define NOT_COVERED ((unsigned int) -1) #define MAX_NESTING_LEVEL 8 +#define MAX_CONTEXT_LENGTH 64 @@ -102,7 +103,8 @@ struct RecordArrayOf : SortedArrayOf<Record<Type> > { } inline bool find_index (hb_tag_t tag, unsigned int *index) const { - int i = this->search (tag); + /* If we want to allow non-sorted data, we can lsearch(). */ + int i = this->/*lsearch*/bsearch (tag); if (i != -1) { if (index) *index = i; return true; @@ -129,8 +131,7 @@ struct RecordListOf : RecordArrayOf<Type> struct RangeRecord { inline int cmp (hb_codepoint_t g) const { - hb_codepoint_t a = start, b = end; - return g < a ? -1 : g <= b ? 0 : +1 ; + return g < start ? -1 : g <= end ? 0 : +1 ; } inline bool sanitize (hb_sanitize_context_t *c) { @@ -189,10 +190,10 @@ struct LangSys unsigned int *feature_indexes /* OUT */) const { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } - inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; } + inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; } inline unsigned int get_required_feature_index (void) const { - if (reqFeatureIndex == 0xffff) + if (reqFeatureIndex == 0xFFFFu) return Index::NOT_FOUND_INDEX; return reqFeatureIndex;; } @@ -203,11 +204,11 @@ struct LangSys return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); } - Offset lookupOrder; /* = Null (reserved for an offset to a + Offset<> lookupOrderZ; /* = Null (reserved for an offset to a * reordering table) */ USHORT reqFeatureIndex;/* Index of a feature required for this * language system--if no required features - * = 0xFFFF */ + * = 0xFFFFu */ IndexArray featureIndex; /* Array of indices into the FeatureList */ public: DEFINE_SIZE_ARRAY (6, featureIndex); @@ -377,7 +378,7 @@ struct FeatureParamsStylisticSet return TRACE_RETURN (c->check_struct (this)); } - USHORT minorVersion; /* (set to 0): This corresponds to a “minor” + USHORT version; /* (set to 0): This corresponds to a “minor” * version number. Additional data may be * added to the end of this Feature Parameters * table in the future. */ @@ -400,6 +401,7 @@ struct FeatureParamsStylisticSet DEFINE_SIZE_STATIC (4); }; +/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ struct FeatureParamsCharacterVariants { inline bool sanitize (hb_sanitize_context_t *c) { @@ -446,9 +448,9 @@ struct FeatureParams TRACE_SANITIZE (this); if (tag == HB_TAG ('s','i','z','e')) return TRACE_RETURN (u.size.sanitize (c)); - if ((tag & 0xFFFF0000) == HB_TAG ('s','s','\0','\0')) /* ssXX */ + if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ return TRACE_RETURN (u.stylisticSet.sanitize (c)); - if ((tag & 0xFFFF0000) == HB_TAG ('c','v','\0','\0')) /* cvXX */ + if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ return TRACE_RETURN (u.characterVariants.sanitize (c)); return TRACE_RETURN (true); } @@ -500,11 +502,11 @@ struct Feature * Adobe tools, only the 'size' feature had FeatureParams defined. */ - Offset orig_offset = featureParams; + OffsetTo<FeatureParams> orig_offset = featureParams; if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) return TRACE_RETURN (false); - if (likely (!orig_offset)) + if (likely (orig_offset.is_null ())) return TRACE_RETURN (true); if (featureParams == 0 && closure && @@ -512,13 +514,13 @@ struct Feature closure->list_base && closure->list_base < this) { unsigned int new_offset_int = (unsigned int) orig_offset - - ((char *) this - (char *) closure->list_base); + (((char *) this) - ((char *) closure->list_base)); - Offset new_offset; + OffsetTo<FeatureParams> new_offset; /* Check that it did not overflow. */ new_offset.set (new_offset_int); if (new_offset == new_offset_int && - featureParams.try_set (c, new_offset) && + c->try_set (&featureParams, new_offset) && !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) return TRACE_RETURN (false); } @@ -583,7 +585,7 @@ struct Lookup TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); lookupType.set (lookup_type); - lookupFlag.set (lookup_props & 0xFFFF); + lookupFlag.set (lookup_props & 0xFFFFu); if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { @@ -607,7 +609,7 @@ struct Lookup USHORT lookupType; /* Different enumerations for GSUB and GPOS */ USHORT lookupFlag; /* Lookup qualifiers */ - ArrayOf<Offset> + ArrayOf<Offset<> > subTable; /* Array of SubTables */ USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets * structure. This field is only present if bit @@ -630,7 +632,7 @@ struct CoverageFormat1 private: inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { - int i = glyphArray.search (glyph_id); + int i = glyphArray.bsearch (glyph_id); ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED); return i; } @@ -695,7 +697,7 @@ struct CoverageFormat2 private: inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { - int i = rangeRecord.search (glyph_id); + int i = rangeRecord.bsearch (glyph_id); if (i != -1) { const RangeRecord &range = rangeRecord[i]; return (unsigned int) range.value + (glyph_id - range.start); @@ -872,16 +874,16 @@ struct Coverage inline void init (const Coverage &c_) { format = c_.u.format; switch (format) { - case 1: return u.format1.init (c_.u.format1); - case 2: return u.format2.init (c_.u.format2); - default:return; + case 1: u.format1.init (c_.u.format1); return; + case 2: u.format2.init (c_.u.format2); return; + default: return; } } inline bool more (void) { switch (format) { case 1: return u.format1.more (); case 2: return u.format2.more (); - default:return true; + default:return false; } } inline void next (void) { @@ -895,14 +897,14 @@ struct Coverage switch (format) { case 1: return u.format1.get_glyph (); case 2: return u.format2.get_glyph (); - default:return true; + default:return 0; } } inline uint16_t get_coverage (void) { switch (format) { case 1: return u.format1.get_coverage (); case 2: return u.format2.get_coverage (); - default:return true; + default:return -1; } } @@ -956,6 +958,19 @@ struct ClassDefFormat1 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { unsigned int count = classValue.len; + if (klass == 0) + { + /* Match if there's any glyph that is not listed! */ + hb_codepoint_t g = -1; + if (!hb_set_next (glyphs, &g)) + return false; + if (g < startGlyph) + return true; + g = startGlyph + count - 1; + if (hb_set_next (glyphs, &g)) + return true; + /* Fall through. */ + } for (unsigned int i = 0; i < count; i++) if (classValue[i] == klass && glyphs->has (startGlyph + i)) return true; @@ -978,7 +993,7 @@ struct ClassDefFormat2 private: inline unsigned int get_class (hb_codepoint_t glyph_id) const { - int i = rangeRecord.search (glyph_id); + int i = rangeRecord.bsearch (glyph_id); if (i != -1) return rangeRecord[i].value; return 0; @@ -999,6 +1014,22 @@ struct ClassDefFormat2 inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { unsigned int count = rangeRecord.len; + if (klass == 0) + { + /* Match if there's any glyph that is not listed! */ + hb_codepoint_t g = (hb_codepoint_t) -1; + for (unsigned int i = 0; i < count; i++) + { + if (!hb_set_next (glyphs, &g)) + break; + if (g < rangeRecord[i].start) + return true; + g = rangeRecord[i].end; + } + if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) + return true; + /* Fall through. */ + } for (unsigned int i = 0; i < count; i++) if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) return true; @@ -1083,7 +1114,7 @@ struct Device if (!pixels) return 0; - return pixels * (int64_t) scale / ppem; + return (int) (pixels * (int64_t) scale / ppem); } @@ -1100,7 +1131,7 @@ struct Device unsigned int byte = deltaValue[s >> (4 - f)]; unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f))); - unsigned int mask = (0xFFFF >> (16 - (1 << f))); + unsigned int mask = (0xFFFFu >> (16 - (1 << f))); int delta = bits & mask; diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index ff2d09c..84a5e79 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -282,7 +282,7 @@ struct MarkGlyphSetsFormat1 protected: USHORT format; /* Format identifier--format = 1 */ - LongOffsetArrayOf<Coverage> + ArrayOf<OffsetTo<Coverage, ULONG> > coverage; /* Array of long offsets to mark set * coverage tables */ public: @@ -324,7 +324,7 @@ struct MarkGlyphSets struct GDEF { - static const hb_tag_t Tag = HB_OT_TAG_GDEF; + static const hb_tag_t tableTag = HB_OT_TAG_GDEF; enum GlyphClasses { UnclassifiedGlyph = 0, @@ -360,9 +360,9 @@ struct GDEF hb_position_t *caret_array /* OUT */) const { return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); } - inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002 && markGlyphSetsDef[0] != 0; } + inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef[0] != 0; } inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const - { return version.to_int () >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); } + { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); } inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); @@ -372,7 +372,7 @@ struct GDEF attachList.sanitize (c, this) && ligCaretList.sanitize (c, this) && markAttachClassDef.sanitize (c, this) && - (version.to_int () < 0x00010002 || markGlyphSetsDef[0].sanitize (c, this))); + (version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this))); } @@ -383,12 +383,14 @@ struct GDEF { 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: - case UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED; + default: return 0; case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH; case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; - case ComponentGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT; case MarkGlyph: klass = get_mark_attachment_type (glyph); return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8); @@ -398,7 +400,7 @@ struct GDEF protected: FixedVersion version; /* Version of the GDEF table--currently - * 0x00010002 */ + * 0x00010002u */ OffsetTo<ClassDef> glyphClassDef; /* Offset to class definition table * for glyph type--from beginning of diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 3e43694..8e2860c 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008,2009,2010 Red Hat, Inc. - * Copyright © 2010,2012 Google, Inc. + * Copyright © 2010,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -49,18 +49,18 @@ typedef Value ValueRecord[VAR]; struct ValueFormat : USHORT { enum Flags { - xPlacement = 0x0001, /* Includes horizontal adjustment for placement */ - yPlacement = 0x0002, /* Includes vertical adjustment for placement */ - xAdvance = 0x0004, /* Includes horizontal adjustment for advance */ - yAdvance = 0x0008, /* Includes vertical adjustment for advance */ - xPlaDevice = 0x0010, /* Includes horizontal Device table for placement */ - yPlaDevice = 0x0020, /* Includes vertical Device table for placement */ - xAdvDevice = 0x0040, /* Includes horizontal Device table for advance */ - yAdvDevice = 0x0080, /* Includes vertical Device table for advance */ - ignored = 0x0F00, /* Was used in TrueType Open for MM fonts */ - reserved = 0xF000, /* For future use */ - - devices = 0x00F0 /* Mask for having any Device table */ + xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */ + yPlacement = 0x0002u, /* Includes vertical adjustment for placement */ + xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */ + yAdvance = 0x0008u, /* Includes vertical adjustment for advance */ + xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */ + yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */ + xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */ + yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */ + ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */ + reserved = 0xF000u, /* For future use */ + + devices = 0x00F0u /* Mask for having any Device table */ }; /* All fields are options. Only those available advance the value pointer. */ @@ -109,11 +109,13 @@ struct ValueFormat : USHORT if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++)); if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++)); if (format & xAdvance) { - if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values++)); else values++; + if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values)); + values++; } /* y_advance values grow downward but font-space grows upward, hence negation */ if (format & yAdvance) { - if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values++)); else values++; + if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values)); + values++; } if (!has_device ()) return; @@ -125,17 +127,21 @@ struct ValueFormat : USHORT /* pixel -> fractional pixel */ if (format & xPlaDevice) { - if (x_ppem) glyph_pos.x_offset += (base + get_device (values++)).get_x_delta (font); else values++; + if (x_ppem) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font); + values++; } if (format & yPlaDevice) { - if (y_ppem) glyph_pos.y_offset += (base + get_device (values++)).get_y_delta (font); else values++; + if (y_ppem) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font); + values++; } if (format & xAdvDevice) { - if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++; + if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font); + values++; } if (format & yAdvDevice) { /* y_advance values grow downward but font-space grows upward, hence negation */ - if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++; + if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font); + values++; } } @@ -240,12 +246,12 @@ struct AnchorFormat2 unsigned int x_ppem = font->x_ppem; unsigned int y_ppem = font->y_ppem; hb_position_t cx, cy; - hb_bool_t ret = false; + hb_bool_t ret; - if (x_ppem || y_ppem) - ret = font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); - *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate); - *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate); + ret = (x_ppem || y_ppem) && + font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); + *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); + *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); } inline bool sanitize (hb_sanitize_context_t *c) { @@ -390,6 +396,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde unsigned int glyph_pos) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); unsigned int mark_class = record.klass; @@ -402,15 +409,15 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde hb_position_t mark_x, mark_y, base_x, base_y; - mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_y); - glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y); + mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); + glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x, &base_y); - hb_glyph_position_t &o = c->buffer->cur_pos(); + hb_glyph_position_t &o = buffer->cur_pos(); o.x_offset = base_x - mark_x; o.y_offset = base_y - mark_y; - o.attach_lookback() = c->buffer->idx - glyph_pos; + o.attach_lookback() = buffer->idx - glyph_pos; - c->buffer->idx++; + buffer->idx++; return TRACE_RETURN (true); } @@ -439,13 +446,14 @@ struct SinglePosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); + hb_buffer_t *buffer = c->buffer; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); valueFormat.apply_value (c->font, c->direction, this, - values, c->buffer->cur_pos()); + values, buffer->cur_pos()); - c->buffer->idx++; + buffer->idx++; return TRACE_RETURN (true); } @@ -484,16 +492,17 @@ struct SinglePosFormat2 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); + hb_buffer_t *buffer = c->buffer; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); if (likely (index >= valueCount)) return TRACE_RETURN (false); valueFormat.apply_value (c->font, c->direction, this, &values[index * valueFormat.get_len ()], - c->buffer->cur_pos()); + buffer->cur_pos()); - c->buffer->idx++; + buffer->idx++; return TRACE_RETURN (true); } @@ -519,12 +528,12 @@ struct SinglePosFormat2 struct SinglePos { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - case 2: return TRACE_RETURN (c->process (u.format2)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + case 2: return TRACE_RETURN (c->dispatch (u.format2)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -588,6 +597,7 @@ struct PairSet unsigned int pos) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; unsigned int len1 = valueFormats[0].get_len (); unsigned int len2 = valueFormats[1].get_len (); unsigned int record_size = USHORT::static_size * (1 + len1 + len2); @@ -596,15 +606,16 @@ struct PairSet unsigned int count = len; for (unsigned int i = 0; i < count; i++) { - if (c->buffer->info[pos].codepoint == record->secondGlyph) + /* TODO bsearch */ + if (buffer->info[pos].codepoint == record->secondGlyph) { valueFormats[0].apply_value (c->font, c->direction, this, - &record->values[0], c->buffer->cur_pos()); + &record->values[0], buffer->cur_pos()); valueFormats[1].apply_value (c->font, c->direction, this, - &record->values[len1], c->buffer->pos[pos]); + &record->values[len1], buffer->pos[pos]); if (len2) pos++; - c->buffer->idx = pos; + buffer->idx = pos; return TRACE_RETURN (true); } record = &StructAtOffset<PairValueRecord> (record, record_size); @@ -658,10 +669,11 @@ struct PairPosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1); + hb_buffer_t *buffer = c->buffer; + hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); if (!skippy_iter.next ()) return TRACE_RETURN (false); @@ -709,8 +721,6 @@ struct PairPosFormat2 TRACE_COLLECT_GLYPHS (this); /* (this+coverage).add_coverage (c->input); // Don't need this. */ - /* TODO only add values for pairs that have nonzero adjustments. */ - unsigned int count1 = class1Count; const ClassDef &klass1 = this+classDef1; for (unsigned int i = 0; i < count1; i++) @@ -730,10 +740,11 @@ struct PairPosFormat2 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1); + hb_buffer_t *buffer = c->buffer; + hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); if (!skippy_iter.next ()) return TRACE_RETURN (false); @@ -742,19 +753,19 @@ struct PairPosFormat2 unsigned int len2 = valueFormat2.get_len (); unsigned int record_len = len1 + len2; - unsigned int klass1 = (this+classDef1).get_class (c->buffer->cur().codepoint); - unsigned int klass2 = (this+classDef2).get_class (c->buffer->info[skippy_iter.idx].codepoint); + unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); + unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; valueFormat1.apply_value (c->font, c->direction, this, - v, c->buffer->cur_pos()); + v, buffer->cur_pos()); valueFormat2.apply_value (c->font, c->direction, this, - v + len1, c->buffer->pos[skippy_iter.idx]); + v + len1, buffer->pos[skippy_iter.idx]); - c->buffer->idx = skippy_iter.idx; + buffer->idx = skippy_iter.idx; if (len2) - c->buffer->idx++; + buffer->idx++; return TRACE_RETURN (true); } @@ -809,12 +820,12 @@ struct PairPosFormat2 struct PairPos { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - case 2: return TRACE_RETURN (c->process (u.format2)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + case 2: return TRACE_RETURN (c->dispatch (u.format2)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -876,29 +887,30 @@ struct CursivePosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; /* We don't handle mark glyphs here. */ - if (c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false); + if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); - hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1); + hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->cur().codepoint)]; + const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.exitAnchor) return TRACE_RETURN (false); if (!skippy_iter.next ()) return TRACE_RETURN (false); - const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint)]; + const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; if (!next_record.entryAnchor) return TRACE_RETURN (false); - unsigned int i = c->buffer->idx; + unsigned int i = buffer->idx; unsigned int j = skippy_iter.idx; hb_position_t entry_x, entry_y, exit_x, exit_y; - (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y); - (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y); + (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y); + (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y); - hb_glyph_position_t *pos = c->buffer->pos; + hb_glyph_position_t *pos = buffer->pos; hb_position_t d; /* Main-direction adjustment */ @@ -951,7 +963,7 @@ struct CursivePosFormat1 pos[j].x_offset = exit_x - entry_x; } - c->buffer->idx = j; + buffer->idx = j; return TRACE_RETURN (true); } @@ -975,11 +987,11 @@ struct CursivePosFormat1 struct CursivePos { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -1013,7 +1025,6 @@ struct MarkBasePosFormat1 TRACE_COLLECT_GLYPHS (this); (this+markCoverage).add_coverage (c->input); (this+baseCoverage).add_coverage (c->input); - /* TODO only add combinations that have nonzero adjustment. */ } inline const Coverage &get_coverage (void) const @@ -1024,23 +1035,24 @@ struct MarkBasePosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint); + hb_buffer_t *buffer = c->buffer; + unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); /* now we search backwards for a non-mark glyph */ - unsigned int property; - hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1); + hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); + skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); do { - if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false); + if (!skippy_iter.prev ()) return TRACE_RETURN (false); /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ - if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break; + if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break; skippy_iter.reject (); } while (1); - /* The following assertion is too strong, so we've disabled it. */ - if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/} + /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ + if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } - unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint); + unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); if (base_index == NOT_COVERED) return TRACE_RETURN (false); return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); @@ -1074,11 +1086,11 @@ struct MarkBasePosFormat1 struct MarkBasePos { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -1117,7 +1129,6 @@ struct MarkLigPosFormat1 TRACE_COLLECT_GLYPHS (this); (this+markCoverage).add_coverage (c->input); (this+ligatureCoverage).add_coverage (c->input); - /* TODO only add combinations that have nonzero adjustment. */ } inline const Coverage &get_coverage (void) const @@ -1128,19 +1139,20 @@ struct MarkLigPosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint); + hb_buffer_t *buffer = c->buffer; + unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); /* now we search backwards for a non-mark glyph */ - unsigned int property; - hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1); - if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false); + hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); + skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); + if (!skippy_iter.prev ()) return TRACE_RETURN (false); - /* The following assertion is too strong, so we've disabled it. */ - if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/} + /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ + if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } unsigned int j = skippy_iter.idx; - unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->info[j].codepoint); + unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); if (lig_index == NOT_COVERED) return TRACE_RETURN (false); const LigatureArray& lig_array = this+ligatureArray; @@ -1155,11 +1167,11 @@ struct MarkLigPosFormat1 * can directly use the component index. If not, we attach the mark * glyph to the last component of the ligature. */ unsigned int comp_index; - unsigned int lig_id = get_lig_id (c->buffer->info[j]); - unsigned int mark_id = get_lig_id (c->buffer->cur()); - unsigned int mark_comp = get_lig_comp (c->buffer->cur()); + unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]); + unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur()); + unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (lig_id && lig_id == mark_id && mark_comp > 0) - comp_index = MIN (comp_count, get_lig_comp (c->buffer->cur())) - 1; + comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1; else comp_index = comp_count - 1; @@ -1195,11 +1207,11 @@ struct MarkLigPosFormat1 struct MarkLigPos { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -1233,7 +1245,6 @@ struct MarkMarkPosFormat1 TRACE_COLLECT_GLYPHS (this); (this+mark1Coverage).add_coverage (c->input); (this+mark2Coverage).add_coverage (c->input); - /* TODO only add combinations that have nonzero adjustment. */ } inline const Coverage &get_coverage (void) const @@ -1244,22 +1255,23 @@ struct MarkMarkPosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cur().codepoint); + hb_buffer_t *buffer = c->buffer; + unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); /* now we search backwards for a suitable mark glyph until a non-mark glyph */ - unsigned int property; - hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1); - if (!skippy_iter.prev (&property)) return TRACE_RETURN (false); + hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); + skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); + if (!skippy_iter.prev ()) return TRACE_RETURN (false); - if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) return TRACE_RETURN (false); + if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); } unsigned int j = skippy_iter.idx; - unsigned int id1 = get_lig_id (c->buffer->cur()); - unsigned int id2 = get_lig_id (c->buffer->info[j]); - unsigned int comp1 = get_lig_comp (c->buffer->cur()); - unsigned int comp2 = get_lig_comp (c->buffer->info[j]); + unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); + unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); + unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); + unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); if (likely (id1 == id2)) { if (id1 == 0) /* Marks belonging to the same base. */ @@ -1277,7 +1289,7 @@ struct MarkMarkPosFormat1 return TRACE_RETURN (false); good: - unsigned int mark2_index = (this+mark2Coverage).get_coverage (c->buffer->info[j].codepoint); + unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); @@ -1314,11 +1326,11 @@ struct MarkMarkPosFormat1 struct MarkMarkPos { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -1373,19 +1385,19 @@ struct PosLookupSubTable }; template <typename context_t> - inline typename context_t::return_t process (context_t *c, unsigned int lookup_type) const + inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.process (c)); - case Pair: return TRACE_RETURN (u.pair.process (c)); - case Cursive: return TRACE_RETURN (u.cursive.process (c)); - case MarkBase: return TRACE_RETURN (u.markBase.process (c)); - case MarkLig: return TRACE_RETURN (u.markLig.process (c)); - case MarkMark: return TRACE_RETURN (u.markMark.process (c)); - case Context: return TRACE_RETURN (u.context.process (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.process (c)); - case Extension: return TRACE_RETURN (u.extension.process (c)); + case Single: return TRACE_RETURN (u.single.dispatch (c)); + case Pair: return TRACE_RETURN (u.pair.dispatch (c)); + case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); + case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); + case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); + case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); + case Context: return TRACE_RETURN (u.context.dispatch (c)); + case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); + case Extension: return TRACE_RETURN (u.extension.dispatch (c)); default: return TRACE_RETURN (c->default_return_value ()); } } @@ -1433,27 +1445,16 @@ struct PosLookup : Lookup inline const PosLookupSubTable& get_subtable (unsigned int i) const { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } - template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline bool is_reverse (void) const { - TRACE_PROCESS (this); - unsigned int lookup_type = get_type (); - unsigned int count = get_subtable_count (); - for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).process (c, lookup_type); - if (c->stop_sublookup_iteration (r)) - return TRACE_RETURN (r); - } - return TRACE_RETURN (c->default_return_value ()); + return false; } - template <typename context_t> - static inline typename context_t::return_t process_recurse_func (context_t *c, unsigned int lookup_index); - inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const + inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); c->set_recurse_func (NULL); - return TRACE_RETURN (process (c)); + return TRACE_RETURN (dispatch (c)); } template <typename set_t> @@ -1463,7 +1464,7 @@ struct PosLookup : Lookup const Coverage *last = NULL; unsigned int count = get_subtable_count (); for (unsigned int i = 0; i < count; i++) { - const Coverage *coverage = &get_subtable (i).process (&c, get_type ()); + const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); if (coverage != last) { coverage->add_coverage (glyphs); last = coverage; @@ -1474,36 +1475,28 @@ struct PosLookup : Lookup inline bool apply_once (hb_apply_context_t *c) const { TRACE_APPLY (this); - if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property)) + if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) return TRACE_RETURN (false); - return TRACE_RETURN (process (c)); + return TRACE_RETURN (dispatch (c)); } static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); - inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const - { - bool ret = false; - - if (unlikely (!c->buffer->len || !c->lookup_mask)) - return false; - - c->set_recurse_func (apply_recurse_func); - c->set_lookup (*this); - - c->buffer->idx = 0; + template <typename context_t> + static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); - while (c->buffer->idx < c->buffer->len) - { - if ((c->buffer->cur().mask & c->lookup_mask) && - digest->may_have (c->buffer->cur().codepoint) && - apply_once (c)) - ret = true; - else - c->buffer->idx++; + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this); + unsigned int lookup_type = get_type (); + unsigned int count = get_subtable_count (); + for (unsigned int i = 0; i < count; i++) { + typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); + if (c->stop_sublookup_iteration (r)) + return TRACE_RETURN (r); } - - return ret; + return TRACE_RETURN (c->default_return_value ()); } inline bool sanitize (hb_sanitize_context_t *c) { @@ -1522,13 +1515,13 @@ typedef OffsetListOf<PosLookup> PosLookupList; struct GPOS : GSUBGPOS { - static const hb_tag_t Tag = HB_OT_TAG_GPOS; + static const hb_tag_t tableTag = HB_OT_TAG_GPOS; inline const PosLookup& get_lookup (unsigned int i) const { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attahced_marks); + static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); @@ -1561,17 +1554,13 @@ fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction } static void -fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, hb_bool_t zero_width_attached_marks) +fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) { if (likely (!(pos[i].attach_lookback()))) return; unsigned int j = i - pos[i].attach_lookback(); - if (zero_width_attached_marks) { - pos[i].x_advance = 0; - pos[i].y_advance = 0; - } pos[i].x_offset += pos[j].x_offset; pos[i].y_offset += pos[j].y_offset; @@ -1598,8 +1587,10 @@ GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) } void -GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks) +GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { + _hb_buffer_assert_gsubgpos_vars (buffer); + unsigned int len; hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); hb_direction_t direction = buffer->props.direction; @@ -1610,34 +1601,28 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t /* Handle attachments */ for (unsigned int i = 0; i < len; i++) - fix_mark_attachment (pos, i, direction, zero_width_attached_marks); - - HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); - HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); - HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props); + fix_mark_attachment (pos, i, direction); } /* Out-of-class implementation for methods recursing */ template <typename context_t> -inline typename context_t::return_t PosLookup::process_recurse_func (context_t *c, unsigned int lookup_index) +/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) { const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); const PosLookup &l = gpos.get_lookup (lookup_index); - return l.process (c); + return l.dispatch (c); } -inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) +/*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) { const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); const PosLookup &l = gpos.get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; - unsigned int saved_property = c->property; c->set_lookup (l); bool ret = l.apply_once (c); c->lookup_props = saved_lookup_props; - c->property = saved_property; return ret; } diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 2642acb..2b421a9 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008,2009,2010 Red Hat, Inc. - * Copyright © 2010,2012 Google, Inc. + * Copyright © 2010,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -44,7 +44,7 @@ struct SingleSubstFormat1 for (iter.init (this+coverage); iter.more (); iter.next ()) { hb_codepoint_t glyph_id = iter.get_glyph (); if (c->glyphs->has (glyph_id)) - c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFF); + c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu); } } @@ -55,7 +55,7 @@ struct SingleSubstFormat1 for (iter.init (this+coverage); iter.more (); iter.next ()) { hb_codepoint_t glyph_id = iter.get_glyph (); c->input->add (glyph_id); - c->output->add ((glyph_id + deltaGlyphID) & 0xFFFF); + c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu); } } @@ -79,7 +79,7 @@ struct SingleSubstFormat1 /* According to the Adobe Annotated OpenType Suite, result is always * limited to 16bit. */ - glyph_id = (glyph_id + deltaGlyphID) & 0xFFFF; + glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; c->replace_glyph (glyph_id); return TRACE_RETURN (true); @@ -192,17 +192,6 @@ struct SingleSubstFormat2 struct SingleSubst { - template <typename context_t> - inline typename context_t::return_t process (context_t *c) const - { - TRACE_PROCESS (this); - switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - case 2: return TRACE_RETURN (c->process (u.format2)); - default:return TRACE_RETURN (c->default_return_value ()); - } - } - inline bool serialize (hb_serialize_context_t *c, Supplier<GlyphID> &glyphs, Supplier<GlyphID> &substitutes, @@ -230,6 +219,17 @@ struct SingleSubst } } + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this); + switch (u.format) { + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + case 2: return TRACE_RETURN (c->dispatch (u.format2)); + default:return TRACE_RETURN (c->default_return_value ()); + } + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); @@ -270,13 +270,32 @@ struct Sequence inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - if (unlikely (!substitute.len)) return TRACE_RETURN (false); - - unsigned int klass = c->property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; unsigned int count = substitute.len; + + /* TODO: + * Testing shows that Uniscribe actually allows zero-len susbstitute, + * which essentially deletes a glyph. We don't allow for now. It + * can be confusing to the client since the cluster from the deleted + * glyph won't be merged with any output cluster... Also, currently + * buffer->move_to() makes assumptions about this too. Perhaps fix + * in the future after figuring out what to do with the clusters. + */ + if (unlikely (!count)) return TRACE_RETURN (false); + + /* Special-case to make it in-place and not consider this + * as a "multiplied" substitution. */ + if (unlikely (count == 1)) + { + c->replace_glyph (substitute.array[0]); + return TRACE_RETURN (true); + } + + unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? + HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; + for (unsigned int i = 0; i < count; i++) { - set_lig_props_for_component (c->buffer->cur(), i); - c->output_glyph (substitute.array[i], klass); + _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); + c->output_glyph_for_component (substitute.array[i], klass); } c->buffer->skip_glyph (); @@ -384,16 +403,6 @@ struct MultipleSubstFormat1 struct MultipleSubst { - template <typename context_t> - inline typename context_t::return_t process (context_t *c) const - { - TRACE_PROCESS (this); - switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); - } - } - inline bool serialize (hb_serialize_context_t *c, Supplier<GlyphID> &glyphs, Supplier<unsigned int> &substitute_len_list, @@ -410,6 +419,16 @@ struct MultipleSubst } } + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this); + switch (u.format) { + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + default:return TRACE_RETURN (c->default_return_value ()); + } + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); @@ -535,16 +554,6 @@ struct AlternateSubstFormat1 struct AlternateSubst { - template <typename context_t> - inline typename context_t::return_t process (context_t *c) const - { - TRACE_PROCESS (this); - switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); - } - } - inline bool serialize (hb_serialize_context_t *c, Supplier<GlyphID> &glyphs, Supplier<unsigned int> &alternate_len_list, @@ -561,6 +570,16 @@ struct AlternateSubst } } + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this); + switch (u.format) { + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + default:return TRACE_RETURN (c->default_return_value ()); + } + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); @@ -616,30 +635,38 @@ struct Ligature { TRACE_APPLY (this); unsigned int count = component.len; - if (unlikely (count < 1)) return TRACE_RETURN (false); - unsigned int end_offset = 0; + if (unlikely (!count)) return TRACE_RETURN (false); + + /* Special-case to make it in-place and not consider this + * as a "ligated" substitution. */ + if (unlikely (count == 1)) + { + c->replace_glyph (ligGlyph); + return TRACE_RETURN (true); + } + bool is_mark_ligature = false; unsigned int total_component_count = 0; + unsigned int match_length = 0; + unsigned int match_positions[MAX_CONTEXT_LENGTH]; + if (likely (!match_input (c, count, &component[1], match_glyph, NULL, - &end_offset, + &match_length, + match_positions, &is_mark_ligature, &total_component_count))) return TRACE_RETURN (false); - /* Deal, we are forming the ligature. */ - c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + end_offset); - ligate_input (c, count, - &component[1], + match_positions, + match_length, ligGlyph, - match_glyph, - NULL, is_mark_ligature, total_component_count); @@ -840,16 +867,6 @@ struct LigatureSubstFormat1 struct LigatureSubst { - template <typename context_t> - inline typename context_t::return_t process (context_t *c) const - { - TRACE_PROCESS (this); - switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); - } - } - inline bool serialize (hb_serialize_context_t *c, Supplier<GlyphID> &first_glyphs, Supplier<unsigned int> &ligature_per_first_glyph_count_list, @@ -869,6 +886,16 @@ struct LigatureSubst } } + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this); + switch (u.format) { + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + default:return TRACE_RETURN (c->default_return_value ()); + } + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); @@ -981,7 +1008,9 @@ struct ReverseChainSingleSubstFormat1 1)) { c->replace_glyph_inplace (substitute[index]); - c->buffer->idx--; /* Reverse! */ + /* Note: We DON'T decrease buffer->idx. The main loop does it + * for us. This is useful for preventing surprises if someone + * calls us through a Context lookup. */ return TRACE_RETURN (true); } @@ -1022,11 +1051,11 @@ struct ReverseChainSingleSubstFormat1 struct ReverseChainSingleSubst { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -1069,18 +1098,18 @@ struct SubstLookupSubTable }; template <typename context_t> - inline typename context_t::return_t process (context_t *c, unsigned int lookup_type) const + inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.process (c)); - case Multiple: return TRACE_RETURN (u.multiple.process (c)); - case Alternate: return TRACE_RETURN (u.alternate.process (c)); - case Ligature: return TRACE_RETURN (u.ligature.process (c)); - case Context: return TRACE_RETURN (u.context.process (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.process (c)); - case Extension: return TRACE_RETURN (u.extension.process (c)); - case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.process (c)); + case Single: return TRACE_RETURN (u.single.dispatch (c)); + case Multiple: return TRACE_RETURN (u.multiple.dispatch (c)); + case Alternate: return TRACE_RETURN (u.alternate.dispatch (c)); + case Ligature: return TRACE_RETURN (u.ligature.dispatch (c)); + case Context: return TRACE_RETURN (u.context.dispatch (c)); + case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); + case Extension: return TRACE_RETURN (u.extension.dispatch (c)); + case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.dispatch (c)); default: return TRACE_RETURN (c->default_return_value ()); } } @@ -1137,34 +1166,18 @@ struct SubstLookup : Lookup return lookup_type_is_reverse (type); } - template <typename context_t> - inline typename context_t::return_t process (context_t *c) const - { - TRACE_PROCESS (this); - unsigned int lookup_type = get_type (); - unsigned int count = get_subtable_count (); - for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).process (c, lookup_type); - if (c->stop_sublookup_iteration (r)) - return TRACE_RETURN (r); - } - return TRACE_RETURN (c->default_return_value ()); - } - template <typename context_t> - static inline typename context_t::return_t process_recurse_func (context_t *c, unsigned int lookup_index); - inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); - c->set_recurse_func (process_recurse_func<hb_closure_context_t>); - return TRACE_RETURN (process (c)); + c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); + return TRACE_RETURN (dispatch (c)); } - inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const + inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - c->set_recurse_func (process_recurse_func<hb_collect_glyphs_context_t>); - return TRACE_RETURN (process (c)); + c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>); + return TRACE_RETURN (dispatch (c)); } template <typename set_t> @@ -1174,7 +1187,7 @@ struct SubstLookup : Lookup const Coverage *last = NULL; unsigned int count = get_subtable_count (); for (unsigned int i = 0; i < count; i++) { - const Coverage *coverage = &get_subtable (i).process (&c, get_type ()); + const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); if (coverage != last) { coverage->add_coverage (glyphs); last = coverage; @@ -1187,66 +1200,18 @@ struct SubstLookup : Lookup TRACE_WOULD_APPLY (this); if (unlikely (!c->len)) return TRACE_RETURN (false); if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false); - return TRACE_RETURN (process (c)); + return TRACE_RETURN (dispatch (c)); } inline bool apply_once (hb_apply_context_t *c) const { TRACE_APPLY (this); - if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property)) + if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) return TRACE_RETURN (false); - return TRACE_RETURN (process (c)); + return TRACE_RETURN (dispatch (c)); } static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); - inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const - { - bool ret = false; - - if (unlikely (!c->buffer->len || !c->lookup_mask)) - return false; - - c->set_recurse_func (apply_recurse_func); - c->set_lookup (*this); - - if (likely (!is_reverse ())) - { - /* in/out forward substitution */ - c->buffer->clear_output (); - c->buffer->idx = 0; - - while (c->buffer->idx < c->buffer->len) - { - if ((c->buffer->cur().mask & c->lookup_mask) && - digest->may_have (c->buffer->cur().codepoint) && - apply_once (c)) - ret = true; - else - c->buffer->next_glyph (); - } - if (ret) - c->buffer->swap_buffers (); - } - else - { - /* in-place backward substitution */ - c->buffer->remove_output (); - c->buffer->idx = c->buffer->len - 1; - do - { - if ((c->buffer->cur().mask & c->lookup_mask) && - digest->may_have (c->buffer->cur().codepoint) && - apply_once (c)) - ret = true; - else - c->buffer->idx--; - - } - while ((int) c->buffer->idx >= 0); - } - - return ret; - } inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, unsigned int i) @@ -1304,6 +1269,23 @@ struct SubstLookup : Lookup ligatures_list, component_count_list, component_list)); } + template <typename context_t> + static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); + + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this); + unsigned int lookup_type = get_type (); + unsigned int count = get_subtable_count (); + for (unsigned int i = 0; i < count; i++) { + typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); + if (c->stop_sublookup_iteration (r)) + return TRACE_RETURN (r); + } + return TRACE_RETURN (c->default_return_value ()); + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); @@ -1315,9 +1297,7 @@ struct SubstLookup : Lookup { /* The spec says all subtables of an Extension lookup should * have the same type. This is specially important if one has - * a reverse type! - * - * We just check that they are all either forward, or reverse. */ + * a reverse type! */ unsigned int type = get_subtable (0).u.extension.get_type (); unsigned int count = get_subtable_count (); for (unsigned int i = 1; i < count; i++) @@ -1336,7 +1316,7 @@ typedef OffsetListOf<SubstLookup> SubstLookupList; struct GSUB : GSUBGPOS { - static const hb_tag_t Tag = HB_OT_TAG_GSUB; + static const hb_tag_t tableTag = HB_OT_TAG_GSUB; inline const SubstLookup& get_lookup (unsigned int i) const { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); } @@ -1358,15 +1338,15 @@ struct GSUB : GSUBGPOS void GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer) { - HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props); - HB_BUFFER_ALLOCATE_VAR (buffer, lig_props); - HB_BUFFER_ALLOCATE_VAR (buffer, syllable); + _hb_buffer_assert_gsubgpos_vars (buffer); const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef; unsigned int count = buffer->len; - for (unsigned int i = 0; i < count; i++) { - buffer->info[i].lig_props() = buffer->info[i].syllable() = 0; - buffer->info[i].glyph_props() = gdef.get_glyph_props (buffer->info[i].codepoint); + for (unsigned int i = 0; i < count; i++) + { + _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint)); + _hb_glyph_info_clear_lig_props (&buffer->info[i]); + buffer->info[i].syllable() = 0; } } @@ -1378,7 +1358,7 @@ GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE /* Out-of-class implementation for methods recursing */ -inline bool ExtensionSubst::is_reverse (void) const +/*static*/ inline bool ExtensionSubst::is_reverse (void) const { unsigned int type = get_type (); if (unlikely (type == SubstLookupSubTable::Extension)) @@ -1387,23 +1367,21 @@ inline bool ExtensionSubst::is_reverse (void) const } template <typename context_t> -inline typename context_t::return_t SubstLookup::process_recurse_func (context_t *c, unsigned int lookup_index) +/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) { const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); const SubstLookup &l = gsub.get_lookup (lookup_index); - return l.process (c); + return l.dispatch (c); } -inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) +/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) { const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); const SubstLookup &l = gsub.get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; - unsigned int saved_property = c->property; c->set_lookup (l); bool ret = l.apply_once (c); c->lookup_props = saved_lookup_props; - c->property = saved_property; return ret; } diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 0b00005..546ff4b 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -38,12 +38,11 @@ namespace OT { -#define TRACE_PROCESS(this) \ +#define TRACE_DISPATCH(this) \ hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ ""); - #ifndef HB_DEBUG_CLOSURE #define HB_DEBUG_CLOSURE (HB_DEBUG+0) #endif @@ -60,7 +59,7 @@ struct hb_closure_context_t typedef hb_void_t return_t; typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); template <typename T> - inline return_t process (const T &obj) { obj.closure (this); return HB_VOID; } + inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } static return_t default_return_value (void) { return HB_VOID; } bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } return_t recurse (unsigned int lookup_index) @@ -109,7 +108,7 @@ struct hb_would_apply_context_t static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; typedef bool return_t; template <typename T> - inline return_t process (const T &obj) { return obj.would_apply (this); } + inline return_t dispatch (const T &obj) { return obj.would_apply (this); } static return_t default_return_value (void) { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } @@ -148,7 +147,7 @@ struct hb_collect_glyphs_context_t typedef hb_void_t return_t; typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); template <typename T> - inline return_t process (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } + inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } static return_t default_return_value (void) { return HB_VOID; } bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } return_t recurse (unsigned int lookup_index) @@ -158,7 +157,13 @@ struct hb_collect_glyphs_context_t /* Note that GPOS sets recurse_func to NULL already, so it doesn't get * past the previous check. For GSUB, we only want to collect the output - * glyphs in the recursion. If output is not requested, we can go home now. */ + * glyphs in the recursion. If output is not requested, we can go home now. + * + * Note further, that the above is not exactly correct. A recursed lookup + * is allowed to match input that is not matched in the context, but that's + * not how most fonts are built. It's possible to relax that and recurse + * with all sets here if it proves to be an issue. + */ if (output == hb_set_get_empty ()) return HB_VOID; @@ -214,7 +219,7 @@ struct hb_get_coverage_context_t static const unsigned int max_debug_depth = 0; typedef const Coverage &return_t; template <typename T> - inline return_t process (const T &obj) { return obj.get_coverage (); } + inline return_t dispatch (const T &obj) { return obj.get_coverage (); } static return_t default_return_value (void) { return Null(Coverage); } hb_get_coverage_context_t (void) : @@ -241,7 +246,7 @@ struct hb_apply_context_t typedef bool return_t; typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); template <typename T> - inline return_t process (const T &obj) { return obj.apply (this); } + inline return_t dispatch (const T &obj) { return obj.apply (this); } static return_t default_return_value (void) { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } return_t recurse (unsigned int lookup_index) @@ -255,132 +260,255 @@ struct hb_apply_context_t return ret; } + unsigned int table_index; /* GSUB/GPOS */ hb_font_t *font; hb_face_t *face; hb_buffer_t *buffer; hb_direction_t direction; hb_mask_t lookup_mask; + bool auto_zwj; recurse_func_t recurse_func; unsigned int nesting_level_left; unsigned int lookup_props; - unsigned int property; /* propety of first glyph */ const GDEF &gdef; bool has_glyph_classes; unsigned int debug_depth; - hb_apply_context_t (hb_font_t *font_, - hb_buffer_t *buffer_, - hb_mask_t lookup_mask_) : + hb_apply_context_t (unsigned int table_index_, + hb_font_t *font_, + hb_buffer_t *buffer_) : + table_index (table_index_), font (font_), face (font->face), buffer (buffer_), direction (buffer_->props.direction), - lookup_mask (lookup_mask_), + lookup_mask (1), + auto_zwj (true), recurse_func (NULL), nesting_level_left (MAX_NESTING_LEVEL), - lookup_props (0), property (0), + lookup_props (0), gdef (*hb_ot_layout_from_face (face)->gdef), has_glyph_classes (gdef.has_glyph_classes ()), debug_depth (0) {} - void set_recurse_func (recurse_func_t func) { recurse_func = func; } - void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } - void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } + inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } + inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } + inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } + inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } + inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } + + struct matcher_t + { + inline matcher_t (void) : + lookup_props (0), + ignore_zwnj (false), + ignore_zwj (false), + mask (-1), +#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ + syllable arg1(0), +#undef arg1 + match_func (NULL), + match_data (NULL) {}; + + typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); + + inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } + inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } + inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } + inline void set_mask (hb_mask_t mask_) { mask = mask_; } + inline void set_syllable (uint8_t syllable_) { syllable = syllable_; } + inline void set_match_func (match_func_t match_func_, + const void *match_data_) + { match_func = match_func_; match_data = match_data_; } + + enum may_match_t { + MATCH_NO, + MATCH_YES, + MATCH_MAYBE + }; - struct mark_skipping_forward_iterator_t - { - inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_, - unsigned int start_index_, - unsigned int num_items_, - bool context_match = false) + inline may_match_t may_match (const hb_glyph_info_t &info, + const USHORT *glyph_data) const { - c = c_; - idx = start_index_; - num_items = num_items_; - mask = context_match ? -1 : c->lookup_mask; - syllable = context_match ? 0 : c->buffer->cur().syllable (); - end = c->buffer->len; + if (!(info.mask & mask) || + (syllable && syllable != info.syllable ())) + return MATCH_NO; + + if (match_func) + return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; + + return MATCH_MAYBE; } - inline bool has_no_chance (void) const + + enum may_skip_t { + SKIP_NO, + SKIP_YES, + SKIP_MAYBE + }; + + inline may_skip_t + may_skip (const hb_apply_context_t *c, + const hb_glyph_info_t &info) const { - return unlikely (num_items && idx + num_items >= end); + if (!c->check_glyph_property (&info, lookup_props)) + return SKIP_YES; + + if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && + (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && + !_hb_glyph_info_ligated (&info))) + return SKIP_MAYBE; + + return SKIP_NO; } - inline void reject (void) + + protected: + unsigned int lookup_props; + bool ignore_zwnj; + bool ignore_zwj; + hb_mask_t mask; + uint8_t syllable; + match_func_t match_func; + const void *match_data; + }; + + struct skipping_forward_iterator_t + { + inline skipping_forward_iterator_t (hb_apply_context_t *c_, + unsigned int start_index_, + unsigned int num_items_, + bool context_match = false) : + idx (start_index_), + c (c_), + match_glyph_data (NULL), + num_items (num_items_), + end (c->buffer->len) { - num_items++; + matcher.set_lookup_props (c->lookup_props); + /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ + matcher.set_ignore_zwnj (context_match || c->table_index == 1); + /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ + matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); + if (!context_match) + matcher.set_mask (c->lookup_mask); + matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); } - inline bool next (unsigned int *property_out, - unsigned int lookup_props) + inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } + inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } + inline void set_match_func (matcher_t::match_func_t match_func, + const void *match_data, + const USHORT glyph_data[]) + { + matcher.set_match_func (match_func, match_data); + match_glyph_data = glyph_data; + } + + inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); } + inline void reject (void) { num_items++; match_glyph_data--; } + inline bool next (void) { assert (num_items > 0); - do + while (!has_no_chance ()) { - if (has_no_chance ()) - return false; idx++; - } while (c->should_skip_mark (&c->buffer->info[idx], lookup_props, property_out)); - num_items--; - return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->buffer->info[idx].syllable ()); - } - inline bool next (unsigned int *property_out = NULL) - { - return next (property_out, c->lookup_props); + const hb_glyph_info_t &info = c->buffer->info[idx]; + + matcher_t::may_skip_t skip = matcher.may_skip (c, info); + if (unlikely (skip == matcher_t::SKIP_YES)) + continue; + + matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); + if (match == matcher_t::MATCH_YES || + (match == matcher_t::MATCH_MAYBE && + skip == matcher_t::SKIP_NO)) + { + num_items--; + match_glyph_data++; + return true; + } + + if (skip == matcher_t::SKIP_NO) + return false; + } + return false; } unsigned int idx; protected: hb_apply_context_t *c; + matcher_t matcher; + const USHORT *match_glyph_data; + unsigned int num_items; - hb_mask_t mask; - uint8_t syllable; unsigned int end; }; - struct mark_skipping_backward_iterator_t + struct skipping_backward_iterator_t { - inline mark_skipping_backward_iterator_t (hb_apply_context_t *c_, - unsigned int start_index_, - unsigned int num_items_, - hb_mask_t mask_ = 0, - bool match_syllable_ = true) - { - c = c_; - idx = start_index_; - num_items = num_items_; - mask = mask_ ? mask_ : c->lookup_mask; - syllable = match_syllable_ ? c->buffer->cur().syllable () : 0; - } - inline bool has_no_chance (void) const + inline skipping_backward_iterator_t (hb_apply_context_t *c_, + unsigned int start_index_, + unsigned int num_items_, + bool context_match = false) : + idx (start_index_), + c (c_), + match_glyph_data (NULL), + num_items (num_items_) { - return unlikely (idx < num_items); + matcher.set_lookup_props (c->lookup_props); + /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ + matcher.set_ignore_zwnj (context_match || c->table_index == 1); + /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ + matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); + if (!context_match) + matcher.set_mask (c->lookup_mask); + matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); } - inline void reject (void) + inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } + inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } + inline void set_match_func (matcher_t::match_func_t match_func, + const void *match_data, + const USHORT glyph_data[]) { - num_items++; + matcher.set_match_func (match_func, match_data); + match_glyph_data = glyph_data; } - inline bool prev (unsigned int *property_out, - unsigned int lookup_props) + + inline bool has_no_chance (void) const { return unlikely (idx < num_items); } + inline void reject (void) { num_items++; } + inline bool prev (void) { assert (num_items > 0); - do + while (!has_no_chance ()) { - if (has_no_chance ()) - return false; idx--; - } while (c->should_skip_mark (&c->buffer->out_info[idx], lookup_props, property_out)); - num_items--; - return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ()); - } - inline bool prev (unsigned int *property_out = NULL) - { - return prev (property_out, c->lookup_props); + const hb_glyph_info_t &info = c->buffer->out_info[idx]; + + matcher_t::may_skip_t skip = matcher.may_skip (c, info); + if (unlikely (skip == matcher_t::SKIP_YES)) + continue; + + matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); + if (match == matcher_t::MATCH_YES || + (match == matcher_t::MATCH_MAYBE && + skip == matcher_t::SKIP_NO)) + { + num_items--; + match_glyph_data++; + return true; + } + + if (skip == matcher_t::SKIP_NO) + return false; + } + return false; } unsigned int idx; protected: hb_apply_context_t *c; + matcher_t matcher; + const USHORT *match_glyph_data; + unsigned int num_items; - hb_mask_t mask; - uint8_t syllable; }; inline bool @@ -405,10 +533,12 @@ struct hb_apply_context_t } inline bool - match_properties (hb_codepoint_t glyph, - unsigned int glyph_props, - unsigned int lookup_props) const + check_glyph_property (const hb_glyph_info_t *info, + unsigned int lookup_props) const { + hb_codepoint_t glyph = info->codepoint; + unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); + /* Not covered, if, for example, glyph class is ligature and * lookup_props includes LookupFlags::IgnoreLigatures */ @@ -421,69 +551,54 @@ struct hb_apply_context_t return true; } - inline bool - check_glyph_property (hb_glyph_info_t *info, - unsigned int lookup_props, - unsigned int *property_out) const - { - unsigned int property; - - property = info->glyph_props(); - *property_out = property; - - return match_properties (info->codepoint, property, lookup_props); - } - - inline bool - should_skip_mark (hb_glyph_info_t *info, - unsigned int lookup_props, - unsigned int *property_out) const - { - unsigned int property; - - property = info->glyph_props(); - if (property_out) - *property_out = property; - - /* If it's a mark, skip it if we don't accept it. */ - if (unlikely (property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) - return !match_properties (info->codepoint, property, lookup_props); - - /* If not a mark, don't skip. */ - return false; - } - - - inline bool should_mark_skip_current_glyph (void) const - { - return should_skip_mark (&buffer->cur(), lookup_props, NULL); - } - - inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const + inline void _set_glyph_props (hb_codepoint_t glyph_index, + unsigned int class_guess = 0, + bool ligature = false, + bool component = false) const { + unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) & + HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE; + add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED; + if (ligature) + { + add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED; + /* In the only place that the MULTIPLIED bit is used, Uniscribe + * seems to only care about the "last" transformation between + * Ligature and Multiple substitions. Ie. if you ligate, expand, + * and ligate again, it forgives the multiplication and acts as + * if only ligation happened. As such, clear MULTIPLIED bit. + */ + add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; + } + if (component) + add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; if (likely (has_glyph_classes)) - buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index); + _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index)); else if (class_guess) - buffer->cur().glyph_props() = class_guess; + _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess); } - inline void output_glyph (hb_codepoint_t glyph_index, - unsigned int class_guess = 0) const + inline void replace_glyph (hb_codepoint_t glyph_index) const { - set_class (glyph_index, class_guess); - buffer->output_glyph (glyph_index); + _set_glyph_props (glyph_index); + buffer->replace_glyph (glyph_index); + } + inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const + { + _set_glyph_props (glyph_index); + buffer->cur().codepoint = glyph_index; } - inline void replace_glyph (hb_codepoint_t glyph_index, - unsigned int class_guess = 0) const + inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index, + unsigned int class_guess) const { - set_class (glyph_index, class_guess); + _set_glyph_props (glyph_index, class_guess, true); buffer->replace_glyph (glyph_index); } - inline void replace_glyph_inplace (hb_codepoint_t glyph_index, - unsigned int class_guess = 0) const + inline void output_glyph_for_component (hb_codepoint_t glyph_index, + unsigned int class_guess) const { - set_class (glyph_index, class_guess); - buffer->cur().codepoint = glyph_index; + _set_glyph_props (glyph_index, class_guess, false, true); + buffer->output_glyph (glyph_index); } }; @@ -596,13 +711,19 @@ static inline bool match_input (hb_apply_context_t *c, const USHORT input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data, - unsigned int *end_offset = NULL, + unsigned int *end_offset, + unsigned int match_positions[MAX_CONTEXT_LENGTH], bool *p_is_mark_ligature = NULL, unsigned int *p_total_component_count = NULL) { TRACE_APPLY (NULL); - hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1); + if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); + + hb_buffer_t *buffer = c->buffer; + + hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1); + skippy_iter.set_match_func (match_func, match_data, input); if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); /* @@ -623,24 +744,23 @@ static inline bool match_input (hb_apply_context_t *c, * ligate with a conjunct...) */ - bool is_mark_ligature = !!(c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK); + bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); unsigned int total_component_count = 0; - total_component_count += get_lig_num_comps (c->buffer->cur()); + total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur()); - unsigned int first_lig_id = get_lig_id (c->buffer->cur()); - unsigned int first_lig_comp = get_lig_comp (c->buffer->cur()); + unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); + unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); + match_positions[0] = buffer->idx; for (unsigned int i = 1; i < count; i++) { - unsigned int property; - - if (!skippy_iter.next (&property)) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return TRACE_RETURN (false); - if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i - 1], match_data))) return TRACE_RETURN (false); + match_positions[i] = skippy_iter.idx; - unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]); - unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]); + unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]); + unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]); if (first_lig_id && first_lig_comp) { /* If first component was attached to a previous ligature component, @@ -656,12 +776,11 @@ static inline bool match_input (hb_apply_context_t *c, return TRACE_RETURN (false); } - is_mark_ligature = is_mark_ligature && (property & HB_OT_LAYOUT_GLYPH_PROPS_MARK); - total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]); + is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); + total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]); } - if (end_offset) - *end_offset = skippy_iter.idx - c->buffer->idx + 1; + *end_offset = skippy_iter.idx - buffer->idx + 1; if (p_is_mark_ligature) *p_is_mark_ligature = is_mark_ligature; @@ -672,14 +791,19 @@ static inline bool match_input (hb_apply_context_t *c, return TRACE_RETURN (true); } static inline void ligate_input (hb_apply_context_t *c, - unsigned int count, /* Including the first glyph (not matched) */ - const USHORT input[] HB_UNUSED, /* Array of input values--start with second glyph */ + unsigned int count, /* Including the first glyph */ + unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ + unsigned int match_length, hb_codepoint_t lig_glyph, - match_func_t match_func HB_UNUSED, - const void *match_data HB_UNUSED, bool is_mark_ligature, unsigned int total_component_count) { + TRACE_APPLY (NULL); + + hb_buffer_t *buffer = c->buffer; + + buffer->merge_clusters (buffer->idx, buffer->idx + match_length); + /* * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave * the ligature to keep its old ligature id. This will allow it to attach to @@ -709,46 +833,54 @@ static inline void ligate_input (hb_apply_context_t *c, */ unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; - unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer); - unsigned int last_lig_id = get_lig_id (c->buffer->cur()); - unsigned int last_num_components = get_lig_num_comps (c->buffer->cur()); + unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer); + unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); + unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); unsigned int components_so_far = last_num_components; if (!is_mark_ligature) - set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count); - c->replace_glyph (lig_glyph, klass); + { + _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count); + if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) + { + _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); + _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0); + } + } + c->replace_glyph_with_ligature (lig_glyph, klass); for (unsigned int i = 1; i < count; i++) { - while (c->should_mark_skip_current_glyph ()) + while (buffer->idx < match_positions[i]) { if (!is_mark_ligature) { unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (MAX (get_lig_comp (c->buffer->cur()), 1u), last_num_components); - set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp); + MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components); + _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); } - c->buffer->next_glyph (); + buffer->next_glyph (); } - last_lig_id = get_lig_id (c->buffer->cur()); - last_num_components = get_lig_num_comps (c->buffer->cur()); + last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); + last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); components_so_far += last_num_components; /* Skip the base glyph */ - c->buffer->idx++; + buffer->idx++; } if (!is_mark_ligature && last_lig_id) { /* Re-adjust components for any marks following. */ - for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) { - if (last_lig_id == get_lig_id (c->buffer->info[i])) { + for (unsigned int i = buffer->idx; i < buffer->len; i++) { + if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components); - set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp); + MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components); + _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); } else break; } } + TRACE_RETURN (true); } static inline bool match_backtrack (hb_apply_context_t *c, @@ -759,19 +891,14 @@ static inline bool match_backtrack (hb_apply_context_t *c, { TRACE_APPLY (NULL); - hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true); - if (skippy_iter.has_no_chance ()) - return TRACE_RETURN (false); + hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true); + skippy_iter.set_match_func (match_func, match_data, backtrack); + if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); for (unsigned int i = 0; i < count; i++) - { if (!skippy_iter.prev ()) return TRACE_RETURN (false); - if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, backtrack[i], match_data))) - return TRACE_RETURN (false); - } - return TRACE_RETURN (true); } @@ -784,19 +911,14 @@ static inline bool match_lookahead (hb_apply_context_t *c, { TRACE_APPLY (NULL); - hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true); - if (skippy_iter.has_no_chance ()) - return TRACE_RETURN (false); + hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true); + skippy_iter.set_match_func (match_func, match_data, lookahead); + if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); for (unsigned int i = 0; i < count; i++) - { if (!skippy_iter.next ()) return TRACE_RETURN (false); - if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahead[i], match_data))) - return TRACE_RETURN (false); - } - return TRACE_RETURN (true); } @@ -824,65 +946,89 @@ static inline void recurse_lookups (context_t *c, const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) { for (unsigned int i = 0; i < lookupCount; i++) - c->recurse (lookupRecord->lookupListIndex); + c->recurse (lookupRecord[i].lookupListIndex); } static inline bool apply_lookup (hb_apply_context_t *c, unsigned int count, /* Including the first glyph */ + unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int lookupCount, - const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) + const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ + unsigned int match_length) { TRACE_APPLY (NULL); - unsigned int end = c->buffer->len; - if (unlikely (count == 0 || c->buffer->idx + count > end)) - return TRACE_RETURN (false); + hb_buffer_t *buffer = c->buffer; + unsigned int end; - /* TODO We don't support lookupRecord arrays that are not increasing: - * Should be easy for in_place ones at least. */ + /* All positions are distance from beginning of *output* buffer. + * Adjust. */ + { + unsigned int bl = buffer->backtrack_len (); + end = bl + match_length; - /* Note: If sublookup is reverse, it will underflow after the first loop - * and we jump out of it. Not entirely disastrous. So we don't check - * for reverse lookup here. - */ - for (unsigned int i = 0; i < count; /* NOP */) + int delta = bl - buffer->idx; + /* Convert positions to new indexing. */ + for (unsigned int j = 0; j < count; j++) + match_positions[j] += delta; + } + + for (unsigned int i = 0; i < lookupCount; i++) { - if (unlikely (c->buffer->idx == end)) - return TRACE_RETURN (true); - while (c->should_mark_skip_current_glyph ()) - { - /* No lookup applied for this index */ - c->buffer->next_glyph (); - if (unlikely (c->buffer->idx == end)) - return TRACE_RETURN (true); - } + unsigned int idx = lookupRecord[i].sequenceIndex; + if (idx >= count) + continue; - if (lookupCount && i == lookupRecord->sequenceIndex) - { - unsigned int old_pos = c->buffer->idx; + buffer->move_to (match_positions[idx]); + + unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); + if (!c->recurse (lookupRecord[i].lookupListIndex)) + continue; + + unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len (); + int delta = new_len - orig_len; + + if (!delta) + continue; + + /* Recursed lookup changed buffer len. Adjust. */ - /* Apply a lookup */ - bool done = c->recurse (lookupRecord->lookupListIndex); + /* end can't go back past the current match position. + * Note: this is only true because we do NOT allow MultipleSubst + * with zero sequence len. */ + end = MAX ((int) match_positions[idx] + 1, int (end) + delta); - lookupRecord++; - lookupCount--; - /* Err, this is wrong if the lookup jumped over some glyphs */ - i += c->buffer->idx - old_pos; - if (unlikely (c->buffer->idx == end)) - return TRACE_RETURN (true); + unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ - if (!done) - goto not_applied; + if (delta > 0) + { + if (unlikely (delta + count > MAX_CONTEXT_LENGTH)) + break; } else { - not_applied: - /* No lookup applied for this index */ - c->buffer->next_glyph (); - i++; + /* NOTE: delta is negative. */ + delta = MAX (delta, (int) next - (int) count); + next -= delta; } + + /* Shift! */ + memmove (match_positions + next + delta, match_positions + next, + (count - next) * sizeof (match_positions[0])); + next += delta; + count += delta; + + /* Fill in new entries. */ + for (unsigned int j = idx + 1; j < next; j++) + match_positions[j] = match_positions[j - 1] + 1; + + /* And fixup the rest. */ + for (; next < count; next++) + match_positions[next] += delta; } + buffer->move_to (end); + return TRACE_RETURN (true); } @@ -954,12 +1100,16 @@ static inline bool context_apply_lookup (hb_apply_context_t *c, const LookupRecord lookupRecord[], ContextApplyLookupContext &lookup_context) { + unsigned int match_length = 0; + unsigned int match_positions[MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, - lookup_context.funcs.match, lookup_context.match_data) + lookup_context.funcs.match, lookup_context.match_data, + &match_length, match_positions) && apply_lookup (c, - inputCount, - lookupCount, lookupRecord); + inputCount, match_positions, + lookupCount, lookupRecord, + match_length); } struct Rule @@ -1353,13 +1503,13 @@ struct ContextFormat3 struct Context { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - case 2: return TRACE_RETURN (c->process (u.format2)); - case 3: return TRACE_RETURN (c->process (u.format3)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + case 2: return TRACE_RETURN (c->dispatch (u.format2)); + case 3: return TRACE_RETURN (c->dispatch (u.format3)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -1422,7 +1572,7 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, && intersects_array (c, inputCount ? inputCount - 1 : 0, input, lookup_context.funcs.intersects, lookup_context.intersects_data[1]) - && intersects_array (c, + && intersects_array (c, lookaheadCount, lookahead, lookup_context.funcs.intersects, lookup_context.intersects_data[2])) recurse_lookups (c, @@ -1481,21 +1631,23 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, const LookupRecord lookupRecord[], ChainContextApplyLookupContext &lookup_context) { - unsigned int lookahead_offset = 0; + unsigned int match_length = 0; + unsigned int match_positions[MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data[1], - &lookahead_offset) + &match_length, match_positions) && match_backtrack (c, backtrackCount, backtrack, lookup_context.funcs.match, lookup_context.match_data[0]) && match_lookahead (c, lookaheadCount, lookahead, lookup_context.funcs.match, lookup_context.match_data[2], - lookahead_offset) + match_length) && apply_lookup (c, - inputCount, - lookupCount, lookupRecord); + inputCount, match_positions, + lookupCount, lookupRecord, + match_length); } struct ChainRule @@ -1968,13 +2120,13 @@ struct ChainContextFormat3 struct ChainContext { template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - TRACE_PROCESS (this); + TRACE_DISPATCH (this); switch (u.format) { - case 1: return TRACE_RETURN (c->process (u.format1)); - case 2: return TRACE_RETURN (c->process (u.format2)); - case 3: return TRACE_RETURN (c->process (u.format3)); + case 1: return TRACE_RETURN (c->dispatch (u.format1)); + case 2: return TRACE_RETURN (c->dispatch (u.format2)); + case 3: return TRACE_RETURN (c->dispatch (u.format3)); default:return TRACE_RETURN (c->default_return_value ()); } } @@ -2048,9 +2200,9 @@ struct Extension } template <typename context_t> - inline typename context_t::return_t process (context_t *c) const + inline typename context_t::return_t dispatch (context_t *c) const { - return get_subtable<typename T::LookupSubTable> ().process (c, get_type ()); + return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); } inline bool sanitize_self (hb_sanitize_context_t *c) { @@ -2102,8 +2254,8 @@ struct GSUBGPOS inline unsigned int get_feature_count (void) const { return (this+featureList).len; } - inline const Tag& get_feature_tag (unsigned int i) const - { return (this+featureList).get_tag (i); } + inline hb_tag_t get_feature_tag (unsigned int i) const + { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); } inline unsigned int get_feature_tags (unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, hb_tag_t *feature_tags /* OUT */) const @@ -2128,7 +2280,7 @@ struct GSUBGPOS protected: FixedVersion version; /* Version of the GSUB/GPOS table--initially set - * to 0x00010000 */ + * to 0x00010000u */ OffsetTo<ScriptList> scriptList; /* ScriptList table */ OffsetTo<FeatureList> diff --git a/src/hb-ot-layout-jstf-table.hh b/src/hb-ot-layout-jstf-table.hh new file mode 100644 index 0000000..67a6df5 --- /dev/null +++ b/src/hb-ot-layout-jstf-table.hh @@ -0,0 +1,229 @@ +/* + * 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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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) { + TRACE_SANITIZE (this); + return TRACE_RETURN (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 */ diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 49093de..ae7daa6 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008,2009 Red Hat, Inc. - * Copyright © 2012 Google, Inc. + * Copyright © 2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -31,39 +31,221 @@ #include "hb-private.hh" -#include "hb-ot-layout.h" - #include "hb-font-private.hh" #include "hb-buffer-private.hh" #include "hb-set-private.hh" -/* buffer var allocations, used during the GSUB/GPOS processing */ -#define glyph_props() var1.u16[0] /* GDEF glyph properties */ -#define syllable() var1.u8[2] /* GSUB/GPOS shaping boundaries */ -#define lig_props() var1.u8[3] /* GSUB/GPOS ligature tracking */ - -#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot) - /* * GDEF */ -typedef enum { - HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED = 0x0001, - HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x0002, - HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x0004, - HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x0008, - HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT = 0x0010 +typedef enum +{ + /* 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_ot_layout_glyph_class_mask_t; - /* * GSUB/GPOS */ -/* lig_id / lig_comp +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 after all the substitute_lookup's are done */ +HB_INTERNAL void +hb_ot_layout_substitute_finish (hb_font_t *font, + hb_buffer_t *buffer); + + +/* Should be called before all the position_lookup's are done. Resets positions to zero. */ +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 */ +HB_INTERNAL void +hb_ot_layout_position_finish (hb_font_t *font, + hb_buffer_t *buffer); + + + +/* + * hb_ot_layout_t + */ + +namespace OT { + struct GDEF; + struct GSUB; + struct GPOS; +} + +struct hb_ot_layout_lookup_accelerator_t +{ + template <typename TLookup> + inline void init (const TLookup &lookup) + { + digest.init (); + lookup.add_coverage (&digest); + } + + template <typename TLookup> + inline void fini (const TLookup &lookup HB_UNUSED) + { + } + + 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; + + const struct OT::GDEF *gdef; + const struct OT::GSUB *gsub; + const struct OT::GPOS *gpos; + + 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_props0() var2.u8[0] +#define unicode_props1() var2.u8[1] + +/* 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 */ + +/* unicode_props */ + +enum { + MASK0_ZWJ = 0x20u, + MASK0_ZWNJ = 0x40u, + MASK0_IGNORABLE = 0x80u, + MASK0_GEN_CAT = 0x1Fu +}; + +static inline void +_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) +{ + /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */ + info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) | + (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) | + (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) | + (info->codepoint == 0x200Du ? MASK0_ZWJ : 0); + info->unicode_props1() = unicode->modified_combining_class (info->codepoint); +} + +static inline void +_hb_glyph_info_set_general_category (hb_glyph_info_t *info, + hb_unicode_general_category_t gen_cat) +{ + info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_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_props0() & MASK0_GEN_CAT); +} + +static inline void +_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, + unsigned int modified_class) +{ + info->unicode_props1() = modified_class; +} + +static inline unsigned int +_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) +{ + return info->unicode_props1(); +} + +static inline hb_bool_t +_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) +{ + return !!(info->unicode_props0() & MASK0_IGNORABLE); +} + +static inline hb_bool_t +_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) +{ + return !!(info->unicode_props0() & MASK0_ZWNJ); +} + +static inline hb_bool_t +_hb_glyph_info_is_zwj (const hb_glyph_info_t *info) +{ + return !!(info->unicode_props0() & MASK0_ZWJ); +} + +static inline void +_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) +{ + info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ; +} + +/* lig_props: aka lig_id / lig_comp * * When a ligature is formed: * @@ -73,7 +255,9 @@ typedef enum { * - 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. + * 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: * @@ -83,138 +267,194 @@ typedef enum { * 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 a ligature in MarkMarPos. + * 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 -set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps) +_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); + info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F); } + static inline void -set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp) +_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); + info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F); } + static inline void -set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp) +_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp) { - set_lig_props_for_mark (info, 0, comp); + _hb_glyph_info_set_lig_props_for_mark (info, 0, comp); } static inline unsigned int -get_lig_id (const hb_glyph_info_t &info) +_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info) { - return info.lig_props() >> 5; + return info->lig_props() >> 5; } + static inline bool -is_a_ligature (const hb_glyph_info_t &info) +_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info) { - return !!(info.lig_props() & IS_LIG_BASE); + return !!(info->lig_props() & IS_LIG_BASE); } + static inline unsigned int -get_lig_comp (const hb_glyph_info_t &info) +_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info) { - if (is_a_ligature (info)) + if (_hb_glyph_info_ligated_internal (info)) return 0; else - return info.lig_props() & 0x0F; + return info->lig_props() & 0x0F; } + static inline unsigned int -get_lig_num_comps (const hb_glyph_info_t &info) +_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info) { - if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info)) - return info.lig_props() & 0x0F; + 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 allocate_lig_id (hb_buffer_t *buffer) { +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 = allocate_lig_id (buffer); /* in case of overflow */ + lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */ return lig_id; } +/* glyph_props: */ -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); +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(); +} -/* 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); +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); +} -HB_INTERNAL hb_bool_t -hb_ot_layout_substitute_lookup (hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask); +static inline bool +_hb_glyph_info_is_ligature (const hb_glyph_info_t *info) +{ + return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE); +} -/* Should be called after all the substitute_lookup's are done */ -HB_INTERNAL void -hb_ot_layout_substitute_finish (hb_font_t *font, - hb_buffer_t *buffer); +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); +} -/* Should be called before all the position_lookup's are done. Resets positions to zero. */ -HB_INTERNAL void -hb_ot_layout_position_start (hb_font_t *font, - hb_buffer_t *buffer); +static inline bool +_hb_glyph_info_ligated (const hb_glyph_info_t *info) +{ + return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED); +} -HB_INTERNAL hb_bool_t -hb_ot_layout_position_lookup (hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask); +static inline bool +_hb_glyph_info_multiplied (const hb_glyph_info_t *info) +{ + return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); +} -/* Should be called after all the position_lookup's are done */ -HB_INTERNAL void -hb_ot_layout_position_finish (hb_font_t *font, - hb_buffer_t *buffer, - hb_bool_t zero_width_attached_marks); +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); +} -/* - * hb_ot_layout_t - */ +/* Allocation / deallocation. */ -namespace OT { - struct GDEF; - struct GSUB; - struct GPOS; +static inline void +_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer) +{ + HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0); + HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1); } -struct hb_ot_layout_t +static inline void +_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer) { - hb_blob_t *gdef_blob; - hb_blob_t *gsub_blob; - hb_blob_t *gpos_blob; - - const struct OT::GDEF *gdef; - const struct OT::GSUB *gsub; - const struct OT::GPOS *gpos; - - unsigned int gsub_lookup_count; - unsigned int gpos_lookup_count; + HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0); + HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1); +} - hb_set_digest_t *gsub_digests; - hb_set_digest_t *gpos_digests; -}; +static inline void +_hb_buffer_assert_unicode_vars (hb_buffer_t *buffer) +{ + HB_BUFFER_ASSERT_VAR (buffer, unicode_props0); + HB_BUFFER_ASSERT_VAR (buffer, unicode_props1); +} +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); +} -HB_INTERNAL hb_ot_layout_t * -_hb_ot_layout_create (hb_face_t *face); +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); +} -HB_INTERNAL void -_hb_ot_layout_destroy (hb_ot_layout_t *layout); +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 */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 3ff6fc8..661d90e 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -2,7 +2,7 @@ * Copyright © 1998-2004 David Turner and Werner Lemberg * Copyright © 2006 Behdad Esfahbod * Copyright © 2007,2008,2009 Red Hat, Inc. - * Copyright © 2012 Google, Inc. + * Copyright © 2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -33,6 +33,9 @@ #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-layout-jstf-table.hh" + +#include "hb-ot-map-private.hh" #include <stdlib.h> #include <string.h> @@ -59,20 +62,20 @@ _hb_ot_layout_create (hb_face_t *face) layout->gsub_lookup_count = layout->gsub->get_lookup_count (); layout->gpos_lookup_count = layout->gpos->get_lookup_count (); - layout->gsub_digests = (hb_set_digest_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_set_digest_t)); - layout->gpos_digests = (hb_set_digest_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_set_digest_t)); + layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); + layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); - if (unlikely ((layout->gsub_lookup_count && !layout->gsub_digests) || - (layout->gpos_lookup_count && !layout->gpos_digests))) + if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) || + (layout->gpos_lookup_count && !layout->gpos_accels))) { _hb_ot_layout_destroy (layout); return NULL; } for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) - layout->gsub->get_lookup (i).add_coverage (&layout->gsub_digests[i]); + layout->gsub_accels[i].init (layout->gsub->get_lookup (i)); for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) - layout->gpos->get_lookup (i).add_coverage (&layout->gpos_digests[i]); + layout->gpos_accels[i].init (layout->gpos->get_lookup (i)); return layout; } @@ -80,13 +83,18 @@ _hb_ot_layout_create (hb_face_t *face) void _hb_ot_layout_destroy (hb_ot_layout_t *layout) { + for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) + layout->gsub_accels[i].fini (layout->gsub->get_lookup (i)); + for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) + layout->gpos_accels[i].fini (layout->gpos->get_lookup (i)); + + free (layout->gsub_accels); + free (layout->gpos_accels); + hb_blob_destroy (layout->gdef_blob); hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); - free (layout->gsub_digests); - free (layout->gpos_digests); - free (layout); } @@ -319,9 +327,28 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, unsigned int language_index, unsigned int *feature_index) { - const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index); + return hb_ot_layout_language_get_required_feature (face, + table_tag, + script_index, + language_index, + feature_index, + NULL); +} - if (feature_index) *feature_index = l.get_required_feature_index (); +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) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); + + unsigned int index = l.get_required_feature_index (); + if (feature_index) *feature_index = index; + if (feature_tag) *feature_tag = g.get_feature_tag (index); return l.has_required_feature (); } @@ -406,6 +433,24 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); } +unsigned int +hb_ot_layout_table_get_lookup_count (hb_face_t *face, + hb_tag_t table_tag) +{ + switch (table_tag) + { + case HB_OT_TAG_GSUB: + { + return hb_ot_layout_from_face (face)->gsub_lookup_count; + } + case HB_OT_TAG_GPOS: + { + return hb_ot_layout_from_face (face)->gpos_lookup_count; + } + } + return 0; +} + static void _hb_ot_layout_collect_lookups_lookups (hb_face_t *face, hb_tag_t table_tag, @@ -439,19 +484,20 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */) { - unsigned int required_feature_index; - if (hb_ot_layout_language_get_required_feature_index (face, - table_tag, - script_index, - language_index, - &required_feature_index)) - _hb_ot_layout_collect_lookups_lookups (face, - table_tag, - required_feature_index, - lookup_indexes); - if (!features) { + unsigned int required_feature_index; + if (hb_ot_layout_language_get_required_feature (face, + table_tag, + script_index, + language_index, + &required_feature_index, + NULL)) + _hb_ot_layout_collect_lookups_lookups (face, + table_tag, + required_feature_index, + lookup_indexes); + /* All features */ unsigned int feature_indices[32]; unsigned int offset, len; @@ -607,13 +653,13 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, case HB_OT_TAG_GSUB: { const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); - l.collect_glyphs_lookup (&c); + l.collect_glyphs (&c); return; } case HB_OT_TAG_GPOS: { const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index); - l.collect_glyphs_lookup (&c); + l.collect_glyphs (&c); return; } } @@ -653,7 +699,7 @@ hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); - return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_digests[lookup_index]); + return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest); } void @@ -662,21 +708,6 @@ hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) OT::GSUB::substitute_start (font, buffer); } -hb_bool_t -hb_ot_layout_substitute_lookup (hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask) -{ - if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gsub_lookup_count)) return false; - - OT::hb_apply_context_t c (font, buffer, mask); - - const OT::SubstLookup& l = hb_ot_layout_from_face (font->face)->gsub->get_lookup (lookup_index); - - return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gsub_digests[lookup_index]); -} - void hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) { @@ -711,25 +742,10 @@ hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) OT::GPOS::position_start (font, buffer); } -hb_bool_t -hb_ot_layout_position_lookup (hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask) -{ - if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gpos_lookup_count)) return false; - - OT::hb_apply_context_t c (font, buffer, mask); - - const OT::PosLookup& l = hb_ot_layout_from_face (font->face)->gpos->get_lookup (lookup_index); - - return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gpos_digests[lookup_index]); -} - void -hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks) +hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) { - OT::GPOS::position_finish (font, buffer, zero_width_attached_marks); + OT::GPOS::position_finish (font, buffer); } hb_bool_t @@ -776,3 +792,159 @@ hb_ot_layout_get_size_params (hb_face_t *face, return false; } + + +/* + * Parts of different types are implemented here such that they have direct + * access to GSUB/GPOS lookups. + */ + + +struct GSUBProxy +{ + static const unsigned int table_index = 0; + static const bool inplace = false; + typedef OT::SubstLookup Lookup; + + GSUBProxy (hb_face_t *face) : + table (*hb_ot_layout_from_face (face)->gsub), + accels (hb_ot_layout_from_face (face)->gsub_accels) {} + + const OT::GSUB &table; + const hb_ot_layout_lookup_accelerator_t *accels; +}; + +struct GPOSProxy +{ + static const unsigned int table_index = 1; + static const bool inplace = true; + typedef OT::PosLookup Lookup; + + GPOSProxy (hb_face_t *face) : + table (*hb_ot_layout_from_face (face)->gpos), + accels (hb_ot_layout_from_face (face)->gpos_accels) {} + + const OT::GPOS &table; + const hb_ot_layout_lookup_accelerator_t *accels; +}; + + +template <typename Lookup> +static inline bool apply_once (OT::hb_apply_context_t *c, + const Lookup &lookup) +{ + if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) + return false; + return lookup.dispatch (c); +} + +template <typename Proxy> +static inline bool +apply_string (OT::hb_apply_context_t *c, + const typename Proxy::Lookup &lookup, + const hb_ot_layout_lookup_accelerator_t &accel) +{ + bool ret = false; + hb_buffer_t *buffer = c->buffer; + + if (unlikely (!buffer->len || !c->lookup_mask)) + return false; + + c->set_lookup (lookup); + + if (likely (!lookup.is_reverse ())) + { + /* in/out forward substitution/positioning */ + if (Proxy::table_index == 0) + buffer->clear_output (); + buffer->idx = 0; + + while (buffer->idx < buffer->len) + { + if (accel.digest.may_have (buffer->cur().codepoint) && + (buffer->cur().mask & c->lookup_mask) && + apply_once (c, lookup)) + ret = true; + else + buffer->next_glyph (); + } + if (ret) + { + if (!Proxy::inplace) + buffer->swap_buffers (); + else + assert (!buffer->has_separate_output ()); + } + } + else + { + /* in-place backward substitution/positioning */ + if (Proxy::table_index == 0) + buffer->remove_output (); + buffer->idx = buffer->len - 1; + do + { + if (accel.digest.may_have (buffer->cur().codepoint) && + (buffer->cur().mask & c->lookup_mask) && + apply_once (c, lookup)) + ret = true; + /* The reverse lookup doesn't "advance" cursor (for good reason). */ + buffer->idx--; + + } + while ((int) buffer->idx >= 0); + } + + return ret; +} + +template <typename Proxy> +inline void hb_ot_map_t::apply (const Proxy &proxy, + const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) const +{ + const unsigned int table_index = proxy.table_index; + unsigned int i = 0; + OT::hb_apply_context_t c (table_index, font, buffer); + c.set_recurse_func (Proxy::Lookup::apply_recurse_func); + + for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { + const stage_map_t *stage = &stages[table_index][stage_index]; + for (; i < stage->last_lookup; i++) + { + unsigned int lookup_index = lookups[table_index][i].index; + c.set_lookup_mask (lookups[table_index][i].mask); + c.set_auto_zwj (lookups[table_index][i].auto_zwj); + apply_string<Proxy> (&c, + proxy.table.get_lookup (lookup_index), + proxy.accels[lookup_index]); + } + + if (stage->pause_func) + { + buffer->clear_output (); + stage->pause_func (plan, font, buffer); + } + } +} + +void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const +{ + GSUBProxy proxy (font->face); + apply (proxy, plan, font, buffer); +} + +void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const +{ + GPOSProxy proxy (font->face); + apply (proxy, plan, font, buffer); +} + +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) +{ + apply_string<GSUBProxy> (c, lookup, accel); +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 134f1a6..949678a 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -41,6 +41,7 @@ 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') /* @@ -91,9 +92,9 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, * GSUB/GPOS feature query and enumeration interface */ -#define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF) -#define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF) -#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF) +#define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu +#define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu +#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu unsigned int hb_ot_layout_table_get_script_tags (hb_face_t *face, @@ -145,6 +146,14 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, unsigned int language_index, unsigned int *feature_index); +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); + unsigned int hb_ot_layout_language_get_feature_indexes (hb_face_t *face, hb_tag_t table_tag, @@ -179,6 +188,11 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_indexes /* OUT */); +unsigned int +hb_ot_layout_table_get_lookup_count (hb_face_t *face, + hb_tag_t table_tag); + + void hb_ot_layout_collect_lookups (hb_face_t *face, hb_tag_t table_tag, @@ -188,11 +202,6 @@ hb_ot_layout_collect_lookups (hb_face_t *face, hb_set_t *lookup_indexes /* OUT */); void -hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, - hb_tag_t table_tag, - hb_set_t *lookup_indexes /* OUT */); - -void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index b140207..86b7e9f 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -1,6 +1,6 @@ /* * Copyright © 2009,2010 Red Hat, Inc. - * Copyright © 2010,2011,2012 Google, Inc. + * Copyright © 2010,2011,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -31,8 +31,8 @@ #include "hb-buffer-private.hh" -#include "hb-ot-layout-private.hh" +struct hb_ot_shape_plan_t; static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; @@ -49,14 +49,16 @@ struct hb_ot_map_t unsigned int shift; hb_mask_t mask; hb_mask_t _1_mask; /* mask for value=1, for quick access */ - hb_bool_t needs_fallback; + 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 int index; + 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) @@ -65,9 +67,9 @@ struct hb_ot_map_t typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); - struct pause_map_t { - unsigned int num_lookups; /* Cumulative */ - pause_func_t callback; + struct stage_map_t { + unsigned int last_lookup; /* Cumulative */ + pause_func_t pause_func; }; @@ -108,23 +110,27 @@ struct hb_ot_map_t *lookup_count = 0; return; } - assert (stage <= pauses[table_index].len); - unsigned int start = stage ? pauses[table_index][stage - 1].num_lookups : 0; - unsigned int end = stage < pauses[table_index].len ? pauses[table_index][stage].num_lookups : lookups[table_index].len; + 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 (); - lookups[0].finish (); - lookups[1].finish (); - pauses[0].finish (); - pauses[1].finish (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + lookups[table_index].finish (); + stages[table_index].finish (); + } } public: @@ -136,14 +142,39 @@ struct hb_ot_map_t HB_INTERNAL void add_lookups (hb_face_t *face, unsigned int table_index, unsigned int feature_index, - hb_mask_t mask); + hb_mask_t mask, + bool auto_zwj); 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<pause_map_t, 1> pauses[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, + F_HAS_FALLBACK = 0x0002u, + F_MANUAL_ZWJ = 0x0004u }; +/* Macro version for where const is desired. */ +#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r))) +static inline hb_ot_map_feature_flags_t +operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r) +{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); } +static inline hb_ot_map_feature_flags_t +operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r) +{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); } +static inline hb_ot_map_feature_flags_t +operator ~ (hb_ot_map_feature_flags_t r) +{ return hb_ot_map_feature_flags_t (~(unsigned int) r); } +static inline hb_ot_map_feature_flags_t& +operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r) +{ l = l | r; return l; } +static inline hb_ot_map_feature_flags_t& +operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r) +{ l = l & r; return l; } struct hb_ot_map_builder_t @@ -153,10 +184,11 @@ struct hb_ot_map_builder_t 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, bool global, bool has_fallback = false); + HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, + hb_ot_map_feature_flags_t flags); - inline void add_bool_feature (hb_tag_t tag, bool global = true, bool has_fallback = false) - { add_feature (tag, 1, global, has_fallback); } + 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); } @@ -167,8 +199,10 @@ struct hb_ot_map_builder_t inline void finish (void) { feature_infos.finish (); - pauses[0].finish (); - pauses[1].finish (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + stages[table_index].finish (); + } } private: @@ -177,8 +211,7 @@ struct hb_ot_map_builder_t hb_tag_t tag; unsigned int seq; /* sequence#, used for stable sorting only */ unsigned int max_value; - bool global; /* whether the feature applies value to every glyph in the buffer */ - bool has_fallback; /* whether to allocate bits even if feature not found */ + 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 */ @@ -186,9 +219,9 @@ struct hb_ot_map_builder_t { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); } }; - struct pause_info_t { - unsigned int stage; - hb_ot_map_t::pause_func_t callback; + 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); @@ -205,8 +238,8 @@ struct hb_ot_map_builder_t private: unsigned int current_stage[2]; /* GSUB/GPOS */ - hb_prealloced_array_t<feature_info_t,16> feature_infos; - hb_prealloced_array_t<pause_info_t, 1> pauses[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 */ }; diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 62f7904..4985eb2 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -1,6 +1,6 @@ /* * Copyright © 2009,2010 Red Hat, Inc. - * Copyright © 2010,2011 Google, Inc. + * Copyright © 2010,2011,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -28,15 +28,21 @@ #include "hb-ot-map-private.hh" +#include "hb-ot-layout-private.hh" + void hb_ot_map_t::add_lookups (hb_face_t *face, unsigned int table_index, unsigned int feature_index, - hb_mask_t mask) + 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 { @@ -47,12 +53,16 @@ hb_ot_map_t::add_lookups (hb_face_t *face, offset, &len, lookup_indices); - for (unsigned int i = 0; i < len; i++) { + for (unsigned int i = 0; i < len; i++) + { + if (lookup_indices[i] >= table_lookup_count) + continue; hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push (); if (unlikely (!lookup)) return; lookup->mask = mask; lookup->index = lookup_indices[i]; + lookup->auto_zwj = auto_zwj; } offset += len; @@ -84,59 +94,21 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, } } -void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback) +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->global = global; - info->has_fallback = has_fallback; - info->default_value = global ? value : 0; + info->flags = flags; + info->default_value = (flags & F_GLOBAL) ? value : 0; info->stage[0] = current_stage[0]; info->stage[1] = current_stage[1]; } -/* Keep the next two functions in sync. */ - -void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const -{ - const unsigned int table_index = 0; - unsigned int i = 0; - - for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { - const pause_map_t *pause = &pauses[table_index][pause_index]; - for (; i < pause->num_lookups; i++) - hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); - - buffer->clear_output (); - - if (pause->callback) - pause->callback (plan, font, buffer); - } - - for (; i < lookups[table_index].len; i++) - hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); -} - -void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const -{ - const unsigned int table_index = 1; - unsigned int i = 0; - - for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { - const pause_map_t *pause = &pauses[table_index][pause_index]; - for (; i < pause->num_lookups; i++) - hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); - - if (pause->callback) - pause->callback (plan, font, buffer); - } - - for (; i < lookups[table_index].len; i++) - hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); -} void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const { @@ -146,10 +118,10 @@ void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_o void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func) { - pause_info_t *p = pauses[table_index].push (); - if (likely (p)) { - p->stage = current_stage[table_index]; - p->callback = 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]++; @@ -160,9 +132,25 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) { m.global_mask = 1; - for (unsigned int table_index = 0; table_index < 2; table_index++) { + 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) @@ -170,24 +158,24 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) /* Sort features and merge duplicates */ { - feature_infos.sort (); + 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].global) { - feature_infos[j].global = true; + 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].global = false; + 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].has_fallback = feature_infos[j].has_fallback || feature_infos[i].has_fallback; + 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]); - /* Inherit default_value from j */ } feature_infos.shrink (j + 1); } @@ -195,12 +183,13 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) /* Allocate bits now */ unsigned int next_bit = 1; - for (unsigned int i = 0; i < feature_infos.len; i++) { + for (unsigned int i = 0; i < feature_infos.len; i++) + { const feature_info_t *info = &feature_infos[i]; unsigned int bits_needed; - if (info->global && info->max_value == 1) + if ((info->flags & F_GLOBAL) && info->max_value == 1) /* Uses the global bit */ bits_needed = 0; else @@ -210,16 +199,24 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) continue; /* Feature disabled, or not enough bits. */ - bool found = false; + 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 = true; + continue; + } 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->has_fallback) + } + if (!found && !(info->flags & F_HAS_FALLBACK)) continue; @@ -232,7 +229,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) map->index[1] = feature_index[1]; map->stage[0] = info->stage[0]; map->stage[1] = info->stage[1]; - if (info->global && info->max_value == 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; @@ -240,8 +238,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) map->shift = next_bit; map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); next_bit += bits_needed; - if (info->global) - m.global_mask |= (info->default_value << map->shift) & map->mask; + m.global_mask |= (info->default_value << map->shift) & map->mask; } map->_1_mask = (1 << map->shift) & map->mask; map->needs_fallback = !found; @@ -253,51 +250,55 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) add_gsub_pause (NULL); add_gpos_pause (NULL); - for (unsigned int table_index = 0; table_index < 2; table_index++) { - hb_tag_t table_tag = table_tags[table_index]; - + for (unsigned int table_index = 0; table_index < 2; table_index++) + { /* Collect lookup indices for features */ - unsigned int required_feature_index; - if (hb_ot_layout_language_get_required_feature_index (face, - table_tag, - script_index[table_index], - language_index[table_index], - &required_feature_index)) - m.add_lookups (face, table_index, required_feature_index, 1); - - unsigned int pause_index = 0; + 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) + m.add_lookups (face, table_index, + required_feature_index[table_index], + 1 /* mask */, + true /* auto_zwj */); + for (unsigned i = 0; i < m.features.len; i++) if (m.features[i].stage[table_index] == stage) - m.add_lookups (face, table_index, m.features[i].index[table_index], m.features[i].mask); + m.add_lookups (face, table_index, + m.features[i].index[table_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].sort (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 (pause_index < pauses[table_index].len && pauses[table_index][pause_index].stage == stage) { - hb_ot_map_t::pause_map_t *pause_map = m.pauses[table_index].push (); - if (likely (pause_map)) { - pause_map->num_lookups = last_num_lookups; - pause_map->callback = pauses[table_index][pause_index].callback; + 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; } - pause_index++; + stage_index++; } } } diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh index 0ce3ebc..b1f8328 100644 --- a/src/hb-ot-maxp-table.hh +++ b/src/hb-ot-maxp-table.hh @@ -41,7 +41,7 @@ namespace OT { struct maxp { - static const hb_tag_t Tag = HB_OT_TAG_maxp; + static const hb_tag_t tableTag = HB_OT_TAG_maxp; inline unsigned int get_num_glyphs (void) const { return numGlyphs; @@ -50,13 +50,13 @@ struct maxp inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && - likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000))); + 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), - * 0x00005000 or 0x00010000. */ + * 0x00005000u or 0x00010000u. */ USHORT numGlyphs; /* The number of glyphs in the font. */ public: DEFINE_SIZE_STATIC (6); diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 75a1b94..31d9fac 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -74,7 +74,7 @@ struct NameRecord struct name { - static const hb_tag_t Tag = HB_OT_TAG_name; + static const hb_tag_t tableTag = HB_OT_TAG_name; inline unsigned int get_name (unsigned int platform_id, unsigned int encoding_id, @@ -98,6 +98,9 @@ struct name 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) { TRACE_SANITIZE (this); char *string_pool = (char *) this + stringOffset; @@ -116,10 +119,9 @@ struct name } /* We only implement format 0 for now. */ - protected: USHORT format; /* Format selector (=0/1). */ USHORT count; /* Number of name records. */ - Offset stringOffset; /* Offset to start of string storage (from start of table). */ + 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); diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh index 4fcd0a2..e5b7ed4 100644 --- a/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/hb-ot-shape-complex-arabic-fallback.hh @@ -33,6 +33,8 @@ #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'), @@ -42,16 +44,6 @@ static const hb_tag_t arabic_fallback_features[] = HB_TAG('r','l','i','g'), }; -/* Same order as the fallback feature array */ -enum { - FALLBACK_INIT, - FALLBACK_MEDI, - FALLBACK_FINA, - FALLBACK_ISOL, - FALLBACK_RLIG, - ARABIC_NUM_FALLBACK_FEATURES -}; - static OT::SubstLookup * arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font, @@ -71,7 +63,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS !hb_font_get_glyph (font, u, 0, &u_glyph) || !hb_font_get_glyph (font, s, 0, &s_glyph) || u_glyph == s_glyph || - u_glyph > 0xFFFF || s_glyph > 0xFFFF) + u_glyph > 0xFFFFu || s_glyph > 0xFFFFu) continue; glyphs[num_glyphs].set (u_glyph); @@ -80,6 +72,9 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS num_glyphs++; } + if (!num_glyphs) + return NULL; + /* Bubble-sort! * May not be good-enough for presidential candidate interviews, but good-enough for us... */ hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]); @@ -157,6 +152,9 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN } } + 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); @@ -193,17 +191,108 @@ arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan, return arabic_fallback_synthesize_lookup_ligature (plan, font); } +#define ARABIC_FALLBACK_MAX_LOOKUPS 5 + struct arabic_fallback_plan_t { ASSERT_POD (); - hb_mask_t mask_array[ARABIC_NUM_FALLBACK_FEATURES]; - OT::SubstLookup *lookup_array[ARABIC_NUM_FALLBACK_FEATURES]; - hb_set_digest_t digest_array[ARABIC_NUM_FALLBACK_FEATURES]; + 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_WITH_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) @@ -212,16 +301,21 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, if (unlikely (!fallback_plan)) return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil); - for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) { - fallback_plan->mask_array[i] = plan->map.get_1_mask (arabic_fallback_features[i]); - if (fallback_plan->mask_array[i]) { - fallback_plan->lookup_array[i] = arabic_fallback_synthesize_lookup (plan, font, i); - if (fallback_plan->lookup_array[i]) - fallback_plan->lookup_array[i]->add_coverage (&fallback_plan->digest_array[i]); - } - } + 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; - 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 @@ -230,9 +324,13 @@ 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 < ARABIC_NUM_FALLBACK_FEATURES; i++) + for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) if (fallback_plan->lookup_array[i]) - free (fallback_plan->lookup_array[i]); + { + fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]); + if (fallback_plan->free_lookups) + free (fallback_plan->lookup_array[i]); + } free (fallback_plan); } @@ -242,10 +340,13 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan, hb_font_t *font, hb_buffer_t *buffer) { - for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) + 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]) { - OT::hb_apply_context_t c (font, buffer, fallback_plan->mask_array[i]); - fallback_plan->lookup_array[i]->apply_string (&c, &fallback_plan->digest_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]); } } diff --git a/src/hb-ot-shape-complex-arabic-table.hh b/src/hb-ot-shape-complex-arabic-table.hh index 730a275..1710049 100644 --- a/src/hb-ot-shape-complex-arabic-table.hh +++ b/src/hb-ot-shape-complex-arabic-table.hh @@ -2,12 +2,14 @@ /* * The following table is generated by running: * - * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt + * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt * * on files with these headers: * - * # ArabicShaping-6.2.0.txt - * # Date: 2012-05-15, 21:05:00 GMT [KW] + * # ArabicShaping-7.0.0.txt + * # Date: 2014-02-14, 21:00:00 GMT [RP, KW, LI] + * # Blocks-7.0.0.txt + * # Date: 2014-04-03, 23:23:00 GMT [RP, KW] * UnicodeData.txt does not have a header. */ @@ -15,903 +17,342 @@ #define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH +#define X JOINING_TYPE_X +#define R JOINING_TYPE_R +#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[] = { - /* Arabic Characters */ - - JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */ - JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */ - JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */ - JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */ - JOINING_TYPE_U, /* 0604; ARABIC SIGN SAMVAT; U; No_Joining_Group */ - JOINING_TYPE_X, /* 0605 */ - JOINING_TYPE_X, /* 0606 */ - JOINING_TYPE_X, /* 0607 */ - JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */ - JOINING_TYPE_X, /* 0609 */ - JOINING_TYPE_X, /* 060A */ - JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */ - JOINING_TYPE_X, /* 060C */ - JOINING_TYPE_X, /* 060D */ - JOINING_TYPE_X, /* 060E */ - JOINING_TYPE_X, /* 060F */ - JOINING_TYPE_X, /* 0610 */ - JOINING_TYPE_X, /* 0611 */ - JOINING_TYPE_X, /* 0612 */ - JOINING_TYPE_X, /* 0613 */ - JOINING_TYPE_X, /* 0614 */ - JOINING_TYPE_X, /* 0615 */ - JOINING_TYPE_X, /* 0616 */ - JOINING_TYPE_X, /* 0617 */ - JOINING_TYPE_X, /* 0618 */ - JOINING_TYPE_X, /* 0619 */ - JOINING_TYPE_X, /* 061A */ - JOINING_TYPE_X, /* 061B */ - JOINING_TYPE_X, /* 061C */ - JOINING_TYPE_X, /* 061D */ - JOINING_TYPE_X, /* 061E */ - JOINING_TYPE_X, /* 061F */ - JOINING_TYPE_D, /* 0620; DOTLESS YEH WITH SEPARATE RING BELOW; D; YEH */ - JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */ - JOINING_TYPE_R, /* 0622; ALEF WITH MADDA ABOVE; R; ALEF */ - JOINING_TYPE_R, /* 0623; ALEF WITH HAMZA ABOVE; R; ALEF */ - JOINING_TYPE_R, /* 0624; WAW WITH HAMZA ABOVE; R; WAW */ - JOINING_TYPE_R, /* 0625; ALEF WITH HAMZA BELOW; R; ALEF */ - JOINING_TYPE_D, /* 0626; DOTLESS YEH WITH HAMZA ABOVE; D; YEH */ - JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */ - JOINING_TYPE_D, /* 0628; BEH; D; BEH */ - JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */ - JOINING_TYPE_D, /* 062A; DOTLESS BEH WITH 2 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 062B; DOTLESS BEH WITH 3 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 062C; HAH WITH DOT BELOW; D; HAH */ - JOINING_TYPE_D, /* 062D; HAH; D; HAH */ - JOINING_TYPE_D, /* 062E; HAH WITH DOT ABOVE; D; HAH */ - JOINING_TYPE_R, /* 062F; DAL; R; DAL */ - JOINING_TYPE_R, /* 0630; DAL WITH DOT ABOVE; R; DAL */ - JOINING_TYPE_R, /* 0631; REH; R; REH */ - JOINING_TYPE_R, /* 0632; REH WITH DOT ABOVE; R; REH */ - JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */ - JOINING_TYPE_D, /* 0634; SEEN WITH 3 DOTS ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 0635; SAD; D; SAD */ - JOINING_TYPE_D, /* 0636; SAD WITH DOT ABOVE; D; SAD */ - JOINING_TYPE_D, /* 0637; TAH; D; TAH */ - JOINING_TYPE_D, /* 0638; TAH WITH DOT ABOVE; D; TAH */ - JOINING_TYPE_D, /* 0639; AIN; D; AIN */ - JOINING_TYPE_D, /* 063A; AIN WITH DOT ABOVE; D; AIN */ - JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */ - JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */ - JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V ABOVE; D; FARSI YEH */ - JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */ - JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */ - JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */ - JOINING_TYPE_D, /* 0641; FEH; D; FEH */ - JOINING_TYPE_D, /* 0642; QAF; D; QAF */ - JOINING_TYPE_D, /* 0643; KAF; D; KAF */ - JOINING_TYPE_D, /* 0644; LAM; D; LAM */ - JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */ - JOINING_TYPE_D, /* 0646; NOON; D; NOON */ - JOINING_TYPE_D, /* 0647; HEH; D; HEH */ - JOINING_TYPE_R, /* 0648; WAW; R; WAW */ - JOINING_TYPE_D, /* 0649; DOTLESS YEH; D; YEH */ - JOINING_TYPE_D, /* 064A; YEH; D; YEH */ - JOINING_TYPE_X, /* 064B */ - JOINING_TYPE_X, /* 064C */ - JOINING_TYPE_X, /* 064D */ - JOINING_TYPE_X, /* 064E */ - JOINING_TYPE_X, /* 064F */ - JOINING_TYPE_X, /* 0650 */ - JOINING_TYPE_X, /* 0651 */ - JOINING_TYPE_X, /* 0652 */ - JOINING_TYPE_X, /* 0653 */ - JOINING_TYPE_X, /* 0654 */ - JOINING_TYPE_X, /* 0655 */ - JOINING_TYPE_X, /* 0656 */ - JOINING_TYPE_X, /* 0657 */ - JOINING_TYPE_X, /* 0658 */ - JOINING_TYPE_X, /* 0659 */ - JOINING_TYPE_X, /* 065A */ - JOINING_TYPE_X, /* 065B */ - JOINING_TYPE_X, /* 065C */ - JOINING_TYPE_X, /* 065D */ - JOINING_TYPE_X, /* 065E */ - JOINING_TYPE_X, /* 065F */ - JOINING_TYPE_X, /* 0660 */ - JOINING_TYPE_X, /* 0661 */ - JOINING_TYPE_X, /* 0662 */ - JOINING_TYPE_X, /* 0663 */ - JOINING_TYPE_X, /* 0664 */ - JOINING_TYPE_X, /* 0665 */ - JOINING_TYPE_X, /* 0666 */ - JOINING_TYPE_X, /* 0667 */ - JOINING_TYPE_X, /* 0668 */ - JOINING_TYPE_X, /* 0669 */ - JOINING_TYPE_X, /* 066A */ - JOINING_TYPE_X, /* 066B */ - JOINING_TYPE_X, /* 066C */ - JOINING_TYPE_X, /* 066D */ - JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */ - JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */ - JOINING_TYPE_X, /* 0670 */ - JOINING_TYPE_R, /* 0671; ALEF WITH WASLA ABOVE; R; ALEF */ - JOINING_TYPE_R, /* 0672; ALEF WITH WAVY HAMZA ABOVE; R; ALEF */ - JOINING_TYPE_R, /* 0673; ALEF WITH WAVY HAMZA BELOW; R; ALEF */ - JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */ - JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */ - JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */ - JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA ABOVE; R; WAW */ - JOINING_TYPE_D, /* 0678; HIGH HAMZA DOTLESS YEH; D; YEH */ - JOINING_TYPE_D, /* 0679; DOTLESS BEH WITH TAH ABOVE; D; BEH */ - JOINING_TYPE_D, /* 067A; DOTLESS BEH WITH VERTICAL 2 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 067B; DOTLESS BEH WITH VERTICAL 2 DOTS BELOW; D; BEH */ - JOINING_TYPE_D, /* 067C; DOTLESS BEH WITH ATTACHED RING BELOW AND 2 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 067D; DOTLESS BEH WITH INVERTED 3 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 067E; DOTLESS BEH WITH 3 DOTS BELOW; D; BEH */ - JOINING_TYPE_D, /* 067F; DOTLESS BEH WITH 4 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 0680; DOTLESS BEH WITH 4 DOTS BELOW; D; BEH */ - JOINING_TYPE_D, /* 0681; HAH WITH HAMZA ABOVE; D; HAH */ - JOINING_TYPE_D, /* 0682; HAH WITH VERTICAL 2 DOTS ABOVE; D; HAH */ - JOINING_TYPE_D, /* 0683; HAH WITH 2 DOTS BELOW; D; HAH */ - JOINING_TYPE_D, /* 0684; HAH WITH VERTICAL 2 DOTS BELOW; D; HAH */ - JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */ - JOINING_TYPE_D, /* 0686; HAH WITH 3 DOTS BELOW; D; HAH */ - JOINING_TYPE_D, /* 0687; HAH WITH 4 DOTS BELOW; D; HAH */ - JOINING_TYPE_R, /* 0688; DAL WITH TAH ABOVE; R; DAL */ - JOINING_TYPE_R, /* 0689; DAL WITH ATTACHED RING BELOW; R; DAL */ - JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */ - JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND TAH ABOVE; R; DAL */ - JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */ - JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */ - JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */ - JOINING_TYPE_R, /* 068F; DAL WITH INVERTED 3 DOTS ABOVE; R; DAL */ - JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */ - JOINING_TYPE_R, /* 0691; REH WITH TAH ABOVE; R; REH */ - JOINING_TYPE_R, /* 0692; REH WITH V ABOVE; R; REH */ - JOINING_TYPE_R, /* 0693; REH WITH ATTACHED RING BELOW; R; REH */ - JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */ - JOINING_TYPE_R, /* 0695; REH WITH V BELOW; R; REH */ - JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT WITHIN; R; REH */ - JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */ - JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */ - JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */ - JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */ - JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */ - JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */ - JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */ - JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */ - JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */ - JOINING_TYPE_D, /* 06A2; DOTLESS FEH WITH DOT BELOW; D; FEH */ - JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */ - JOINING_TYPE_D, /* 06A4; DOTLESS FEH WITH 3 DOTS ABOVE; D; FEH */ - JOINING_TYPE_D, /* 06A5; DOTLESS FEH WITH 3 DOTS BELOW; D; FEH */ - JOINING_TYPE_D, /* 06A6; DOTLESS FEH WITH 4 DOTS ABOVE; D; FEH */ - JOINING_TYPE_D, /* 06A7; DOTLESS QAF WITH DOT ABOVE; D; QAF */ - JOINING_TYPE_D, /* 06A8; DOTLESS QAF WITH 3 DOTS ABOVE; D; QAF */ - JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */ - JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */ - JOINING_TYPE_D, /* 06AB; KEHEH WITH ATTACHED RING BELOW; D; GAF */ - JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */ - JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */ - JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */ - JOINING_TYPE_D, /* 06AF; GAF; D; GAF */ - JOINING_TYPE_D, /* 06B0; GAF WITH ATTACHED RING BELOW; D; GAF */ - JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */ - JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */ - JOINING_TYPE_D, /* 06B3; GAF WITH VERTICAL 2 DOTS BELOW; D; GAF */ - JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */ - JOINING_TYPE_D, /* 06B5; LAM WITH V ABOVE; D; LAM */ - JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */ - JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */ - JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */ - JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */ - JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */ - JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH TAH ABOVE; D; NOON */ - JOINING_TYPE_D, /* 06BC; NOON WITH ATTACHED RING BELOW; D; NOON */ - JOINING_TYPE_D, /* 06BD; NYA; D; NYA */ - JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */ - JOINING_TYPE_D, /* 06BF; HAH WITH 3 DOTS BELOW AND DOT ABOVE; D; HAH */ - JOINING_TYPE_R, /* 06C0; DOTLESS TEH MARBUTA WITH HAMZA ABOVE; R; TEH MARBUTA */ - JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */ - JOINING_TYPE_D, /* 06C2; HEH GOAL WITH HAMZA ABOVE; D; HEH GOAL */ - JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */ - JOINING_TYPE_R, /* 06C4; WAW WITH ATTACHED RING WITHIN; R; WAW */ - JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */ - JOINING_TYPE_R, /* 06C6; WAW WITH V ABOVE; R; WAW */ - JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA ABOVE; R; WAW */ - JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */ - JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED V ABOVE; R; WAW */ - JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */ - JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */ - JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */ - JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */ - JOINING_TYPE_D, /* 06CE; FARSI YEH WITH V ABOVE; D; FARSI YEH */ - JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */ - JOINING_TYPE_D, /* 06D0; DOTLESS YEH WITH VERTICAL 2 DOTS BELOW; D; YEH */ - JOINING_TYPE_D, /* 06D1; DOTLESS YEH WITH 3 DOTS BELOW; D; YEH */ - JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */ - JOINING_TYPE_R, /* 06D3; YEH BARREE WITH HAMZA ABOVE; R; YEH BARREE */ - JOINING_TYPE_X, /* 06D4 */ - JOINING_TYPE_R, /* 06D5; DOTLESS TEH MARBUTA; R; TEH MARBUTA */ - JOINING_TYPE_X, /* 06D6 */ - JOINING_TYPE_X, /* 06D7 */ - JOINING_TYPE_X, /* 06D8 */ - JOINING_TYPE_X, /* 06D9 */ - JOINING_TYPE_X, /* 06DA */ - JOINING_TYPE_X, /* 06DB */ - JOINING_TYPE_X, /* 06DC */ - JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */ - JOINING_TYPE_X, /* 06DE */ - JOINING_TYPE_X, /* 06DF */ - JOINING_TYPE_X, /* 06E0 */ - JOINING_TYPE_X, /* 06E1 */ - JOINING_TYPE_X, /* 06E2 */ - JOINING_TYPE_X, /* 06E3 */ - JOINING_TYPE_X, /* 06E4 */ - JOINING_TYPE_X, /* 06E5 */ - JOINING_TYPE_X, /* 06E6 */ - JOINING_TYPE_X, /* 06E7 */ - JOINING_TYPE_X, /* 06E8 */ - JOINING_TYPE_X, /* 06E9 */ - JOINING_TYPE_X, /* 06EA */ - JOINING_TYPE_X, /* 06EB */ - JOINING_TYPE_X, /* 06EC */ - JOINING_TYPE_X, /* 06ED */ - JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V ABOVE; R; DAL */ - JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V ABOVE; R; REH */ - JOINING_TYPE_X, /* 06F0 */ - JOINING_TYPE_X, /* 06F1 */ - JOINING_TYPE_X, /* 06F2 */ - JOINING_TYPE_X, /* 06F3 */ - JOINING_TYPE_X, /* 06F4 */ - JOINING_TYPE_X, /* 06F5 */ - JOINING_TYPE_X, /* 06F6 */ - JOINING_TYPE_X, /* 06F7 */ - JOINING_TYPE_X, /* 06F8 */ - JOINING_TYPE_X, /* 06F9 */ - JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 06FB; SAD WITH DOT BELOW AND DOT ABOVE; D; SAD */ - JOINING_TYPE_D, /* 06FC; AIN WITH DOT BELOW AND DOT ABOVE; D; AIN */ - JOINING_TYPE_X, /* 06FD */ - JOINING_TYPE_X, /* 06FE */ - JOINING_TYPE_D, /* 06FF; KNOTTED HEH WITH INVERTED V ABOVE; D; KNOTTED HEH */ - - /* Syriac Characters */ - - JOINING_TYPE_X, /* 0700 */ - JOINING_TYPE_X, /* 0701 */ - JOINING_TYPE_X, /* 0702 */ - JOINING_TYPE_X, /* 0703 */ - JOINING_TYPE_X, /* 0704 */ - JOINING_TYPE_X, /* 0705 */ - JOINING_TYPE_X, /* 0706 */ - JOINING_TYPE_X, /* 0707 */ - JOINING_TYPE_X, /* 0708 */ - JOINING_TYPE_X, /* 0709 */ - JOINING_TYPE_X, /* 070A */ - JOINING_TYPE_X, /* 070B */ - JOINING_TYPE_X, /* 070C */ - JOINING_TYPE_X, /* 070D */ - JOINING_TYPE_X, /* 070E */ - JOINING_TYPE_X, /* 070F */ - JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */ - JOINING_TYPE_X, /* 0711 */ - JOINING_TYPE_D, /* 0712; BETH; D; BETH */ - JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */ - JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */ - JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */ - JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */ - JOINING_TYPE_R, /* 0717; HE; R; HE */ - JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */ - JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */ - JOINING_TYPE_D, /* 071A; HETH; D; HETH */ - JOINING_TYPE_D, /* 071B; TETH; D; TETH */ - JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */ - JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */ - JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */ - JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */ - JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */ - JOINING_TYPE_D, /* 0721; MIM; D; MIM */ - JOINING_TYPE_D, /* 0722; NUN; D; NUN */ - JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */ - JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */ - JOINING_TYPE_D, /* 0725; E; D; E */ - JOINING_TYPE_D, /* 0726; PE; D; PE */ - JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */ - JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */ - JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */ - JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */ - JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */ - JOINING_TYPE_R, /* 072C; TAW; R; TAW */ - JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */ - JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */ - JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */ - JOINING_TYPE_X, /* 0730 */ - JOINING_TYPE_X, /* 0731 */ - JOINING_TYPE_X, /* 0732 */ - JOINING_TYPE_X, /* 0733 */ - JOINING_TYPE_X, /* 0734 */ - JOINING_TYPE_X, /* 0735 */ - JOINING_TYPE_X, /* 0736 */ - JOINING_TYPE_X, /* 0737 */ - JOINING_TYPE_X, /* 0738 */ - JOINING_TYPE_X, /* 0739 */ - JOINING_TYPE_X, /* 073A */ - JOINING_TYPE_X, /* 073B */ - JOINING_TYPE_X, /* 073C */ - JOINING_TYPE_X, /* 073D */ - JOINING_TYPE_X, /* 073E */ - JOINING_TYPE_X, /* 073F */ - JOINING_TYPE_X, /* 0740 */ - JOINING_TYPE_X, /* 0741 */ - JOINING_TYPE_X, /* 0742 */ - JOINING_TYPE_X, /* 0743 */ - JOINING_TYPE_X, /* 0744 */ - JOINING_TYPE_X, /* 0745 */ - JOINING_TYPE_X, /* 0746 */ - JOINING_TYPE_X, /* 0747 */ - JOINING_TYPE_X, /* 0748 */ - JOINING_TYPE_X, /* 0749 */ - JOINING_TYPE_X, /* 074A */ - JOINING_TYPE_X, /* 074B */ - JOINING_TYPE_X, /* 074C */ - JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */ - JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */ - JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */ - - /* Arabic Supplement Characters */ - - JOINING_TYPE_D, /* 0750; DOTLESS BEH WITH HORIZONTAL 3 DOTS BELOW; D; BEH */ - JOINING_TYPE_D, /* 0751; BEH WITH 3 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 0752; DOTLESS BEH WITH INVERTED 3 DOTS BELOW; D; BEH */ - JOINING_TYPE_D, /* 0753; DOTLESS BEH WITH INVERTED 3 DOTS BELOW AND 2 DOTS ABOVE; D; BEH */ - JOINING_TYPE_D, /* 0754; DOTLESS BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */ - JOINING_TYPE_D, /* 0755; DOTLESS BEH WITH INVERTED V BELOW; D; BEH */ - JOINING_TYPE_D, /* 0756; DOTLESS BEH WITH V ABOVE; D; BEH */ - JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */ - JOINING_TYPE_D, /* 0758; HAH WITH INVERTED 3 DOTS BELOW; D; HAH */ - JOINING_TYPE_R, /* 0759; DAL WITH VERTICAL 2 DOTS BELOW AND TAH ABOVE; R; DAL */ - JOINING_TYPE_R, /* 075A; DAL WITH INVERTED V BELOW; R; DAL */ - JOINING_TYPE_R, /* 075B; REH WITH BAR; R; REH */ - JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */ - JOINING_TYPE_D, /* 075E; AIN WITH INVERTED 3 DOTS ABOVE; D; AIN */ - JOINING_TYPE_D, /* 075F; AIN WITH VERTICAL 2 DOTS ABOVE; D; AIN */ - JOINING_TYPE_D, /* 0760; DOTLESS FEH WITH 2 DOTS BELOW; D; FEH */ - JOINING_TYPE_D, /* 0761; DOTLESS FEH WITH INVERTED 3 DOTS BELOW; D; FEH */ - JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */ - JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */ - JOINING_TYPE_D, /* 0764; KEHEH WITH INVERTED 3 DOTS BELOW; D; GAF */ - JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */ - JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */ - JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */ - JOINING_TYPE_D, /* 0768; NOON WITH TAH ABOVE; D; NOON */ - JOINING_TYPE_D, /* 0769; NOON WITH V ABOVE; D; NOON */ - JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */ - JOINING_TYPE_R, /* 076B; REH WITH VERTICAL 2 DOTS ABOVE; R; REH */ - JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */ - JOINING_TYPE_D, /* 076D; SEEN WITH VERTICAL 2 DOTS ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 076E; HAH WITH TAH BELOW; D; HAH */ - JOINING_TYPE_D, /* 076F; HAH WITH TAH AND 2 DOTS BELOW; D; HAH */ - JOINING_TYPE_D, /* 0770; SEEN WITH 2 DOTS AND TAH ABOVE; D; SEEN */ - JOINING_TYPE_R, /* 0771; REH WITH 2 DOTS AND TAH ABOVE; R; REH */ - JOINING_TYPE_D, /* 0772; HAH WITH TAH ABOVE; D; HAH */ - JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */ - JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */ - JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */ - JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */ - JOINING_TYPE_D, /* 0777; DOTLESS YEH WITH DIGIT FOUR BELOW; D; YEH */ - JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */ - JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */ - JOINING_TYPE_D, /* 077A; BURUSHASKI YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */ - JOINING_TYPE_D, /* 077B; BURUSHASKI YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */ - JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */ - JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V ABOVE; D; SEEN */ - JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */ - - /* N'Ko Characters */ - - JOINING_TYPE_X, /* 0780 */ - JOINING_TYPE_X, /* 0781 */ - JOINING_TYPE_X, /* 0782 */ - JOINING_TYPE_X, /* 0783 */ - JOINING_TYPE_X, /* 0784 */ - JOINING_TYPE_X, /* 0785 */ - JOINING_TYPE_X, /* 0786 */ - JOINING_TYPE_X, /* 0787 */ - JOINING_TYPE_X, /* 0788 */ - JOINING_TYPE_X, /* 0789 */ - JOINING_TYPE_X, /* 078A */ - JOINING_TYPE_X, /* 078B */ - JOINING_TYPE_X, /* 078C */ - JOINING_TYPE_X, /* 078D */ - JOINING_TYPE_X, /* 078E */ - JOINING_TYPE_X, /* 078F */ - JOINING_TYPE_X, /* 0790 */ - JOINING_TYPE_X, /* 0791 */ - JOINING_TYPE_X, /* 0792 */ - JOINING_TYPE_X, /* 0793 */ - JOINING_TYPE_X, /* 0794 */ - JOINING_TYPE_X, /* 0795 */ - JOINING_TYPE_X, /* 0796 */ - JOINING_TYPE_X, /* 0797 */ - JOINING_TYPE_X, /* 0798 */ - JOINING_TYPE_X, /* 0799 */ - JOINING_TYPE_X, /* 079A */ - JOINING_TYPE_X, /* 079B */ - JOINING_TYPE_X, /* 079C */ - JOINING_TYPE_X, /* 079D */ - JOINING_TYPE_X, /* 079E */ - JOINING_TYPE_X, /* 079F */ - JOINING_TYPE_X, /* 07A0 */ - JOINING_TYPE_X, /* 07A1 */ - JOINING_TYPE_X, /* 07A2 */ - JOINING_TYPE_X, /* 07A3 */ - JOINING_TYPE_X, /* 07A4 */ - JOINING_TYPE_X, /* 07A5 */ - JOINING_TYPE_X, /* 07A6 */ - JOINING_TYPE_X, /* 07A7 */ - JOINING_TYPE_X, /* 07A8 */ - JOINING_TYPE_X, /* 07A9 */ - JOINING_TYPE_X, /* 07AA */ - JOINING_TYPE_X, /* 07AB */ - JOINING_TYPE_X, /* 07AC */ - JOINING_TYPE_X, /* 07AD */ - JOINING_TYPE_X, /* 07AE */ - JOINING_TYPE_X, /* 07AF */ - JOINING_TYPE_X, /* 07B0 */ - JOINING_TYPE_X, /* 07B1 */ - JOINING_TYPE_X, /* 07B2 */ - JOINING_TYPE_X, /* 07B3 */ - JOINING_TYPE_X, /* 07B4 */ - JOINING_TYPE_X, /* 07B5 */ - JOINING_TYPE_X, /* 07B6 */ - JOINING_TYPE_X, /* 07B7 */ - JOINING_TYPE_X, /* 07B8 */ - JOINING_TYPE_X, /* 07B9 */ - JOINING_TYPE_X, /* 07BA */ - JOINING_TYPE_X, /* 07BB */ - JOINING_TYPE_X, /* 07BC */ - JOINING_TYPE_X, /* 07BD */ - JOINING_TYPE_X, /* 07BE */ - JOINING_TYPE_X, /* 07BF */ - JOINING_TYPE_X, /* 07C0 */ - JOINING_TYPE_X, /* 07C1 */ - JOINING_TYPE_X, /* 07C2 */ - JOINING_TYPE_X, /* 07C3 */ - JOINING_TYPE_X, /* 07C4 */ - JOINING_TYPE_X, /* 07C5 */ - JOINING_TYPE_X, /* 07C6 */ - JOINING_TYPE_X, /* 07C7 */ - JOINING_TYPE_X, /* 07C8 */ - JOINING_TYPE_X, /* 07C9 */ - JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */ - JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */ - JOINING_TYPE_X, /* 07EB */ - JOINING_TYPE_X, /* 07EC */ - JOINING_TYPE_X, /* 07ED */ - JOINING_TYPE_X, /* 07EE */ - JOINING_TYPE_X, /* 07EF */ - JOINING_TYPE_X, /* 07F0 */ - JOINING_TYPE_X, /* 07F1 */ - JOINING_TYPE_X, /* 07F2 */ - JOINING_TYPE_X, /* 07F3 */ - JOINING_TYPE_X, /* 07F4 */ - JOINING_TYPE_X, /* 07F5 */ - JOINING_TYPE_X, /* 07F6 */ - JOINING_TYPE_X, /* 07F7 */ - JOINING_TYPE_X, /* 07F8 */ - JOINING_TYPE_X, /* 07F9 */ - JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */ - - /* Mandaic Characters */ - - JOINING_TYPE_X, /* 07FB */ - JOINING_TYPE_X, /* 07FC */ - JOINING_TYPE_X, /* 07FD */ - JOINING_TYPE_X, /* 07FE */ - JOINING_TYPE_X, /* 07FF */ - JOINING_TYPE_X, /* 0800 */ - JOINING_TYPE_X, /* 0801 */ - JOINING_TYPE_X, /* 0802 */ - JOINING_TYPE_X, /* 0803 */ - JOINING_TYPE_X, /* 0804 */ - JOINING_TYPE_X, /* 0805 */ - JOINING_TYPE_X, /* 0806 */ - JOINING_TYPE_X, /* 0807 */ - JOINING_TYPE_X, /* 0808 */ - JOINING_TYPE_X, /* 0809 */ - JOINING_TYPE_X, /* 080A */ - JOINING_TYPE_X, /* 080B */ - JOINING_TYPE_X, /* 080C */ - JOINING_TYPE_X, /* 080D */ - JOINING_TYPE_X, /* 080E */ - JOINING_TYPE_X, /* 080F */ - JOINING_TYPE_X, /* 0810 */ - JOINING_TYPE_X, /* 0811 */ - JOINING_TYPE_X, /* 0812 */ - JOINING_TYPE_X, /* 0813 */ - JOINING_TYPE_X, /* 0814 */ - JOINING_TYPE_X, /* 0815 */ - JOINING_TYPE_X, /* 0816 */ - JOINING_TYPE_X, /* 0817 */ - JOINING_TYPE_X, /* 0818 */ - JOINING_TYPE_X, /* 0819 */ - JOINING_TYPE_X, /* 081A */ - JOINING_TYPE_X, /* 081B */ - JOINING_TYPE_X, /* 081C */ - JOINING_TYPE_X, /* 081D */ - JOINING_TYPE_X, /* 081E */ - JOINING_TYPE_X, /* 081F */ - JOINING_TYPE_X, /* 0820 */ - JOINING_TYPE_X, /* 0821 */ - JOINING_TYPE_X, /* 0822 */ - JOINING_TYPE_X, /* 0823 */ - JOINING_TYPE_X, /* 0824 */ - JOINING_TYPE_X, /* 0825 */ - JOINING_TYPE_X, /* 0826 */ - JOINING_TYPE_X, /* 0827 */ - JOINING_TYPE_X, /* 0828 */ - JOINING_TYPE_X, /* 0829 */ - JOINING_TYPE_X, /* 082A */ - JOINING_TYPE_X, /* 082B */ - JOINING_TYPE_X, /* 082C */ - JOINING_TYPE_X, /* 082D */ - JOINING_TYPE_X, /* 082E */ - JOINING_TYPE_X, /* 082F */ - JOINING_TYPE_X, /* 0830 */ - JOINING_TYPE_X, /* 0831 */ - JOINING_TYPE_X, /* 0832 */ - JOINING_TYPE_X, /* 0833 */ - JOINING_TYPE_X, /* 0834 */ - JOINING_TYPE_X, /* 0835 */ - JOINING_TYPE_X, /* 0836 */ - JOINING_TYPE_X, /* 0837 */ - JOINING_TYPE_X, /* 0838 */ - JOINING_TYPE_X, /* 0839 */ - JOINING_TYPE_X, /* 083A */ - JOINING_TYPE_X, /* 083B */ - JOINING_TYPE_X, /* 083C */ - JOINING_TYPE_X, /* 083D */ - JOINING_TYPE_X, /* 083E */ - JOINING_TYPE_X, /* 083F */ - JOINING_TYPE_R, /* 0840; MANDAIC HALQA; R; No_Joining_Group */ - JOINING_TYPE_D, /* 0841; MANDAIC AB; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0842; MANDAIC AG; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0843; MANDAIC AD; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0844; MANDAIC AH; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0845; MANDAIC USHENNA; D; No_Joining_Group */ - JOINING_TYPE_R, /* 0846; MANDAIC AZ; R; No_Joining_Group */ - JOINING_TYPE_D, /* 0847; MANDAIC IT; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0848; MANDAIC ATT; D; No_Joining_Group */ - JOINING_TYPE_R, /* 0849; MANDAIC AKSA; R; No_Joining_Group */ - JOINING_TYPE_D, /* 084A; MANDAIC AK; D; No_Joining_Group */ - JOINING_TYPE_D, /* 084B; MANDAIC AL; D; No_Joining_Group */ - JOINING_TYPE_D, /* 084C; MANDAIC AM; D; No_Joining_Group */ - JOINING_TYPE_D, /* 084D; MANDAIC AN; D; No_Joining_Group */ - JOINING_TYPE_D, /* 084E; MANDAIC AS; D; No_Joining_Group */ - JOINING_TYPE_R, /* 084F; MANDAIC IN; R; No_Joining_Group */ - JOINING_TYPE_D, /* 0850; MANDAIC AP; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0851; MANDAIC ASZ; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0852; MANDAIC AQ; D; No_Joining_Group */ - JOINING_TYPE_D, /* 0853; MANDAIC AR; D; No_Joining_Group */ - JOINING_TYPE_R, /* 0854; MANDAIC ASH; R; No_Joining_Group */ - JOINING_TYPE_D, /* 0855; MANDAIC AT; D; No_Joining_Group */ - JOINING_TYPE_U, /* 0856; MANDAIC DUSHENNA; U; No_Joining_Group */ - JOINING_TYPE_U, /* 0857; MANDAIC KAD; U; No_Joining_Group */ - JOINING_TYPE_U, /* 0858; MANDAIC AIN; U; No_Joining_Group */ - - /* Arabic Extended-A Characters */ - - JOINING_TYPE_X, /* 0859 */ - JOINING_TYPE_X, /* 085A */ - JOINING_TYPE_X, /* 085B */ - JOINING_TYPE_X, /* 085C */ - JOINING_TYPE_X, /* 085D */ - JOINING_TYPE_X, /* 085E */ - JOINING_TYPE_X, /* 085F */ - JOINING_TYPE_X, /* 0860 */ - JOINING_TYPE_X, /* 0861 */ - JOINING_TYPE_X, /* 0862 */ - JOINING_TYPE_X, /* 0863 */ - JOINING_TYPE_X, /* 0864 */ - JOINING_TYPE_X, /* 0865 */ - JOINING_TYPE_X, /* 0866 */ - JOINING_TYPE_X, /* 0867 */ - JOINING_TYPE_X, /* 0868 */ - JOINING_TYPE_X, /* 0869 */ - JOINING_TYPE_X, /* 086A */ - JOINING_TYPE_X, /* 086B */ - JOINING_TYPE_X, /* 086C */ - JOINING_TYPE_X, /* 086D */ - JOINING_TYPE_X, /* 086E */ - JOINING_TYPE_X, /* 086F */ - JOINING_TYPE_X, /* 0870 */ - JOINING_TYPE_X, /* 0871 */ - JOINING_TYPE_X, /* 0872 */ - JOINING_TYPE_X, /* 0873 */ - JOINING_TYPE_X, /* 0874 */ - JOINING_TYPE_X, /* 0875 */ - JOINING_TYPE_X, /* 0876 */ - JOINING_TYPE_X, /* 0877 */ - JOINING_TYPE_X, /* 0878 */ - JOINING_TYPE_X, /* 0879 */ - JOINING_TYPE_X, /* 087A */ - JOINING_TYPE_X, /* 087B */ - JOINING_TYPE_X, /* 087C */ - JOINING_TYPE_X, /* 087D */ - JOINING_TYPE_X, /* 087E */ - JOINING_TYPE_X, /* 087F */ - JOINING_TYPE_X, /* 0880 */ - JOINING_TYPE_X, /* 0881 */ - JOINING_TYPE_X, /* 0882 */ - JOINING_TYPE_X, /* 0883 */ - JOINING_TYPE_X, /* 0884 */ - JOINING_TYPE_X, /* 0885 */ - JOINING_TYPE_X, /* 0886 */ - JOINING_TYPE_X, /* 0887 */ - JOINING_TYPE_X, /* 0888 */ - JOINING_TYPE_X, /* 0889 */ - JOINING_TYPE_X, /* 088A */ - JOINING_TYPE_X, /* 088B */ - JOINING_TYPE_X, /* 088C */ - JOINING_TYPE_X, /* 088D */ - JOINING_TYPE_X, /* 088E */ - JOINING_TYPE_X, /* 088F */ - JOINING_TYPE_X, /* 0890 */ - JOINING_TYPE_X, /* 0891 */ - JOINING_TYPE_X, /* 0892 */ - JOINING_TYPE_X, /* 0893 */ - JOINING_TYPE_X, /* 0894 */ - JOINING_TYPE_X, /* 0895 */ - JOINING_TYPE_X, /* 0896 */ - JOINING_TYPE_X, /* 0897 */ - JOINING_TYPE_X, /* 0898 */ - JOINING_TYPE_X, /* 0899 */ - JOINING_TYPE_X, /* 089A */ - JOINING_TYPE_X, /* 089B */ - JOINING_TYPE_X, /* 089C */ - JOINING_TYPE_X, /* 089D */ - JOINING_TYPE_X, /* 089E */ - JOINING_TYPE_X, /* 089F */ - JOINING_TYPE_D, /* 08A0; DOTLESS BEH WITH V BELOW; D; BEH */ - JOINING_TYPE_X, /* 08A1 */ - JOINING_TYPE_D, /* 08A2; HAH WITH DOT BELOW AND 2 DOTS ABOVE; D; HAH */ - JOINING_TYPE_D, /* 08A3; TAH WITH 2 DOTS ABOVE; D; TAH */ - JOINING_TYPE_D, /* 08A4; DOTLESS FEH WITH DOT BELOW AND 3 DOTS ABOVE; D; FEH */ - JOINING_TYPE_D, /* 08A5; QAF WITH DOT BELOW; D; QAF */ - JOINING_TYPE_D, /* 08A6; LAM WITH DOUBLE BAR; D; LAM */ - JOINING_TYPE_D, /* 08A7; MEEM WITH 3 DOTS ABOVE; D; MEEM */ - JOINING_TYPE_D, /* 08A8; YEH WITH HAMZA ABOVE; D; YEH */ - JOINING_TYPE_D, /* 08A9; YEH WITH DOT ABOVE; D; YEH */ - JOINING_TYPE_R, /* 08AA; REH WITH LOOP; R; REH */ - JOINING_TYPE_R, /* 08AB; WAW WITH DOT WITHIN; R; WAW */ - JOINING_TYPE_R, /* 08AC; ROHINGYA YEH; R; ROHINGYA YEH */ +#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, + +#define joining_offset_0x1806u 691 + + /* 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,U,U,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 856 + + /* General Punctuation */ + + /* 2000 */ U,C, + +#define joining_offset_0x2066u 858 + + /* General Punctuation */ + + /* 2060 */ U,U,U,U, + +#define joining_offset_0xa840u 862 + + /* 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 914 + + /* 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 962 + + /* 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, + +}; /* Table items: 1010; occupancy: 57% */ + + +static unsigned int +joining_type (hb_codepoint_t u) +{ + switch (u >> 12) + { + case 0x0u: + if (hb_in_range (u, 0x0600u, 0x08B2u)) 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, 0x200Du)) return joining_table[u - 0x200Cu + joining_offset_0x200cu]; + if (hb_in_range (u, 0x2066u, 0x2069u)) return joining_table[u - 0x2066u + joining_offset_0x2066u]; + 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; + + default: + break; + } + return X; +} -#define JOINING_TABLE_FIRST 0x0600 -#define JOINING_TABLE_LAST 0x08AC +#undef X +#undef R +#undef U +#undef A +#undef DR +#undef L +#undef C +#undef D static const uint16_t shaping_table[][4] = { - {0x0000, 0x0000, 0x0000, 0xFE80}, /* U+0621 ARABIC LETTER HAMZA ISOLATED FORM */ - {0x0000, 0x0000, 0xFE82, 0xFE81}, /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */ - {0x0000, 0x0000, 0xFE84, 0xFE83}, /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */ - {0x0000, 0x0000, 0xFE86, 0xFE85}, /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */ - {0x0000, 0x0000, 0xFE88, 0xFE87}, /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */ - {0xFE8B, 0xFE8C, 0xFE8A, 0xFE89}, /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */ - {0x0000, 0x0000, 0xFE8E, 0xFE8D}, /* U+0627 ARABIC LETTER ALEF */ - {0xFE91, 0xFE92, 0xFE90, 0xFE8F}, /* U+0628 ARABIC LETTER BEH */ - {0x0000, 0x0000, 0xFE94, 0xFE93}, /* U+0629 ARABIC LETTER TEH MARBUTA */ - {0xFE97, 0xFE98, 0xFE96, 0xFE95}, /* U+062A ARABIC LETTER TEH */ - {0xFE9B, 0xFE9C, 0xFE9A, 0xFE99}, /* U+062B ARABIC LETTER THEH */ - {0xFE9F, 0xFEA0, 0xFE9E, 0xFE9D}, /* U+062C ARABIC LETTER JEEM */ - {0xFEA3, 0xFEA4, 0xFEA2, 0xFEA1}, /* U+062D ARABIC LETTER HAH */ - {0xFEA7, 0xFEA8, 0xFEA6, 0xFEA5}, /* U+062E ARABIC LETTER KHAH */ - {0x0000, 0x0000, 0xFEAA, 0xFEA9}, /* U+062F ARABIC LETTER DAL */ - {0x0000, 0x0000, 0xFEAC, 0xFEAB}, /* U+0630 ARABIC LETTER THAL */ - {0x0000, 0x0000, 0xFEAE, 0xFEAD}, /* U+0631 ARABIC LETTER REH */ - {0x0000, 0x0000, 0xFEB0, 0xFEAF}, /* U+0632 ARABIC LETTER ZAIN */ - {0xFEB3, 0xFEB4, 0xFEB2, 0xFEB1}, /* U+0633 ARABIC LETTER SEEN */ - {0xFEB7, 0xFEB8, 0xFEB6, 0xFEB5}, /* U+0634 ARABIC LETTER SHEEN */ - {0xFEBB, 0xFEBC, 0xFEBA, 0xFEB9}, /* U+0635 ARABIC LETTER SAD */ - {0xFEBF, 0xFEC0, 0xFEBE, 0xFEBD}, /* U+0636 ARABIC LETTER DAD */ - {0xFEC3, 0xFEC4, 0xFEC2, 0xFEC1}, /* U+0637 ARABIC LETTER TAH */ - {0xFEC7, 0xFEC8, 0xFEC6, 0xFEC5}, /* U+0638 ARABIC LETTER ZAH */ - {0xFECB, 0xFECC, 0xFECA, 0xFEC9}, /* U+0639 ARABIC LETTER AIN */ - {0xFECF, 0xFED0, 0xFECE, 0xFECD}, /* U+063A ARABIC LETTER GHAIN */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063B */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063C */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063D */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063E */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063F */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0640 */ - {0xFED3, 0xFED4, 0xFED2, 0xFED1}, /* U+0641 ARABIC LETTER FEH */ - {0xFED7, 0xFED8, 0xFED6, 0xFED5}, /* U+0642 ARABIC LETTER QAF */ - {0xFEDB, 0xFEDC, 0xFEDA, 0xFED9}, /* U+0643 ARABIC LETTER KAF */ - {0xFEDF, 0xFEE0, 0xFEDE, 0xFEDD}, /* U+0644 ARABIC LETTER LAM */ - {0xFEE3, 0xFEE4, 0xFEE2, 0xFEE1}, /* U+0645 ARABIC LETTER MEEM */ - {0xFEE7, 0xFEE8, 0xFEE6, 0xFEE5}, /* U+0646 ARABIC LETTER NOON */ - {0xFEEB, 0xFEEC, 0xFEEA, 0xFEE9}, /* U+0647 ARABIC LETTER HEH */ - {0x0000, 0x0000, 0xFEEE, 0xFEED}, /* U+0648 ARABIC LETTER WAW */ - {0xFBE8, 0xFBE9, 0xFEF0, 0xFEEF}, /* U+0649 ARABIC LETTER */ - {0xFEF3, 0xFEF4, 0xFEF2, 0xFEF1}, /* U+064A ARABIC LETTER YEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064B */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064C */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064D */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064E */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064F */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0650 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0651 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0652 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0653 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0654 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0655 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0656 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0657 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0658 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0659 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065A */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065B */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065C */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065D */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065E */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065F */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0660 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0661 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0662 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0663 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0664 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0665 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0666 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0667 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0668 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0669 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066A */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066B */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066C */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066D */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066E */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066F */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0670 */ - {0x0000, 0x0000, 0xFB51, 0xFB50}, /* U+0671 ARABIC LETTER ALEF WASLA */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0672 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0673 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0674 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0675 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0676 */ - {0x0000, 0x0000, 0x0000, 0xFBDD}, /* U+0677 ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0678 */ - {0xFB68, 0xFB69, 0xFB67, 0xFB66}, /* U+0679 ARABIC LETTER TTEH */ - {0xFB60, 0xFB61, 0xFB5F, 0xFB5E}, /* U+067A ARABIC LETTER TTEHEH */ - {0xFB54, 0xFB55, 0xFB53, 0xFB52}, /* U+067B ARABIC LETTER BEEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+067C */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+067D */ - {0xFB58, 0xFB59, 0xFB57, 0xFB56}, /* U+067E ARABIC LETTER PEH */ - {0xFB64, 0xFB65, 0xFB63, 0xFB62}, /* U+067F ARABIC LETTER TEHEH */ - {0xFB5C, 0xFB5D, 0xFB5B, 0xFB5A}, /* U+0680 ARABIC LETTER BEHEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0681 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0682 */ - {0xFB78, 0xFB79, 0xFB77, 0xFB76}, /* U+0683 ARABIC LETTER NYEH */ - {0xFB74, 0xFB75, 0xFB73, 0xFB72}, /* U+0684 ARABIC LETTER DYEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0685 */ - {0xFB7C, 0xFB7D, 0xFB7B, 0xFB7A}, /* U+0686 ARABIC LETTER TCHEH */ - {0xFB80, 0xFB81, 0xFB7F, 0xFB7E}, /* U+0687 ARABIC LETTER TCHEHEH */ - {0x0000, 0x0000, 0xFB89, 0xFB88}, /* U+0688 ARABIC LETTER DDAL */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0689 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+068A */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+068B */ - {0x0000, 0x0000, 0xFB85, 0xFB84}, /* U+068C ARABIC LETTER DAHAL */ - {0x0000, 0x0000, 0xFB83, 0xFB82}, /* U+068D ARABIC LETTER DDAHAL */ - {0x0000, 0x0000, 0xFB87, 0xFB86}, /* U+068E ARABIC LETTER DUL */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+068F */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0690 */ - {0x0000, 0x0000, 0xFB8D, 0xFB8C}, /* U+0691 ARABIC LETTER RREH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0692 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0693 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0694 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0695 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0696 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0697 */ - {0x0000, 0x0000, 0xFB8B, 0xFB8A}, /* U+0698 ARABIC LETTER JEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0699 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069A */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069B */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069C */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069D */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069E */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069F */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A0 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A1 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A2 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A3 */ - {0xFB6C, 0xFB6D, 0xFB6B, 0xFB6A}, /* U+06A4 ARABIC LETTER VEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A5 */ - {0xFB70, 0xFB71, 0xFB6F, 0xFB6E}, /* U+06A6 ARABIC LETTER PEHEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A7 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A8 */ - {0xFB90, 0xFB91, 0xFB8F, 0xFB8E}, /* U+06A9 ARABIC LETTER KEHEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AA */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AB */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AC */ - {0xFBD5, 0xFBD6, 0xFBD4, 0xFBD3}, /* U+06AD ARABIC LETTER NG */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AE */ - {0xFB94, 0xFB95, 0xFB93, 0xFB92}, /* U+06AF ARABIC LETTER GAF */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B0 */ - {0xFB9C, 0xFB9D, 0xFB9B, 0xFB9A}, /* U+06B1 ARABIC LETTER NGOEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B2 */ - {0xFB98, 0xFB99, 0xFB97, 0xFB96}, /* U+06B3 ARABIC LETTER GUEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B4 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B5 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B6 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B7 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B8 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B9 */ - {0x0000, 0x0000, 0xFB9F, 0xFB9E}, /* U+06BA ARABIC LETTER NOON GHUNNA */ - {0xFBA2, 0xFBA3, 0xFBA1, 0xFBA0}, /* U+06BB ARABIC LETTER RNOON */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BC */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BD */ - {0xFBAC, 0xFBAD, 0xFBAB, 0xFBAA}, /* U+06BE ARABIC LETTER HEH DOACHASHMEE */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BF */ - {0x0000, 0x0000, 0xFBA5, 0xFBA4}, /* U+06C0 ARABIC LETTER HEH WITH YEH ABOVE */ - {0xFBA8, 0xFBA9, 0xFBA7, 0xFBA6}, /* U+06C1 ARABIC LETTER HEH GOAL */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C2 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C3 */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C4 */ - {0x0000, 0x0000, 0xFBE1, 0xFBE0}, /* U+06C5 ARABIC LETTER KIRGHIZ OE */ - {0x0000, 0x0000, 0xFBDA, 0xFBD9}, /* U+06C6 ARABIC LETTER OE */ - {0x0000, 0x0000, 0xFBD8, 0xFBD7}, /* U+06C7 ARABIC LETTER U */ - {0x0000, 0x0000, 0xFBDC, 0xFBDB}, /* U+06C8 ARABIC LETTER YU */ - {0x0000, 0x0000, 0xFBE3, 0xFBE2}, /* U+06C9 ARABIC LETTER KIRGHIZ YU */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CA */ - {0x0000, 0x0000, 0xFBDF, 0xFBDE}, /* U+06CB ARABIC LETTER VE */ - {0xFBFE, 0xFBFF, 0xFBFD, 0xFBFC}, /* U+06CC ARABIC LETTER FARSI YEH */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CD */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CE */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CF */ - {0xFBE6, 0xFBE7, 0xFBE5, 0xFBE4}, /* U+06D0 ARABIC LETTER E */ - {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06D1 */ - {0x0000, 0x0000, 0xFBAF, 0xFBAE}, /* U+06D2 ARABIC LETTER YEH BARREE */ - {0x0000, 0x0000, 0xFBB1, 0xFBB0}, /* U+06D3 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE */ + {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 0x0621 -#define SHAPING_TABLE_LAST 0x06D3 +#define SHAPING_TABLE_FIRST 0x0621u +#define SHAPING_TABLE_LAST 0x06D3u static const struct ligature_set_t { @@ -922,17 +363,17 @@ static const struct ligature_set_t { } ligatures[4]; } ligature_table[] = { - { 0xFEDF, { - { 0xFE88, 0xFEF9 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */ - { 0xFE82, 0xFEF5 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */ - { 0xFE8E, 0xFEFB }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */ - { 0xFE84, 0xFEF7 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */ + { 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 */ }}, - { 0xFEE0, { - { 0xFE88, 0xFEFA }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */ - { 0xFE82, 0xFEF6 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */ - { 0xFE8E, 0xFEFC }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */ - { 0xFE84, 0xFEF8 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL 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 */ }}, }; diff --git a/src/hb-ot-shape-complex-arabic-win1256.hh b/src/hb-ot-shape-complex-arabic-win1256.hh new file mode 100644 index 0000000..63ed3f8 --- /dev/null +++ b/src/hb-ot-shape-complex-arabic-win1256.hh @@ -0,0 +1,321 @@ +/* + * 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_MULTIPLE 2u +#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 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 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... + */ +#ifdef OT_MEASURE +#include __FILE__ +#endif + +#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH +#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */ diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index 35356fe..ae90864 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -37,17 +37,16 @@ */ enum { JOINING_TYPE_U = 0, - JOINING_TYPE_R = 1, - JOINING_TYPE_D = 2, + JOINING_TYPE_L = 1, + JOINING_TYPE_R = 2, + JOINING_TYPE_D = 3, JOINING_TYPE_C = JOINING_TYPE_D, - JOINING_GROUP_ALAPH = 3, - JOINING_GROUP_DALATH_RISH = 4, - NUM_STATE_MACHINE_COLS = 5, + JOINING_GROUP_ALAPH = 4, + JOINING_GROUP_DALATH_RISH = 5, + NUM_STATE_MACHINE_COLS = 6, - /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode. */ - - JOINING_TYPE_T = 6, - JOINING_TYPE_X = 7 /* means: use general-category to choose between U or T. */ + JOINING_TYPE_T = 7, + JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */ }; /* @@ -58,69 +57,41 @@ enum { static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat) { - if (likely (hb_in_range<hb_codepoint_t> (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) { - unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST]; - if (likely (j_type != JOINING_TYPE_X)) - return j_type; - } - - /* Mongolian joining data is not in ArabicJoining.txt yet. */ - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1800, 0x18AF))) - { - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1880, 0x1886))) - return JOINING_TYPE_U; - - /* All letters, SIBE SYLLABLE BOUNDARY MARKER, and NIRUGU are D */ - if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | - FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER))) - || u == 0x1807 || u == 0x180A) - return JOINING_TYPE_D; - } - - /* 'Phags-pa joining data is not in ArabicJoining.txt yet. */ - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872))) - { - if (unlikely (u == 0xA872)) - /* XXX Looks like this should be TYPE_L, but we don't support that yet! */ - return JOINING_TYPE_R; - - return JOINING_TYPE_D; - } - - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D))) - { - return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C; - } - - return (FLAG(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; + unsigned int j_type = joining_type(u); + if (likely (j_type != JOINING_TYPE_X)) + return j_type; + + return (FLAG(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','n','i','t'), - HB_TAG('m','e','d','i'), - HB_TAG('f','i','n','a'), HB_TAG('i','s','o','l'), - /* Syriac */ - HB_TAG('m','e','d','2'), + 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 { - INIT, - MEDI, - FINA, ISOL, - - /* Syriac */ - MED2, + FINA, FIN2, FIN3, + MEDI, + MED2, + INIT, NONE, @@ -133,32 +104,37 @@ static const struct arabic_state_table_entry { uint16_t next_state; } arabic_state_table[][NUM_STATE_MACHINE_COLS] = { - /* jt_U, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */ + /* 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,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, }, + { {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,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, }, + { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, }, - /* State 2: prev was D/ISOL, willing to join. */ - { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,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/FINA, willing to join. */ - { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,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}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, }, + { {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}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, }, + { {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,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, } + { {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); @@ -168,35 +144,56 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) { hb_ot_map_builder_t *map = &plan->map; - /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together, - * then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH - * ligature work correctly. It's unfortunate though... + /* We apply features according to the Arabic spec, with pauses + * in between most. * - * This also makes Arial Bold in Windows7 work. See: + * The pause between init/medi/... and rlig is required. See eg: * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 * - * TODO: Add test cases for these two. + * 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_bool_feature (HB_TAG('c','c','m','p')); - map->add_bool_feature (HB_TAG('l','o','c','l')); + map->add_gsub_pause (nuke_joiners); + + 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++) - map->add_bool_feature (arabic_features[i], false, i < 4); /* The first four features have fallback. */ - - map->add_gsub_pause (NULL); + { + 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_bool_feature (HB_TAG('r','l','i','g'), true, true); - map->add_gsub_pause (arabic_fallback_shape); + 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_bool_feature (HB_TAG('c','a','l','t')); + map->add_global_bool_feature (HB_TAG('c','a','l','t')); map->add_gsub_pause (NULL); - map->add_bool_feature (HB_TAG('c','s','w','h')); - map->add_bool_feature (HB_TAG('d','l','i','g')); - map->add_bool_feature (HB_TAG('m','s','e','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_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" @@ -225,8 +222,9 @@ data_create_arabic (const hb_ot_shape_plan_t *plan) arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC; for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]); - if (i < 4) - arabic_plan->do_fallback = arabic_plan->do_fallback && plan->map.needs_fallback (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; @@ -246,60 +244,65 @@ 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; - HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); - /* Check pre-context */ - if (!(buffer->flags & HB_BUFFER_FLAG_BOT)) - 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])); + 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; + 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; - } + 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 (buffer->info[i].codepoint, _hb_glyph_info_get_general_category (&buffer->info[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)) { - buffer->info[i].arabic_shaping_action() = NONE; + 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) - buffer->info[prev].arabic_shaping_action() = entry->prev_action; + info[prev].arabic_shaping_action() = entry->prev_action; - buffer->info[i].arabic_shaping_action() = entry->curr_action; + info[i].arabic_shaping_action() = entry->curr_action; prev = i; state = entry->next_state; } - if (!(buffer->flags & HB_BUFFER_FLAG_EOT)) - 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; + 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])); - const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; - if (entry->prev_action != NONE && prev != (unsigned int) -1) - buffer->info[prev].arabic_shaping_action() = entry->prev_action; - break; - } + 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; + } +} - HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); +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(); } static void @@ -307,16 +310,36 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font HB_UNUSED) { + HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; arabic_joining (buffer); + if (plan->props.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++) - buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()]; + info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()]; + + HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } 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) @@ -350,10 +373,10 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = data_create_arabic, data_destroy_arabic, NULL, /* preprocess_text_arabic */ - NULL, /* normalization_preference */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ NULL, /* compose */ setup_masks_arabic, - true, /* zero_width_attached_marks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/src/hb-ot-shape-complex-default.cc b/src/hb-ot-shape-complex-default.cc index 5340293..f7f097e 100644 --- a/src/hb-ot-shape-complex-default.cc +++ b/src/hb-ot-shape-complex-default.cc @@ -27,200 +27,18 @@ #include "hb-ot-shape-complex-private.hh" -/* TODO Add kana, and other small shapers here */ - - -/* The default shaper *only* adds additional per-script features.*/ - -static const hb_tag_t hangul_features[] = -{ - HB_TAG('l','j','m','o'), - HB_TAG('v','j','m','o'), - HB_TAG('t','j','m','o'), - HB_TAG_NONE -}; - -static const hb_tag_t tibetan_features[] = -{ - HB_TAG('a','b','v','s'), - HB_TAG('b','l','w','s'), - HB_TAG('a','b','v','m'), - HB_TAG('b','l','w','m'), - HB_TAG_NONE -}; - -static void -collect_features_default (hb_ot_shape_planner_t *plan) -{ - const hb_tag_t *script_features = NULL; - - switch ((hb_tag_t) plan->props.script) - { - /* Unicode-1.1 additions */ - case HB_SCRIPT_HANGUL: - script_features = hangul_features; - break; - - /* Unicode-2.0 additions */ - case HB_SCRIPT_TIBETAN: - script_features = tibetan_features; - break; - } - - for (; script_features && *script_features; script_features++) - plan->map.add_bool_feature (*script_features); -} - -static hb_ot_shape_normalization_mode_t -normalization_preference_default (const hb_segment_properties_t *props) -{ - switch ((hb_tag_t) props->script) - { - /* Unicode-1.1 additions */ - case HB_SCRIPT_HANGUL: - return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL; - } - return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS; -} - -static bool -compose_default (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 0x05D0..0x05EA; - * Note that some letters do not have a dagesh presForm encoded. - */ - static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = { - 0xFB30, /* ALEF */ - 0xFB31, /* BET */ - 0xFB32, /* GIMEL */ - 0xFB33, /* DALET */ - 0xFB34, /* HE */ - 0xFB35, /* VAV */ - 0xFB36, /* ZAYIN */ - 0x0000, /* HET */ - 0xFB38, /* TET */ - 0xFB39, /* YOD */ - 0xFB3A, /* FINAL KAF */ - 0xFB3B, /* KAF */ - 0xFB3C, /* LAMED */ - 0x0000, /* FINAL MEM */ - 0xFB3E, /* MEM */ - 0x0000, /* FINAL NUN */ - 0xFB40, /* NUN */ - 0xFB41, /* SAMEKH */ - 0x0000, /* AYIN */ - 0xFB43, /* FINAL PE */ - 0xFB44, /* PE */ - 0x0000, /* FINAL TSADI */ - 0xFB46, /* TSADI */ - 0xFB47, /* QOF */ - 0xFB48, /* RESH */ - 0xFB49, /* SHIN */ - 0xFB4A /* TAV */ - }; - - bool found = c->unicode->compose (a, b, ab); - - if (!found && (b & ~0x7F) == 0x0580) { - /* Special-case Hebrew presentation forms that are excluded from - * standard normalization, but wanted for old fonts. */ - switch (b) { - case 0x05B4: /* HIRIQ */ - if (a == 0x05D9) { /* YOD */ - *ab = 0xFB1D; - found = true; - } - break; - case 0x05B7: /* patah */ - if (a == 0x05F2) { /* YIDDISH YOD YOD */ - *ab = 0xFB1F; - found = true; - } else if (a == 0x05D0) { /* ALEF */ - *ab = 0xFB2E; - found = true; - } - break; - case 0x05B8: /* QAMATS */ - if (a == 0x05D0) { /* ALEF */ - *ab = 0xFB2F; - found = true; - } - break; - case 0x05B9: /* HOLAM */ - if (a == 0x05D5) { /* VAV */ - *ab = 0xFB4B; - found = true; - } - break; - case 0x05BC: /* DAGESH */ - if (a >= 0x05D0 && a <= 0x05EA) { - *ab = sDageshForms[a - 0x05D0]; - found = (*ab != 0); - } else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */ - *ab = 0xFB2C; - found = true; - } else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */ - *ab = 0xFB2D; - found = true; - } - break; - case 0x05BF: /* RAFE */ - switch (a) { - case 0x05D1: /* BET */ - *ab = 0xFB4C; - found = true; - break; - case 0x05DB: /* KAF */ - *ab = 0xFB4D; - found = true; - break; - case 0x05E4: /* PE */ - *ab = 0xFB4E; - found = true; - break; - } - break; - case 0x05C1: /* SHIN DOT */ - if (a == 0x05E9) { /* SHIN */ - *ab = 0xFB2A; - found = true; - } else if (a == 0xFB49) { /* SHIN WITH DAGESH */ - *ab = 0xFB2C; - found = true; - } - break; - case 0x05C2: /* SIN DOT */ - if (a == 0x05E9) { /* SHIN */ - *ab = 0xFB2B; - found = true; - } else if (a == 0xFB49) { /* SHIN WITH DAGESH */ - *ab = 0xFB2D; - found = true; - } - break; - } - } - - return found; -} - const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = { "default", - collect_features_default, + NULL, /* collect_features */ NULL, /* override_features */ NULL, /* data_create */ NULL, /* data_destroy */ NULL, /* preprocess_text */ - normalization_preference_default, + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ - compose_default, + NULL, /* compose */ NULL, /* setup_masks */ - true, /* zero_width_attached_marks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, true, /* fallback_position */ }; diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc new file mode 100644 index 0000000..6ac18b0 --- /dev/null +++ b/src/hb-ot-shape-complex-hangul.cc @@ -0,0 +1,426 @@ +/* + * 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;) + { + 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)) + { + 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; + } + /* Merge clusters across the (possibly reordered) syllable+tone. + * We want to merge even in the zero-width tone mark case here, + * so that clustering behavior isn't dependent on how the tone mark + * is handled by the font. + */ + buffer->merge_out_clusters (start, end + 1); + } + 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; + 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; + 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_create */ + data_destroy_hangul, /* data_destroy */ + preprocess_text_hangul, + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, + NULL, /* decompose */ + NULL, /* compose */ + setup_masks_hangul, /* setup_masks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + false, /* fallback_position */ +}; diff --git a/src/hb-ot-shape-complex-hebrew.cc b/src/hb-ot-shape-complex-hebrew.cc new file mode 100644 index 0000000..c7b7a5e --- /dev/null +++ b/src/hb-ot-shape-complex-hebrew.cc @@ -0,0 +1,172 @@ +/* + * 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 = 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; +} + + +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 */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, + NULL, /* decompose */ + compose_hebrew, + NULL, /* setup_masks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, + true, /* fallback_position */ +}; diff --git a/src/hb-ot-shape-complex-indic-machine.hh b/src/hb-ot-shape-complex-indic-machine.hh index ed40b96..5fbdcc8 100644 --- a/src/hb-ot-shape-complex-indic-machine.hh +++ b/src/hb-ot-shape-complex-indic-machine.hh @@ -55,48 +55,52 @@ static const unsigned char _indic_syllable_machine_trans_keys[] = { 4u, 14u, 5u, 7u, 5u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 1u, 16u, 13u, 13u, 4u, 4u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, - 6u, 6u, 16u, 16u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, - 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, - 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, - 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u, - 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, - 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, - 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, - 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 3u, 14u, 3u, 14u, - 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, - 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, - 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, - 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, - 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, - 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, - 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 1u, 16u, 3u, 14u, - 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, - 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, - 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, - 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, + 6u, 6u, 16u, 16u, 1u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, + 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, + 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, + 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, + 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, + 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, + 6u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 31u, 3u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, + 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, + 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, + 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, + 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, - 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, - 3u, 14u, 4u, 14u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, - 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, - 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, - 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u, + 6u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 4u, 14u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, + 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, + 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, 5u, 10u, + 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, + 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, + 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, + 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 4u, 14u, 3u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, + 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, + 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, + 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, + 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, - 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 14u, 1u, 16u, 3u, 17u, 1u, 16u, 4u, 14u, 1u, 16u, - 3u, 17u, 3u, 14u, 4u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 14u, 3u, 14u, - 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, - 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 8u, 14u, 3u, 17u, 3u, 9u, 8u, 9u, - 3u, 9u, 3u, 13u, 1u, 16u, 0 + 6u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 31u, 1u, 31u, 3u, 31u, 1u, 31u, 4u, 14u, 1u, 16u, 3u, 31u, + 3u, 31u, 4u, 31u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, + 5u, 10u, 3u, 31u, 3u, 31u, 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, + 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 8u, 14u, + 3u, 13u, 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 3u, 10u, 8u, 10u, + 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 0 }; static const char _indic_syllable_machine_key_spans[] = { @@ -121,48 +125,52 @@ static const char _indic_syllable_machine_key_spans[] = { 11, 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, 1, 16, 1, 1, 1, 1, 4, 1, 1, 4, 1, 1, 4, - 1, 1, 16, 15, 12, 11, 16, 15, - 12, 11, 16, 15, 12, 11, 16, 15, - 12, 11, 16, 15, 12, 11, 10, 7, - 5, 1, 1, 15, 7, 2, 7, 11, - 12, 12, 11, 10, 12, 11, 10, 12, - 11, 10, 12, 11, 9, 12, 11, 16, - 12, 12, 16, 16, 16, 16, 16, 12, - 12, 16, 16, 16, 16, 16, 12, 12, - 16, 16, 16, 16, 16, 12, 12, 16, - 16, 16, 16, 16, 12, 12, 12, 12, - 11, 16, 15, 12, 11, 16, 15, 12, - 11, 16, 15, 12, 11, 16, 15, 12, - 11, 10, 7, 5, 1, 1, 15, 7, - 2, 7, 11, 12, 12, 11, 10, 12, - 11, 10, 12, 11, 10, 12, 11, 9, - 12, 16, 12, 12, 16, 16, 16, 16, - 16, 12, 12, 16, 16, 16, 16, 16, - 12, 12, 16, 16, 16, 16, 16, 12, - 12, 16, 16, 16, 16, 11, 16, 12, - 12, 11, 16, 15, 12, 11, 16, 15, - 12, 11, 16, 15, 12, 11, 16, 15, - 12, 11, 10, 7, 5, 1, 1, 15, - 7, 2, 7, 11, 12, 12, 11, 10, + 1, 1, 31, 29, 29, 28, 16, 29, + 29, 28, 16, 29, 29, 28, 16, 29, + 29, 28, 16, 29, 29, 28, 10, 7, + 6, 2, 1, 2, 2, 1, 6, 11, + 8, 3, 8, 11, 12, 12, 11, 10, + 12, 11, 10, 12, 11, 10, 12, 11, + 9, 12, 16, 28, 11, 29, 29, 16, + 16, 16, 16, 16, 29, 29, 16, 16, + 16, 16, 16, 29, 29, 16, 16, 16, + 16, 16, 29, 29, 16, 16, 16, 16, + 16, 29, 29, 29, 29, 28, 16, 29, + 29, 28, 16, 29, 29, 28, 16, 29, + 29, 28, 16, 29, 29, 28, 10, 7, + 6, 2, 1, 2, 2, 1, 6, 11, + 8, 3, 8, 11, 12, 12, 11, 10, 12, 11, 10, 12, 11, 10, 12, 11, - 9, 12, 16, 12, 12, 16, 16, 16, - 16, 16, 12, 12, 16, 16, 16, 16, - 16, 12, 12, 16, 16, 16, 16, 16, - 12, 12, 16, 16, 16, 16, 16, 11, - 12, 11, 12, 12, 11, 16, 15, 12, - 11, 16, 15, 12, 11, 16, 15, 12, - 11, 16, 15, 12, 11, 10, 7, 5, - 1, 1, 15, 7, 2, 7, 11, 12, + 9, 12, 16, 28, 11, 29, 29, 16, + 16, 16, 16, 16, 29, 29, 16, 16, + 16, 16, 16, 29, 29, 16, 16, 16, + 16, 16, 29, 29, 16, 16, 16, 16, + 11, 16, 29, 29, 28, 16, 29, 29, + 28, 16, 29, 29, 28, 16, 29, 29, + 28, 16, 29, 29, 28, 10, 7, 6, + 2, 1, 2, 2, 1, 6, 11, 8, + 3, 8, 11, 12, 12, 11, 10, 12, + 11, 10, 12, 11, 10, 12, 11, 9, + 12, 16, 28, 11, 29, 29, 16, 16, + 16, 16, 16, 29, 29, 16, 16, 16, + 16, 16, 29, 29, 16, 16, 16, 16, + 16, 29, 29, 16, 16, 16, 16, 16, + 11, 29, 11, 29, 29, 28, 16, 29, + 29, 28, 16, 29, 29, 28, 16, 29, + 29, 28, 16, 29, 29, 28, 10, 7, + 6, 2, 1, 2, 2, 1, 6, 11, + 8, 3, 8, 11, 12, 12, 11, 10, 12, 11, 10, 12, 11, 10, 12, 11, - 10, 12, 11, 9, 12, 16, 12, 12, - 16, 16, 16, 16, 16, 12, 12, 16, - 16, 16, 16, 16, 12, 12, 16, 16, - 16, 16, 16, 12, 12, 16, 16, 16, - 16, 16, 12, 16, 15, 16, 11, 16, - 15, 12, 11, 5, 1, 1, 12, 12, - 16, 12, 11, 10, 12, 11, 10, 12, - 11, 10, 12, 11, 7, 15, 7, 2, - 7, 11, 16 + 9, 12, 16, 28, 11, 29, 29, 16, + 16, 16, 16, 16, 29, 29, 16, 16, + 16, 16, 16, 29, 29, 16, 16, 16, + 16, 16, 29, 29, 16, 16, 16, 16, + 16, 29, 31, 29, 31, 11, 16, 29, + 29, 28, 6, 2, 1, 2, 2, 1, + 6, 29, 29, 16, 12, 11, 10, 12, + 11, 10, 12, 11, 10, 12, 11, 7, + 11, 8, 3, 8, 11, 16, 8, 3, + 6, 2, 1, 2, 2, 1, 6 }; static const short _indic_syllable_machine_index_offsets[] = { @@ -187,48 +195,52 @@ static const short _indic_syllable_machine_index_offsets[] = { 848, 860, 864, 868, 872, 876, 878, 882, 886, 888, 892, 896, 898, 915, 917, 919, 921, 923, 928, 930, 932, 937, 939, 941, - 946, 948, 950, 967, 983, 996, 1008, 1025, - 1041, 1054, 1066, 1083, 1099, 1112, 1124, 1141, - 1157, 1170, 1182, 1199, 1215, 1228, 1240, 1251, - 1259, 1265, 1267, 1269, 1285, 1293, 1296, 1304, - 1316, 1329, 1342, 1354, 1365, 1378, 1390, 1401, - 1414, 1426, 1437, 1450, 1462, 1472, 1485, 1497, - 1514, 1527, 1540, 1557, 1574, 1591, 1608, 1625, - 1638, 1651, 1668, 1685, 1702, 1719, 1736, 1749, - 1762, 1779, 1796, 1813, 1830, 1847, 1860, 1873, - 1890, 1907, 1924, 1941, 1958, 1971, 1984, 1997, - 2010, 2022, 2039, 2055, 2068, 2080, 2097, 2113, - 2126, 2138, 2155, 2171, 2184, 2196, 2213, 2229, - 2242, 2254, 2265, 2273, 2279, 2281, 2283, 2299, - 2307, 2310, 2318, 2330, 2343, 2356, 2368, 2379, - 2392, 2404, 2415, 2428, 2440, 2451, 2464, 2476, - 2486, 2499, 2516, 2529, 2542, 2559, 2576, 2593, - 2610, 2627, 2640, 2653, 2670, 2687, 2704, 2721, - 2738, 2751, 2764, 2781, 2798, 2815, 2832, 2849, - 2862, 2875, 2892, 2909, 2926, 2943, 2955, 2972, - 2985, 2998, 3010, 3027, 3043, 3056, 3068, 3085, - 3101, 3114, 3126, 3143, 3159, 3172, 3184, 3201, - 3217, 3230, 3242, 3253, 3261, 3267, 3269, 3271, - 3287, 3295, 3298, 3306, 3318, 3331, 3344, 3356, - 3367, 3380, 3392, 3403, 3416, 3428, 3439, 3452, - 3464, 3474, 3487, 3504, 3517, 3530, 3547, 3564, - 3581, 3598, 3615, 3628, 3641, 3658, 3675, 3692, - 3709, 3726, 3739, 3752, 3769, 3786, 3803, 3820, - 3837, 3850, 3863, 3880, 3897, 3914, 3931, 3948, - 3960, 3973, 3985, 3998, 4011, 4023, 4040, 4056, - 4069, 4081, 4098, 4114, 4127, 4139, 4156, 4172, - 4185, 4197, 4214, 4230, 4243, 4255, 4266, 4274, - 4280, 4282, 4284, 4300, 4308, 4311, 4319, 4331, - 4344, 4357, 4369, 4380, 4393, 4405, 4416, 4429, - 4441, 4452, 4465, 4477, 4487, 4500, 4517, 4530, - 4543, 4560, 4577, 4594, 4611, 4628, 4641, 4654, - 4671, 4688, 4705, 4722, 4739, 4752, 4765, 4782, - 4799, 4816, 4833, 4850, 4863, 4876, 4893, 4910, - 4927, 4944, 4961, 4974, 4991, 5007, 5024, 5036, - 5053, 5069, 5082, 5094, 5100, 5102, 5104, 5117, - 5130, 5147, 5160, 5172, 5183, 5196, 5208, 5219, - 5232, 5244, 5255, 5268, 5280, 5288, 5304, 5312, - 5315, 5323, 5335 + 946, 948, 950, 982, 1012, 1042, 1071, 1088, + 1118, 1148, 1177, 1194, 1224, 1254, 1283, 1300, + 1330, 1360, 1389, 1406, 1436, 1466, 1495, 1506, + 1514, 1521, 1524, 1526, 1529, 1532, 1534, 1541, + 1553, 1562, 1566, 1575, 1587, 1600, 1613, 1625, + 1636, 1649, 1661, 1672, 1685, 1697, 1708, 1721, + 1733, 1743, 1756, 1773, 1802, 1814, 1844, 1874, + 1891, 1908, 1925, 1942, 1959, 1989, 2019, 2036, + 2053, 2070, 2087, 2104, 2134, 2164, 2181, 2198, + 2215, 2232, 2249, 2279, 2309, 2326, 2343, 2360, + 2377, 2394, 2424, 2454, 2484, 2514, 2543, 2560, + 2590, 2620, 2649, 2666, 2696, 2726, 2755, 2772, + 2802, 2832, 2861, 2878, 2908, 2938, 2967, 2978, + 2986, 2993, 2996, 2998, 3001, 3004, 3006, 3013, + 3025, 3034, 3038, 3047, 3059, 3072, 3085, 3097, + 3108, 3121, 3133, 3144, 3157, 3169, 3180, 3193, + 3205, 3215, 3228, 3245, 3274, 3286, 3316, 3346, + 3363, 3380, 3397, 3414, 3431, 3461, 3491, 3508, + 3525, 3542, 3559, 3576, 3606, 3636, 3653, 3670, + 3687, 3704, 3721, 3751, 3781, 3798, 3815, 3832, + 3849, 3861, 3878, 3908, 3938, 3967, 3984, 4014, + 4044, 4073, 4090, 4120, 4150, 4179, 4196, 4226, + 4256, 4285, 4302, 4332, 4362, 4391, 4402, 4410, + 4417, 4420, 4422, 4425, 4428, 4430, 4437, 4449, + 4458, 4462, 4471, 4483, 4496, 4509, 4521, 4532, + 4545, 4557, 4568, 4581, 4593, 4604, 4617, 4629, + 4639, 4652, 4669, 4698, 4710, 4740, 4770, 4787, + 4804, 4821, 4838, 4855, 4885, 4915, 4932, 4949, + 4966, 4983, 5000, 5030, 5060, 5077, 5094, 5111, + 5128, 5145, 5175, 5205, 5222, 5239, 5256, 5273, + 5290, 5302, 5332, 5344, 5374, 5404, 5433, 5450, + 5480, 5510, 5539, 5556, 5586, 5616, 5645, 5662, + 5692, 5722, 5751, 5768, 5798, 5828, 5857, 5868, + 5876, 5883, 5886, 5888, 5891, 5894, 5896, 5903, + 5915, 5924, 5928, 5937, 5949, 5962, 5975, 5987, + 5998, 6011, 6023, 6034, 6047, 6059, 6070, 6083, + 6095, 6105, 6118, 6135, 6164, 6176, 6206, 6236, + 6253, 6270, 6287, 6304, 6321, 6351, 6381, 6398, + 6415, 6432, 6449, 6466, 6496, 6526, 6543, 6560, + 6577, 6594, 6611, 6641, 6671, 6688, 6705, 6722, + 6739, 6756, 6786, 6818, 6848, 6880, 6892, 6909, + 6939, 6969, 6998, 7005, 7008, 7010, 7013, 7016, + 7018, 7025, 7055, 7085, 7102, 7115, 7127, 7138, + 7151, 7163, 7174, 7187, 7199, 7210, 7223, 7235, + 7243, 7255, 7264, 7268, 7277, 7289, 7306, 7315, + 7319, 7326, 7329, 7331, 7334, 7337, 7339 }; static const short _indic_syllable_machine_indicies[] = { @@ -351,625 +363,878 @@ static const short _indic_syllable_machine_indicies[] = { 172, 0, 173, 0, 174, 159, 159, 160, 0, 175, 0, 176, 0, 177, 156, 156, 157, 0, 178, 0, 179, 0, 181, 182, - 183, 184, 185, 186, 81, 187, 188, 180, - 189, 189, 152, 190, 191, 192, 180, 194, - 195, 196, 197, 5, 198, 199, 200, 193, - 193, 37, 201, 193, 193, 181, 193, 202, - 195, 203, 203, 5, 198, 199, 200, 193, - 193, 193, 201, 193, 195, 203, 203, 5, - 198, 199, 200, 193, 193, 193, 201, 193, - 204, 193, 193, 193, 18, 205, 193, 198, - 199, 193, 193, 193, 193, 206, 193, 204, - 193, 207, 208, 209, 210, 5, 198, 199, - 200, 193, 193, 35, 211, 193, 193, 204, - 193, 212, 208, 213, 213, 5, 198, 199, - 200, 193, 193, 193, 211, 193, 208, 213, - 213, 5, 198, 199, 200, 193, 193, 193, - 211, 193, 214, 193, 193, 193, 18, 215, - 193, 198, 199, 193, 193, 193, 193, 206, - 193, 214, 193, 216, 217, 218, 219, 5, - 198, 199, 200, 193, 193, 33, 220, 193, - 193, 214, 193, 221, 217, 222, 222, 5, - 198, 199, 200, 193, 193, 193, 220, 193, - 217, 222, 222, 5, 198, 199, 200, 193, - 193, 193, 220, 193, 223, 193, 193, 193, - 18, 224, 193, 198, 199, 193, 193, 193, - 193, 206, 193, 223, 193, 225, 226, 227, - 228, 5, 198, 199, 200, 193, 193, 31, - 229, 193, 193, 223, 193, 230, 226, 231, - 231, 5, 198, 199, 200, 193, 193, 193, - 229, 193, 226, 231, 231, 5, 198, 199, - 200, 193, 193, 193, 229, 193, 232, 193, - 193, 193, 18, 233, 193, 198, 199, 193, - 193, 193, 193, 206, 193, 232, 193, 234, - 235, 236, 237, 5, 198, 199, 200, 193, - 193, 29, 238, 193, 193, 232, 193, 239, - 235, 240, 240, 5, 198, 199, 200, 193, - 193, 193, 238, 193, 235, 240, 240, 5, - 198, 199, 200, 193, 193, 193, 238, 193, - 18, 241, 193, 198, 199, 193, 193, 193, - 193, 206, 193, 198, 199, 193, 193, 193, - 193, 206, 193, 242, 193, 193, 193, 199, - 193, 199, 193, 243, 193, 244, 193, 245, - 246, 193, 198, 199, 193, 193, 193, 3, - 193, 193, 193, 1, 193, 2, 193, 193, - 193, 193, 198, 199, 193, 198, 199, 193, - 244, 193, 193, 193, 193, 198, 199, 193, - 244, 193, 245, 193, 193, 198, 199, 193, - 193, 193, 3, 193, 18, 193, 247, 247, - 5, 198, 199, 193, 193, 193, 193, 206, - 193, 248, 27, 249, 250, 8, 198, 199, - 193, 193, 193, 193, 206, 193, 27, 249, - 250, 8, 198, 199, 193, 193, 193, 193, - 206, 193, 249, 249, 8, 198, 199, 193, - 193, 193, 193, 206, 193, 251, 24, 252, - 253, 11, 198, 199, 193, 193, 193, 193, - 206, 193, 24, 252, 253, 11, 198, 199, - 193, 193, 193, 193, 206, 193, 252, 252, - 11, 198, 199, 193, 193, 193, 193, 206, - 193, 254, 21, 255, 256, 14, 198, 199, - 193, 193, 193, 193, 206, 193, 21, 255, - 256, 14, 198, 199, 193, 193, 193, 193, - 206, 193, 255, 255, 14, 198, 199, 193, - 193, 193, 193, 206, 193, 257, 18, 193, - 258, 193, 198, 199, 193, 193, 193, 193, - 206, 193, 18, 193, 258, 193, 198, 199, - 193, 193, 193, 193, 206, 193, 259, 193, - 198, 199, 193, 193, 193, 193, 206, 193, - 18, 193, 193, 193, 193, 198, 199, 193, - 193, 193, 193, 206, 193, 235, 240, 240, - 5, 198, 199, 193, 193, 193, 193, 238, - 193, 1, 2, 193, 193, 18, 241, 193, - 198, 199, 193, 193, 193, 193, 206, 193, - 1, 193, 234, 235, 240, 240, 5, 198, - 199, 200, 193, 193, 193, 238, 193, 234, - 235, 236, 240, 5, 198, 199, 200, 193, - 193, 29, 238, 193, 232, 193, 260, 193, - 247, 247, 5, 198, 199, 193, 193, 193, - 193, 206, 193, 232, 193, 232, 193, 193, - 193, 193, 193, 193, 198, 199, 193, 193, - 193, 193, 206, 193, 232, 193, 232, 193, - 193, 193, 193, 261, 193, 198, 199, 193, - 193, 193, 193, 206, 193, 232, 193, 232, - 193, 260, 193, 193, 193, 193, 198, 199, - 193, 193, 193, 193, 206, 193, 232, 193, - 232, 2, 193, 193, 18, 233, 193, 198, - 199, 193, 193, 193, 193, 206, 193, 232, - 193, 225, 226, 231, 231, 5, 198, 199, - 200, 193, 193, 193, 229, 193, 225, 226, - 227, 231, 5, 198, 199, 200, 193, 193, - 31, 229, 193, 223, 193, 262, 193, 247, - 247, 5, 198, 199, 193, 193, 193, 193, - 206, 193, 223, 193, 223, 193, 193, 193, - 193, 193, 193, 198, 199, 193, 193, 193, - 193, 206, 193, 223, 193, 223, 193, 193, - 193, 193, 263, 193, 198, 199, 193, 193, - 193, 193, 206, 193, 223, 193, 223, 193, - 262, 193, 193, 193, 193, 198, 199, 193, - 193, 193, 193, 206, 193, 223, 193, 223, - 2, 193, 193, 18, 224, 193, 198, 199, - 193, 193, 193, 193, 206, 193, 223, 193, - 216, 217, 222, 222, 5, 198, 199, 200, - 193, 193, 193, 220, 193, 216, 217, 218, - 222, 5, 198, 199, 200, 193, 193, 33, - 220, 193, 214, 193, 264, 193, 247, 247, - 5, 198, 199, 193, 193, 193, 193, 206, - 193, 214, 193, 214, 193, 193, 193, 193, - 193, 193, 198, 199, 193, 193, 193, 193, - 206, 193, 214, 193, 214, 193, 193, 193, - 193, 265, 193, 198, 199, 193, 193, 193, - 193, 206, 193, 214, 193, 214, 193, 264, - 193, 193, 193, 193, 198, 199, 193, 193, - 193, 193, 206, 193, 214, 193, 214, 2, - 193, 193, 18, 215, 193, 198, 199, 193, - 193, 193, 193, 206, 193, 214, 193, 207, - 208, 213, 213, 5, 198, 199, 200, 193, - 193, 193, 211, 193, 207, 208, 209, 213, - 5, 198, 199, 200, 193, 193, 35, 211, - 193, 204, 193, 266, 193, 247, 247, 5, - 198, 199, 193, 193, 193, 193, 206, 193, - 204, 193, 204, 193, 193, 193, 193, 193, - 193, 198, 199, 193, 193, 193, 193, 206, - 193, 204, 193, 204, 193, 193, 193, 193, - 267, 193, 198, 199, 193, 193, 193, 193, - 206, 193, 204, 193, 204, 193, 266, 193, - 193, 193, 193, 198, 199, 193, 193, 193, - 193, 206, 193, 204, 193, 204, 2, 193, - 193, 18, 205, 193, 198, 199, 193, 193, - 193, 193, 206, 193, 204, 193, 194, 195, - 203, 203, 5, 198, 199, 200, 193, 193, - 193, 201, 193, 194, 195, 196, 203, 5, - 198, 199, 200, 193, 193, 37, 201, 193, - 269, 270, 271, 272, 43, 273, 274, 268, - 268, 268, 75, 275, 268, 276, 270, 277, - 272, 43, 273, 274, 268, 268, 268, 268, - 275, 268, 270, 277, 272, 43, 273, 274, - 268, 268, 268, 268, 275, 268, 278, 268, - 268, 268, 56, 279, 268, 273, 274, 268, - 268, 268, 268, 280, 268, 278, 268, 281, - 282, 283, 284, 43, 273, 274, 268, 268, - 268, 73, 285, 268, 268, 278, 268, 286, - 282, 287, 287, 43, 273, 274, 268, 268, - 268, 268, 285, 268, 282, 287, 287, 43, - 273, 274, 268, 268, 268, 268, 285, 268, - 288, 268, 268, 268, 56, 289, 268, 273, - 274, 268, 268, 268, 268, 280, 268, 288, - 268, 290, 291, 292, 293, 43, 273, 274, - 268, 268, 268, 71, 294, 268, 268, 288, - 268, 295, 291, 296, 296, 43, 273, 274, - 268, 268, 268, 268, 294, 268, 291, 296, - 296, 43, 273, 274, 268, 268, 268, 268, - 294, 268, 297, 268, 268, 268, 56, 298, - 268, 273, 274, 268, 268, 268, 268, 280, - 268, 297, 268, 299, 300, 301, 302, 43, - 273, 274, 268, 268, 268, 69, 303, 268, - 268, 297, 268, 304, 300, 305, 305, 43, - 273, 274, 268, 268, 268, 268, 303, 268, - 300, 305, 305, 43, 273, 274, 268, 268, - 268, 268, 303, 268, 306, 268, 268, 268, - 56, 307, 268, 273, 274, 268, 268, 268, - 268, 280, 268, 306, 268, 308, 309, 310, - 311, 43, 273, 274, 268, 268, 268, 67, - 312, 268, 268, 306, 268, 313, 309, 314, - 314, 43, 273, 274, 268, 268, 268, 268, - 312, 268, 309, 314, 314, 43, 273, 274, - 268, 268, 268, 268, 312, 268, 56, 315, - 268, 273, 274, 268, 268, 268, 268, 280, - 268, 273, 274, 268, 268, 268, 268, 280, - 268, 316, 268, 268, 268, 274, 268, 274, - 268, 317, 268, 318, 268, 319, 320, 268, - 273, 274, 268, 268, 268, 41, 268, 268, - 268, 39, 268, 40, 268, 268, 268, 268, - 273, 274, 268, 273, 274, 268, 318, 268, - 268, 268, 268, 273, 274, 268, 318, 268, - 319, 268, 268, 273, 274, 268, 268, 268, - 41, 268, 56, 268, 321, 321, 43, 273, - 274, 268, 268, 268, 268, 280, 268, 322, - 65, 323, 324, 46, 273, 274, 268, 268, - 268, 268, 280, 268, 65, 323, 324, 46, - 273, 274, 268, 268, 268, 268, 280, 268, - 323, 323, 46, 273, 274, 268, 268, 268, - 268, 280, 268, 325, 62, 326, 327, 49, - 273, 274, 268, 268, 268, 268, 280, 268, - 62, 326, 327, 49, 273, 274, 268, 268, - 268, 268, 280, 268, 326, 326, 49, 273, - 274, 268, 268, 268, 268, 280, 268, 328, - 59, 329, 330, 52, 273, 274, 268, 268, - 268, 268, 280, 268, 59, 329, 330, 52, - 273, 274, 268, 268, 268, 268, 280, 268, - 329, 329, 52, 273, 274, 268, 268, 268, - 268, 280, 268, 331, 56, 268, 332, 268, - 273, 274, 268, 268, 268, 268, 280, 268, - 56, 268, 332, 268, 273, 274, 268, 268, - 268, 268, 280, 268, 333, 268, 273, 274, - 268, 268, 268, 268, 280, 268, 56, 268, - 268, 268, 268, 273, 274, 268, 268, 268, - 268, 280, 268, 39, 40, 268, 268, 56, - 315, 268, 273, 274, 268, 268, 268, 268, - 280, 268, 39, 268, 308, 309, 314, 314, - 43, 273, 274, 268, 268, 268, 268, 312, - 268, 308, 309, 310, 314, 43, 273, 274, - 268, 268, 268, 67, 312, 268, 306, 268, - 334, 268, 321, 321, 43, 273, 274, 268, - 268, 268, 268, 280, 268, 306, 268, 306, - 268, 268, 268, 268, 268, 268, 273, 274, - 268, 268, 268, 268, 280, 268, 306, 268, - 306, 268, 268, 268, 268, 335, 268, 273, - 274, 268, 268, 268, 268, 280, 268, 306, - 268, 306, 268, 334, 268, 268, 268, 268, - 273, 274, 268, 268, 268, 268, 280, 268, - 306, 268, 306, 40, 268, 268, 56, 307, - 268, 273, 274, 268, 268, 268, 268, 280, - 268, 306, 268, 299, 300, 305, 305, 43, - 273, 274, 268, 268, 268, 268, 303, 268, - 299, 300, 301, 305, 43, 273, 274, 268, - 268, 268, 69, 303, 268, 297, 268, 336, - 268, 321, 321, 43, 273, 274, 268, 268, - 268, 268, 280, 268, 297, 268, 297, 268, - 268, 268, 268, 268, 268, 273, 274, 268, - 268, 268, 268, 280, 268, 297, 268, 297, - 268, 268, 268, 268, 337, 268, 273, 274, - 268, 268, 268, 268, 280, 268, 297, 268, - 297, 268, 336, 268, 268, 268, 268, 273, - 274, 268, 268, 268, 268, 280, 268, 297, - 268, 297, 40, 268, 268, 56, 298, 268, - 273, 274, 268, 268, 268, 268, 280, 268, - 297, 268, 290, 291, 296, 296, 43, 273, - 274, 268, 268, 268, 268, 294, 268, 290, - 291, 292, 296, 43, 273, 274, 268, 268, - 268, 71, 294, 268, 288, 268, 338, 268, - 321, 321, 43, 273, 274, 268, 268, 268, - 268, 280, 268, 288, 268, 288, 268, 268, - 268, 268, 268, 268, 273, 274, 268, 268, - 268, 268, 280, 268, 288, 268, 288, 268, - 268, 268, 268, 339, 268, 273, 274, 268, - 268, 268, 268, 280, 268, 288, 268, 288, - 268, 338, 268, 268, 268, 268, 273, 274, - 268, 268, 268, 268, 280, 268, 288, 268, - 288, 40, 268, 268, 56, 289, 268, 273, - 274, 268, 268, 268, 268, 280, 268, 288, - 268, 281, 282, 287, 287, 43, 273, 274, - 268, 268, 268, 268, 285, 268, 281, 282, - 283, 287, 43, 273, 274, 268, 268, 268, - 73, 285, 268, 278, 268, 340, 268, 321, - 321, 43, 273, 274, 268, 268, 268, 268, - 280, 268, 278, 268, 278, 268, 268, 268, - 268, 268, 268, 273, 274, 268, 268, 268, - 268, 280, 268, 278, 268, 278, 268, 268, - 268, 268, 341, 268, 273, 274, 268, 268, - 268, 268, 280, 268, 278, 268, 278, 268, - 340, 268, 268, 268, 268, 273, 274, 268, - 268, 268, 268, 280, 268, 278, 268, 74, - 42, 42, 43, 268, 268, 268, 268, 268, - 268, 74, 268, 278, 40, 268, 268, 56, - 279, 268, 273, 274, 268, 268, 268, 268, - 280, 268, 278, 268, 269, 270, 277, 272, - 43, 273, 274, 268, 268, 268, 268, 275, - 268, 343, 184, 344, 344, 81, 187, 188, - 342, 342, 342, 342, 190, 342, 184, 344, - 344, 81, 187, 188, 342, 342, 342, 342, - 190, 342, 345, 342, 342, 342, 95, 346, - 342, 187, 188, 342, 342, 342, 342, 347, - 342, 345, 342, 348, 349, 350, 351, 81, - 187, 188, 342, 342, 342, 112, 352, 342, - 342, 345, 342, 353, 349, 354, 354, 81, - 187, 188, 342, 342, 342, 342, 352, 342, - 349, 354, 354, 81, 187, 188, 342, 342, - 342, 342, 352, 342, 355, 342, 342, 342, - 95, 356, 342, 187, 188, 342, 342, 342, - 342, 347, 342, 355, 342, 357, 358, 359, - 360, 81, 187, 188, 342, 342, 342, 110, - 361, 342, 342, 355, 342, 362, 358, 363, - 363, 81, 187, 188, 342, 342, 342, 342, - 361, 342, 358, 363, 363, 81, 187, 188, - 342, 342, 342, 342, 361, 342, 364, 342, - 342, 342, 95, 365, 342, 187, 188, 342, - 342, 342, 342, 347, 342, 364, 342, 366, - 367, 368, 369, 81, 187, 188, 342, 342, - 342, 108, 370, 342, 342, 364, 342, 371, - 367, 372, 372, 81, 187, 188, 342, 342, - 342, 342, 370, 342, 367, 372, 372, 81, - 187, 188, 342, 342, 342, 342, 370, 342, - 373, 342, 342, 342, 95, 374, 342, 187, - 188, 342, 342, 342, 342, 347, 342, 373, - 342, 375, 376, 377, 378, 81, 187, 188, - 342, 342, 342, 106, 379, 342, 342, 373, - 342, 380, 376, 381, 381, 81, 187, 188, - 342, 342, 342, 342, 379, 342, 376, 381, - 381, 81, 187, 188, 342, 342, 342, 342, - 379, 342, 95, 382, 342, 187, 188, 342, - 342, 342, 342, 347, 342, 187, 188, 342, - 342, 342, 342, 347, 342, 383, 342, 342, - 342, 188, 342, 188, 342, 384, 342, 385, - 342, 386, 387, 342, 187, 188, 342, 342, - 342, 79, 342, 342, 342, 77, 342, 78, - 342, 342, 342, 342, 187, 188, 342, 187, - 188, 342, 385, 342, 342, 342, 342, 187, - 188, 342, 385, 342, 386, 342, 342, 187, - 188, 342, 342, 342, 79, 342, 95, 342, - 388, 388, 81, 187, 188, 342, 342, 342, - 342, 347, 342, 389, 104, 390, 391, 85, - 187, 188, 342, 342, 342, 342, 347, 342, - 104, 390, 391, 85, 187, 188, 342, 342, - 342, 342, 347, 342, 390, 390, 85, 187, - 188, 342, 342, 342, 342, 347, 342, 392, - 101, 393, 394, 88, 187, 188, 342, 342, - 342, 342, 347, 342, 101, 393, 394, 88, - 187, 188, 342, 342, 342, 342, 347, 342, - 393, 393, 88, 187, 188, 342, 342, 342, - 342, 347, 342, 395, 98, 396, 397, 91, - 187, 188, 342, 342, 342, 342, 347, 342, - 98, 396, 397, 91, 187, 188, 342, 342, - 342, 342, 347, 342, 396, 396, 91, 187, - 188, 342, 342, 342, 342, 347, 342, 398, - 95, 342, 399, 342, 187, 188, 342, 342, - 342, 342, 347, 342, 95, 342, 399, 342, - 187, 188, 342, 342, 342, 342, 347, 342, - 400, 342, 187, 188, 342, 342, 342, 342, - 347, 342, 95, 342, 342, 342, 342, 187, - 188, 342, 342, 342, 342, 347, 342, 77, - 78, 342, 342, 95, 382, 342, 187, 188, - 342, 342, 342, 342, 347, 342, 77, 342, - 375, 376, 381, 381, 81, 187, 188, 342, - 342, 342, 342, 379, 342, 375, 376, 377, - 381, 81, 187, 188, 342, 342, 342, 106, - 379, 342, 373, 342, 401, 342, 388, 388, - 81, 187, 188, 342, 342, 342, 342, 347, - 342, 373, 342, 373, 342, 342, 342, 342, - 342, 342, 187, 188, 342, 342, 342, 342, - 347, 342, 373, 342, 373, 342, 342, 342, - 342, 402, 342, 187, 188, 342, 342, 342, - 342, 347, 342, 373, 342, 373, 342, 401, - 342, 342, 342, 342, 187, 188, 342, 342, - 342, 342, 347, 342, 373, 342, 373, 78, - 342, 342, 95, 374, 342, 187, 188, 342, - 342, 342, 342, 347, 342, 373, 342, 366, - 367, 372, 372, 81, 187, 188, 342, 342, - 342, 342, 370, 342, 366, 367, 368, 372, - 81, 187, 188, 342, 342, 342, 108, 370, - 342, 364, 342, 403, 342, 388, 388, 81, - 187, 188, 342, 342, 342, 342, 347, 342, - 364, 342, 364, 342, 342, 342, 342, 342, - 342, 187, 188, 342, 342, 342, 342, 347, - 342, 364, 342, 364, 342, 342, 342, 342, - 404, 342, 187, 188, 342, 342, 342, 342, - 347, 342, 364, 342, 364, 342, 403, 342, - 342, 342, 342, 187, 188, 342, 342, 342, - 342, 347, 342, 364, 342, 364, 78, 342, - 342, 95, 365, 342, 187, 188, 342, 342, - 342, 342, 347, 342, 364, 342, 357, 358, - 363, 363, 81, 187, 188, 342, 342, 342, - 342, 361, 342, 357, 358, 359, 363, 81, - 187, 188, 342, 342, 342, 110, 361, 342, - 355, 342, 405, 342, 388, 388, 81, 187, - 188, 342, 342, 342, 342, 347, 342, 355, - 342, 355, 342, 342, 342, 342, 342, 342, - 187, 188, 342, 342, 342, 342, 347, 342, - 355, 342, 355, 342, 342, 342, 342, 406, - 342, 187, 188, 342, 342, 342, 342, 347, - 342, 355, 342, 355, 342, 405, 342, 342, - 342, 342, 187, 188, 342, 342, 342, 342, - 347, 342, 355, 342, 355, 78, 342, 342, - 95, 356, 342, 187, 188, 342, 342, 342, - 342, 347, 342, 355, 342, 348, 349, 354, - 354, 81, 187, 188, 342, 342, 342, 342, - 352, 342, 348, 349, 350, 354, 81, 187, - 188, 342, 342, 342, 112, 352, 342, 345, - 342, 407, 342, 388, 388, 81, 187, 188, - 342, 342, 342, 342, 347, 342, 345, 342, - 345, 342, 342, 342, 342, 342, 342, 187, - 188, 342, 342, 342, 342, 347, 342, 345, - 342, 345, 342, 342, 342, 342, 408, 342, - 187, 188, 342, 342, 342, 342, 347, 342, - 345, 342, 345, 342, 407, 342, 342, 342, - 342, 187, 188, 342, 342, 342, 342, 347, - 342, 345, 342, 345, 78, 342, 342, 95, - 346, 342, 187, 188, 342, 342, 342, 342, - 347, 342, 345, 342, 113, 80, 80, 81, - 409, 409, 409, 409, 409, 152, 113, 409, - 183, 184, 344, 344, 81, 187, 188, 342, - 342, 342, 342, 190, 342, 113, 80, 80, - 81, 409, 409, 409, 409, 409, 409, 113, - 409, 411, 412, 413, 414, 119, 415, 416, - 410, 410, 410, 151, 417, 410, 418, 412, - 414, 414, 119, 415, 416, 410, 410, 410, - 410, 417, 410, 412, 414, 414, 119, 415, - 416, 410, 410, 410, 410, 417, 410, 419, - 410, 410, 410, 132, 420, 410, 415, 416, - 410, 410, 410, 410, 421, 410, 419, 410, - 422, 423, 424, 425, 119, 415, 416, 410, - 410, 410, 149, 426, 410, 410, 419, 410, - 427, 423, 428, 428, 119, 415, 416, 410, - 410, 410, 410, 426, 410, 423, 428, 428, - 119, 415, 416, 410, 410, 410, 410, 426, - 410, 429, 410, 410, 410, 132, 430, 410, - 415, 416, 410, 410, 410, 410, 421, 410, - 429, 410, 431, 432, 433, 434, 119, 415, - 416, 410, 410, 410, 147, 435, 410, 410, - 429, 410, 436, 432, 437, 437, 119, 415, - 416, 410, 410, 410, 410, 435, 410, 432, - 437, 437, 119, 415, 416, 410, 410, 410, - 410, 435, 410, 438, 410, 410, 410, 132, - 439, 410, 415, 416, 410, 410, 410, 410, - 421, 410, 438, 410, 440, 441, 442, 443, - 119, 415, 416, 410, 410, 410, 145, 444, - 410, 410, 438, 410, 445, 441, 446, 446, - 119, 415, 416, 410, 410, 410, 410, 444, - 410, 441, 446, 446, 119, 415, 416, 410, - 410, 410, 410, 444, 410, 447, 410, 410, - 410, 132, 448, 410, 415, 416, 410, 410, - 410, 410, 421, 410, 447, 410, 449, 450, - 451, 452, 119, 415, 416, 410, 410, 410, - 143, 453, 410, 410, 447, 410, 454, 450, - 455, 455, 119, 415, 416, 410, 410, 410, - 410, 453, 410, 450, 455, 455, 119, 415, - 416, 410, 410, 410, 410, 453, 410, 132, - 456, 410, 415, 416, 410, 410, 410, 410, - 421, 410, 415, 416, 410, 410, 410, 410, - 421, 410, 457, 410, 410, 410, 416, 410, - 416, 410, 458, 410, 459, 410, 460, 461, - 410, 415, 416, 410, 410, 410, 117, 410, - 410, 410, 115, 410, 116, 410, 410, 410, - 410, 415, 416, 410, 415, 416, 410, 459, - 410, 410, 410, 410, 415, 416, 410, 459, - 410, 460, 410, 410, 415, 416, 410, 410, - 410, 117, 410, 132, 410, 462, 462, 119, - 415, 416, 410, 410, 410, 410, 421, 410, - 463, 141, 464, 465, 122, 415, 416, 410, - 410, 410, 410, 421, 410, 141, 464, 465, - 122, 415, 416, 410, 410, 410, 410, 421, - 410, 464, 464, 122, 415, 416, 410, 410, - 410, 410, 421, 410, 466, 138, 467, 468, - 125, 415, 416, 410, 410, 410, 410, 421, - 410, 138, 467, 468, 125, 415, 416, 410, - 410, 410, 410, 421, 410, 467, 467, 125, - 415, 416, 410, 410, 410, 410, 421, 410, - 469, 135, 470, 471, 128, 415, 416, 410, - 410, 410, 410, 421, 410, 135, 470, 471, - 128, 415, 416, 410, 410, 410, 410, 421, - 410, 470, 470, 128, 415, 416, 410, 410, - 410, 410, 421, 410, 472, 132, 410, 473, - 410, 415, 416, 410, 410, 410, 410, 421, - 410, 132, 410, 473, 410, 415, 416, 410, - 410, 410, 410, 421, 410, 474, 410, 415, - 416, 410, 410, 410, 410, 421, 410, 132, - 410, 410, 410, 410, 415, 416, 410, 410, - 410, 410, 421, 410, 115, 116, 410, 410, - 132, 456, 410, 415, 416, 410, 410, 410, - 410, 421, 410, 115, 410, 449, 450, 455, - 455, 119, 415, 416, 410, 410, 410, 410, - 453, 410, 449, 450, 451, 455, 119, 415, - 416, 410, 410, 410, 143, 453, 410, 447, - 410, 475, 410, 462, 462, 119, 415, 416, - 410, 410, 410, 410, 421, 410, 447, 410, - 447, 410, 410, 410, 410, 410, 410, 415, - 416, 410, 410, 410, 410, 421, 410, 447, - 410, 447, 410, 410, 410, 410, 476, 410, - 415, 416, 410, 410, 410, 410, 421, 410, - 447, 410, 447, 410, 475, 410, 410, 410, - 410, 415, 416, 410, 410, 410, 410, 421, - 410, 447, 410, 447, 116, 410, 410, 132, - 448, 410, 415, 416, 410, 410, 410, 410, - 421, 410, 447, 410, 440, 441, 446, 446, - 119, 415, 416, 410, 410, 410, 410, 444, - 410, 440, 441, 442, 446, 119, 415, 416, - 410, 410, 410, 145, 444, 410, 438, 410, - 477, 410, 462, 462, 119, 415, 416, 410, - 410, 410, 410, 421, 410, 438, 410, 438, - 410, 410, 410, 410, 410, 410, 415, 416, - 410, 410, 410, 410, 421, 410, 438, 410, - 438, 410, 410, 410, 410, 478, 410, 415, - 416, 410, 410, 410, 410, 421, 410, 438, - 410, 438, 410, 477, 410, 410, 410, 410, - 415, 416, 410, 410, 410, 410, 421, 410, - 438, 410, 438, 116, 410, 410, 132, 439, - 410, 415, 416, 410, 410, 410, 410, 421, - 410, 438, 410, 431, 432, 437, 437, 119, - 415, 416, 410, 410, 410, 410, 435, 410, - 431, 432, 433, 437, 119, 415, 416, 410, - 410, 410, 147, 435, 410, 429, 410, 479, - 410, 462, 462, 119, 415, 416, 410, 410, - 410, 410, 421, 410, 429, 410, 429, 410, - 410, 410, 410, 410, 410, 415, 416, 410, - 410, 410, 410, 421, 410, 429, 410, 429, - 410, 410, 410, 410, 480, 410, 415, 416, - 410, 410, 410, 410, 421, 410, 429, 410, - 429, 410, 479, 410, 410, 410, 410, 415, - 416, 410, 410, 410, 410, 421, 410, 429, - 410, 429, 116, 410, 410, 132, 430, 410, - 415, 416, 410, 410, 410, 410, 421, 410, - 429, 410, 422, 423, 428, 428, 119, 415, - 416, 410, 410, 410, 410, 426, 410, 422, - 423, 424, 428, 119, 415, 416, 410, 410, - 410, 149, 426, 410, 419, 410, 481, 410, - 462, 462, 119, 415, 416, 410, 410, 410, - 410, 421, 410, 419, 410, 419, 410, 410, - 410, 410, 410, 410, 415, 416, 410, 410, - 410, 410, 421, 410, 419, 410, 419, 410, - 410, 410, 410, 482, 410, 415, 416, 410, - 410, 410, 410, 421, 410, 419, 410, 419, - 410, 481, 410, 410, 410, 410, 415, 416, - 410, 410, 410, 410, 421, 410, 419, 410, - 419, 116, 410, 410, 132, 420, 410, 415, - 416, 410, 410, 410, 410, 421, 410, 419, - 410, 411, 412, 414, 414, 119, 415, 416, - 410, 410, 410, 410, 417, 410, 181, 182, - 183, 184, 483, 344, 81, 187, 188, 342, - 189, 189, 152, 190, 342, 181, 342, 194, - 484, 196, 197, 5, 198, 199, 200, 193, - 193, 37, 201, 193, 193, 181, 193, 204, - 182, 183, 184, 485, 486, 81, 487, 488, - 193, 189, 189, 152, 489, 193, 204, 193, - 113, 80, 80, 81, 198, 199, 193, 193, - 193, 152, 490, 193, 491, 2, 342, 342, - 342, 408, 342, 187, 188, 342, 342, 342, - 342, 347, 342, 491, 342, 492, 349, 493, - 494, 81, 487, 488, 193, 193, 193, 153, - 352, 193, 193, 491, 193, 495, 349, 354, - 354, 81, 487, 488, 193, 193, 193, 193, - 352, 193, 349, 354, 354, 81, 487, 488, - 193, 193, 193, 193, 352, 193, 496, 193, - 193, 193, 488, 193, 488, 193, 243, 193, - 492, 349, 354, 354, 81, 487, 488, 193, - 193, 193, 193, 352, 193, 492, 349, 493, - 354, 81, 487, 488, 193, 193, 193, 153, - 352, 193, 204, 193, 266, 113, 497, 497, - 155, 198, 199, 193, 193, 193, 193, 490, - 193, 204, 193, 498, 179, 499, 500, 157, - 487, 488, 193, 193, 193, 193, 501, 193, - 179, 499, 500, 157, 487, 488, 193, 193, - 193, 193, 501, 193, 499, 499, 157, 487, - 488, 193, 193, 193, 193, 501, 193, 502, - 176, 503, 504, 160, 487, 488, 193, 193, - 193, 193, 501, 193, 176, 503, 504, 160, - 487, 488, 193, 193, 193, 193, 501, 193, - 503, 503, 160, 487, 488, 193, 193, 193, - 193, 501, 193, 505, 173, 506, 507, 163, - 487, 488, 193, 193, 193, 193, 501, 193, - 173, 506, 507, 163, 487, 488, 193, 193, - 193, 193, 501, 193, 506, 506, 163, 487, - 488, 193, 193, 193, 193, 501, 193, 508, - 170, 193, 509, 193, 487, 488, 193, 193, - 193, 193, 501, 193, 170, 193, 509, 193, - 487, 488, 193, 193, 193, 193, 501, 193, - 487, 488, 193, 193, 193, 193, 501, 193, - 510, 193, 511, 512, 193, 487, 488, 193, - 193, 193, 167, 193, 193, 193, 165, 193, - 166, 193, 193, 193, 193, 487, 488, 193, - 487, 488, 193, 510, 193, 193, 193, 193, - 487, 488, 193, 510, 193, 511, 193, 193, - 487, 488, 193, 193, 193, 167, 193, 491, - 166, 342, 342, 95, 346, 342, 187, 188, - 342, 342, 342, 342, 347, 342, 491, 342, - 0 + 183, 184, 185, 186, 81, 187, 188, 189, + 190, 190, 152, 191, 192, 193, 194, 195, + 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 196, 180, 198, 199, + 200, 201, 5, 202, 203, 204, 197, 197, + 37, 205, 197, 197, 206, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 207, 197, 208, 199, 209, 209, + 5, 202, 203, 204, 197, 197, 197, 205, + 197, 197, 206, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 207, 197, 199, 209, 209, 5, 202, 203, + 204, 197, 197, 197, 205, 197, 197, 206, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 207, 197, 210, + 197, 197, 197, 18, 211, 197, 202, 203, + 204, 197, 197, 197, 212, 197, 210, 197, + 213, 214, 215, 216, 5, 202, 203, 204, + 197, 197, 35, 217, 197, 197, 206, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 207, 197, 218, 214, + 219, 219, 5, 202, 203, 204, 197, 197, + 197, 217, 197, 197, 206, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 207, 197, 214, 219, 219, 5, + 202, 203, 204, 197, 197, 197, 217, 197, + 197, 206, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 207, + 197, 220, 197, 197, 197, 18, 221, 197, + 202, 203, 204, 197, 197, 197, 212, 197, + 220, 197, 222, 223, 224, 225, 5, 202, + 203, 204, 197, 197, 33, 226, 197, 197, + 206, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 207, 197, + 227, 223, 228, 228, 5, 202, 203, 204, + 197, 197, 197, 226, 197, 197, 206, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 207, 197, 223, 228, + 228, 5, 202, 203, 204, 197, 197, 197, + 226, 197, 197, 206, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 207, 197, 229, 197, 197, 197, 18, + 230, 197, 202, 203, 204, 197, 197, 197, + 212, 197, 229, 197, 231, 232, 233, 234, + 5, 202, 203, 204, 197, 197, 31, 235, + 197, 197, 206, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 207, 197, 236, 232, 237, 237, 5, 202, + 203, 204, 197, 197, 197, 235, 197, 197, + 206, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 207, 197, + 232, 237, 237, 5, 202, 203, 204, 197, + 197, 197, 235, 197, 197, 206, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 207, 197, 238, 197, 197, + 197, 18, 239, 197, 202, 203, 204, 197, + 197, 197, 212, 197, 238, 197, 240, 241, + 242, 243, 5, 202, 203, 204, 197, 197, + 29, 244, 197, 197, 206, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 207, 197, 245, 241, 246, 246, + 5, 202, 203, 204, 197, 197, 197, 244, + 197, 197, 206, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 207, 197, 241, 246, 246, 5, 202, 203, + 204, 197, 197, 197, 244, 197, 197, 206, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 207, 197, 18, + 247, 197, 202, 203, 204, 197, 197, 197, + 212, 197, 202, 203, 204, 197, 197, 197, + 212, 197, 248, 197, 197, 249, 203, 204, + 197, 203, 204, 197, 250, 197, 203, 251, + 197, 203, 252, 197, 203, 197, 248, 197, + 197, 197, 203, 204, 197, 253, 197, 254, + 255, 197, 202, 203, 204, 197, 197, 3, + 197, 2, 197, 197, 197, 197, 202, 203, + 204, 197, 202, 203, 204, 197, 253, 197, + 197, 197, 197, 202, 203, 204, 197, 253, + 197, 254, 197, 197, 202, 203, 204, 197, + 197, 3, 197, 18, 197, 256, 256, 5, + 202, 203, 204, 197, 197, 197, 212, 197, + 257, 27, 258, 259, 8, 202, 203, 204, + 197, 197, 197, 212, 197, 27, 258, 259, + 8, 202, 203, 204, 197, 197, 197, 212, + 197, 258, 258, 8, 202, 203, 204, 197, + 197, 197, 212, 197, 260, 24, 261, 262, + 11, 202, 203, 204, 197, 197, 197, 212, + 197, 24, 261, 262, 11, 202, 203, 204, + 197, 197, 197, 212, 197, 261, 261, 11, + 202, 203, 204, 197, 197, 197, 212, 197, + 263, 21, 264, 265, 14, 202, 203, 204, + 197, 197, 197, 212, 197, 21, 264, 265, + 14, 202, 203, 204, 197, 197, 197, 212, + 197, 264, 264, 14, 202, 203, 204, 197, + 197, 197, 212, 197, 266, 18, 197, 267, + 197, 202, 203, 204, 197, 197, 197, 212, + 197, 18, 197, 267, 197, 202, 203, 204, + 197, 197, 197, 212, 197, 268, 197, 202, + 203, 204, 197, 197, 197, 212, 197, 18, + 197, 197, 197, 197, 202, 203, 204, 197, + 197, 197, 212, 197, 1, 2, 197, 197, + 18, 247, 197, 202, 203, 204, 197, 197, + 197, 212, 197, 1, 197, 241, 246, 246, + 5, 202, 203, 204, 197, 197, 197, 244, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 207, 197, 241, 246, 246, 5, 202, 203, + 204, 197, 197, 197, 244, 197, 240, 241, + 246, 246, 5, 202, 203, 204, 197, 197, + 197, 244, 197, 197, 206, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 207, 197, 240, 241, 242, 246, + 5, 202, 203, 204, 197, 197, 29, 244, + 197, 197, 206, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 207, 197, 238, 197, 269, 197, 256, 256, + 5, 202, 203, 204, 197, 197, 197, 212, + 197, 238, 197, 238, 197, 197, 197, 197, + 197, 197, 202, 203, 204, 197, 197, 197, + 212, 197, 238, 197, 238, 197, 197, 197, + 197, 270, 197, 202, 203, 204, 197, 197, + 197, 212, 197, 238, 197, 238, 197, 269, + 197, 197, 197, 197, 202, 203, 204, 197, + 197, 197, 212, 197, 238, 197, 238, 2, + 197, 197, 18, 239, 197, 202, 203, 204, + 197, 197, 197, 212, 197, 238, 197, 231, + 232, 237, 237, 5, 202, 203, 204, 197, + 197, 197, 235, 197, 197, 206, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 207, 197, 231, 232, 233, + 237, 5, 202, 203, 204, 197, 197, 31, + 235, 197, 197, 206, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 207, 197, 229, 197, 271, 197, 256, + 256, 5, 202, 203, 204, 197, 197, 197, + 212, 197, 229, 197, 229, 197, 197, 197, + 197, 197, 197, 202, 203, 204, 197, 197, + 197, 212, 197, 229, 197, 229, 197, 197, + 197, 197, 272, 197, 202, 203, 204, 197, + 197, 197, 212, 197, 229, 197, 229, 197, + 271, 197, 197, 197, 197, 202, 203, 204, + 197, 197, 197, 212, 197, 229, 197, 229, + 2, 197, 197, 18, 230, 197, 202, 203, + 204, 197, 197, 197, 212, 197, 229, 197, + 222, 223, 228, 228, 5, 202, 203, 204, + 197, 197, 197, 226, 197, 197, 206, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 207, 197, 222, 223, + 224, 228, 5, 202, 203, 204, 197, 197, + 33, 226, 197, 197, 206, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 207, 197, 220, 197, 273, 197, + 256, 256, 5, 202, 203, 204, 197, 197, + 197, 212, 197, 220, 197, 220, 197, 197, + 197, 197, 197, 197, 202, 203, 204, 197, + 197, 197, 212, 197, 220, 197, 220, 197, + 197, 197, 197, 274, 197, 202, 203, 204, + 197, 197, 197, 212, 197, 220, 197, 220, + 197, 273, 197, 197, 197, 197, 202, 203, + 204, 197, 197, 197, 212, 197, 220, 197, + 220, 2, 197, 197, 18, 221, 197, 202, + 203, 204, 197, 197, 197, 212, 197, 220, + 197, 213, 214, 219, 219, 5, 202, 203, + 204, 197, 197, 197, 217, 197, 197, 206, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 207, 197, 213, + 214, 215, 219, 5, 202, 203, 204, 197, + 197, 35, 217, 197, 197, 206, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 207, 197, 210, 197, 275, + 197, 256, 256, 5, 202, 203, 204, 197, + 197, 197, 212, 197, 210, 197, 210, 197, + 197, 197, 197, 197, 197, 202, 203, 204, + 197, 197, 197, 212, 197, 210, 197, 210, + 197, 197, 197, 197, 276, 197, 202, 203, + 204, 197, 197, 197, 212, 197, 210, 197, + 210, 197, 275, 197, 197, 197, 197, 202, + 203, 204, 197, 197, 197, 212, 197, 210, + 197, 210, 2, 197, 197, 18, 211, 197, + 202, 203, 204, 197, 197, 197, 212, 197, + 210, 197, 198, 199, 209, 209, 5, 202, + 203, 204, 197, 197, 197, 205, 197, 197, + 206, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 207, 197, + 198, 199, 200, 209, 5, 202, 203, 204, + 197, 197, 37, 205, 197, 197, 206, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 207, 197, 278, 279, + 280, 281, 43, 282, 283, 284, 277, 277, + 75, 285, 277, 277, 286, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 287, 277, 288, 279, 289, 281, + 43, 282, 283, 284, 277, 277, 277, 285, + 277, 277, 286, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 287, 277, 279, 289, 281, 43, 282, 283, + 284, 277, 277, 277, 285, 277, 277, 286, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 287, 277, 290, + 277, 277, 277, 56, 291, 277, 282, 283, + 284, 277, 277, 277, 292, 277, 290, 277, + 293, 294, 295, 296, 43, 282, 283, 284, + 277, 277, 73, 297, 277, 277, 286, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 287, 277, 298, 294, + 299, 299, 43, 282, 283, 284, 277, 277, + 277, 297, 277, 277, 286, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 287, 277, 294, 299, 299, 43, + 282, 283, 284, 277, 277, 277, 297, 277, + 277, 286, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 287, + 277, 300, 277, 277, 277, 56, 301, 277, + 282, 283, 284, 277, 277, 277, 292, 277, + 300, 277, 302, 303, 304, 305, 43, 282, + 283, 284, 277, 277, 71, 306, 277, 277, + 286, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 287, 277, + 307, 303, 308, 308, 43, 282, 283, 284, + 277, 277, 277, 306, 277, 277, 286, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 287, 277, 303, 308, + 308, 43, 282, 283, 284, 277, 277, 277, + 306, 277, 277, 286, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 287, 277, 309, 277, 277, 277, 56, + 310, 277, 282, 283, 284, 277, 277, 277, + 292, 277, 309, 277, 311, 312, 313, 314, + 43, 282, 283, 284, 277, 277, 69, 315, + 277, 277, 286, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 287, 277, 316, 312, 317, 317, 43, 282, + 283, 284, 277, 277, 277, 315, 277, 277, + 286, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 287, 277, + 312, 317, 317, 43, 282, 283, 284, 277, + 277, 277, 315, 277, 277, 286, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 287, 277, 318, 277, 277, + 277, 56, 319, 277, 282, 283, 284, 277, + 277, 277, 292, 277, 318, 277, 320, 321, + 322, 323, 43, 282, 283, 284, 277, 277, + 67, 324, 277, 277, 286, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 287, 277, 325, 321, 326, 326, + 43, 282, 283, 284, 277, 277, 277, 324, + 277, 277, 286, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 287, 277, 321, 326, 326, 43, 282, 283, + 284, 277, 277, 277, 324, 277, 277, 286, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 287, 277, 56, + 327, 277, 282, 283, 284, 277, 277, 277, + 292, 277, 282, 283, 284, 277, 277, 277, + 292, 277, 328, 277, 277, 329, 283, 284, + 277, 283, 284, 277, 330, 277, 283, 331, + 277, 283, 332, 277, 283, 277, 328, 277, + 277, 277, 283, 284, 277, 333, 277, 334, + 335, 277, 282, 283, 284, 277, 277, 41, + 277, 40, 277, 277, 277, 277, 282, 283, + 284, 277, 282, 283, 284, 277, 333, 277, + 277, 277, 277, 282, 283, 284, 277, 333, + 277, 334, 277, 277, 282, 283, 284, 277, + 277, 41, 277, 56, 277, 336, 336, 43, + 282, 283, 284, 277, 277, 277, 292, 277, + 337, 65, 338, 339, 46, 282, 283, 284, + 277, 277, 277, 292, 277, 65, 338, 339, + 46, 282, 283, 284, 277, 277, 277, 292, + 277, 338, 338, 46, 282, 283, 284, 277, + 277, 277, 292, 277, 340, 62, 341, 342, + 49, 282, 283, 284, 277, 277, 277, 292, + 277, 62, 341, 342, 49, 282, 283, 284, + 277, 277, 277, 292, 277, 341, 341, 49, + 282, 283, 284, 277, 277, 277, 292, 277, + 343, 59, 344, 345, 52, 282, 283, 284, + 277, 277, 277, 292, 277, 59, 344, 345, + 52, 282, 283, 284, 277, 277, 277, 292, + 277, 344, 344, 52, 282, 283, 284, 277, + 277, 277, 292, 277, 346, 56, 277, 347, + 277, 282, 283, 284, 277, 277, 277, 292, + 277, 56, 277, 347, 277, 282, 283, 284, + 277, 277, 277, 292, 277, 348, 277, 282, + 283, 284, 277, 277, 277, 292, 277, 56, + 277, 277, 277, 277, 282, 283, 284, 277, + 277, 277, 292, 277, 39, 40, 277, 277, + 56, 327, 277, 282, 283, 284, 277, 277, + 277, 292, 277, 39, 277, 321, 326, 326, + 43, 282, 283, 284, 277, 277, 277, 324, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 287, 277, 321, 326, 326, 43, 282, 283, + 284, 277, 277, 277, 324, 277, 320, 321, + 326, 326, 43, 282, 283, 284, 277, 277, + 277, 324, 277, 277, 286, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 287, 277, 320, 321, 322, 326, + 43, 282, 283, 284, 277, 277, 67, 324, + 277, 277, 286, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 287, 277, 318, 277, 349, 277, 336, 336, + 43, 282, 283, 284, 277, 277, 277, 292, + 277, 318, 277, 318, 277, 277, 277, 277, + 277, 277, 282, 283, 284, 277, 277, 277, + 292, 277, 318, 277, 318, 277, 277, 277, + 277, 350, 277, 282, 283, 284, 277, 277, + 277, 292, 277, 318, 277, 318, 277, 349, + 277, 277, 277, 277, 282, 283, 284, 277, + 277, 277, 292, 277, 318, 277, 318, 40, + 277, 277, 56, 319, 277, 282, 283, 284, + 277, 277, 277, 292, 277, 318, 277, 311, + 312, 317, 317, 43, 282, 283, 284, 277, + 277, 277, 315, 277, 277, 286, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 287, 277, 311, 312, 313, + 317, 43, 282, 283, 284, 277, 277, 69, + 315, 277, 277, 286, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 287, 277, 309, 277, 351, 277, 336, + 336, 43, 282, 283, 284, 277, 277, 277, + 292, 277, 309, 277, 309, 277, 277, 277, + 277, 277, 277, 282, 283, 284, 277, 277, + 277, 292, 277, 309, 277, 309, 277, 277, + 277, 277, 352, 277, 282, 283, 284, 277, + 277, 277, 292, 277, 309, 277, 309, 277, + 351, 277, 277, 277, 277, 282, 283, 284, + 277, 277, 277, 292, 277, 309, 277, 309, + 40, 277, 277, 56, 310, 277, 282, 283, + 284, 277, 277, 277, 292, 277, 309, 277, + 302, 303, 308, 308, 43, 282, 283, 284, + 277, 277, 277, 306, 277, 277, 286, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 287, 277, 302, 303, + 304, 308, 43, 282, 283, 284, 277, 277, + 71, 306, 277, 277, 286, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 287, 277, 300, 277, 353, 277, + 336, 336, 43, 282, 283, 284, 277, 277, + 277, 292, 277, 300, 277, 300, 277, 277, + 277, 277, 277, 277, 282, 283, 284, 277, + 277, 277, 292, 277, 300, 277, 300, 277, + 277, 277, 277, 354, 277, 282, 283, 284, + 277, 277, 277, 292, 277, 300, 277, 300, + 277, 353, 277, 277, 277, 277, 282, 283, + 284, 277, 277, 277, 292, 277, 300, 277, + 300, 40, 277, 277, 56, 301, 277, 282, + 283, 284, 277, 277, 277, 292, 277, 300, + 277, 293, 294, 299, 299, 43, 282, 283, + 284, 277, 277, 277, 297, 277, 277, 286, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 287, 277, 293, + 294, 295, 299, 43, 282, 283, 284, 277, + 277, 73, 297, 277, 277, 286, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 287, 277, 290, 277, 355, + 277, 336, 336, 43, 282, 283, 284, 277, + 277, 277, 292, 277, 290, 277, 290, 277, + 277, 277, 277, 277, 277, 282, 283, 284, + 277, 277, 277, 292, 277, 290, 277, 290, + 277, 277, 277, 277, 356, 277, 282, 283, + 284, 277, 277, 277, 292, 277, 290, 277, + 290, 277, 355, 277, 277, 277, 277, 282, + 283, 284, 277, 277, 277, 292, 277, 290, + 277, 74, 42, 42, 43, 277, 277, 277, + 277, 277, 277, 74, 277, 290, 40, 277, + 277, 56, 291, 277, 282, 283, 284, 277, + 277, 277, 292, 277, 290, 277, 278, 279, + 289, 281, 43, 282, 283, 284, 277, 277, + 277, 285, 277, 277, 286, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 287, 277, 358, 184, 359, 359, + 81, 187, 188, 189, 357, 357, 357, 191, + 357, 357, 194, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 196, 357, 184, 359, 359, 81, 187, 188, + 189, 357, 357, 357, 191, 357, 357, 194, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 196, 357, 360, + 357, 357, 357, 95, 361, 357, 187, 188, + 189, 357, 357, 357, 362, 357, 360, 357, + 363, 364, 365, 366, 81, 187, 188, 189, + 357, 357, 112, 367, 357, 357, 194, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 196, 357, 368, 364, + 369, 369, 81, 187, 188, 189, 357, 357, + 357, 367, 357, 357, 194, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 196, 357, 364, 369, 369, 81, + 187, 188, 189, 357, 357, 357, 367, 357, + 357, 194, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 196, + 357, 370, 357, 357, 357, 95, 371, 357, + 187, 188, 189, 357, 357, 357, 362, 357, + 370, 357, 372, 373, 374, 375, 81, 187, + 188, 189, 357, 357, 110, 376, 357, 357, + 194, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 196, 357, + 377, 373, 378, 378, 81, 187, 188, 189, + 357, 357, 357, 376, 357, 357, 194, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 196, 357, 373, 378, + 378, 81, 187, 188, 189, 357, 357, 357, + 376, 357, 357, 194, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 196, 357, 379, 357, 357, 357, 95, + 380, 357, 187, 188, 189, 357, 357, 357, + 362, 357, 379, 357, 381, 382, 383, 384, + 81, 187, 188, 189, 357, 357, 108, 385, + 357, 357, 194, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 196, 357, 386, 382, 387, 387, 81, 187, + 188, 189, 357, 357, 357, 385, 357, 357, + 194, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 196, 357, + 382, 387, 387, 81, 187, 188, 189, 357, + 357, 357, 385, 357, 357, 194, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 196, 357, 388, 357, 357, + 357, 95, 389, 357, 187, 188, 189, 357, + 357, 357, 362, 357, 388, 357, 390, 391, + 392, 393, 81, 187, 188, 189, 357, 357, + 106, 394, 357, 357, 194, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 196, 357, 395, 391, 396, 396, + 81, 187, 188, 189, 357, 357, 357, 394, + 357, 357, 194, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 196, 357, 391, 396, 396, 81, 187, 188, + 189, 357, 357, 357, 394, 357, 357, 194, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 196, 357, 95, + 397, 357, 187, 188, 189, 357, 357, 357, + 362, 357, 187, 188, 189, 357, 357, 357, + 362, 357, 398, 357, 357, 399, 188, 189, + 357, 188, 189, 357, 400, 357, 188, 401, + 357, 188, 402, 357, 188, 357, 398, 357, + 357, 357, 188, 189, 357, 403, 357, 404, + 405, 357, 187, 188, 189, 357, 357, 79, + 357, 78, 357, 357, 357, 357, 187, 188, + 189, 357, 187, 188, 189, 357, 403, 357, + 357, 357, 357, 187, 188, 189, 357, 403, + 357, 404, 357, 357, 187, 188, 189, 357, + 357, 79, 357, 95, 357, 406, 406, 81, + 187, 188, 189, 357, 357, 357, 362, 357, + 407, 104, 408, 409, 85, 187, 188, 189, + 357, 357, 357, 362, 357, 104, 408, 409, + 85, 187, 188, 189, 357, 357, 357, 362, + 357, 408, 408, 85, 187, 188, 189, 357, + 357, 357, 362, 357, 410, 101, 411, 412, + 88, 187, 188, 189, 357, 357, 357, 362, + 357, 101, 411, 412, 88, 187, 188, 189, + 357, 357, 357, 362, 357, 411, 411, 88, + 187, 188, 189, 357, 357, 357, 362, 357, + 413, 98, 414, 415, 91, 187, 188, 189, + 357, 357, 357, 362, 357, 98, 414, 415, + 91, 187, 188, 189, 357, 357, 357, 362, + 357, 414, 414, 91, 187, 188, 189, 357, + 357, 357, 362, 357, 416, 95, 357, 417, + 357, 187, 188, 189, 357, 357, 357, 362, + 357, 95, 357, 417, 357, 187, 188, 189, + 357, 357, 357, 362, 357, 418, 357, 187, + 188, 189, 357, 357, 357, 362, 357, 95, + 357, 357, 357, 357, 187, 188, 189, 357, + 357, 357, 362, 357, 77, 78, 357, 357, + 95, 397, 357, 187, 188, 189, 357, 357, + 357, 362, 357, 77, 357, 391, 396, 396, + 81, 187, 188, 189, 357, 357, 357, 394, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 196, 357, 391, 396, 396, 81, 187, 188, + 189, 357, 357, 357, 394, 357, 390, 391, + 396, 396, 81, 187, 188, 189, 357, 357, + 357, 394, 357, 357, 194, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 196, 357, 390, 391, 392, 396, + 81, 187, 188, 189, 357, 357, 106, 394, + 357, 357, 194, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 196, 357, 388, 357, 419, 357, 406, 406, + 81, 187, 188, 189, 357, 357, 357, 362, + 357, 388, 357, 388, 357, 357, 357, 357, + 357, 357, 187, 188, 189, 357, 357, 357, + 362, 357, 388, 357, 388, 357, 357, 357, + 357, 420, 357, 187, 188, 189, 357, 357, + 357, 362, 357, 388, 357, 388, 357, 419, + 357, 357, 357, 357, 187, 188, 189, 357, + 357, 357, 362, 357, 388, 357, 388, 78, + 357, 357, 95, 389, 357, 187, 188, 189, + 357, 357, 357, 362, 357, 388, 357, 381, + 382, 387, 387, 81, 187, 188, 189, 357, + 357, 357, 385, 357, 357, 194, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 196, 357, 381, 382, 383, + 387, 81, 187, 188, 189, 357, 357, 108, + 385, 357, 357, 194, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 196, 357, 379, 357, 421, 357, 406, + 406, 81, 187, 188, 189, 357, 357, 357, + 362, 357, 379, 357, 379, 357, 357, 357, + 357, 357, 357, 187, 188, 189, 357, 357, + 357, 362, 357, 379, 357, 379, 357, 357, + 357, 357, 422, 357, 187, 188, 189, 357, + 357, 357, 362, 357, 379, 357, 379, 357, + 421, 357, 357, 357, 357, 187, 188, 189, + 357, 357, 357, 362, 357, 379, 357, 379, + 78, 357, 357, 95, 380, 357, 187, 188, + 189, 357, 357, 357, 362, 357, 379, 357, + 372, 373, 378, 378, 81, 187, 188, 189, + 357, 357, 357, 376, 357, 357, 194, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 196, 357, 372, 373, + 374, 378, 81, 187, 188, 189, 357, 357, + 110, 376, 357, 357, 194, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 196, 357, 370, 357, 423, 357, + 406, 406, 81, 187, 188, 189, 357, 357, + 357, 362, 357, 370, 357, 370, 357, 357, + 357, 357, 357, 357, 187, 188, 189, 357, + 357, 357, 362, 357, 370, 357, 370, 357, + 357, 357, 357, 424, 357, 187, 188, 189, + 357, 357, 357, 362, 357, 370, 357, 370, + 357, 423, 357, 357, 357, 357, 187, 188, + 189, 357, 357, 357, 362, 357, 370, 357, + 370, 78, 357, 357, 95, 371, 357, 187, + 188, 189, 357, 357, 357, 362, 357, 370, + 357, 363, 364, 369, 369, 81, 187, 188, + 189, 357, 357, 357, 367, 357, 357, 194, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 196, 357, 363, + 364, 365, 369, 81, 187, 188, 189, 357, + 357, 112, 367, 357, 357, 194, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 196, 357, 360, 357, 425, + 357, 406, 406, 81, 187, 188, 189, 357, + 357, 357, 362, 357, 360, 357, 360, 357, + 357, 357, 357, 357, 357, 187, 188, 189, + 357, 357, 357, 362, 357, 360, 357, 360, + 357, 357, 357, 357, 426, 357, 187, 188, + 189, 357, 357, 357, 362, 357, 360, 357, + 360, 357, 425, 357, 357, 357, 357, 187, + 188, 189, 357, 357, 357, 362, 357, 360, + 357, 360, 78, 357, 357, 95, 361, 357, + 187, 188, 189, 357, 357, 357, 362, 357, + 360, 357, 113, 80, 80, 81, 427, 427, + 427, 427, 427, 152, 113, 427, 183, 184, + 359, 359, 81, 187, 188, 189, 357, 357, + 357, 191, 357, 357, 194, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 196, 357, 113, 80, 80, 81, + 427, 427, 427, 427, 427, 427, 113, 427, + 429, 430, 431, 432, 119, 433, 434, 435, + 428, 428, 151, 436, 428, 428, 437, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 438, 428, 439, 430, + 432, 432, 119, 433, 434, 435, 428, 428, + 428, 436, 428, 428, 437, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 438, 428, 430, 432, 432, 119, + 433, 434, 435, 428, 428, 428, 436, 428, + 428, 437, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 438, + 428, 440, 428, 428, 428, 132, 441, 428, + 433, 434, 435, 428, 428, 428, 442, 428, + 440, 428, 443, 444, 445, 446, 119, 433, + 434, 435, 428, 428, 149, 447, 428, 428, + 437, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 438, 428, + 448, 444, 449, 449, 119, 433, 434, 435, + 428, 428, 428, 447, 428, 428, 437, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 438, 428, 444, 449, + 449, 119, 433, 434, 435, 428, 428, 428, + 447, 428, 428, 437, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 438, 428, 450, 428, 428, 428, 132, + 451, 428, 433, 434, 435, 428, 428, 428, + 442, 428, 450, 428, 452, 453, 454, 455, + 119, 433, 434, 435, 428, 428, 147, 456, + 428, 428, 437, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 438, 428, 457, 453, 458, 458, 119, 433, + 434, 435, 428, 428, 428, 456, 428, 428, + 437, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 438, 428, + 453, 458, 458, 119, 433, 434, 435, 428, + 428, 428, 456, 428, 428, 437, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 438, 428, 459, 428, 428, + 428, 132, 460, 428, 433, 434, 435, 428, + 428, 428, 442, 428, 459, 428, 461, 462, + 463, 464, 119, 433, 434, 435, 428, 428, + 145, 465, 428, 428, 437, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 438, 428, 466, 462, 467, 467, + 119, 433, 434, 435, 428, 428, 428, 465, + 428, 428, 437, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 438, 428, 462, 467, 467, 119, 433, 434, + 435, 428, 428, 428, 465, 428, 428, 437, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 438, 428, 468, + 428, 428, 428, 132, 469, 428, 433, 434, + 435, 428, 428, 428, 442, 428, 468, 428, + 470, 471, 472, 473, 119, 433, 434, 435, + 428, 428, 143, 474, 428, 428, 437, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 438, 428, 475, 471, + 476, 476, 119, 433, 434, 435, 428, 428, + 428, 474, 428, 428, 437, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 438, 428, 471, 476, 476, 119, + 433, 434, 435, 428, 428, 428, 474, 428, + 428, 437, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 438, + 428, 132, 477, 428, 433, 434, 435, 428, + 428, 428, 442, 428, 433, 434, 435, 428, + 428, 428, 442, 428, 478, 428, 428, 479, + 434, 435, 428, 434, 435, 428, 480, 428, + 434, 481, 428, 434, 482, 428, 434, 428, + 478, 428, 428, 428, 434, 435, 428, 483, + 428, 484, 485, 428, 433, 434, 435, 428, + 428, 117, 428, 116, 428, 428, 428, 428, + 433, 434, 435, 428, 433, 434, 435, 428, + 483, 428, 428, 428, 428, 433, 434, 435, + 428, 483, 428, 484, 428, 428, 433, 434, + 435, 428, 428, 117, 428, 132, 428, 486, + 486, 119, 433, 434, 435, 428, 428, 428, + 442, 428, 487, 141, 488, 489, 122, 433, + 434, 435, 428, 428, 428, 442, 428, 141, + 488, 489, 122, 433, 434, 435, 428, 428, + 428, 442, 428, 488, 488, 122, 433, 434, + 435, 428, 428, 428, 442, 428, 490, 138, + 491, 492, 125, 433, 434, 435, 428, 428, + 428, 442, 428, 138, 491, 492, 125, 433, + 434, 435, 428, 428, 428, 442, 428, 491, + 491, 125, 433, 434, 435, 428, 428, 428, + 442, 428, 493, 135, 494, 495, 128, 433, + 434, 435, 428, 428, 428, 442, 428, 135, + 494, 495, 128, 433, 434, 435, 428, 428, + 428, 442, 428, 494, 494, 128, 433, 434, + 435, 428, 428, 428, 442, 428, 496, 132, + 428, 497, 428, 433, 434, 435, 428, 428, + 428, 442, 428, 132, 428, 497, 428, 433, + 434, 435, 428, 428, 428, 442, 428, 498, + 428, 433, 434, 435, 428, 428, 428, 442, + 428, 132, 428, 428, 428, 428, 433, 434, + 435, 428, 428, 428, 442, 428, 115, 116, + 428, 428, 132, 477, 428, 433, 434, 435, + 428, 428, 428, 442, 428, 115, 428, 471, + 476, 476, 119, 433, 434, 435, 428, 428, + 428, 474, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 438, 428, 471, 476, 476, 119, + 433, 434, 435, 428, 428, 428, 474, 428, + 470, 471, 476, 476, 119, 433, 434, 435, + 428, 428, 428, 474, 428, 428, 437, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 438, 428, 470, 471, + 472, 476, 119, 433, 434, 435, 428, 428, + 143, 474, 428, 428, 437, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 438, 428, 468, 428, 499, 428, + 486, 486, 119, 433, 434, 435, 428, 428, + 428, 442, 428, 468, 428, 468, 428, 428, + 428, 428, 428, 428, 433, 434, 435, 428, + 428, 428, 442, 428, 468, 428, 468, 428, + 428, 428, 428, 500, 428, 433, 434, 435, + 428, 428, 428, 442, 428, 468, 428, 468, + 428, 499, 428, 428, 428, 428, 433, 434, + 435, 428, 428, 428, 442, 428, 468, 428, + 468, 116, 428, 428, 132, 469, 428, 433, + 434, 435, 428, 428, 428, 442, 428, 468, + 428, 461, 462, 467, 467, 119, 433, 434, + 435, 428, 428, 428, 465, 428, 428, 437, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 438, 428, 461, + 462, 463, 467, 119, 433, 434, 435, 428, + 428, 145, 465, 428, 428, 437, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 438, 428, 459, 428, 501, + 428, 486, 486, 119, 433, 434, 435, 428, + 428, 428, 442, 428, 459, 428, 459, 428, + 428, 428, 428, 428, 428, 433, 434, 435, + 428, 428, 428, 442, 428, 459, 428, 459, + 428, 428, 428, 428, 502, 428, 433, 434, + 435, 428, 428, 428, 442, 428, 459, 428, + 459, 428, 501, 428, 428, 428, 428, 433, + 434, 435, 428, 428, 428, 442, 428, 459, + 428, 459, 116, 428, 428, 132, 460, 428, + 433, 434, 435, 428, 428, 428, 442, 428, + 459, 428, 452, 453, 458, 458, 119, 433, + 434, 435, 428, 428, 428, 456, 428, 428, + 437, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 438, 428, + 452, 453, 454, 458, 119, 433, 434, 435, + 428, 428, 147, 456, 428, 428, 437, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 438, 428, 450, 428, + 503, 428, 486, 486, 119, 433, 434, 435, + 428, 428, 428, 442, 428, 450, 428, 450, + 428, 428, 428, 428, 428, 428, 433, 434, + 435, 428, 428, 428, 442, 428, 450, 428, + 450, 428, 428, 428, 428, 504, 428, 433, + 434, 435, 428, 428, 428, 442, 428, 450, + 428, 450, 428, 503, 428, 428, 428, 428, + 433, 434, 435, 428, 428, 428, 442, 428, + 450, 428, 450, 116, 428, 428, 132, 451, + 428, 433, 434, 435, 428, 428, 428, 442, + 428, 450, 428, 443, 444, 449, 449, 119, + 433, 434, 435, 428, 428, 428, 447, 428, + 428, 437, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 438, + 428, 443, 444, 445, 449, 119, 433, 434, + 435, 428, 428, 149, 447, 428, 428, 437, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 438, 428, 440, + 428, 505, 428, 486, 486, 119, 433, 434, + 435, 428, 428, 428, 442, 428, 440, 428, + 440, 428, 428, 428, 428, 428, 428, 433, + 434, 435, 428, 428, 428, 442, 428, 440, + 428, 440, 428, 428, 428, 428, 506, 428, + 433, 434, 435, 428, 428, 428, 442, 428, + 440, 428, 440, 428, 505, 428, 428, 428, + 428, 433, 434, 435, 428, 428, 428, 442, + 428, 440, 428, 440, 116, 428, 428, 132, + 441, 428, 433, 434, 435, 428, 428, 428, + 442, 428, 440, 428, 429, 430, 432, 432, + 119, 433, 434, 435, 428, 428, 428, 436, + 428, 428, 437, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 438, 428, 181, 182, 183, 184, 507, 359, + 81, 187, 188, 189, 190, 190, 152, 191, + 357, 181, 194, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 196, 357, 198, 508, 200, 201, 5, 202, + 203, 204, 197, 197, 37, 205, 197, 197, + 206, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 207, 197, + 210, 182, 183, 184, 509, 510, 81, 511, + 512, 513, 197, 190, 152, 514, 197, 210, + 194, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 196, 197, + 113, 80, 80, 81, 202, 203, 204, 197, + 197, 152, 515, 197, 516, 2, 357, 357, + 357, 426, 357, 187, 188, 189, 357, 357, + 357, 362, 357, 516, 357, 517, 364, 518, + 519, 81, 511, 512, 513, 197, 197, 153, + 367, 197, 197, 194, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 196, 197, 520, 364, 369, 369, 81, + 511, 512, 513, 197, 197, 197, 367, 197, + 197, 194, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 196, + 197, 364, 369, 369, 81, 511, 512, 513, + 197, 197, 197, 367, 197, 197, 194, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 196, 197, 521, 197, + 197, 522, 512, 513, 197, 512, 513, 197, + 250, 197, 512, 523, 197, 512, 524, 197, + 512, 197, 521, 197, 197, 197, 512, 513, + 197, 517, 364, 369, 369, 81, 511, 512, + 513, 197, 197, 197, 367, 197, 197, 194, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 196, 197, 517, + 364, 518, 369, 81, 511, 512, 513, 197, + 197, 153, 367, 197, 197, 194, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 196, 197, 210, 197, 275, + 113, 525, 525, 155, 202, 203, 204, 197, + 197, 197, 515, 197, 210, 197, 526, 179, + 527, 528, 157, 511, 512, 513, 197, 197, + 197, 529, 197, 179, 527, 528, 157, 511, + 512, 513, 197, 197, 197, 529, 197, 527, + 527, 157, 511, 512, 513, 197, 197, 197, + 529, 197, 530, 176, 531, 532, 160, 511, + 512, 513, 197, 197, 197, 529, 197, 176, + 531, 532, 160, 511, 512, 513, 197, 197, + 197, 529, 197, 531, 531, 160, 511, 512, + 513, 197, 197, 197, 529, 197, 533, 173, + 534, 535, 163, 511, 512, 513, 197, 197, + 197, 529, 197, 173, 534, 535, 163, 511, + 512, 513, 197, 197, 197, 529, 197, 534, + 534, 163, 511, 512, 513, 197, 197, 197, + 529, 197, 536, 170, 197, 537, 197, 511, + 512, 513, 197, 197, 197, 529, 197, 170, + 197, 537, 197, 511, 512, 513, 197, 197, + 197, 529, 197, 511, 512, 513, 197, 197, + 197, 529, 197, 538, 197, 539, 540, 197, + 511, 512, 513, 197, 197, 167, 197, 166, + 197, 197, 197, 197, 511, 512, 513, 197, + 511, 512, 513, 197, 538, 197, 197, 197, + 197, 511, 512, 513, 197, 538, 197, 539, + 197, 197, 511, 512, 513, 197, 197, 167, + 197, 516, 166, 357, 357, 95, 361, 357, + 187, 188, 189, 357, 357, 357, 362, 357, + 516, 357, 542, 541, 541, 541, 541, 543, + 544, 545, 541, 543, 544, 545, 541, 546, + 541, 541, 547, 544, 545, 541, 544, 545, + 541, 548, 541, 544, 549, 541, 544, 550, + 541, 544, 541, 546, 541, 541, 541, 544, + 545, 541, 0 }; static const short _indic_syllable_machine_trans_targs[] = { - 170, 195, 197, 198, 3, 201, 4, 6, - 204, 7, 9, 207, 10, 12, 210, 13, - 15, 16, 191, 18, 19, 209, 21, 22, - 206, 24, 25, 203, 212, 216, 220, 223, - 227, 230, 234, 237, 241, 244, 170, 270, - 272, 273, 39, 276, 40, 42, 279, 43, - 45, 282, 46, 48, 285, 49, 51, 52, - 266, 54, 55, 284, 57, 58, 281, 60, - 61, 278, 287, 290, 294, 297, 301, 304, - 308, 311, 315, 319, 170, 343, 345, 346, - 75, 349, 170, 76, 78, 352, 79, 81, - 355, 82, 84, 358, 85, 87, 88, 339, - 90, 91, 357, 93, 94, 354, 96, 97, - 351, 360, 363, 367, 370, 374, 377, 381, - 384, 388, 170, 418, 420, 421, 110, 424, - 111, 113, 427, 114, 116, 430, 117, 119, - 433, 120, 122, 123, 414, 125, 126, 432, - 128, 129, 429, 131, 132, 426, 435, 438, - 442, 445, 449, 452, 456, 459, 463, 466, - 392, 478, 146, 481, 148, 484, 149, 151, - 487, 152, 154, 490, 155, 493, 495, 496, - 159, 160, 492, 162, 163, 489, 165, 166, - 486, 168, 169, 483, 170, 171, 246, 320, - 322, 391, 393, 340, 342, 394, 390, 467, - 468, 170, 172, 174, 35, 245, 192, 194, - 214, 243, 173, 34, 175, 239, 0, 176, - 178, 33, 238, 236, 177, 32, 179, 232, - 180, 182, 31, 231, 229, 181, 30, 183, - 225, 184, 186, 29, 224, 222, 185, 28, - 187, 218, 188, 190, 27, 217, 215, 189, - 26, 200, 193, 170, 196, 1, 199, 2, - 202, 5, 23, 205, 8, 20, 208, 11, - 17, 211, 14, 213, 219, 221, 226, 228, - 233, 235, 240, 242, 170, 247, 249, 71, - 317, 267, 269, 318, 248, 70, 250, 313, - 36, 251, 253, 69, 312, 310, 252, 68, - 254, 306, 255, 257, 67, 305, 303, 256, - 66, 258, 299, 259, 261, 65, 298, 296, - 260, 64, 262, 292, 263, 265, 63, 291, - 289, 264, 62, 275, 268, 170, 271, 37, - 274, 38, 277, 41, 59, 280, 44, 56, - 283, 47, 53, 286, 50, 288, 293, 295, - 300, 302, 307, 309, 314, 316, 170, 321, - 106, 323, 386, 72, 324, 326, 105, 385, - 383, 325, 104, 327, 379, 328, 330, 103, - 378, 376, 329, 102, 331, 372, 332, 334, - 101, 371, 369, 333, 100, 335, 365, 336, - 338, 99, 364, 362, 337, 98, 348, 341, - 170, 344, 73, 347, 74, 350, 77, 95, - 353, 80, 92, 356, 83, 89, 359, 86, - 361, 366, 368, 373, 375, 380, 382, 387, - 389, 170, 170, 395, 397, 142, 141, 415, - 417, 465, 396, 398, 461, 107, 399, 401, - 140, 460, 458, 400, 139, 402, 454, 403, - 405, 138, 453, 451, 404, 137, 406, 447, - 407, 409, 136, 446, 444, 408, 135, 410, - 440, 411, 413, 134, 439, 437, 412, 133, - 423, 416, 170, 419, 108, 422, 109, 425, - 112, 130, 428, 115, 127, 431, 118, 124, - 434, 121, 436, 441, 443, 448, 450, 455, - 457, 462, 464, 143, 469, 470, 480, 475, - 477, 498, 471, 472, 473, 144, 479, 474, - 476, 145, 482, 147, 167, 156, 485, 150, - 164, 488, 153, 161, 491, 158, 494, 157, - 497 + 170, 199, 201, 202, 3, 205, 4, 6, + 208, 7, 9, 211, 10, 12, 214, 13, + 15, 16, 191, 18, 19, 213, 21, 22, + 210, 24, 25, 207, 216, 221, 225, 228, + 232, 235, 239, 242, 246, 249, 170, 279, + 281, 282, 39, 285, 40, 42, 288, 43, + 45, 291, 46, 48, 294, 49, 51, 52, + 271, 54, 55, 293, 57, 58, 290, 60, + 61, 287, 296, 301, 305, 308, 312, 315, + 319, 322, 326, 330, 170, 358, 360, 361, + 75, 364, 170, 76, 78, 367, 79, 81, + 370, 82, 84, 373, 85, 87, 88, 350, + 90, 91, 372, 93, 94, 369, 96, 97, + 366, 375, 380, 384, 387, 391, 394, 398, + 401, 405, 170, 439, 441, 442, 110, 445, + 111, 113, 448, 114, 116, 451, 117, 119, + 454, 120, 122, 123, 431, 125, 126, 453, + 128, 129, 450, 131, 132, 447, 456, 461, + 465, 468, 472, 475, 479, 482, 486, 489, + 409, 505, 146, 508, 148, 511, 149, 151, + 514, 152, 154, 517, 155, 520, 522, 523, + 159, 160, 519, 162, 163, 516, 165, 166, + 513, 168, 169, 510, 170, 171, 251, 331, + 333, 408, 410, 351, 353, 354, 411, 407, + 490, 491, 378, 526, 379, 170, 172, 174, + 35, 250, 192, 194, 195, 248, 219, 220, + 173, 34, 175, 244, 0, 176, 178, 33, + 243, 241, 177, 32, 179, 237, 180, 182, + 31, 236, 234, 181, 30, 183, 230, 184, + 186, 29, 229, 227, 185, 28, 187, 223, + 188, 190, 27, 222, 218, 189, 26, 204, + 193, 198, 170, 196, 197, 200, 1, 203, + 2, 206, 5, 23, 209, 8, 20, 212, + 11, 17, 215, 14, 217, 224, 226, 231, + 233, 238, 240, 245, 247, 170, 252, 254, + 71, 328, 272, 274, 275, 329, 299, 300, + 253, 70, 255, 324, 36, 256, 258, 69, + 323, 321, 257, 68, 259, 317, 260, 262, + 67, 316, 314, 261, 66, 263, 310, 264, + 266, 65, 309, 307, 265, 64, 267, 303, + 268, 270, 63, 302, 298, 269, 62, 284, + 273, 278, 170, 276, 277, 280, 37, 283, + 38, 286, 41, 59, 289, 44, 56, 292, + 47, 53, 295, 50, 297, 304, 306, 311, + 313, 318, 320, 325, 327, 170, 332, 106, + 334, 403, 72, 335, 337, 105, 402, 400, + 336, 104, 338, 396, 339, 341, 103, 395, + 393, 340, 102, 342, 389, 343, 345, 101, + 388, 386, 344, 100, 346, 382, 347, 349, + 99, 381, 377, 348, 98, 363, 352, 357, + 170, 355, 356, 359, 73, 362, 74, 365, + 77, 95, 368, 80, 92, 371, 83, 89, + 374, 86, 376, 383, 385, 390, 392, 397, + 399, 404, 406, 170, 170, 412, 414, 142, + 141, 432, 434, 435, 488, 459, 460, 413, + 415, 484, 107, 416, 418, 140, 483, 481, + 417, 139, 419, 477, 420, 422, 138, 476, + 474, 421, 137, 423, 470, 424, 426, 136, + 469, 467, 425, 135, 427, 463, 428, 430, + 134, 462, 458, 429, 133, 444, 433, 438, + 170, 436, 437, 440, 108, 443, 109, 446, + 112, 130, 449, 115, 127, 452, 118, 124, + 455, 121, 457, 464, 466, 471, 473, 478, + 480, 485, 487, 143, 492, 493, 507, 498, + 500, 501, 525, 494, 495, 496, 144, 506, + 497, 499, 504, 502, 503, 145, 509, 147, + 167, 156, 512, 150, 164, 515, 153, 161, + 518, 158, 521, 157, 524, 170, 527, 528, + 530, 531, 529, 534, 170, 532, 533 }; static const char _indic_syllable_machine_trans_actions[] = { @@ -996,48 +1261,52 @@ static const char _indic_syllable_machine_trans_actions[] = { 2, 0, 0, 2, 0, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 11, 2, 2, 6, - 2, 12, 12, 0, 0, 2, 2, 6, - 2, 13, 2, 2, 0, 2, 0, 0, - 2, 2, 2, 0, 2, 2, 0, 2, + 2, 12, 12, 0, 0, 0, 2, 2, + 6, 2, 6, 0, 6, 13, 2, 2, + 0, 2, 0, 0, 0, 2, 2, 2, + 2, 0, 2, 2, 0, 2, 2, 0, + 2, 2, 2, 0, 2, 2, 2, 2, + 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, - 2, 2, 2, 0, 2, 2, 2, 0, - 2, 2, 2, 2, 0, 2, 2, 2, - 0, 2, 0, 14, 0, 0, 2, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 2, 0, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 15, 2, 2, 0, - 2, 0, 0, 2, 2, 0, 2, 2, - 0, 2, 2, 0, 2, 2, 2, 0, - 2, 2, 2, 2, 0, 2, 2, 2, - 0, 2, 2, 2, 2, 0, 2, 2, - 2, 0, 2, 2, 2, 2, 0, 2, - 2, 2, 0, 2, 0, 16, 0, 0, - 2, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 0, 2, 0, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 17, 6, - 0, 6, 6, 0, 6, 2, 0, 6, - 2, 6, 0, 6, 6, 6, 2, 0, - 6, 2, 6, 0, 6, 6, 6, 2, - 0, 6, 2, 6, 0, 6, 6, 6, - 2, 0, 6, 2, 6, 0, 6, 0, - 18, 0, 0, 2, 0, 2, 0, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 19, 20, 2, 2, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, + 0, 0, 14, 0, 0, 0, 0, 2, + 0, 2, 0, 0, 2, 0, 0, 2, + 0, 0, 2, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 15, 2, 2, + 0, 2, 0, 0, 0, 2, 2, 2, + 2, 0, 2, 2, 0, 2, 2, 0, + 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, - 2, 2, 2, 0, 2, 2, 2, 0, - 2, 0, 21, 0, 0, 2, 0, 2, + 0, 0, 16, 0, 0, 0, 0, 2, + 0, 2, 0, 0, 2, 0, 0, 2, + 0, 0, 2, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 17, 6, 0, + 6, 6, 0, 6, 2, 0, 6, 2, + 6, 0, 6, 6, 6, 2, 0, 6, + 2, 6, 0, 6, 6, 6, 2, 0, + 6, 2, 6, 0, 6, 6, 6, 2, + 0, 6, 2, 6, 0, 6, 0, 0, + 18, 0, 0, 0, 0, 2, 0, 2, + 0, 0, 2, 0, 0, 2, 0, 0, + 2, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 19, 20, 2, 2, 0, + 0, 0, 0, 0, 2, 2, 2, 2, + 2, 2, 0, 2, 2, 0, 2, 2, + 2, 0, 2, 2, 2, 2, 0, 2, + 2, 2, 0, 2, 2, 2, 2, 0, + 2, 2, 2, 0, 2, 2, 2, 2, + 0, 2, 2, 2, 0, 2, 0, 0, + 21, 0, 0, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 8, 2, 0, - 0, 2, 2, 8, 8, 0, 8, 8, - 0, 0, 2, 0, 0, 0, 2, 0, - 0, 2, 0, 0, 2, 0, 0, 0, - 2 + 0, 0, 2, 2, 8, 8, 0, 8, + 8, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 2, 0, 0, + 2, 0, 0, 0, 2, 22, 0, 0, + 0, 0, 0, 0, 23, 0, 0 }; static const char _indic_syllable_machine_to_state_actions[] = { @@ -1103,7 +1372,11 @@ static const char _indic_syllable_machine_to_state_actions[] = { 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }; static const char _indic_syllable_machine_from_state_actions[] = { @@ -1169,7 +1442,11 @@ static const char _indic_syllable_machine_from_state_actions[] = { 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }; static const short _indic_syllable_machine_eof_trans[] = { @@ -1194,48 +1471,52 @@ static const short _indic_syllable_machine_eof_trans[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 410, - 343, 410, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 411, 411, 411, 411, 411, - 411, 411, 411, 343, 194, 194, 194, 343, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 343 + 1, 1, 0, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 428, 358, 428, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 358, 198, 198, 198, 358, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 358, 542, 542, + 542, 542, 542, 542, 542, 542, 542 }; static const int indic_syllable_machine_start = 170; @@ -1249,7 +1530,7 @@ static const int indic_syllable_machine_en_main = 170; -#line 91 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 97 "../../src/hb-ot-shape-complex-indic-machine.rl" #define found_syllable(syllable_type) \ @@ -1265,11 +1546,11 @@ static const int indic_syllable_machine_en_main = 170; static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te, act; + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; -#line 1273 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" +#line 1554 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" { cs = indic_syllable_machine_start; ts = 0; @@ -1277,7 +1558,7 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 112 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 118 "../../src/hb-ot-shape-complex-indic-machine.rl" p = 0; @@ -1286,7 +1567,7 @@ find_syllables (hb_buffer_t *buffer) unsigned int last = 0; unsigned int syllable_serial = 1; -#line 1290 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" +#line 1571 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" { int _slen; int _trans; @@ -1300,7 +1581,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 1304 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" +#line 1585 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -1323,59 +1604,67 @@ _eof_trans: {te = p+1;} break; case 14: -#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 88 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (consonant_syllable); }} break; case 16: -#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 89 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (vowel_syllable); }} break; case 21: -#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 90 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (standalone_cluster); }} break; + case 23: +#line 91 "../../src/hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ found_syllable (symbol_cluster); }} + break; case 18: -#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 92 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; case 11: -#line 87 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 93 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (non_indic_cluster); }} break; case 13: -#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 88 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (consonant_syllable); }} break; case 15: -#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 89 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (vowel_syllable); }} break; case 20: -#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 90 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (standalone_cluster); }} break; + case 22: +#line 91 "../../src/hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (symbol_cluster); }} + break; case 17: -#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 92 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; case 19: -#line 87 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 93 "../../src/hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (non_indic_cluster); }} break; case 1: -#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 88 "../../src/hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} break; case 3: -#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 89 "../../src/hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (vowel_syllable); }} break; case 7: -#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 90 "../../src/hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (standalone_cluster); }} break; case 4: -#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 92 "../../src/hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; case 5: @@ -1384,10 +1673,10 @@ _eof_trans: case 1: {{p = ((te))-1;} found_syllable (consonant_syllable); } break; - case 4: + case 5: {{p = ((te))-1;} found_syllable (broken_cluster); } break; - case 5: + case 6: {{p = ((te))-1;} found_syllable (non_indic_cluster); } break; } @@ -1396,22 +1685,22 @@ _eof_trans: case 8: #line 1 "NONE" {te = p+1;} -#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 88 "../../src/hb-ot-shape-complex-indic-machine.rl" {act = 1;} break; case 6: #line 1 "NONE" {te = p+1;} -#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl" - {act = 4;} +#line 92 "../../src/hb-ot-shape-complex-indic-machine.rl" + {act = 5;} break; case 12: #line 1 "NONE" {te = p+1;} -#line 87 "../../src/hb-ot-shape-complex-indic-machine.rl" - {act = 5;} +#line 93 "../../src/hb-ot-shape-complex-indic-machine.rl" + {act = 6;} break; -#line 1415 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" +#line 1704 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" } _again: @@ -1420,7 +1709,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1424 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" +#line 1713 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp" } if ( ++p != pe ) @@ -1436,7 +1725,7 @@ _again: } -#line 121 "../../src/hb-ot-shape-complex-indic-machine.rl" +#line 127 "../../src/hb-ot-shape-complex-indic-machine.rl" } diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl index 11115c9..f6768a5 100644 --- a/src/hb-ot-shape-complex-indic-machine.rl +++ b/src/hb-ot-shape-complex-indic-machine.rl @@ -49,15 +49,17 @@ M = 7; SM = 8; VD = 9; A = 10; -NBSP = 11; +PLACEHOLDER = 11; DOTTEDCIRCLE = 12; -RS = 13; +RS = 13; Coeng = 14; Repha = 15; Ra = 16; CM = 17; +Symbol= 18; +CM2 = 31; -c = (C | Ra)CM*; # is_consonant +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 @@ -65,24 +67,28 @@ 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 = (Coeng (cn|V))? (SM.ZWNJ?)? (VD VD?)?; -place_holder = NBSP | DOTTEDCIRCLE; +syllable_tail = (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; -halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}); +medial_group = CM?.CM2?; +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 A? halant_or_matra_group? syllable_tail; -vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} halant_or_matra_group? syllable_tail); -standalone_cluster = reph? place_holder.n? (halant_group.cn){0,4} halant_or_matra_group? syllable_tail; -broken_cluster = reph? n? (halant_group.cn){0,4} halant_or_matra_group syllable_tail; +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); }; *|; @@ -103,7 +109,7 @@ main := |* static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te, act; + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; %%{ diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh index e36090e..d8dfc65 100644 --- a/src/hb-ot-shape-complex-indic-private.hh +++ b/src/hb-ot-shape-complex-indic-private.hh @@ -34,11 +34,6 @@ #include "hb-ot-shape-private.hh" /* XXX Remove */ -/* buffer var allocations */ -#define indic_category() complex_var_u8_0() /* indic_category_t */ -#define indic_position() complex_var_u8_1() /* indic_matra_category_t */ - - #define INDIC_TABLE_ELEMENT_TYPE uint16_t /* Cateories used in the OpenType spec: @@ -48,25 +43,39 @@ * Not sure how to avoid duplication. */ enum indic_category_t { OT_X = 0, - OT_C, - OT_V, - OT_N, - OT_H, - OT_ZWNJ, - OT_ZWJ, - OT_M, - OT_SM, - OT_VD, - OT_A, - OT_NBSP, - OT_DOTTEDCIRCLE, /* Not in the spec, but special in Uniscribe. /Very very/ special! */ - OT_RS, /* Register Shifter, used in Khmer OT spec */ - OT_Coeng, - OT_Repha, - OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */ - OT_CM + 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). */ + OT_CM2 = 31 /* Consonant-Medial, second slot. */ }; +#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2)) + +/* 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, @@ -96,293 +105,78 @@ enum indic_position_t { /* Categories used in IndicSyllabicCategory.txt from UCD. */ enum indic_syllabic_category_t { - INDIC_SYLLABIC_CATEGORY_OTHER = OT_X, - - INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_X, - INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM, - INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM, - INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP, - INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_Repha, - INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X, - INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N, - INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS, - 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 + 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, /* TODO */ + 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_MEDIAL = OT_CM, + INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_PLACEHOLDER, + INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha, + INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM, + INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N, + INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, + INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_H, /* TODO */ + 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, /* TODO */ + INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_H, /* TODO */ + INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS, + 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_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, + 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_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE, - INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN, - INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M + 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 }; /* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation * because gcc fails to optimize the latter and fills the table in at runtime. */ #define INDIC_COMBINE_CATEGORIES(S,M) \ - (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || (S == INDIC_SYLLABIC_CATEGORY_VIRAMA || S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT)) + \ + (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || \ + ( \ + 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)) + \ ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \ ((M << 8) | S)) - -#include "hb-ot-shape-complex-indic-table.hh" - - -#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7F) == (Base)) - -#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900)) -#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980)) -#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00)) -#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80)) -#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00)) -#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80)) -#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00)) -#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80)) -#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00)) -#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80)) -#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780)) - - -#define MATRA_POS_LEFT(u) POS_PRE_M -#define MATRA_POS_RIGHT(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_POST : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_POST : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? (u <= 0x0C42 ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_KNDA(u) ? (u < 0x0CC3 || u > 0xCD6 ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - IS_KHMR(u) ? POS_AFTER_POST : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \ - IS_GUJR(u) ? POS_AFTER_SUB : \ - IS_ORYA(u) ? POS_AFTER_MAIN : \ - IS_TAML(u) ? POS_AFTER_SUB : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - IS_KHMR(u) ? POS_AFTER_POST : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_BOTTOM(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_SUB : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - IS_KHMR(u) ? POS_AFTER_POST : \ - /*default*/ POS_AFTER_SUB \ - ) - - -static inline indic_position_t -matra_position (hb_codepoint_t u, indic_position_t side) -{ - switch ((int) side) - { - case POS_PRE_C: return MATRA_POS_LEFT (u); - case POS_POST_C: return MATRA_POS_RIGHT (u); - case POS_ABOVE_C: return MATRA_POS_TOP (u); - case POS_BELOW_C: return MATRA_POS_BOTTOM (u); - }; - return side; -} - - - -/* XXX - * This is a hack for now. We should move this data into the main Indic table. - * Or completely remove it and just check in the tables. - */ -static const hb_codepoint_t ra_chars[] = { - 0x0930, /* Devanagari */ - 0x09B0, /* Bengali */ - 0x09F0, /* Bengali */ - 0x0A30, /* Gurmukhi */ /* No Reph */ - 0x0AB0, /* Gujarati */ - 0x0B30, /* Oriya */ - 0x0BB0, /* Tamil */ /* No Reph */ - 0x0C30, /* Telugu */ /* Reph formed only with ZWJ */ - 0x0CB0, /* Kannada */ - 0x0D30, /* Malayalam */ /* No Reph, Logical Repha */ - - 0x0DBB, /* Sinhala */ /* Reph formed only with ZWJ */ - - 0x179A, /* Khmer */ /* No Reph, Visual Repha */ -}; - -static inline indic_position_t -consonant_position (hb_codepoint_t u) -{ - if ((u & ~0x007F) == 0x1780) - return POS_BELOW_C; /* In Khmer coeng model, post and below forms should not be reordered. */ - return POS_BASE_C; /* Will recategorize later based on font lookups. */ -} - -static inline bool -is_ra (hb_codepoint_t u) -{ - for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) - if (u == ra_chars[i]) - return true; - return false; -} - - -static inline bool -is_one_of (const hb_glyph_info_t &info, unsigned int flags) -{ - /* If it ligated, all bets are off. */ - if (is_a_ligature (info)) return false; - return !!(FLAG (info.indic_category()) & flags); -} - -#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ)) -static inline bool -is_joiner (const hb_glyph_info_t &info) -{ - return is_one_of (info, JOINER_FLAGS); -} - -/* 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_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE)) -static inline bool -is_consonant (const hb_glyph_info_t &info) -{ - return is_one_of (info, CONSONANT_FLAGS); -} - -#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng)) -static inline bool -is_halant_or_coeng (const hb_glyph_info_t &info) -{ - return is_one_of (info, HALANT_OR_COENG_FLAGS); -} - -static inline void -set_indic_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = get_indic_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7F); - indic_position_t pos = (indic_position_t) (type >> 8); - - - /* - * Re-assign category - */ - - - /* The spec says U+0952 is OT_A. However, testing shows that Uniscribe - * treats U+0951..U+0952 all as OT_VD. - * TESTS: - * U+092E,U+0947,U+0952 - * U+092E,U+0952,U+0947 - * U+092E,U+0947,U+0951 - * U+092E,U+0951,U+0947 - * */ - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0951, 0x0954))) - cat = OT_VD; - - if (unlikely (u == 0x17D1)) - cat = OT_X; - if (cat == OT_X && - unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CB, 0x17D3))) /* Khmer Various signs */ - { - /* These are like Top Matras. */ - cat = OT_M; - pos = POS_ABOVE_C; - } - if (u == 0x17C6) /* Khmer Bindu doesn't like to be repositioned. */ - cat = OT_N; - - if (unlikely (u == 0x17D2)) cat = OT_Coeng; /* Khmer coeng */ - else if (unlikely (u == 0x200C)) cat = OT_ZWNJ; - else if (unlikely (u == 0x200D)) cat = OT_ZWJ; - else if (unlikely (u == 0x25CC)) cat = OT_DOTTEDCIRCLE; - else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK. More like consonant medial. like 0A75. */ - - if (cat == OT_Repha) { - /* There are two kinds of characters marked as Repha: - * - The ones that are GenCat=Mn are already positioned visually, ie. after base. (eg. Khmer) - * - The ones that are GenCat=Lo is encoded logically, ie. beginning of syllable. (eg. Malayalam) - * - * We recategorize the first kind to look like a Nukta and attached to the base directly. - */ - if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) - cat = OT_N; - } - - - - /* - * Re-assign position. - */ - - if ((FLAG (cat) & CONSONANT_FLAGS)) - { - pos = consonant_position (u); - if (is_ra (u)) - cat = OT_Ra; - } - else if (cat == OT_M) - { - pos = matra_position (u, pos); - } - else if (cat == OT_SM || cat == OT_VD) - { - pos = POS_SMVD; - } - - if (unlikely (u == 0x0B01)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */ - - - - info.indic_category() = cat; - info.indic_position() = pos; -} - - +HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE +hb_indic_get_categories (hb_codepoint_t u); #endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */ diff --git a/src/hb-ot-shape-complex-indic-table.hh b/src/hb-ot-shape-complex-indic-table.cc index 70765b6..f58380e 100644 --- a/src/hb-ot-shape-complex-indic-table.hh +++ b/src/hb-ot-shape-complex-indic-table.cc @@ -6,55 +6,63 @@ * * on files with these headers: * - * # IndicSyllabicCategory-6.2.0.txt - * # Date: 2012-05-15, 21:12:00 GMT [KW] - * # IndicMatraCategory-6.2.0.txt - * # Date: 2012-05-15, 21:10:00 GMT [KW] - * # Blocks-6.2.0.txt - * # Date: 2012-05-14, 22:42:00 GMT [KW, LI] + * # IndicSyllabicCategory-7.0.0.txt + * # Date: 2014-06-03, 07:00:00 GMT [KW, LI, AG, RP] + * # IndicMatraCategory-7.0.0.txt + * # Date: 2014-06-03, 07:00:00 GMT [KW, LI, AG, RP] + * # Blocks-7.0.0.txt + * # Date: 2014-04-03, 23:23:00 GMT [RP, KW] */ -#ifndef HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH -#define HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH - - -#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 11 chars; Avagraha */ -#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 34 chars; Bindu */ -#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 123 chars; Consonant */ -#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 2 chars; Consonant_Dead */ -#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 17 chars; Consonant_Final */ -#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 1 chars; Consonant_Head_Letter */ -#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 12 chars; Consonant_Medial */ -#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 4 chars; Consonant_Placeholder */ -#define ISC_CR INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA /* 5 chars; Consonant_Repha */ -#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 10 chars; Consonant_Subjoined */ +#include "hb-ot-shape-complex-indic-private.hh" + + +#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 13 chars; Avagraha */ +#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 59 chars; Bindu */ +#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ +#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 30 chars; Cantillation_Mark */ +#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1744 chars; Consonant */ +#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 7 chars; Consonant_Dead */ +#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 61 chars; Consonant_Final */ +#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ +#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 19 chars; Consonant_Medial */ +#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 11 chars; Consonant_Placeholder */ +#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 1 chars; Consonant_Preceding_Repha */ +#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 61 chars; Consonant_Subjoined */ +#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */ +#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_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 12 chars; Nukta */ +#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ +#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 18 chars; Nukta */ +#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 408 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_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 1 chars; Register_Shifter */ -#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 3 chars; Tone_Letter */ -#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 16 chars; Tone_Mark */ -#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 34 chars; Virama */ -#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 25 chars; Visarga */ -#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 5 chars; Vowel */ -#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 165 chars; Vowel_Dependent */ -#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 59 chars; Vowel_Independent */ - -#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 65 chars; Bottom */ +#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 15 chars; Pure_Killer */ +#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 3 chars; Register_Shifter */ +#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ +#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 62 chars; Tone_Mark */ +#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 22 chars; Virama */ +#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 29 chars; Visarga */ +#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ +#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 553 chars; Vowel_Dependent */ +#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 395 chars; Vowel_Independent */ + +#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 142 chars; Bottom */ #define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */ -#define IMC_I INDIC_MATRA_CATEGORY_INVISIBLE /* 6 chars; Invisible */ -#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 30 chars; Left */ -#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 8 chars; Left_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 /* 2 chars; Overstruck */ -#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 75 chars; Right */ -#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 83 chars; Top */ -#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 6 chars; Top_And_Bottom */ +#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 163 chars; Right */ +#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 169 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 /* 4 chars; Top_And_Left */ -#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 2 chars; Top_And_Left_And_Right */ -#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 8 chars; Top_And_Right */ -#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 5 chars; Visual_Order_Left */ +#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 /* 15 chars; Visual_Order_Left */ #define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M) @@ -62,10 +70,26 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { -#define indic_offset_0x0900 0 +#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_0x00d0u 24 + + /* Latin-1 Supplement */ - /* Devanagari (0900..097F) */ + /* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), + +#define indic_offset_0x0900u 32 + + + /* Devanagari */ /* 0900 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), @@ -77,14 +101,14 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,x), _(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), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(M,B), + /* 0950 */ _(x,x), _(TM,x), _(TM,x), _(x,x), _(x,x), _(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), _(x,x), _(x,x), - /* 0968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,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 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 0978 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* Bengali (0980..09FF) */ + /* Bengali */ /* 0980 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), @@ -98,12 +122,12 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(x,x), _(x,x), - /* 09E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,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..0A7F) */ + /* Gurmukhi */ /* 0A00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), @@ -117,12 +141,12 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(x,x), _(x,x), - /* 0A68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0A70 */ _(Bi,x), _(x,x), _(CP,x), _(CP,x), _(x,x), _(CM,x), _(x,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,x), _(GM,T), _(CP,x), _(CP,x), _(x,x), _(CM,x), _(x,x), _(x,x), /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Gujarati (0A80..0AFF) */ + /* Gujarati */ /* 0A80 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), @@ -136,12 +160,12 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(x,x), _(x,x), - /* 0AE8 */ _(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), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Oriya (0B00..0B7F) */ + /* Oriya */ /* 0B00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), @@ -155,12 +179,12 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(x,x), _(x,x), - /* 0B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,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..0BFF) */ + /* Tamil */ /* 0B80 */ _(x,x), _(x,x), _(Bi,x), _(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), @@ -174,33 +198,33 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(x,x), _(x,x), - /* 0BE8 */ _(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..0C7F) */ + /* Telugu */ - /* 0C00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0C00 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), _(x,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), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0C68 */ _(x,x), _(x,x), _(x,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..0CFF) */ + /* Kannada */ - /* 0C80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0C80 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), @@ -212,14 +236,14 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(x,x), _(x,x), - /* 0CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,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), _(x,x), _(x,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..0D7F) */ + /* Malayalam */ - /* 0D00 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0D00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(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), @@ -228,15 +252,15 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(CR,x), _(x,x), + /* 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), _(x,x), _(x,x), _(x,x), _(M,R), /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0D68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,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..0DFF) */ + /* Sinhala */ /* 0D80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(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), @@ -249,86 +273,15 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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,LR), _(M,LR), _(M,R), - /* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0DE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(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), - /* 0DF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Thai (0E00..0E7F) */ - - /* 0E00 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0E08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0E10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0E18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0E20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0E28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), - /* 0E30 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T), - /* 0E38 */ _(M,B), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0E40 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(M,R), _(x,x), _(M,T), - /* 0E48 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(V,T), _(x,x), - /* 0E50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0E58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0E60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0E68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0E70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0E78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Lao (0E80..0EFF) */ - - /* 0E80 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x), - /* 0E88 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x), _(x,x), _(x,x), - /* 0E90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0E98 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0EA0 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), - /* 0EA8 */ _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), - /* 0EB0 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T), - /* 0EB8 */ _(M,B), _(M,B), _(x,x), _(M,T), _(CM,x), _(CM,x), _(x,x), _(x,x), - /* 0EC0 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(x,x), _(x,x), _(x,x), - /* 0EC8 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(x,x), _(x,x), - /* 0ED0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0ED8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), - /* 0EE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0EE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0EF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0EF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Tibetan (0F00..0FFF) */ - - /* 0F00 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F10 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F18 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F20 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F28 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F30 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0F40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0F48 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0F50 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0F58 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0F60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0F68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), - /* 0F70 */ _(x,x), _(M,B), _(M,T), _(M,TB), _(M,B), _(M,B), _(M,TB), _(M,TB), - /* 0F78 */ _(M,TB), _(M,TB), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(Vs,x), - /* 0F80 */ _(M,T), _(M,TB), _(Bi,x), _(Bi,x), _(V,B), _(A,x), _(x,x), _(x,x), - /* 0F88 */_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x), _(CS,x), _(CS,x), _(CS,x), - /* 0F90 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), - /* 0F98 */ _(x,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), - /* 0FA0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), - /* 0FA8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), - /* 0FB0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), - /* 0FB8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x), - /* 0FC0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0FC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0FD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0FD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0FE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0FE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0FF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0FF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Myanmar (1000..109F) */ + +#define indic_offset_0x1000u 1304 + + + /* 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), @@ -337,9 +290,9 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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,x), _(TM,x), - /* 1038 */ _(Vs,x), _(V,I), _(V,T), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(C,x), - /* 1040 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1038 */ _(Vs,x), _(IS,x), _(PK,T), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(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,x), _(CM,x), /* 1060 */ _(CM,x), _(C,x), _(M,R), _(TM,x), _(TM,x), _(C,x), _(C,x), _(M,R), @@ -348,41 +301,41 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1080 */ _(C,x), _(C,x), _(CM,x), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,x), /* 1088 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(TM,x), - /* 1090 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1098 */ _(x,x), _(x,x), _(TM,x), _(TM,x), _(M,R), _(M,T), _(x,x), _(x,x), + /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1098 */ _(Nd,x), _(Nd,x), _(TM,x), _(TM,x), _(M,R), _(M,T), _(x,x), _(x,x), -#define indic_offset_0x1700 1952 +#define indic_offset_0x1700u 1464 - /* Tagalog (1700..171F) */ + /* Tagalog */ /* 1700 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1708 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), - /* 1710 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x), + /* 1710 */ _(C,x), _(C,x), _(M,T), _(M,B), _(PK,B), _(x,x), _(x,x), _(x,x), /* 1718 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Hanunoo (1720..173F) */ + /* Hanunoo */ /* 1720 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1728 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1730 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x), + /* 1730 */ _(C,x), _(C,x), _(M,T), _(M,B), _(PK,B), _(x,x), _(x,x), _(x,x), /* 1738 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Buhid (1740..175F) */ + /* Buhid */ /* 1740 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1748 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1750 */ _(C,x), _(C,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), /* 1758 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Tagbanwa (1760..177F) */ + /* Tagbanwa */ /* 1760 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1768 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), /* 1770 */ _(C,x), _(x,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), /* 1778 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Khmer (1780..17FF) */ + /* 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), @@ -393,31 +346,29 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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,x), _(Vs,x), - /* 17C8 */ _(M,R), _(RS,x), _(RS,x), _(x,x), _(CR,x), _(x,x), _(x,x), _(x,x), - /* 17D0 */ _(x,x), _(V,T), _(V,I), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(RS,T),_(CSR,T), _(M,T), _(M,T), _(M,T), + /* 17D0 */ _(M,T), _(PK,T), _(IS,x), _(M,T), _(x,x), _(x,x), _(x,x), _(x,x), /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(x,x), _(x,x), _(x,x), - /* 17E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 17E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 17F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 17F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(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_0x1900 2208 +#define indic_offset_0x1900u 1704 - /* Limbu (1900..194F) */ + /* Limbu */ /* 1900 */ _(CP,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1908 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), + /* 1918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), /* 1920 */ _(M,T), _(M,T), _(M,B), _(M,R), _(M,R), _(M,TR), _(M,TR), _(M,T), /* 1928 */ _(M,T), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 1930 */ _(CF,x), _(CF,x), _(Bi,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), /* 1938 */ _(CF,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1948 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), + /* 1948 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* Tai Le (1950..197F) */ + /* Tai Le */ /* 1950 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -426,7 +377,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1970 */ _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(x,x), _(x,x), _(x,x), /* 1978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* New Tai Lue (1980..19DF) */ + /* New Tai Lue */ /* 1980 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1988 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -438,24 +389,21 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 19B8 */ _(M,R), _(M,R), _(M,L), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), /* 19C0 */ _(M,R), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), /* 19C8 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* FILLER (19E0..19FF) */ - + /* 19D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 19D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 19E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 19E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 19F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 19F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Buginese (1A00..1A1F) */ + /* Buginese */ /* 1A00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1A08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), - /* 1A18 */ _(M,B), _(M,L), _(M,R), _(M,L), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1A18 */ _(M,B), _(M,L), _(M,R), _(M,T), _(x,x), _(x,x), _(x,x), _(x,x), - /* Tai Tham (1A20..1AAF) */ + /* Tai Tham */ /* 1A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -463,25 +411,23 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1A38 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1A40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1A48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), - /* 1A50 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(CM,x), _(CM,x), _(CF,x), + /* 1A50 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(CM,L), _(CM,x), _(CF,x), /* 1A58 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x), - /* 1A60 */ _(V,I), _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), + /* 1A60 */ _(IS,x), _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), /* 1A68 */ _(M,T), _(M,B), _(M,B), _(M,T), _(M,B), _(M,R), _(M,L), _(M,L), /* 1A70 */ _(M,L), _(M,L), _(M,L), _(M,T), _(M,T), _(TM,x), _(TM,x), _(TM,x), /* 1A78 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1A80 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1A88 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1A90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1A98 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1AA0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1AA8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1A80 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1A88 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1A90 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1A98 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x1b00 2640 +#define indic_offset_0x1b00u 2120 - /* Balinese (1B00..1B7F) */ + /* Balinese */ - /* 1B00 */ _(Bi,x), _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), + /* 1B00 */ _(Bi,x), _(Bi,x), _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), /* 1B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 1B10 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -491,36 +437,36 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1B38 */ _(M,B), _(M,B), _(M,B), _(M,BR), _(M,TB),_(M,TBR), _(M,L), _(M,L), /* 1B40 */ _(M,LR), _(M,LR), _(M,T), _(M,TR), _(V,R), _(C,x), _(C,x), _(C,x), /* 1B48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1B50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1B58 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 1B60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 1B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 1B70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 1B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Sundanese (1B80..1BBF) */ + /* Sundanese */ - /* 1B80 */ _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 1B80 */ _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 1B88 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1B90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1B98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1BA0 */ _(C,x), _(CS,x), _(CS,x), _(CS,x), _(M,T), _(M,B), _(M,L), _(M,R), - /* 1BA8 */ _(M,T), _(M,T), _(V,R), _(V,x), _(CS,x), _(CS,x), _(C,x), _(C,x), - /* 1BB0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1BB8 */ _(x,x), _(x,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), + /* 1BA8 */ _(M,T), _(M,T), _(PK,R), _(IS,x), _(CS,x), _(CS,x), _(C,x), _(C,x), + /* 1BB0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1BB8 */ _(Nd,x), _(Nd,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), - /* Batak (1BC0..1BFF) */ + /* Batak */ /* 1BC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1BC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1BD0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1BD8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1BE0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(N,x), _(M,x), - /* 1BE8 */ _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), - /* 1BF0 */ _(CF,x), _(CF,x), _(V,R), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1BE0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(N,x), _(M,R), + /* 1BE8 */ _(M,T), _(M,T), _(M,R), _(M,R), _(M,R), _(M,T), _(M,R), _(M,T), + /* 1BF0 */ _(CF,x), _(CF,x), _(PK,R), _(PK,R), _(x,x), _(x,x), _(x,x), _(x,x), /* 1BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Lepcha (1C00..1C4F) */ + /* Lepcha */ /* 1C00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1C08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -528,41 +474,45 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CS,x), _(CS,x), _(M,R), _(M,L), /* 1C28 */ _(M,L), _(M,TL), _(M,R), _(M,R), _(M,B), _(CF,x), _(CF,x), _(CF,x), - /* 1C30 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(Bi,x), _(Bi,x), _(x,x), _(N,x), + /* 1C30 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(Bi,L), _(Bi,L), _(x,x), _(N,x), /* 1C38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1C40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1C48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), + /* 1C40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1C48 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), -#define indic_offset_0x1cd0 2976 +#define indic_offset_0x1cd0u 2456 - /* Vedic Extensions (1CD0..1CFF) */ + /* Vedic Extensions */ - /* 1CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1CE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1CD0 */ _(TM,x), _(TM,x), _(TM,x), _(x,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), + /* 1CD8 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), + /* 1CE0 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 1CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(TM,x), _(x,x), _(x,x), _(x,x), + +#define indic_offset_0x2008u 2496 + + + /* General Punctuation */ -#define indic_offset_0xa800 3024 + /* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x), + /* 2010 */ _(x,x), _(x,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x), +#define indic_offset_0xa800u 2512 - /* Syloti Nagri (A800..A82F) */ - /* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(V,T), _(C,x), + /* Syloti Nagri */ + + /* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(PK,T), _(C,x), /* A808 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A810 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A818 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A820 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,B), _(M,T), _(M,R), /* A828 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* FILLER (A830..A83F) */ - /* A830 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* A838 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Phags-pa (A840..A87F) */ + /* Phags-pa */ /* A840 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A848 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -573,7 +523,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* A870 */ _(C,x), _(CS,x), _(C,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x), /* A878 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Saurashtra (A880..A8DF) */ + /* Saurashtra */ /* A880 */ _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* A888 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), @@ -585,44 +535,41 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* A8B8 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), /* A8C0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x), _(x,x), /* A8C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A8D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A8D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A8D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* A8D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* FILLER (A8E0..A8FF) */ + /* Devanagari Extended */ - /* A8E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A8E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A8F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A8E0 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), + /* A8E8 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), + /* A8F0 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Kayah Li (A900..A92F) */ + /* Kayah Li */ - /* A900 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A908 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* A900 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* A908 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A920 */ _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), /* A928 */ _(Vo,x), _(Vo,x), _(Vo,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(x,x), - /* Rejang (A930..A95F) */ + /* Rejang */ /* A930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A938 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A940 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,B), /* A948 */ _(M,B), _(M,B), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B), _(CF,x), - /* A950 */ _(CF,x), _(CF,x), _(CF,x), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x), + /* A950 */ _(CF,x), _(CF,x), _(CF,x), _(PK,R), _(x,x), _(x,x), _(x,x), _(x,x), /* A958 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* FILLER (A960..A97F) */ - /* A960 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* A968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* A970 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* A978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Javanese (A980..A9DF) */ + /* Javanese */ - /* A980 */ _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* A980 */ _(Bi,x), _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* A988 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), /* A990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -632,17 +579,17 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* A9B8 */ _(M,B), _(M,B), _(M,L), _(M,L), _(M,T), _(CS,x), _(CM,x), _(CM,x), /* A9C0 */ _(V,BR), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* A9C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A9D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A9D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A9D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* A9D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* FILLER (A9E0..A9FF) */ + /* Myanmar Extended-B */ - /* A9E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A9E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A9F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A9F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(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), - /* Cham (AA00..AA5F) */ + /* Cham */ /* AA00 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), /* AA08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -650,21 +597,21 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* AA18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* AA20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* AA28 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,T), _(M,L), - /* AA30 */ _(M,L), _(M,T), _(M,B), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(x,x), + /* AA30 */ _(M,L), _(M,T), _(M,B), _(CM,x), _(CM,L), _(CM,x), _(CM,x), _(x,x), /* AA38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* AA40 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), /* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x), _(x,x), - /* AA50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* AA58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* AA50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* AA58 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Myanmar Extended-A (AA60..AA7F) */ + /* 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), _(x,x), _(x,x), _(x,x), _(x,x), - /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(C,x), - /* Tai Viet (AA80..AADF) */ + /* Tai Viet */ /* AA80 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* AA88 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -679,31 +626,30 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* AAD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* AAD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Meetei Mayek Extensions (AAE0..AAFF) */ + /* Meetei Mayek Extensions */ /* AAE0 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* AAE8 */ _(C,x), _(C,x), _(C,x), _(M,L), _(M,B), _(M,T), _(M,L), _(M,R), - /* AAF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Vs,x), _(V,I), _(x,x), - /* AAF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* AAF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Vs,x), _(IS,x), _(x,x), -#define indic_offset_0xabc0 3792 +#define indic_offset_0xabc0u 3272 - /* Meetei Mayek (ABC0..ABFF) */ + /* Meetei Mayek */ /* ABC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* ABC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), /* ABD0 */ _(C,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* ABD8 */ _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), /* ABE0 */ _(CF,x), _(CF,x), _(CF,x), _(M,R), _(M,R), _(M,T), _(M,R), _(M,R), - /* ABE8 */ _(M,B), _(M,R), _(M,R), _(x,x), _(TM,x), _(V,B), _(x,x), _(x,x), - /* ABF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* ABF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* ABE8 */ _(M,B), _(M,R), _(M,R), _(x,x), _(TM,x), _(PK,B), _(x,x), _(x,x), + /* ABF0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* ABF8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x10a00 3856 +#define indic_offset_0x10a00u 3336 - /* Kharoshthi (10A00..10A5F) */ + /* Kharoshthi */ /* 10A00 */ _(C,x), _(M,O), _(M,B), _(M,B), _(x,x), _(M,T), _(M,O), _(x,x), /* 10A08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(M,B), _(x,x), _(Bi,x), _(Vs,x), @@ -712,16 +658,13 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 10A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 10A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 10A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 10A38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(V,I), - /* 10A40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 10A48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 10A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 10A58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 10A38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(IS,x), + /* 10A40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), -#define indic_offset_0x11000 3952 +#define indic_offset_0x11000u 3408 - /* Brahmi (11000..1107F) */ + /* Brahmi */ /* 11000 */ _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 11008 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), @@ -733,14 +676,14 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 11038 */ _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B), /* 11040 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), /* 11048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11050 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11058 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11060 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11068 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11050 */ _(x,x), _(x,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), + /* 11058 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), + /* 11060 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), _(Nd,x), _(Nd,x), + /* 11068 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 11070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(NJ,x), - /* Kaithi (11080..110CF) */ + /* Kaithi */ /* 11080 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 11088 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), @@ -750,13 +693,11 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 110A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 110B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,R), /* 110B8 */ _(M,R), _(V,B), _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 110C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 110C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x11100 4160 +#define indic_offset_0x11100u 3600 - /* Chakma (11100..1114F) */ + /* Chakma */ /* 11100 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), /* 11108 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -764,15 +705,21 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 11118 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 11120 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), /* 11128 */ _(M,T), _(M,T), _(M,B), _(M,B), _(M,L), _(M,T), _(M,TB), _(M,TB), - /* 11130 */ _(M,T), _(M,B), _(M,B), _(V,I), _(V,T), _(x,x), _(x,x), _(x,x), - /* 11138 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11130 */ _(M,T), _(M,B), _(M,B), _(IS,x), _(PK,T), _(x,x), _(Nd,x), _(Nd,x), + /* 11138 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 11140 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 11148 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x11180 4240 + /* Mahajani */ + /* 11150 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), + /* 11158 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11160 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11168 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11170 */ _(C,x), _(C,x), _(C,x), _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11178 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Sharada (11180..111DF) */ + /* Sharada */ /* 11180 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 11188 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), @@ -784,13 +731,116 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 111B8 */ _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,TR), /* 111C0 */ _(V,R), _(A,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 111C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 111D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 111D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x11680 4336 - - - /* Takri (11680..116CF) */ + /* 111D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 111D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Sinhala Archaic Numbers */ + + /* 111E0 */ _(x,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 111E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 111F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), + /* 111F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Khojki */ + + /* 11200 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11208 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11210 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11218 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11220 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11228 */ _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,R), _(M,B), + /* 11230 */ _(M,T), _(M,T), _(M,TR), _(M,TR), _(Bi,x), _(V,R), _(N,x), _(GM,T), + +#define indic_offset_0x112b0u 3912 + + + /* Khudawadi */ + + /* 112B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 112B8 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112C0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112C8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112D0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112D8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Bi,x), + /* 112E0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), + /* 112E8 */ _(M,T), _(N,x), _(PK,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 112F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 112F8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Grantha */ + + /* 11300 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 11308 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), + /* 11310 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), + /* 11318 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11320 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11328 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11330 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), + /* 11338 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,R), + /* 11340 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(x,x), _(M,L), + /* 11348 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,R), _(x,x), _(x,x), + /* 11350 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), + /* 11358 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11360 */ _(VI,x), _(VI,x), _(M,R), _(M,R), _(x,x), _(x,x), _(Ca,x), _(Ca,x), + /* 11368 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), + /* 11370 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), + +#define indic_offset_0x11480u 4112 + + + /* Tirhuta */ + + /* 11480 */ _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11488 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), + /* 11490 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11498 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 114A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 114A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 114B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), + /* 114B8 */ _(M,B), _(M,L), _(M,T), _(M,TL), _(M,LR), _(M,R), _(M,LR), _(Bi,x), + /* 114C0 */ _(Bi,x), _(Vs,x), _(V,B), _(N,x), _(A,x), _(x,x), _(x,x), _(x,x), + /* 114C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 114D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 114D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define indic_offset_0x11580u 4208 + + + /* Siddham */ + + /* 11580 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11588 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), + /* 11590 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11598 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 115A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 115A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), + /* 115B0 */ _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), + /* 115B8 */ _(M,L), _(M,TL), _(M,LR),_(M,TLR), _(Bi,x), _(Bi,x), _(Vs,x), _(V,B), + /* 115C0 */ _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define indic_offset_0x11600u 4280 + + + /* Modi */ + + /* 11600 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11608 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), + /* 11610 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11618 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11620 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11628 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11630 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), + /* 11638 */ _(M,B), _(M,T), _(M,T), _(M,R), _(M,R), _(Bi,x), _(Vs,x), _(V,B), + /* 11640 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11648 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11650 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 11658 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11660 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11668 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11670 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11678 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Takri */ /* 11680 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 11688 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -800,30 +850,57 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 116A8 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(Vs,x), _(M,T), _(M,L), _(M,R), /* 116B0 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(N,x), /* 116B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_total 4416 + /* 116C0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 116C8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -}; /* Table occupancy: 60% */ +}; /* Table items: 4488; occupancy: 73% */ -static INDIC_TABLE_ELEMENT_TYPE -get_indic_categories (hb_codepoint_t u) +INDIC_TABLE_ELEMENT_TYPE +hb_indic_get_categories (hb_codepoint_t u) { - if (0x0900 <= u && u <= 0x10A0) return indic_table[u - 0x0900 + indic_offset_0x0900]; - if (0x1700 <= u && u <= 0x1800) return indic_table[u - 0x1700 + indic_offset_0x1700]; - if (0x1900 <= u && u <= 0x1AB0) return indic_table[u - 0x1900 + indic_offset_0x1900]; - if (0x1B00 <= u && u <= 0x1C50) return indic_table[u - 0x1B00 + indic_offset_0x1b00]; - if (0x1CD0 <= u && u <= 0x1D00) return indic_table[u - 0x1CD0 + indic_offset_0x1cd0]; - if (0xA800 <= u && u <= 0xAB00) return indic_table[u - 0xA800 + indic_offset_0xa800]; - if (0xABC0 <= u && u <= 0xAC00) return indic_table[u - 0xABC0 + indic_offset_0xabc0]; - if (0x10A00 <= u && u <= 0x10A60) return indic_table[u - 0x10A00 + indic_offset_0x10a00]; - if (0x11000 <= u && u <= 0x110D0) return indic_table[u - 0x11000 + indic_offset_0x11000]; - if (0x11100 <= u && u <= 0x11150) return indic_table[u - 0x11100 + indic_offset_0x11100]; - if (0x11180 <= u && u <= 0x111E0) return indic_table[u - 0x11180 + indic_offset_0x11180]; - if (0x11680 <= u && u <= 0x116D0) return indic_table[u - 0x11680 + indic_offset_0x11680]; - if (unlikely (u == 0x00A0)) return _(CP,x); - if (unlikely (u == 0x25CC)) return _(CP,x); + switch (u >> 12) + { + case 0x0u: + if (hb_in_range (u, 0x0028u, 0x0040u)) return indic_table[u - 0x0028u + indic_offset_0x0028u]; + if (hb_in_range (u, 0x00D0u, 0x00D8u)) return indic_table[u - 0x00D0u + indic_offset_0x00d0u]; + if (hb_in_range (u, 0x0900u, 0x0DF8u)) return indic_table[u - 0x0900u + indic_offset_0x0900u]; + if (unlikely (u == 0x00A0u)) return _(CP,x); + break; + + case 0x1u: + if (hb_in_range (u, 0x1000u, 0x10A0u)) return indic_table[u - 0x1000u + indic_offset_0x1000u]; + if (hb_in_range (u, 0x1700u, 0x17F0u)) return indic_table[u - 0x1700u + indic_offset_0x1700u]; + if (hb_in_range (u, 0x1900u, 0x1AA0u)) return indic_table[u - 0x1900u + indic_offset_0x1900u]; + if (hb_in_range (u, 0x1B00u, 0x1C50u)) return indic_table[u - 0x1B00u + indic_offset_0x1b00u]; + if (hb_in_range (u, 0x1CD0u, 0x1CF8u)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u]; + break; + + case 0x2u: + if (hb_in_range (u, 0x2008u, 0x2018u)) return indic_table[u - 0x2008u + indic_offset_0x2008u]; + if (unlikely (u == 0x25CCu)) return _(CP,x); + break; + + case 0xAu: + if (hb_in_range (u, 0xA800u, 0xAAF8u)) return indic_table[u - 0xA800u + indic_offset_0xa800u]; + if (hb_in_range (u, 0xABC0u, 0xAC00u)) return indic_table[u - 0xABC0u + indic_offset_0xabc0u]; + break; + + case 0x10u: + if (hb_in_range (u, 0x10A00u, 0x10A48u)) return indic_table[u - 0x10A00u + indic_offset_0x10a00u]; + break; + + case 0x11u: + if (hb_in_range (u, 0x11000u, 0x110C0u)) return indic_table[u - 0x11000u + indic_offset_0x11000u]; + if (hb_in_range (u, 0x11100u, 0x11238u)) return indic_table[u - 0x11100u + indic_offset_0x11100u]; + if (hb_in_range (u, 0x112B0u, 0x11378u)) return indic_table[u - 0x112B0u + indic_offset_0x112b0u]; + if (hb_in_range (u, 0x11480u, 0x114E0u)) return indic_table[u - 0x11480u + indic_offset_0x11480u]; + if (hb_in_range (u, 0x11580u, 0x115C8u)) return indic_table[u - 0x11580u + indic_offset_0x11580u]; + if (hb_in_range (u, 0x11600u, 0x116D0u)) return indic_table[u - 0x11600u + indic_offset_0x11600u]; + break; + + default: + break; + } return _(x,x); } @@ -831,17 +908,27 @@ get_indic_categories (hb_codepoint_t u) #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_CM #undef ISC_CP -#undef ISC_CR +#undef ISC_CPR #undef ISC_CS +#undef ISC_CSR +#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_TL #undef ISC_TM @@ -853,7 +940,6 @@ get_indic_categories (hb_codepoint_t u) #undef IMC_B #undef IMC_BR -#undef IMC_I #undef IMC_L #undef IMC_LR #undef IMC_x @@ -867,6 +953,4 @@ get_indic_categories (hb_codepoint_t u) #undef IMC_TR #undef IMC_VOL -#endif /* HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH */ - /* == End of generated table == */ diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 5afede0..7723600 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -27,49 +27,243 @@ #include "hb-ot-shape-complex-indic-private.hh" #include "hb-ot-layout-private.hh" +/* buffer var allocations */ +#define indic_category() complex_var_u8_0() /* indic_category_t */ +#define indic_position() complex_var_u8_1() /* indic_position_t */ + /* - * Global Indic shaper options. + * Indic shaper. */ -struct indic_options_t + +#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base)) + +#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u)) +#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u)) +#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u)) +#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u)) +#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u)) +#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u)) +#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u)) +#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u)) +#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u)) +#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u)) +#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780u)) + + +#define MATRA_POS_LEFT(u) POS_PRE_M +#define MATRA_POS_RIGHT(u) ( \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_BENG(u) ? POS_AFTER_POST : \ + IS_GURU(u) ? POS_AFTER_POST : \ + IS_GUJR(u) ? POS_AFTER_POST : \ + IS_ORYA(u) ? POS_AFTER_POST : \ + IS_TAML(u) ? POS_AFTER_POST : \ + IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ + IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ + IS_MLYM(u) ? POS_AFTER_POST : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + IS_KHMR(u) ? POS_AFTER_POST : \ + /*default*/ POS_AFTER_SUB \ + ) +#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \ + IS_GUJR(u) ? POS_AFTER_SUB : \ + IS_ORYA(u) ? POS_AFTER_MAIN : \ + IS_TAML(u) ? POS_AFTER_SUB : \ + IS_TELU(u) ? POS_BEFORE_SUB : \ + IS_KNDA(u) ? POS_BEFORE_SUB : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + IS_KHMR(u) ? POS_AFTER_POST : \ + /*default*/ POS_AFTER_SUB \ + ) +#define MATRA_POS_BOTTOM(u) ( \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_BENG(u) ? POS_AFTER_SUB : \ + IS_GURU(u) ? POS_AFTER_POST : \ + IS_GUJR(u) ? POS_AFTER_POST : \ + IS_ORYA(u) ? POS_AFTER_SUB : \ + IS_TAML(u) ? POS_AFTER_POST : \ + IS_TELU(u) ? POS_BEFORE_SUB : \ + IS_KNDA(u) ? POS_BEFORE_SUB : \ + IS_MLYM(u) ? POS_AFTER_POST : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + IS_KHMR(u) ? POS_AFTER_POST : \ + /*default*/ POS_AFTER_SUB \ + ) + +static inline indic_position_t +matra_position (hb_codepoint_t u, indic_position_t side) { - int initialized : 1; - int uniscribe_bug_compatible : 1; -}; + switch ((int) side) + { + case POS_PRE_C: return MATRA_POS_LEFT (u); + case POS_POST_C: return MATRA_POS_RIGHT (u); + case POS_ABOVE_C: return MATRA_POS_TOP (u); + case POS_BELOW_C: return MATRA_POS_BOTTOM (u); + }; + return side; +} -union indic_options_union_t { - int i; - indic_options_t opts; +/* XXX + * This is a hack for now. We should move this data into the main Indic table. + * Or completely remove it and just check in the tables. + */ +static const hb_codepoint_t ra_chars[] = { + 0x0930u, /* Devanagari */ + 0x09B0u, /* Bengali */ + 0x09F0u, /* Bengali */ + 0x0A30u, /* Gurmukhi */ /* No Reph */ + 0x0AB0u, /* Gujarati */ + 0x0B30u, /* Oriya */ + 0x0BB0u, /* Tamil */ /* No Reph */ + 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */ + 0x0CB0u, /* Kannada */ + 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ + + 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ + + 0x179Au, /* Khmer */ /* No Reph, Visual Repha */ }; -ASSERT_STATIC (sizeof (int) == sizeof (indic_options_union_t)); -static indic_options_union_t -indic_options_init (void) +static inline bool +is_ra (hb_codepoint_t u) +{ + for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) + if (u == ra_chars[i]) + return true; + return false; +} + +static inline bool +is_one_of (const hb_glyph_info_t &info, unsigned int flags) { - indic_options_union_t u; - u.i = 0; - u.opts.initialized = 1; + /* If it ligated, all bets are off. */ + if (_hb_glyph_info_ligated (&info)) return false; + return !!(FLAG (info.indic_category()) & flags); +} - char *c = getenv ("HB_OT_INDIC_OPTIONS"); - u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); +static inline bool +is_joiner (const hb_glyph_info_t &info) +{ + return is_one_of (info, JOINER_FLAGS); +} - return u; +static inline bool +is_consonant (const hb_glyph_info_t &info) +{ + return is_one_of (info, CONSONANT_FLAGS); } -static inline indic_options_t -indic_options (void) +static inline bool +is_halant_or_coeng (const hb_glyph_info_t &info) { - static indic_options_union_t options; + return is_one_of (info, HALANT_OR_COENG_FLAGS); +} + +static inline void +set_indic_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_position_t pos = (indic_position_t) (type >> 8); + + + /* + * Re-assign category + */ + + + /* The spec says U+0952 is OT_A. However, testing shows that Uniscribe + * treats a whole bunch of characters similarly. + * TESTS: For example, for U+0951: + * U+092E,U+0947,U+0952 + * U+092E,U+0952,U+0947 + * U+092E,U+0947,U+0951 + * U+092E,U+0951,U+0947 + * U+092E,U+0951,U+0952 + * U+092E,U+0952,U+0951 + */ + if (unlikely (hb_in_ranges (u, 0x0951u, 0x0952u, + 0x1CD0u, 0x1CD2u, + 0x1CD4u, 0x1CE1u) || + u == 0x1CF4u)) + cat = OT_A; + /* The following act more like the Bindus. */ + else if (unlikely (hb_in_range (u, 0x0953u, 0x0954u))) + cat = OT_SM; + /* The following act like consonants. */ + else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u, + 0x1CF5u, 0x1CF6u))) + cat = OT_C; + /* TODO: The following should only be allowed after a Visarga. + * For now, just treat them like regular tone marks. */ + else if (unlikely (hb_in_range (u, 0x1CE2u, 0x1CE8u))) + cat = OT_A; + /* TODO: The following should only be allowed after some of + * the nasalization marks, maybe only for U+1CE9..U+1CF1. + * For now, just treat them like tone marks. */ + else if (unlikely (u == 0x1CEDu)) + cat = OT_A; + /* The following take marks in standalone clusters, similar to Avagraha. */ + else if (unlikely (hb_in_ranges (u, 0xA8F2u, 0xA8F7u, + 0x1CE9u, 0x1CECu, + 0x1CEEu, 0x1CF1u))) + { + cat = OT_Symbol; + ASSERT_STATIC ((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol); + } + else if (unlikely (hb_in_range (u, 0x17CDu, 0x17D1u) || + u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ + { + /* These are like Top Matras. */ + cat = OT_M; + pos = POS_ABOVE_C; + } + else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ + else if (unlikely (u == 0x17D2u)) cat = OT_Coeng; /* Khmer coeng */ + else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u))) + cat = OT_PLACEHOLDER; + else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; + else if (unlikely (u == 0xA982u)) cat = OT_SM; /* Javanese repha. */ + else if (unlikely (u == 0xA9BEu)) cat = OT_CM2; /* Javanese medial ya. */ + else if (unlikely (u == 0xA9BDu)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */ + + + /* + * Re-assign position. + */ - if (unlikely (!options.i)) { - /* This is idempotent and threadsafe. */ - options = indic_options_init (); + if ((FLAG (cat) & CONSONANT_FLAGS)) + { + pos = POS_BASE_C; + if (is_ra (u)) + cat = OT_Ra; + } + else if (cat == OT_M) + { + pos = matra_position (u, pos); + } + else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) + { + pos = POS_SMVD; } - return options.opts; + if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */ + + + + info.indic_category() = cat; + info.indic_position() = pos; } +/* + * Things above this line should ideally be moved to the Indic table itself. + */ + /* * Indic configurations. Note that we do not want to keep every single script-specific @@ -81,16 +275,16 @@ indic_options (void) enum base_position_t { BASE_POS_FIRST, + BASE_POS_LAST_SINHALA, BASE_POS_LAST }; enum reph_position_t { - REPH_POS_DEFAULT = POS_BEFORE_POST, - REPH_POS_AFTER_MAIN = POS_AFTER_MAIN, REPH_POS_BEFORE_SUB = POS_BEFORE_SUB, REPH_POS_AFTER_SUB = POS_AFTER_SUB, REPH_POS_BEFORE_POST = POS_BEFORE_POST, - REPH_POS_AFTER_POST = POS_AFTER_POST + REPH_POS_AFTER_POST = POS_AFTER_POST, + REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH }; enum reph_mode_t { REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */ @@ -98,6 +292,15 @@ enum reph_mode_t { REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */ REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */ }; +enum blwf_mode_t { + BLWF_MODE_PRE_AND_POST, /* Below-forms feature applied to pre-base and post-base. */ + BLWF_MODE_POST_ONLY /* Below-forms feature applied to post-base only. */ +}; +enum pref_len_t { + PREF_LEN_1 = 1, + PREF_LEN_2 = 2, + PREF_LEN_DONT_CARE = PREF_LEN_2 +}; struct indic_config_t { hb_script_t script; @@ -106,25 +309,27 @@ struct indic_config_t base_position_t base_pos; reph_position_t reph_pos; reph_mode_t reph_mode; + blwf_mode_t blwf_mode; + pref_len_t pref_len; }; static const indic_config_t indic_configs[] = { /* Default. Should be first. */ - {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT}, - {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT}, - {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT}, - {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT}, - {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT}, - {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT}, - {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT}, - {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT}, - {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT}, - {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA}, - {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT}, - {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT, REPH_MODE_VIS_REPHA}, - /* Myanmar does not have the "old_indic" behavior, even though it has a "new" tag. */ - {HB_SCRIPT_MYANMAR, false,0x1039,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_EXPLICIT}, + {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1}, + {HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, + {HB_SCRIPT_BENGALI, true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, + {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, + {HB_SCRIPT_GUJARATI, true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, + {HB_SCRIPT_ORIYA, true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, + {HB_SCRIPT_TAMIL, true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2}, + {HB_SCRIPT_TELUGU, true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2}, + {HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2}, + {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2}, + {HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA, + REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, + {HB_SCRIPT_KHMER, false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2}, + {HB_SCRIPT_JAVANESE, false,0xA9C0u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1}, }; @@ -135,7 +340,7 @@ static const indic_config_t indic_configs[] = struct feature_list_t { hb_tag_t tag; - hb_bool_t is_global; + hb_ot_map_feature_flags_t flags; }; static const feature_list_t @@ -145,32 +350,34 @@ indic_features[] = * Basic features. * These features are applied in order, one at a time, after initial_reordering. */ - {HB_TAG('n','u','k','t'), true}, - {HB_TAG('a','k','h','n'), true}, - {HB_TAG('r','p','h','f'), false}, - {HB_TAG('r','k','r','f'), true}, - {HB_TAG('p','r','e','f'), false}, - {HB_TAG('h','a','l','f'), false}, - {HB_TAG('b','l','w','f'), false}, - {HB_TAG('a','b','v','f'), false}, - {HB_TAG('p','s','t','f'), false}, - {HB_TAG('c','f','a','r'), false}, - {HB_TAG('c','j','c','t'), true}, - {HB_TAG('v','a','t','u'), true}, + {HB_TAG('n','u','k','t'), F_GLOBAL}, + {HB_TAG('a','k','h','n'), F_GLOBAL}, + {HB_TAG('r','p','h','f'), F_NONE}, + {HB_TAG('r','k','r','f'), F_GLOBAL}, + {HB_TAG('p','r','e','f'), F_NONE}, + {HB_TAG('b','l','w','f'), F_NONE}, + {HB_TAG('a','b','v','f'), F_NONE}, + {HB_TAG('h','a','l','f'), F_NONE}, + {HB_TAG('p','s','t','f'), F_NONE}, + {HB_TAG('v','a','t','u'), F_GLOBAL}, + {HB_TAG('c','j','c','t'), F_GLOBAL}, + {HB_TAG('c','f','a','r'), F_NONE}, /* * Other features. * These features are applied all at once, after final_reordering. + * Default Bengali font in Windows for example has intermixed + * lookups for init,pres,abvs,blws features. */ - {HB_TAG('i','n','i','t'), false}, - {HB_TAG('p','r','e','s'), true}, - {HB_TAG('a','b','v','s'), true}, - {HB_TAG('b','l','w','s'), true}, - {HB_TAG('p','s','t','s'), true}, - {HB_TAG('h','a','l','n'), true}, + {HB_TAG('i','n','i','t'), F_NONE}, + {HB_TAG('p','r','e','s'), F_GLOBAL}, + {HB_TAG('a','b','v','s'), F_GLOBAL}, + {HB_TAG('b','l','w','s'), F_GLOBAL}, + {HB_TAG('p','s','t','s'), F_GLOBAL}, + {HB_TAG('h','a','l','n'), F_GLOBAL}, /* Positioning features, though we don't care about the types. */ - {HB_TAG('d','i','s','t'), true}, - {HB_TAG('a','b','v','m'), true}, - {HB_TAG('b','l','w','m'), true}, + {HB_TAG('d','i','s','t'), F_GLOBAL}, + {HB_TAG('a','b','v','m'), F_GLOBAL}, + {HB_TAG('b','l','w','m'), F_GLOBAL}, }; /* @@ -182,13 +389,13 @@ enum { RPHF, _RKRF, PREF, - HALF, BLWF, ABVF, + HALF, PSTF, - CFAR, - _CJCT, _VATU, + _CJCT, + CFAR, INIT, _PRES, @@ -216,6 +423,10 @@ static void final_reordering (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +static void +clear_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); static void collect_features_indic (hb_ot_shape_planner_t *plan) @@ -225,48 +436,60 @@ collect_features_indic (hb_ot_shape_planner_t *plan) /* Do this before any lookups have been applied. */ map->add_gsub_pause (setup_syllables); - map->add_bool_feature (HB_TAG('l','o','c','l')); + map->add_global_bool_feature (HB_TAG('l','o','c','l')); /* The Indic specs do not require ccmp, but we apply it here since if * there is a use of it, it's typically at the beginning. */ - map->add_bool_feature (HB_TAG('c','c','m','p')); + map->add_global_bool_feature (HB_TAG('c','c','m','p')); unsigned int i = 0; map->add_gsub_pause (initial_reordering); for (; i < INDIC_BASIC_FEATURES; i++) { - map->add_bool_feature (indic_features[i].tag, indic_features[i].is_global); + map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ); map->add_gsub_pause (NULL); } map->add_gsub_pause (final_reordering); for (; i < INDIC_NUM_FEATURES; i++) { - map->add_bool_feature (indic_features[i].tag, indic_features[i].is_global); + map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ); } + + map->add_global_bool_feature (HB_TAG('c','a','l','t')); + map->add_global_bool_feature (HB_TAG('c','l','i','g')); + + map->add_gsub_pause (clear_syllables); } static void override_features_indic (hb_ot_shape_planner_t *plan) { - /* Uniscribe does not apply 'kern'. */ - if (indic_options ().uniscribe_bug_compatible) - plan->map.add_feature (HB_TAG('k','e','r','n'), 0, true); + /* Uniscribe does not apply 'kern' in Khmer. */ + if (hb_options ().uniscribe_bug_compatible) + { + switch ((hb_tag_t) plan->props.script) + { + case HB_SCRIPT_KHMER: + plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL); + break; + } + } - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true); + plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); } struct would_substitute_feature_t { - inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag) + inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_) { + zero_context = zero_context_; map->get_stage_lookups (0/*GSUB*/, map->get_feature_stage (0/*GSUB*/, feature_tag), &lookups, &count); } - inline bool would_substitute (hb_codepoint_t *glyphs, - unsigned int glyphs_count, - bool zero_context, - hb_face_t *face) const + inline bool would_substitute (const hb_codepoint_t *glyphs, + unsigned int glyphs_count, + hb_face_t *face) const { for (unsigned int i = 0; i < count; i++) if (hb_ot_layout_lookup_would_substitute_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context)) @@ -277,6 +500,7 @@ struct would_substitute_feature_t private: const hb_ot_map_t::lookup_map_t *lookups; unsigned int count; + bool zero_context; }; struct indic_shape_plan_t @@ -329,16 +553,20 @@ data_create_indic (const hb_ot_shape_plan_t *plan) break; } - indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FF) != '2'); + indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2'); indic_plan->virama_glyph = (hb_codepoint_t) -1; - indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f')); - indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f')); - indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f')); - indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f')); + /* Use zero-context would_substitute() matching for new-spec of the main + * Indic scripts, and scripts with one spec only, but not for old-specs. */ + bool zero_context = !indic_plan->is_old_spec; + indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context); + indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context); + indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context); + indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context); for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++) - indic_plan->mask_array[i] = indic_features[i].is_global ? 0 : plan->map.get_1_mask (indic_features[i].tag); + indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ? + 0 : plan->map.get_1_mask (indic_features[i].tag); return indic_plan; } @@ -351,13 +579,34 @@ data_destroy_indic (void *data) static indic_position_t consonant_position_from_face (const indic_shape_plan_t *indic_plan, - hb_codepoint_t *glyphs, unsigned int glyphs_len, - hb_face_t *face) + const hb_codepoint_t consonant, + const hb_codepoint_t virama, + hb_face_t *face) { - bool zero_context = indic_plan->is_old_spec ? false : true; - if (indic_plan->pref.would_substitute (glyphs, glyphs_len, zero_context, face)) return POS_BELOW_C; - if (indic_plan->blwf.would_substitute (glyphs, glyphs_len, zero_context, face)) return POS_BELOW_C; - if (indic_plan->pstf.would_substitute (glyphs, glyphs_len, zero_context, face)) return POS_POST_C; + /* For old-spec, the order of glyphs is Consonant,Virama, + * whereas for new-spec, it's Virama,Consonant. However, + * some broken fonts (like Free Sans) simply copied lookups + * from old-spec to new-spec without modification. + * And oddly enough, Uniscribe seems to respect those lookups. + * Eg. in the sequence U+0924,U+094D,U+0930, Uniscribe finds + * base at 0. The font however, only has lookups matching + * 930,94D in 'blwf', not the expected 94D,930 (with new-spec + * table). As such, we simply match both sequences. Seems + * to work. */ + hb_codepoint_t glyphs[3] = {virama, consonant, virama}; + if (indic_plan->blwf.would_substitute (glyphs , 2, face) || + indic_plan->blwf.would_substitute (glyphs+1, 2, face)) + return POS_BELOW_C; + if (indic_plan->pstf.would_substitute (glyphs , 2, face) || + indic_plan->pstf.would_substitute (glyphs+1, 2, face)) + return POS_POST_C; + unsigned int pref_len = indic_plan->config->pref_len; + if ((pref_len == PREF_LEN_2 && + (indic_plan->pref.would_substitute (glyphs , 2, face) || + indic_plan->pref.would_substitute (glyphs+1, 2, face))) + || (pref_len == PREF_LEN_1 && + indic_plan->pref.would_substitute (glyphs+1, 1, face))) + return POS_POST_C; return POS_BASE_C; } @@ -366,6 +615,7 @@ enum syllable_type_t { consonant_syllable, vowel_syllable, standalone_cluster, + symbol_cluster, broken_cluster, non_indic_cluster, }; @@ -385,8 +635,9 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, * and setup masks later on in a pause-callback. */ unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - set_indic_properties (buffer->info[i]); + set_indic_properties (info[i]); } static void @@ -415,16 +666,20 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan, { const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; - unsigned int consonant_pos = indic_plan->is_old_spec ? 0 : 1; - hb_codepoint_t glyphs[2]; - if (indic_plan->get_virama_glyph (font, &glyphs[1 - consonant_pos])) + if (indic_plan->config->base_pos != BASE_POS_LAST) + return; + + hb_codepoint_t virama; + if (indic_plan->get_virama_glyph (font, &virama)) { hb_face_t *face = font->face; unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - if (buffer->info[i].indic_position() == POS_BASE_C) { - glyphs[consonant_pos] = buffer->info[i].codepoint; - buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, glyphs, 2, face); + if (info[i].indic_position() == POS_BASE_C) + { + hb_codepoint_t consonant = info[i].codepoint; + info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face); } } } @@ -465,7 +720,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * and has more than one consonant, Ra is excluded from candidates for * base consonants. */ unsigned int limit = start; - if (indic_plan->mask_array[RPHF] && + if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE && + indic_plan->mask_array[RPHF] && start + 3 <= end && ( (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) || @@ -473,8 +729,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, )) { /* See if it matches the 'rphf' feature. */ - hb_codepoint_t glyphs[2] = {info[start].codepoint, info[start + 1].codepoint}; - if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face)) + hb_codepoint_t glyphs[3] = {info[start].codepoint, + info[start + 1].codepoint, + indic_plan->config->reph_mode == REPH_MODE_EXPLICIT ? + info[start + 2].codepoint : 0}; + if (indic_plan->rphf.would_substitute (glyphs, 2, face) || + (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && + indic_plan->rphf.would_substitute (glyphs, 3, face))) { limit += 2; while (limit < end && is_joiner (info[limit])) @@ -522,7 +783,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * * IMPLEMENTATION NOTES: * - * Our pre-base reordering Ra's are marked POS_BELOW, so will be skipped + * Our pre-base reordering Ra's are marked POS_POST_C, so will be skipped * by the logic above already. */ @@ -546,9 +807,12 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, } break; - case BASE_POS_FIRST: + case BASE_POS_LAST_SINHALA: { - /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */ + /* Sinhala base positioning is slightly different from main Indic, in that: + * 1. Its ZWJ behavior is different, + * 2. We don't need to look into the font for consonant positions. + */ if (!has_reph) base = limit; @@ -556,7 +820,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, /* Find the last base consonant that is not blocked by ZWJ. If there is * a ZWJ right before a base consonant, that would request a subjoined form. */ for (unsigned int i = limit; i < end; i++) - if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C) + if (is_consonant (info[i])) { if (limit < i && info[i - 1].indic_category() == OT_ZWJ) break; @@ -566,7 +830,23 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, /* Mark all subsequent consonants as below. */ for (unsigned int i = base + 1; i < end; i++) - if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C) + if (is_consonant (info[i])) + info[i].indic_position() = POS_BELOW_C; + } + break; + + case BASE_POS_FIRST: + { + /* The first consonant is always the base. */ + + assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA); + assert (!has_reph); + + base = start; + + /* Mark all subsequent consonants as below. */ + for (unsigned int i = base + 1; i < end; i++) + if (is_consonant (info[i])) info[i].indic_position() = POS_BELOW_C; } break; @@ -577,15 +857,12 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * base consonants. * * Only do this for unforced Reph. (ie. not for Ra,H,ZWJ. */ - if (has_reph && base == start && start - limit <= 2) { + if (has_reph && base == start && limit - base <= 2) { /* Have no other consonant, so Reph is not formed and Ra becomes base. */ has_reph = false; } } - if (base < end) - info[base].indic_position() = POS_BASE_C; - /* 2. Decompose and reorder Matras: * @@ -644,14 +921,32 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, info[start].indic_position() = POS_RA_TO_BECOME_REPH; /* For old-style Indic script tags, move the first post-base Halant after - * last consonant. Only do this if there is *not* a Halant after last - * consonant. Otherwise it becomes messy. */ - if (indic_plan->is_old_spec) { + * last consonant. + * + * Reports suggest that in some scripts Uniscribe does this only if there + * is *not* a Halant after last consonant already (eg. Kannada), while it + * does it unconditionally in other scripts (eg. Malayalam). We don't + * currently know about other scripts, so we single out Malayalam for now. + * + * Kannada test case: + * U+0C9A,U+0CCD,U+0C9A,U+0CCD + * With some versions of Lohit Kannada. + * https://bugs.freedesktop.org/show_bug.cgi?id=59118 + * + * Malayalam test case: + * U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D + * With lohit-ttf-20121122/Lohit-Malayalam.ttf + */ + if (indic_plan->is_old_spec) + { + bool disallow_double_halants = buffer->props.script != HB_SCRIPT_MALAYALAM; for (unsigned int i = base + 1; i < end; i++) - if (info[i].indic_category() == OT_H) { + if (info[i].indic_category() == OT_H) + { unsigned int j; for (j = end - 1; j > i; j--) - if (is_consonant (info[j]) || info[j].indic_category() == OT_H) + if (is_consonant (info[j]) || + (disallow_double_halants && info[j].indic_category() == OT_H)) break; if (info[j].indic_category() != OT_H && j > i) { /* Move Halant to after last consonant. */ @@ -668,7 +963,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, indic_position_t last_pos = POS_START; for (unsigned int i = start; i < end; i++) { - if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | HALANT_OR_COENG_FLAGS))) + if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS))) { info[i].indic_position() = last_pos; if (unlikely (info[i].indic_category() == OT_H && @@ -694,33 +989,68 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, } } } - /* Re-attach ZWJ, ZWNJ, and halant to next char, for after-base consonants. */ + /* For post-base consonants let them own anything before them + * since the last consonant or matra. */ { - unsigned int last_halant = end; + unsigned int last = base; for (unsigned int i = base + 1; i < end; i++) - if (is_halant_or_coeng (info[i])) - last_halant = i; - else if (is_consonant (info[i])) { - for (unsigned int j = last_halant; j < i; j++) - if (info[j].indic_position() != POS_SMVD) + if (is_consonant (info[i])) + { + for (unsigned int j = last + 1; j < i; j++) + if (info[j].indic_position() < POS_SMVD) info[j].indic_position() = info[i].indic_position(); - } + last = i; + } else if (info[i].indic_category() == OT_M) + last = i; } + { - /* Things are out-of-control for post base positions, they may shuffle - * around like crazy, so merge clusters. For pre-base stuff, we handle - * cluster issues in final reordering. */ - buffer->merge_clusters (base, end); + /* Use syllable() for sort accounting temporarily. */ + unsigned int syllable = info[start].syllable(); + for (unsigned int i = start; i < end; i++) + info[i].syllable() = i - start; + /* Sit tight, rock 'n roll! */ hb_bubble_sort (info + start, end - start, compare_indic_order); /* Find base again */ base = end; for (unsigned int i = start; i < end; i++) - if (info[i].indic_position() == POS_BASE_C) { - base = i; + if (info[i].indic_position() == POS_BASE_C) + { + base = i; break; } + /* Things are out-of-control for post base positions, they may shuffle + * around like crazy. In old-spec mode, we move halants around, so in + * that case merge all clusters after base. Otherwise, check the sort + * order and merge as needed. + * For pre-base stuff, we handle cluster issues in final reordering. */ + if (indic_plan->is_old_spec || end - base > 127) + buffer->merge_clusters (base, end); + else + { + /* Note! syllable() is a one-byte field. */ + for (unsigned int i = base; i < end; i++) + if (info[i].syllable() != 255) + { + unsigned int max = i; + unsigned int j = start + info[i].syllable(); + while (j != i) + { + max = MAX (max, j); + unsigned int next = start + info[j].syllable(); + info[j].syllable() = 255; /* So we don't process j later again. */ + j = next; + } + if (i != max) + buffer->merge_clusters (i, max + 1); + } + } + + /* Put syllable back in. */ + for (unsigned int i = start; i < end; i++) + info[i].syllable() = syllable; } /* Setup masks now */ @@ -734,6 +1064,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, /* Pre-base */ mask = indic_plan->mask_array[HALF]; + if (!indic_plan->is_old_spec && + indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST) + mask |= indic_plan->mask_array[BLWF]; for (unsigned int i = start; i < base; i++) info[i].mask |= mask; /* Base */ @@ -746,15 +1079,51 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, info[i].mask |= mask; } - if (indic_plan->mask_array[PREF] && base + 2 < end) + if (indic_plan->is_old_spec && + buffer->props.script == HB_SCRIPT_DEVANAGARI) + { + /* Old-spec eye-lash Ra needs special handling. From the + * spec: + * + * "The feature 'below-base form' is applied to consonants + * having below-base forms and following the base consonant. + * The exception is vattu, which may appear below half forms + * as well as below the base glyph. The feature 'below-base + * form' will be applied to all such occurrences of Ra as well." + * + * Test case: U+0924,U+094D,U+0930,U+094d,U+0915 + * with Sanskrit 2003 font. + * + * However, note that Ra,Halant,ZWJ is the correct way to + * request eyelash form of Ra, so we wouldbn't inhibit it + * in that sequence. + * + * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915 + */ + for (unsigned int i = start; i + 1 < base; i++) + if (info[i ].indic_category() == OT_Ra && + info[i+1].indic_category() == OT_H && + (i + 2 == base || + info[i+2].indic_category() != OT_ZWJ)) + { + info[i ].mask |= indic_plan->mask_array[BLWF]; + info[i+1].mask |= indic_plan->mask_array[BLWF]; + } + } + + unsigned int pref_len = indic_plan->config->pref_len; + if (indic_plan->mask_array[PREF] && base + pref_len < end) { + assert (1 <= pref_len && pref_len <= 2); /* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */ - for (unsigned int i = base + 1; i + 1 < end; i++) { - hb_codepoint_t glyphs[2] = {info[i].codepoint, info[i + 1].codepoint}; - if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face)) + for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) { + hb_codepoint_t glyphs[2]; + for (unsigned int j = 0; j < pref_len; j++) + glyphs[j] = info[i + j].codepoint; + if (indic_plan->pref.would_substitute (glyphs, pref_len, face)) { - info[i++].mask |= indic_plan->mask_array[PREF]; - info[i++].mask |= indic_plan->mask_array[PREF]; + for (unsigned int j = 0; j < pref_len; j++) + info[i++].mask |= indic_plan->mask_array[PREF]; /* Mark the subsequent stuff with 'cfar'. Used in Khmer. * Read the feature spec. @@ -762,8 +1131,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * U+1784,U+17D2,U+179A,U+17D2,U+1782 * U+1784,U+17D2,U+1782,U+17D2,U+179A */ - for (; i < end; i++) - info[i].mask |= indic_plan->mask_array[CFAR]; + if (indic_plan->mask_array[CFAR]) + for (; i < end; i++) + info[i].mask |= indic_plan->mask_array[CFAR]; break; } @@ -779,8 +1149,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, do { j--; - /* A ZWJ disables CJCT, however, it's mere presence is enough - * to disable ligation. No explicit action needed. */ + /* ZWJ/ZWNJ should disable CJCT. They do that by simply + * being there, since we don't skip them for the CJCT + * feature (ie. F_MANUAL_ZWJ) */ /* A ZWNJ disables HALF. */ if (non_joiner) @@ -807,10 +1178,10 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, unsigned int start, unsigned int end) { - /* We treat NBSP/dotted-circle as if they are consonants, so we should just chain. - * Only if not in compatibility mode that is... */ + /* We treat placeholder/dotted-circle as if they are consonants, so we + * should just chain. Only if not in compatibility mode that is... */ - if (indic_options ().uniscribe_bug_compatible) + if (hb_options ().uniscribe_bug_compatible) { /* For dotted-circle, this is what Uniscribe does: * If dotted-circle is the last glyph, it just does nothing. @@ -833,6 +1204,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, } static void +initial_reordering_symbol_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_face_t *face HB_UNUSED, + hb_buffer_t *buffer HB_UNUSED, + unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) +{ + /* Nothing to do right now. If we ever switch to using the output + * buffer in the reordering process, we'd need to next_glyph() here. */ +} + +static void initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_face_t *face HB_UNUSED, hb_buffer_t *buffer HB_UNUSED, @@ -854,6 +1235,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan, case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return; case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return; case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return; + case symbol_cluster: initial_reordering_symbol_cluster (plan, face, buffer, start, end); return; case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return; case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return; } @@ -867,8 +1249,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* Note: This loop is extra overhead, but should not be measurable. */ bool has_broken_syllables = false; unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) { + if ((info[i].syllable() & 0x0F) == broken_cluster) + { has_broken_syllables = true; break; } @@ -877,11 +1261,11 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph)) + if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) return; hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CC; + dottedcircle.codepoint = 0x25CCu; set_indic_properties (dottedcircle); dottedcircle.codepoint = dottedcircle_glyph; @@ -901,6 +1285,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, info.cluster = buffer->cur().cluster; info.mask = buffer->cur().mask; info.syllable() = buffer->cur().syllable(); + /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ while (buffer->idx < buffer->len && @@ -947,6 +1332,27 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; hb_glyph_info_t *info = buffer->info; + + /* This function relies heavily on halant glyphs. Lots of ligation + * and possibly multiplication substitutions happened prior to this + * phase, and that might have messed up our properties. Recover + * from a particular case of that where we're fairly sure that a + * class of OT_H is desired but has been lost. */ + if (indic_plan->virama_glyph) + { + unsigned int virama_glyph = indic_plan->virama_glyph; + for (unsigned int i = start; i < end; i++) + if (info[i].codepoint == virama_glyph && + _hb_glyph_info_ligated (&info[i]) && + _hb_glyph_info_multiplied (&info[i])) + { + /* This will make sure that this glyph passes is_halant_or_coeng() test. */ + info[i].indic_category() = OT_H; + _hb_glyph_info_clear_ligated_and_multiplied (&info[i]); + } + } + + /* 4. Final reordering: * * After the localized forms and basic shaping forms GSUB features have been @@ -955,14 +1361,45 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * cluster. */ + bool try_pref = !!indic_plan->mask_array[PREF]; + /* Find base again */ unsigned int base; for (base = start; base < end; base++) - if (info[base].indic_position() >= POS_BASE_C) { + if (info[base].indic_position() >= POS_BASE_C) + { + if (try_pref && base + 1 < end && indic_plan->config->pref_len == 2) + { + for (unsigned int i = base + 1; i < end; i++) + if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) + { + if (!(_hb_glyph_info_substituted (&info[i]) && + _hb_glyph_info_ligated_and_didnt_multiply (&info[i]))) + { + /* Ok, this was a 'pref' candidate but didn't form any. + * Base is around here... */ + base = i; + while (base < end && is_halant_or_coeng (info[base])) + base++; + info[base].indic_position() = POS_BASE_C; + + try_pref = false; + } + break; + } + } + if (start < base && info[base].indic_position() > POS_BASE_C) base--; break; } + if (base == end && start < base && + is_one_of (info[base - 1], FLAG (OT_ZWJ))) + base--; + if (base < end) + while (start < base && + is_one_of (info[base], (FLAG (OT_N) | HALANT_OR_COENG_FLAGS))) + base--; /* o Reorder matras: @@ -987,7 +1424,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL) { while (new_pos > start && - !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H) | FLAG (OT_Coeng))))) + !(is_one_of (info[new_pos], (FLAG (OT_M) | HALANT_OR_COENG_FLAGS)))) new_pos--; /* If we found no Halant we are done. @@ -1014,9 +1451,11 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, hb_glyph_info_t tmp = info[old_pos]; memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0])); info[new_pos] = tmp; + if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */ + base--; + buffer->merge_clusters (new_pos, MIN (end, base + 1)); new_pos--; } - buffer->merge_clusters (new_pos, MIN (end, base + 1)); } else { for (unsigned int i = start; i < base; i++) if (info[i].indic_position () == POS_PRE_M) { @@ -1036,17 +1475,24 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * before post-base consonant forms, and after post-base consonant forms. */ - /* If there's anything after the Ra that has the REPH pos, it ought to be halant. - * Which means that the font has failed to ligate the Reph. In which case, we - * shouldn't move. */ + /* Two cases: + * + * - If repha is encoded as a sequence of characters (Ra,H or Ra,H,ZWJ), then + * we should only move it if the sequence ligated to the repha form. + * + * - If repha is encoded separately and in the logical position, we should only + * move it if it did NOT ligate. If it ligated, it's probably the font trying + * to make it work without the reordering. + */ if (start + 1 < end && info[start].indic_position() == POS_RA_TO_BECOME_REPH && - info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH) + ((info[start].indic_category() == OT_Repha) ^ + _hb_glyph_info_ligated_and_didnt_multiply (&info[start]))) { unsigned int new_reph_pos; reph_position_t reph_pos = indic_plan->config->reph_pos; - /* XXX Figure out old behavior too */ + assert (reph_pos != REPH_POS_DONT_CARE); /* 1. If reph should be positioned after post-base consonant forms, * proceed to step 5. @@ -1072,7 +1518,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos])) new_reph_pos++; - if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) { + if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) + { /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */ if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1])) new_reph_pos++; @@ -1087,7 +1534,6 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, if (reph_pos == REPH_POS_AFTER_MAIN) { new_reph_pos = base; - /* XXX Skip potential pre-base reordering Ra. */ while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN) new_reph_pos++; if (new_reph_pos < end) @@ -1124,7 +1570,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos])) new_reph_pos++; - if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) { + if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) + { /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */ if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1])) new_reph_pos++; @@ -1146,7 +1593,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * Uniscribe doesn't do this. * TEST: U+0930,U+094D,U+0915,U+094B,U+094D */ - if (!indic_options ().uniscribe_bug_compatible && + if (!hb_options ().uniscribe_bug_compatible && unlikely (is_halant_or_coeng (info[new_reph_pos]))) { for (unsigned int i = base + 1; i < new_reph_pos; i++) if (info[i].indic_category() == OT_M) { @@ -1159,13 +1606,14 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, reph_move: { - /* Yay, one big cluster! Merge before moving. */ - buffer->merge_clusters (start, end); + buffer->merge_clusters (start, new_reph_pos + 1); /* Move */ hb_glyph_info_t reph = info[start]; memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (info[0])); info[new_reph_pos] = reph; + if (start < base && base <= new_reph_pos) + base--; } } @@ -1176,8 +1624,9 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * the following rules: */ - if (indic_plan->mask_array[PREF] && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */ + if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */ { + unsigned int pref_len = indic_plan->config->pref_len; for (unsigned int i = base + 1; i < end; i++) if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) { @@ -1185,7 +1634,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * of the <pref> feature. (Note that a font may shape a Ra consonant with * the feature generally but block it in certain contexts.) */ - if (i + 1 == end || (info[i + 1].mask & indic_plan->mask_array[PREF]) == 0) + /* Note: We just check that something got substituted. We don't check that + * the <pref> feature actually did it... + * + * If pref len is longer than one, then only reorder if it ligated. If + * pref len is one, only reorder if it didn't ligate with other things. */ + if (_hb_glyph_info_substituted (&info[i]) && + ((pref_len == 1) ^ _hb_glyph_info_ligated_and_didnt_multiply (&info[i]))) { /* * 2. Try to find a target position the same way as for pre-base matra. @@ -1206,7 +1661,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, !(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS))) new_pos--; - /* In Khmer coeng model, a V,Ra can go *after* matras. If it goes after a + /* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a * split matra, it should be reordered to *before* the left part of such matra. */ if (new_pos > start && info[new_pos - 1].indic_category() == OT_M) { @@ -1221,9 +1676,11 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, } if (new_pos > start && is_halant_or_coeng (info[new_pos - 1])) + { /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ if (new_pos < end && is_joiner (info[new_pos])) new_pos++; + } { unsigned int old_pos = i; @@ -1231,6 +1688,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, hb_glyph_info_t tmp = info[old_pos]; memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0])); info[new_pos] = tmp; + if (new_pos <= base && base < old_pos) + base++; } } @@ -1250,13 +1709,22 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, /* * Finish off the clusters and go home! */ - if (indic_options ().uniscribe_bug_compatible) + if (hb_options ().uniscribe_bug_compatible) { - /* Uniscribe merges the entire cluster. - * This means, half forms are submerged into the main consonants cluster. - * This is unnecessary, and makes cursor positioning harder, but that's what - * Uniscribe does. */ - buffer->merge_clusters (start, end); + switch ((hb_tag_t) plan->props.script) + { + case HB_SCRIPT_TAMIL: + case HB_SCRIPT_SINHALA: + break; + + default: + /* Uniscribe merges the entire cluster... Except for Tamil & Sinhala. + * This means, half forms are submerged into the main consonants cluster. + * This is unnecessary, and makes cursor positioning harder, but that's what + * Uniscribe does. */ + buffer->merge_clusters (start, end); + break; + } } } @@ -1280,21 +1748,23 @@ final_reordering (const hb_ot_shape_plan_t *plan, } final_reordering_syllable (plan, buffer, last, count); - /* Zero syllables now... */ - for (unsigned int i = 0; i < count; i++) - info[i].syllable() = 0; - HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category); HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position); } -static hb_ot_shape_normalization_mode_t -normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED) +static void +clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) { - return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT; + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + info[i].syllable() = 0; } + static bool decompose_indic (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t ab, @@ -1304,37 +1774,37 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, switch (ab) { /* Don't decompose these. */ - case 0x0931 : return false; - case 0x0B94 : return false; + case 0x0931u : return false; + case 0x0B94u : return false; /* * Decompose split matras that don't have Unicode decompositions. */ - case 0x0F77 : *a = 0x0FB2; *b= 0x0F81; return true; - case 0x0F79 : *a = 0x0FB3; *b= 0x0F81; return true; - case 0x17BE : *a = 0x17C1; *b= 0x17BE; return true; - case 0x17BF : *a = 0x17C1; *b= 0x17BF; return true; - case 0x17C0 : *a = 0x17C1; *b= 0x17C0; return true; - case 0x17C4 : *a = 0x17C1; *b= 0x17C4; return true; - case 0x17C5 : *a = 0x17C1; *b= 0x17C5; return true; - case 0x1925 : *a = 0x1920; *b= 0x1923; return true; - case 0x1926 : *a = 0x1920; *b= 0x1924; return true; - case 0x1B3C : *a = 0x1B42; *b= 0x1B3C; return true; - case 0x1112E : *a = 0x11127; *b= 0x11131; return true; - case 0x1112F : *a = 0x11127; *b= 0x11132; return true; + case 0x0F77u : *a = 0x0FB2u; *b= 0x0F81u; return true; + case 0x0F79u : *a = 0x0FB3u; *b= 0x0F81u; return true; + case 0x17BEu : *a = 0x17C1u; *b= 0x17BEu; return true; + case 0x17BFu : *a = 0x17C1u; *b= 0x17BFu; return true; + case 0x17C0u : *a = 0x17C1u; *b= 0x17C0u; return true; + case 0x17C4u : *a = 0x17C1u; *b= 0x17C4u; return true; + case 0x17C5u : *a = 0x17C1u; *b= 0x17C5u; return true; + case 0x1925u : *a = 0x1920u; *b= 0x1923u; return true; + case 0x1926u : *a = 0x1920u; *b= 0x1924u; return true; + case 0x1B3Cu : *a = 0x1B42u; *b= 0x1B3Cu; return true; + case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true; + case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true; #if 0 /* This one has no decomposition in Unicode, but needs no decomposition either. */ - /* case 0x0AC9 : return false; */ - case 0x0B57 : *a = no decomp, -> RIGHT; return true; - case 0x1C29 : *a = no decomp, -> LEFT; return true; - case 0xA9C0 : *a = no decomp, -> RIGHT; return true; - case 0x111BF : *a = no decomp, -> ABOVE; return true; + /* case 0x0AC9u : return false; */ + case 0x0B57u : *a = no decomp, -> RIGHT; return true; + case 0x1C29u : *a = no decomp, -> LEFT; return true; + case 0xA9C0u : *a = no decomp, -> RIGHT; return true; + case 0x111BuF : *a = no decomp, -> ABOVE; return true; #endif } - if ((ab == 0x0DDA || hb_in_range<hb_codepoint_t> (ab, 0x0DDC, 0x0DDE))) + if ((ab == 0x0DDAu || hb_in_range (ab, 0x0DDCu, 0x0DDEu))) { /* * Sinhala split matras... Let the fun begin. @@ -1366,12 +1836,12 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t glyph; - if (indic_options ().uniscribe_bug_compatible || + if (hb_options ().uniscribe_bug_compatible || (c->font->get_glyph (ab, 0, &glyph) && - indic_plan->pstf.would_substitute (&glyph, 1, true, c->font->face))) + indic_plan->pstf.would_substitute (&glyph, 1, c->font->face))) { /* Ok, safe to use Uniscribe-style decomposition. */ - *a = 0x0DD9; + *a = 0x0DD9u; *b = ab; return true; } @@ -1391,7 +1861,7 @@ compose_indic (const hb_ot_shape_normalize_context_t *c, return false; /* Composition-exclusion exceptions that we want to recompose. */ - if (a == 0x09AF && b == 0x09BC) { *ab = 0x09DF; return true; } + if (a == 0x09AFu && b == 0x09BCu) { *ab = 0x09DFu; return true; } return c->unicode->compose (a, b, ab); } @@ -1405,10 +1875,10 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic = data_create_indic, data_destroy_indic, NULL, /* preprocess_text */ - normalization_preference_indic, + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, decompose_indic, compose_indic, setup_masks_indic, - false, /* zero_width_attached_marks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/src/hb-ot-shape-complex-myanmar-machine.hh b/src/hb-ot-shape-complex-myanmar-machine.hh new file mode 100644 index 0000000..bb80d7a --- /dev/null +++ b/src/hb-ot-shape-complex-myanmar-machine.hh @@ -0,0 +1,400 @@ + +#line 1 "../../src/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.tmp" +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 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + + + +#line 93 "../../src/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.tmp" + { + cs = myanmar_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 114 "../../src/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.tmp" + { + 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.tmp" + } + + _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 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (consonant_syllable); }} + break; + case 5: +#line 86 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (non_myanmar_cluster); }} + break; + case 10: +#line 87 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (punctuation_cluster); }} + break; + case 4: +#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (broken_cluster); }} + break; + case 3: +#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (non_myanmar_cluster); }} + break; + case 6: +#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (consonant_syllable); }} + break; + case 8: +#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (broken_cluster); }} + break; + case 9: +#line 89 "../../src/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.tmp" + } + +_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.tmp" + } + + 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 "../../src/hb-ot-shape-complex-myanmar-machine.rl" + +} + +#undef found_syllable + +#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */ diff --git a/src/hb-ot-shape-complex-myanmar-machine.rl b/src/hb-ot-shape-complex-myanmar-machine.rl new file mode 100644 index 0000000..9649a91 --- /dev/null +++ b/src/hb-ot-shape-complex-myanmar-machine.rl @@ -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 */ diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc new file mode 100644 index 0000000..d016380 --- /dev/null +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -0,0 +1,571 @@ +/* + * Copyright © 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-ot-shape-complex-indic-private.hh" + +/* buffer var allocations */ +#define myanmar_category() complex_var_u8_0() /* myanmar_category_t */ +#define myanmar_position() complex_var_u8_1() /* myanmar_position_t */ + + +/* + * Myanmar shaper. + */ + +static const hb_tag_t +basic_features[] = +{ + /* + * Basic features. + * These features are applied in order, one at a time, after initial_reordering. + */ + HB_TAG('r','p','h','f'), + HB_TAG('p','r','e','f'), + HB_TAG('b','l','w','f'), + HB_TAG('p','s','t','f'), +}; +static const hb_tag_t +other_features[] = +{ + /* + * Other features. + * These features are applied all at once, after final_reordering. + */ + HB_TAG('p','r','e','s'), + HB_TAG('a','b','v','s'), + HB_TAG('b','l','w','s'), + HB_TAG('p','s','t','s'), + /* Positioning features, though we don't care about the types. */ + HB_TAG('d','i','s','t'), + /* Pre-release version of Windows 8 Myanmar font had abvm,blwm + * features. The released Windows 8 version of the font (as well + * as the released spec) used 'mark' instead. The Windows 8 + * shaper however didn't apply 'mark' but did apply 'mkmk'. + * Perhaps it applied abvm/blwm. This was fixed in a Windows 8 + * update, so now it applies mark/mkmk. We are guessing that + * it still applies abvm/blwm too. + */ + HB_TAG('a','b','v','m'), + HB_TAG('b','l','w','m'), +}; + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +initial_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +final_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +static void +collect_features_myanmar (hb_ot_shape_planner_t *plan) +{ + hb_ot_map_builder_t *map = &plan->map; + + /* Do this before any lookups have been applied. */ + map->add_gsub_pause (setup_syllables); + + map->add_global_bool_feature (HB_TAG('l','o','c','l')); + /* The Indic specs do not require ccmp, but we apply it here since if + * there is a use of it, it's typically at the beginning. */ + map->add_global_bool_feature (HB_TAG('c','c','m','p')); + + + map->add_gsub_pause (initial_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) + { + map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->add_gsub_pause (NULL); + } + map->add_gsub_pause (final_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) + map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); +} + +static void +override_features_myanmar (hb_ot_shape_planner_t *plan) +{ + plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); +} + + +enum syllable_type_t { + consonant_syllable, + punctuation_cluster, + broken_cluster, + non_myanmar_cluster, +}; + +#include "hb-ot-shape-complex-myanmar-machine.hh" + + +/* Note: This enum is duplicated in the -machine.rl source file. + * Not sure how to avoid duplication. */ +enum myanmar_category_t { + OT_As = 18, /* Asat */ + OT_D = 19, /* Digits except zero */ + OT_D0 = 20, /* Digit zero */ + OT_DB = OT_N, /* Dot below */ + OT_GB = OT_PLACEHOLDER, + OT_MH = 21, /* Various consonant medial types */ + OT_MR = 22, /* Various consonant medial types */ + OT_MW = 23, /* Various consonant medial types */ + OT_MY = 24, /* Various consonant medial types */ + OT_PT = 25, /* Pwo and other tones */ + OT_VAbv = 26, + OT_VBlw = 27, + OT_VPre = 28, + OT_VPst = 29, + OT_VS = 30, /* Variation selectors */ + OT_P = 31 /* Punctuation */ +}; + + +static inline bool +is_one_of (const hb_glyph_info_t &info, unsigned int flags) +{ + /* If it ligated, all bets are off. */ + if (_hb_glyph_info_ligated (&info)) return false; + return !!(FLAG (info.myanmar_category()) & flags); +} + +static inline bool +is_consonant (const hb_glyph_info_t &info) +{ + return is_one_of (info, CONSONANT_FLAGS); +} + + +static inline void +set_myanmar_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_position_t pos = (indic_position_t) (type >> 8); + + /* Myanmar + * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze + */ + if (unlikely (hb_in_range (u, 0xFE00u, 0xFE0Fu))) + cat = (indic_category_t) OT_VS; + + switch (u) + { + case 0x104Eu: + cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ + break; + + case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u: + case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u: + case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu: + case 0x25FEu: + cat = (indic_category_t) OT_GB; + break; + + case 0x1004u: case 0x101Bu: case 0x105Au: + cat = (indic_category_t) OT_Ra; + break; + + case 0x1032u: case 0x1036u: + cat = (indic_category_t) OT_A; + break; + + case 0x103Au: + cat = (indic_category_t) OT_As; + break; + + case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u: + case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u: + case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u: + case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u: + case 0x1097u: case 0x1098u: case 0x1099u: + cat = (indic_category_t) OT_D; + break; + + case 0x1040u: + cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ + break; + + case 0x103Eu: case 0x1060u: + cat = (indic_category_t) OT_MH; + break; + + case 0x103Cu: + cat = (indic_category_t) OT_MR; + break; + + case 0x103Du: case 0x1082u: + cat = (indic_category_t) OT_MW; + break; + + case 0x103Bu: case 0x105Eu: case 0x105Fu: + cat = (indic_category_t) OT_MY; + break; + + case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au: + case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu: + cat = (indic_category_t) OT_PT; + break; + + case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u: + case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du: + case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu: + cat = (indic_category_t) OT_SM; + break; + + case 0x104Au: case 0x104Bu: + cat = (indic_category_t) OT_P; + break; + } + + if (cat == OT_M) + { + switch ((int) pos) + { + case POS_PRE_C: cat = (indic_category_t) OT_VPre; + pos = POS_PRE_M; break; + case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; + case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; + case POS_POST_C: cat = (indic_category_t) OT_VPst; break; + } + } + + info.myanmar_category() = (myanmar_category_t) cat; + info.myanmar_position() = pos; +} + + + +static void +setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) +{ + HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category); + HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position); + + /* We cannot setup masks here. We save information about characters + * and setup masks later on in a pause-callback. */ + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + set_myanmar_properties (info[i]); +} + +static void +setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + find_syllables (buffer); +} + +static int +compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) +{ + int a = pa->myanmar_position(); + int b = pb->myanmar_position(); + + return a < b ? -1 : a == b ? 0 : +1; +} + + +/* Rules from: + * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */ + +static void +initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + hb_glyph_info_t *info = buffer->info; + + unsigned int base = end; + bool has_reph = false; + + { + unsigned int limit = start; + if (start + 3 <= end && + info[start ].myanmar_category() == OT_Ra && + info[start+1].myanmar_category() == OT_As && + info[start+2].myanmar_category() == OT_H) + { + limit += 3; + base = start; + has_reph = true; + } + + { + if (!has_reph) + base = limit; + + for (unsigned int i = limit; i < end; i++) + if (is_consonant (info[i])) + { + base = i; + break; + } + } + } + + /* Reorder! */ + { + unsigned int i = start; + for (; i < start + (has_reph ? 3 : 0); i++) + info[i].myanmar_position() = POS_AFTER_MAIN; + for (; i < base; i++) + info[i].myanmar_position() = POS_PRE_C; + if (i < end) + { + info[i].myanmar_position() = POS_BASE_C; + i++; + } + indic_position_t pos = POS_AFTER_MAIN; + /* The following loop may be ugly, but it implements all of + * Myanmar reordering! */ + for (; i < end; i++) + { + if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */ + { + info[i].myanmar_position() = POS_PRE_C; + continue; + } + if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */ + { + continue; + } + + if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw) + { + pos = POS_BELOW_C; + info[i].myanmar_position() = pos; + continue; + } + + if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A) + { + info[i].myanmar_position() = POS_BEFORE_SUB; + continue; + } + if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw) + { + info[i].myanmar_position() = pos; + continue; + } + if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A) + { + pos = POS_AFTER_SUB; + info[i].myanmar_position() = pos; + continue; + } + info[i].myanmar_position() = pos; + } + } + + buffer->merge_clusters (start, end); + /* Sit tight, rock 'n roll! */ + hb_bubble_sort (info + start, end - start, compare_myanmar_order); +} + +static void +initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + /* We already inserted dotted-circles, so just call the consonant_syllable. */ + initial_reordering_consonant_syllable (plan, face, buffer, start, end); +} + +static void +initial_reordering_punctuation_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_face_t *face HB_UNUSED, + hb_buffer_t *buffer HB_UNUSED, + unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) +{ + /* Nothing to do right now. If we ever switch to using the output + * buffer in the reordering process, we'd need to next_glyph() here. */ +} + +static void +initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_face_t *face HB_UNUSED, + hb_buffer_t *buffer HB_UNUSED, + unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) +{ + /* Nothing to do right now. If we ever switch to using the output + * buffer in the reordering process, we'd need to next_glyph() here. */ +} + + +static void +initial_reordering_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); + switch (syllable_type) { + case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return; + case punctuation_cluster: initial_reordering_punctuation_cluster (plan, face, buffer, start, end); return; + case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return; + case non_myanmar_cluster: initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return; + } +} + +static inline void +insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font, + hb_buffer_t *buffer) +{ + /* Note: This loop is extra overhead, but should not be measurable. */ + bool has_broken_syllables = false; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if ((info[i].syllable() & 0x0F) == broken_cluster) + { + has_broken_syllables = true; + break; + } + if (likely (!has_broken_syllables)) + return; + + + hb_codepoint_t dottedcircle_glyph; + if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) + return; + + hb_glyph_info_t dottedcircle = {0}; + dottedcircle.codepoint = 0x25CCu; + set_myanmar_properties (dottedcircle); + dottedcircle.codepoint = dottedcircle_glyph; + + buffer->clear_output (); + + buffer->idx = 0; + unsigned int last_syllable = 0; + while (buffer->idx < buffer->len) + { + unsigned int syllable = buffer->cur().syllable(); + syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); + if (unlikely (last_syllable != syllable && syllable_type == broken_cluster)) + { + last_syllable = syllable; + + hb_glyph_info_t info = dottedcircle; + info.cluster = buffer->cur().cluster; + info.mask = buffer->cur().mask; + info.syllable() = buffer->cur().syllable(); + + buffer->output_info (info); + } + else + buffer->next_glyph (); + } + + buffer->swap_buffers (); +} + +static void +initial_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + insert_dotted_circles (plan, font, buffer); + + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + if (unlikely (!count)) return; + unsigned int last = 0; + unsigned int last_syllable = info[0].syllable(); + for (unsigned int i = 1; i < count; i++) + if (last_syllable != info[i].syllable()) { + initial_reordering_syllable (plan, font->face, buffer, last, i); + last = i; + last_syllable = info[last].syllable(); + } + initial_reordering_syllable (plan, font->face, buffer, last, count); +} + +static void +final_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + /* Zero syllables now... */ + for (unsigned int i = 0; i < count; i++) + info[i].syllable() = 0; + + HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category); + HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position); +} + + +/* Uniscribe seems to have a shaper for 'mymr' that is like the + * generic shaper, except that it zeros mark advances GDEF_LATE. */ +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old = +{ + "default", + NULL, /* collect_features */ + NULL, /* override_features */ + NULL, /* data_create */ + NULL, /* data_destroy */ + NULL, /* preprocess_text */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, + NULL, /* decompose */ + NULL, /* compose */ + NULL, /* setup_masks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, + true, /* fallback_position */ +}; + +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = +{ + "myanmar", + collect_features_myanmar, + override_features_myanmar, + NULL, /* data_create */ + NULL, /* data_destroy */ + NULL, /* preprocess_text */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, + NULL, /* decompose */ + NULL, /* compose */ + setup_masks_myanmar, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, + false, /* fallback_position */ +}; diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 26871c2..9a7afcb 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -39,13 +39,29 @@ #define complex_var_u8_1() var2.u8[3] +enum hb_ot_shape_zero_width_marks_type_t { + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, +// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, + + HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT = HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE +}; + /* Master OT shaper list */ #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \ HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \ HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \ + HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \ + HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \ + HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \ HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ + HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ + HB_COMPLEX_SHAPER_IMPLEMENT (sea) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ + HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \ /* ^--- Add new shapers here */ @@ -95,12 +111,7 @@ struct hb_ot_complex_shaper_t hb_font_t *font); - /* normalization_preference() - * Called during shape(). - * May be NULL. - */ - hb_ot_shape_normalization_mode_t - (*normalization_preference) (const hb_segment_properties_t *props); + hb_ot_shape_normalization_mode_t normalization_preference; /* decompose() * Called during shape()'s normalization. @@ -130,7 +141,8 @@ struct hb_ot_complex_shaper_t hb_buffer_t *buffer, hb_font_t *font); - bool zero_width_attached_marks; + hb_ot_shape_zero_width_marks_type_t zero_width_marks; + bool fallback_position; }; @@ -150,6 +162,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-1.1 additions */ case HB_SCRIPT_ARABIC: + + /* Unicode-3.0 additions */ case HB_SCRIPT_MONGOLIAN: case HB_SCRIPT_SYRIAC: @@ -160,6 +174,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-6.0 additions */ case HB_SCRIPT_MANDAIC: + /* Unicode-7.0 additions */ + case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_PSALTER_PAHLAVI: + /* For Arabic script, use the Arabic shaper even if no OT script tag was found. * This is because we do fallback shaping for Arabic script (and not others). */ if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || @@ -176,6 +194,23 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_thai; + /* Unicode-1.1 additions */ + case HB_SCRIPT_HANGUL: + + return &_hb_ot_complex_shaper_hangul; + + + /* Unicode-2.0 additions */ + case HB_SCRIPT_TIBETAN: + + return &_hb_ot_complex_shaper_tibetan; + + + /* Unicode-1.1 additions */ + case HB_SCRIPT_HEBREW: + + return &_hb_ot_complex_shaper_hebrew; + /* ^--- Add new shapers here */ @@ -214,9 +249,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_LAO: case HB_SCRIPT_THAI: - /* Unicode-2.0 additions */ - case HB_SCRIPT_TIBETAN: - /* Unicode-3.2 additions */ case HB_SCRIPT_TAGALOG: case HB_SCRIPT_TAGBANWA: @@ -252,15 +284,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-3.0 additions */ case HB_SCRIPT_SINHALA: - /* Unicode-4.1 additions */ - case HB_SCRIPT_BUGINESE: - case HB_SCRIPT_NEW_TAI_LUE: - /* Unicode-5.0 additions */ case HB_SCRIPT_BALINESE: /* Unicode-5.1 additions */ - case HB_SCRIPT_CHAM: case HB_SCRIPT_LEPCHA: case HB_SCRIPT_REJANG: case HB_SCRIPT_SUNDANESE: @@ -269,19 +296,22 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_JAVANESE: case HB_SCRIPT_KAITHI: case HB_SCRIPT_MEETEI_MAYEK: - case HB_SCRIPT_TAI_THAM: + /* Unicode-6.0 additions */ /* Unicode-6.1 additions */ case HB_SCRIPT_CHAKMA: case HB_SCRIPT_SHARADA: case HB_SCRIPT_TAKRI: - /* Only use Indic shaper if the font has Indic tables. */ - if (planner->map.found_script[0]) - return &_hb_ot_complex_shaper_indic; - else + /* If the designer designed the font for the 'DFLT' script, + * use the default shaper. Otherwise, use the Indic shaper. + * Note that for some simple scripts, there may not be *any* + * GSUB/GPOS needed, so there may be no scripts found! */ + if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) return &_hb_ot_complex_shaper_default; + else + return &_hb_ot_complex_shaper_indic; case HB_SCRIPT_KHMER: /* A number of Khmer fonts in the wild don't have a 'pref' feature, @@ -300,12 +330,31 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_default; case HB_SCRIPT_MYANMAR: - /* For Myanmar, we only want to use the Indic shaper if the "new" script - * tag is found. For "old" script tag we want to use the default shaper. */ if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2')) - return &_hb_ot_complex_shaper_indic; + return &_hb_ot_complex_shaper_myanmar; + else if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','r')) + return &_hb_ot_complex_shaper_myanmar_old; else return &_hb_ot_complex_shaper_default; + + /* Unicode-4.1 additions */ + case HB_SCRIPT_BUGINESE: + case HB_SCRIPT_NEW_TAI_LUE: + + /* Unicode-5.1 additions */ + case HB_SCRIPT_CHAM: + + /* Unicode-5.2 additions */ + case HB_SCRIPT_TAI_THAM: + + /* If the designer designed the font for the 'DFLT' script, + * use the default shaper. Otherwise, use the Indic shaper. + * Note that for some simple scripts, there may not be *any* + * GSUB/GPOS needed, so there may be no scripts found! */ + if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) + return &_hb_ot_complex_shaper_default; + else + return &_hb_ot_complex_shaper_sea; } } diff --git a/src/hb-ot-shape-complex-sea-machine.hh b/src/hb-ot-shape-complex-sea-machine.hh new file mode 100644 index 0000000..86b7ae7 --- /dev/null +++ b/src/hb-ot-shape-complex-sea-machine.hh @@ -0,0 +1,224 @@ + +#line 1 "../../src/hb-ot-shape-complex-sea-machine.rl" +/* + * Copyright © 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH + +#include "hb-private.hh" + + +#line 36 "hb-ot-shape-complex-sea-machine.hh.tmp" +static const unsigned char _sea_syllable_machine_trans_keys[] = { + 1u, 1u, 1u, 1u, 1u, 29u, 3u, 29u, 3u, 29u, 1u, 1u, 0 +}; + +static const char _sea_syllable_machine_key_spans[] = { + 1, 1, 29, 27, 27, 1 +}; + +static const char _sea_syllable_machine_index_offsets[] = { + 0, 2, 4, 34, 62, 90 +}; + +static const char _sea_syllable_machine_indicies[] = { + 1, 0, 3, 2, 1, 1, 3, 5, + 4, 4, 4, 4, 4, 3, 4, 1, + 4, 4, 4, 4, 3, 4, 4, 4, + 4, 3, 4, 4, 4, 3, 3, 3, + 3, 4, 1, 7, 6, 6, 6, 6, + 6, 1, 6, 6, 6, 6, 6, 6, + 1, 6, 6, 6, 6, 1, 6, 6, + 6, 1, 1, 1, 1, 6, 3, 9, + 8, 8, 8, 8, 8, 3, 8, 8, + 8, 8, 8, 8, 3, 8, 8, 8, + 8, 3, 8, 8, 8, 3, 3, 3, + 3, 8, 3, 10, 0 +}; + +static const char _sea_syllable_machine_trans_targs[] = { + 2, 3, 2, 4, 2, 5, 2, 0, + 2, 1, 2 +}; + +static const char _sea_syllable_machine_trans_actions[] = { + 1, 2, 3, 2, 6, 0, 7, 0, + 8, 0, 9 +}; + +static const char _sea_syllable_machine_to_state_actions[] = { + 0, 0, 4, 0, 0, 0 +}; + +static const char _sea_syllable_machine_from_state_actions[] = { + 0, 0, 5, 0, 0, 0 +}; + +static const char _sea_syllable_machine_eof_trans[] = { + 1, 3, 0, 7, 9, 11 +}; + +static const int sea_syllable_machine_start = 2; +static const int sea_syllable_machine_first_final = 2; +static const int sea_syllable_machine_error = -1; + +static const int sea_syllable_machine_en_main = 2; + + +#line 36 "../../src/hb-ot-shape-complex-sea-machine.rl" + + + +#line 67 "../../src/hb-ot-shape-complex-sea-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 117 "hb-ot-shape-complex-sea-machine.hh.tmp" + { + cs = sea_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 88 "../../src/hb-ot-shape-complex-sea-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + +#line 134 "hb-ot-shape-complex-sea-machine.hh.tmp" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; +_resume: + switch ( _sea_syllable_machine_from_state_actions[cs] ) { + case 5: +#line 1 "NONE" + {ts = p;} + break; +#line 148 "hb-ot-shape-complex-sea-machine.hh.tmp" + } + + _keys = _sea_syllable_machine_trans_keys + (cs<<1); + _inds = _sea_syllable_machine_indicies + _sea_syllable_machine_index_offsets[cs]; + + _slen = _sea_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].sea_category()) && + ( info[p].sea_category()) <= _keys[1] ? + ( info[p].sea_category()) - _keys[0] : _slen ]; + +_eof_trans: + cs = _sea_syllable_machine_trans_targs[_trans]; + + if ( _sea_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _sea_syllable_machine_trans_actions[_trans] ) { + case 2: +#line 1 "NONE" + {te = p+1;} + break; + case 6: +#line 63 "../../src/hb-ot-shape-complex-sea-machine.rl" + {te = p+1;{ found_syllable (non_sea_cluster); }} + break; + case 7: +#line 61 "../../src/hb-ot-shape-complex-sea-machine.rl" + {te = p;p--;{ found_syllable (consonant_syllable); }} + break; + case 8: +#line 62 "../../src/hb-ot-shape-complex-sea-machine.rl" + {te = p;p--;{ found_syllable (broken_cluster); }} + break; + case 9: +#line 63 "../../src/hb-ot-shape-complex-sea-machine.rl" + {te = p;p--;{ found_syllable (non_sea_cluster); }} + break; + case 1: +#line 61 "../../src/hb-ot-shape-complex-sea-machine.rl" + {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} + break; + case 3: +#line 62 "../../src/hb-ot-shape-complex-sea-machine.rl" + {{p = ((te))-1;}{ found_syllable (broken_cluster); }} + break; +#line 194 "hb-ot-shape-complex-sea-machine.hh.tmp" + } + +_again: + switch ( _sea_syllable_machine_to_state_actions[cs] ) { + case 4: +#line 1 "NONE" + {ts = 0;} + break; +#line 203 "hb-ot-shape-complex-sea-machine.hh.tmp" + } + + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _sea_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _sea_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + } + +#line 97 "../../src/hb-ot-shape-complex-sea-machine.rl" + +} + +#undef found_syllable + +#endif /* HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH */ diff --git a/src/hb-ot-shape-complex-sea-machine.rl b/src/hb-ot-shape-complex-sea-machine.rl new file mode 100644 index 0000000..46140fc --- /dev/null +++ b/src/hb-ot-shape-complex-sea-machine.rl @@ -0,0 +1,102 @@ +/* + * Copyright © 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH + +#include "hb-private.hh" + +%%{ + machine sea_syllable_machine; + alphtype unsigned char; + write data; +}%% + +%%{ + +# Same order as enum sea_category_t. Not sure how to avoid duplication. +C = 1; +GB = 12; # Generic Base +H = 4; # Halant +IV = 2; # Independent Vowel +MR = 22; # Medial Ra +CM = 17; # Consonant Medial +VAbv = 26; +VBlw = 27; +VPre = 28; +VPst = 29; +T = 3; # Tone Marks +A = 10; # Anusvara + +syllable_tail = (VPre|VAbv|VBlw|VPst|H.C|CM|MR|T|A)*; + +consonant_syllable = (C|IV|GB) syllable_tail; +broken_cluster = syllable_tail; +other = any; + +main := |* + consonant_syllable => { found_syllable (consonant_syllable); }; + broken_cluster => { found_syllable (broken_cluster); }; + other => { found_syllable (non_sea_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].sea_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_SEA_MACHINE_HH */ diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc new file mode 100644 index 0000000..f08b7cc --- /dev/null +++ b/src/hb-ot-shape-complex-sea.cc @@ -0,0 +1,380 @@ +/* + * Copyright © 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-ot-shape-complex-indic-private.hh" + +/* buffer var allocations */ +#define sea_category() complex_var_u8_0() /* indic_category_t */ +#define sea_position() complex_var_u8_1() /* indic_position_t */ + + +/* + * South-East Asian shaper. + * Loosely based on the Myanmar spec / shaper. + * There is no OpenType spec for this. + */ + +static const hb_tag_t +basic_features[] = +{ + /* + * Basic features. + * These features are applied in order, one at a time, after initial_reordering. + */ + HB_TAG('p','r','e','f'), + HB_TAG('a','b','v','f'), + HB_TAG('b','l','w','f'), + HB_TAG('p','s','t','f'), +}; +static const hb_tag_t +other_features[] = +{ + /* + * Other features. + * These features are applied all at once, after final_reordering. + */ + HB_TAG('p','r','e','s'), + HB_TAG('a','b','v','s'), + HB_TAG('b','l','w','s'), + HB_TAG('p','s','t','s'), + /* Positioning features, though we don't care about the types. */ + HB_TAG('d','i','s','t'), +}; + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +initial_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +final_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +static void +collect_features_sea (hb_ot_shape_planner_t *plan) +{ + hb_ot_map_builder_t *map = &plan->map; + + /* Do this before any lookups have been applied. */ + map->add_gsub_pause (setup_syllables); + + map->add_global_bool_feature (HB_TAG('l','o','c','l')); + /* The Indic specs do not require ccmp, but we apply it here since if + * there is a use of it, it's typically at the beginning. */ + map->add_global_bool_feature (HB_TAG('c','c','m','p')); + + map->add_gsub_pause (initial_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) + { + map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->add_gsub_pause (NULL); + } + map->add_gsub_pause (final_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) + map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); +} + +static void +override_features_sea (hb_ot_shape_planner_t *plan) +{ + plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); +} + + +enum syllable_type_t { + consonant_syllable, + broken_cluster, + non_sea_cluster, +}; + +#include "hb-ot-shape-complex-sea-machine.hh" + + +/* Note: This enum is duplicated in the -machine.rl source file. + * Not sure how to avoid duplication. */ +enum sea_category_t { +// OT_C = 1, + OT_GB = 12, /* Generic Base XXX DOTTED CIRCLE only for now */ +// OT_H = 4, /* Halant */ + OT_IV = 2, /* Independent Vowel */ + OT_MR = 22, /* Medial Ra */ +// OT_CM = 17, /* Consonant Medial */ + OT_VAbv = 26, + OT_VBlw = 27, + OT_VPre = 28, + OT_VPst = 29, + OT_T = 3, /* Tone Marks */ +// OT_A = 10, /* Anusvara */ +}; + +static inline void +set_sea_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_position_t pos = (indic_position_t) (type >> 8); + + /* Medial Ra */ + if (u == 0x1A55u || u == 0xAA34u) + cat = (indic_category_t) OT_MR; + + if (cat == OT_M) + { + switch ((int) pos) + { + case POS_PRE_C: cat = (indic_category_t) OT_VPre; break; + case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; + case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; + case POS_POST_C: cat = (indic_category_t) OT_VPst; break; + } + } + + info.sea_category() = (sea_category_t) cat; + info.sea_position() = pos; +} + + +static void +setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) +{ + HB_BUFFER_ALLOCATE_VAR (buffer, sea_category); + HB_BUFFER_ALLOCATE_VAR (buffer, sea_position); + + /* We cannot setup masks here. We save information about characters + * and setup masks later on in a pause-callback. */ + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + set_sea_properties (info[i]); +} + +static void +setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + find_syllables (buffer); +} + +static int +compare_sea_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) +{ + int a = pa->sea_position(); + int b = pb->sea_position(); + + return a < b ? -1 : a == b ? 0 : +1; +} + + +static void +initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int base = start; + + /* Reorder! */ + unsigned int i = start; + for (; i < base; i++) + info[i].sea_position() = POS_PRE_C; + if (i < end) + { + info[i].sea_position() = POS_BASE_C; + i++; + } + for (; i < end; i++) + { + if (info[i].sea_category() == OT_MR) /* Pre-base reordering */ + { + info[i].sea_position() = POS_PRE_C; + continue; + } + if (info[i].sea_category() == OT_VPre) /* Left matra */ + { + info[i].sea_position() = POS_PRE_M; + continue; + } + + info[i].sea_position() = POS_AFTER_MAIN; + } + + buffer->merge_clusters (start, end); + /* Sit tight, rock 'n roll! */ + hb_bubble_sort (info + start, end - start, compare_sea_order); +} + +static void +initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + /* We already inserted dotted-circles, so just call the consonant_syllable. */ + initial_reordering_consonant_syllable (plan, face, buffer, start, end); +} + +static void +initial_reordering_non_sea_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_face_t *face HB_UNUSED, + hb_buffer_t *buffer HB_UNUSED, + unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) +{ + /* Nothing to do right now. If we ever switch to using the output + * buffer in the reordering process, we'd need to next_glyph() here. */ +} + + +static void +initial_reordering_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); + switch (syllable_type) { + case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return; + case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return; + case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return; + } +} + +static inline void +insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font, + hb_buffer_t *buffer) +{ + /* Note: This loop is extra overhead, but should not be measurable. */ + bool has_broken_syllables = false; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if ((info[i].syllable() & 0x0F) == broken_cluster) + { + has_broken_syllables = true; + break; + } + if (likely (!has_broken_syllables)) + return; + + + hb_codepoint_t dottedcircle_glyph; + if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) + return; + + hb_glyph_info_t dottedcircle = {0}; + dottedcircle.codepoint = 0x25CCu; + set_sea_properties (dottedcircle); + dottedcircle.codepoint = dottedcircle_glyph; + + buffer->clear_output (); + + buffer->idx = 0; + unsigned int last_syllable = 0; + while (buffer->idx < buffer->len) + { + unsigned int syllable = buffer->cur().syllable(); + syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); + if (unlikely (last_syllable != syllable && syllable_type == broken_cluster)) + { + last_syllable = syllable; + + hb_glyph_info_t info = dottedcircle; + info.cluster = buffer->cur().cluster; + info.mask = buffer->cur().mask; + info.syllable() = buffer->cur().syllable(); + + buffer->output_info (info); + } + else + buffer->next_glyph (); + } + + buffer->swap_buffers (); +} + +static void +initial_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + insert_dotted_circles (plan, font, buffer); + + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + if (unlikely (!count)) return; + unsigned int last = 0; + unsigned int last_syllable = info[0].syllable(); + for (unsigned int i = 1; i < count; i++) + if (last_syllable != info[i].syllable()) { + initial_reordering_syllable (plan, font->face, buffer, last, i); + last = i; + last_syllable = info[last].syllable(); + } + initial_reordering_syllable (plan, font->face, buffer, last, count); +} + +static void +final_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + /* Zero syllables now... */ + for (unsigned int i = 0; i < count; i++) + info[i].syllable() = 0; + + HB_BUFFER_DEALLOCATE_VAR (buffer, sea_category); + HB_BUFFER_DEALLOCATE_VAR (buffer, sea_position); +} + + +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea = +{ + "sea", + collect_features_sea, + override_features_sea, + NULL, /* data_create */ + NULL, /* data_destroy */ + NULL, /* preprocess_text */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, + NULL, /* decompose */ + NULL, /* compose */ + setup_masks_sea, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + false, /* fallback_position */ +}; diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc index 24d476a..feb7fc7 100644 --- a/src/hb-ot-shape-complex-thai.cc +++ b/src/hb-ot-shape-complex-thai.cc @@ -46,13 +46,13 @@ enum thai_consonant_type_t static thai_consonant_type_t get_consonant_type (hb_codepoint_t u) { - if (u == 0x0E1B || u == 0x0E1D || u == 0x0E1F/* || u == 0x0E2C*/) + if (u == 0x0E1Bu || u == 0x0E1Du || u == 0x0E1Fu/* || u == 0x0E2Cu*/) return AC; - if (u == 0x0E0D || u == 0x0E10) + if (u == 0x0E0Du || u == 0x0E10u) return RC; - if (u == 0x0E0E || u == 0x0E0F) + if (u == 0x0E0Eu || u == 0x0E0Fu) return DC; - if (hb_in_range<hb_codepoint_t> (u, 0x0E01, 0x0E2E)) + if (hb_in_range (u, 0x0E01u, 0x0E2Eu)) return NC; return NOT_CONSONANT; } @@ -70,12 +70,12 @@ enum thai_mark_type_t static thai_mark_type_t get_mark_type (hb_codepoint_t u) { - if (u == 0x0E31 || hb_in_range<hb_codepoint_t> (u, 0x0E34, 0x0E37) || - u == 0x0E47 || hb_in_range<hb_codepoint_t> (u, 0x0E4D, 0x0E4E)) + if (u == 0x0E31u || hb_in_range (u, 0x0E34u, 0x0E37u) || + u == 0x0E47u || hb_in_range (u, 0x0E4Du, 0x0E4Eu)) return AV; - if (hb_in_range<hb_codepoint_t> (u, 0x0E38, 0x0E3A)) + if (hb_in_range (u, 0x0E38u, 0x0E3Au)) return BV; - if (hb_in_range<hb_codepoint_t> (u, 0x0E48, 0x0E4C)) + if (hb_in_range (u, 0x0E48u, 0x0E4Cu)) return T; return NOT_MARK; } @@ -99,43 +99,43 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) hb_codepoint_t mac_pua; } const *pua_mappings = NULL; static const thai_pua_mapping_t SD_mappings[] = { - {0x0E48, 0xF70A, 0xF88B}, /* MAI EK */ - {0x0E49, 0xF70B, 0xF88E}, /* MAI THO */ - {0x0E4A, 0xF70C, 0xF891}, /* MAI TRI */ - {0x0E4B, 0xF70D, 0xF894}, /* MAI CHATTAWA */ - {0x0E4C, 0xF70E, 0xF897}, /* THANTHAKHAT */ - {0x0E38, 0xF718, 0xF89B}, /* SARA U */ - {0x0E39, 0xF719, 0xF89C}, /* SARA UU */ - {0x0E3A, 0xF71A, 0xF89D}, /* PHINTHU */ - {0x0000, 0x0000, 0x0000} + {0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */ + {0x0E49u, 0xF70Bu, 0xF88Eu}, /* MAI THO */ + {0x0E4Au, 0xF70Cu, 0xF891u}, /* MAI TRI */ + {0x0E4Bu, 0xF70Du, 0xF894u}, /* MAI CHATTAWA */ + {0x0E4Cu, 0xF70Eu, 0xF897u}, /* THANTHAKHAT */ + {0x0E38u, 0xF718u, 0xF89Bu}, /* SARA U */ + {0x0E39u, 0xF719u, 0xF89Cu}, /* SARA UU */ + {0x0E3Au, 0xF71Au, 0xF89Du}, /* PHINTHU */ + {0x0000u, 0x0000u, 0x0000u} }; static const thai_pua_mapping_t SDL_mappings[] = { - {0x0E48, 0xF705, 0xF88C}, /* MAI EK */ - {0x0E49, 0xF706, 0xF88F}, /* MAI THO */ - {0x0E4A, 0xF707, 0xF892}, /* MAI TRI */ - {0x0E4B, 0xF708, 0xF895}, /* MAI CHATTAWA */ - {0x0E4C, 0xF709, 0xF898}, /* THANTHAKHAT */ - {0x0000, 0x0000, 0x0000} + {0x0E48u, 0xF705u, 0xF88Cu}, /* MAI EK */ + {0x0E49u, 0xF706u, 0xF88Fu}, /* MAI THO */ + {0x0E4Au, 0xF707u, 0xF892u}, /* MAI TRI */ + {0x0E4Bu, 0xF708u, 0xF895u}, /* MAI CHATTAWA */ + {0x0E4Cu, 0xF709u, 0xF898u}, /* THANTHAKHAT */ + {0x0000u, 0x0000u, 0x0000u} }; static const thai_pua_mapping_t SL_mappings[] = { - {0x0E48, 0xF713, 0xF88A}, /* MAI EK */ - {0x0E49, 0xF714, 0xF88D}, /* MAI THO */ - {0x0E4A, 0xF715, 0xF890}, /* MAI TRI */ - {0x0E4B, 0xF716, 0xF893}, /* MAI CHATTAWA */ - {0x0E4C, 0xF717, 0xF896}, /* THANTHAKHAT */ - {0x0E31, 0xF710, 0xF884}, /* MAI HAN-AKAT */ - {0x0E34, 0xF701, 0xF885}, /* SARA I */ - {0x0E35, 0xF702, 0xF886}, /* SARA II */ - {0x0E36, 0xF703, 0xF887}, /* SARA UE */ - {0x0E37, 0xF704, 0xF888}, /* SARA UEE */ - {0x0E47, 0xF712, 0xF889}, /* MAITAIKHU */ - {0x0E4D, 0xF711, 0xF899}, /* NIKHAHIT */ - {0x0000, 0x0000, 0x0000} + {0x0E48u, 0xF713u, 0xF88Au}, /* MAI EK */ + {0x0E49u, 0xF714u, 0xF88Du}, /* MAI THO */ + {0x0E4Au, 0xF715u, 0xF890u}, /* MAI TRI */ + {0x0E4Bu, 0xF716u, 0xF893u}, /* MAI CHATTAWA */ + {0x0E4Cu, 0xF717u, 0xF896u}, /* THANTHAKHAT */ + {0x0E31u, 0xF710u, 0xF884u}, /* MAI HAN-AKAT */ + {0x0E34u, 0xF701u, 0xF885u}, /* SARA I */ + {0x0E35u, 0xF702u, 0xF886u}, /* SARA II */ + {0x0E36u, 0xF703u, 0xF887u}, /* SARA UE */ + {0x0E37u, 0xF704u, 0xF888u}, /* SARA UEE */ + {0x0E47u, 0xF712u, 0xF889u}, /* MAITAIKHU */ + {0x0E4Du, 0xF711u, 0xF899u}, /* NIKHAHIT */ + {0x0000u, 0x0000u, 0x0000u} }; static const thai_pua_mapping_t RD_mappings[] = { - {0x0E0D, 0xF70F, 0xF89A}, /* YO YING */ - {0x0E10, 0xF700, 0xF89E}, /* THO THAN */ - {0x0000, 0x0000, 0x0000} + {0x0E0Du, 0xF70Fu, 0xF89Au}, /* YO YING */ + {0x0E10u, 0xF700u, 0xF89Eu}, /* THO THAN */ + {0x0000u, 0x0000u, 0x0000u} }; switch (action) { @@ -308,10 +308,10 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, /* We only get one script at a time, so a script-agnostic implementation * is adequate here. */ -#define IS_SARA_AM(x) (((x) & ~0x0080) == 0x0E33) -#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0xE33 + 0xE4D) +#define IS_SARA_AM(x) (((x) & ~0x0080u) == 0x0E33u) +#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0x0E33u + 0x0E4Du) #define SARA_AA_FROM_SARA_AM(x) ((x) - 1) -#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080, 0x0E34, 0x0E37, 0x0E47, 0x0E4E, 0x0E31, 0x0E31)) +#define IS_TONE_MARK(x) (hb_in_ranges ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u)) buffer->clear_output (); unsigned int count = buffer->len; @@ -330,8 +330,11 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, if (unlikely (buffer->in_error)) return; - /* Ok, let's see... */ + /* Make Nikhahit be recognized as a mark when zeroing widths. */ unsigned int end = buffer->out_len; + _hb_glyph_info_set_general_category (&buffer->out_info[end - 2], HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK); + + /* Ok, let's see... */ unsigned int start = end - 2; while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint)) start--; @@ -369,10 +372,10 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai = NULL, /* data_create */ NULL, /* data_destroy */ preprocess_text_thai, - NULL, /* normalization_preference */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - true, /* zero_width_attached_marks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, false,/* fallback_position */ }; diff --git a/src/hb-tt-font.cc b/src/hb-ot-shape-complex-tibetan.cc index c503a40..01465a4 100644 --- a/src/hb-tt-font.cc +++ b/src/hb-ot-shape-complex-tibetan.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2011 Google, Inc. + * Copyright © 2010,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -24,56 +24,38 @@ * Google Author(s): Behdad Esfahbod */ -#include "hb-font-private.hh" /* Shall be first since may include windows.h */ +#include "hb-ot-shape-complex-private.hh" -#include "hb-open-type-private.hh" -#include "hb-ot-hhea-table.hh" -#include "hb-ot-hmtx-table.hh" - -#include "hb-blob.h" - -#include <string.h> - - - -#if 0 -struct hb_tt_font_t +static const hb_tag_t tibetan_features[] = { - const struct hhea *hhea; - hb_blob_t *hhea_blob; + HB_TAG('a','b','v','s'), + HB_TAG('b','l','w','s'), + HB_TAG('a','b','v','m'), + HB_TAG('b','l','w','m'), + HB_TAG_NONE }; - -static hb_tt_font_t * -_hb_tt_font_create (hb_font_t *font) -{ - /* TODO Remove this object altogether */ - hb_tt_font_t *tt = (hb_tt_font_t *) calloc (1, sizeof (hb_tt_font_t)); - - tt->hhea_blob = Sanitizer<hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea)); - tt->hhea = Sanitizer<hhea>::lock_instance (tt->hhea_blob); - - return tt; -} - static void -_hb_tt_font_destroy (hb_tt_font_t *tt) -{ - hb_blob_destroy (tt->hhea_blob); - - free (tt); -} - -static inline const hhea& -_get_hhea (hb_face_t *face) +collect_features_tibetan (hb_ot_shape_planner_t *plan) { - return likely (face->tt && face->tt->hhea) ? *face->tt->hhea : Null(hhea); + for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++) + plan->map.add_global_bool_feature (*script_features); } -/* - * hb_tt_font_funcs_t - */ - -#endif +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan = +{ + "default", + collect_features_tibetan, + NULL, /* override_features */ + NULL, /* data_create */ + NULL, /* data_destroy */ + NULL, /* preprocess_text */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, + NULL, /* decompose */ + NULL, /* compose */ + NULL, /* setup_masks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, + true, /* fallback_position */ +}; diff --git a/src/hb-ot-shape-fallback-private.hh b/src/hb-ot-shape-fallback-private.hh index 5e9cb06..ec65351 100644 --- a/src/hb-ot-shape-fallback-private.hh +++ b/src/hb-ot-shape-fallback-private.hh @@ -41,4 +41,9 @@ HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_ hb_buffer_t *buffer); +HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + + #endif /* HB_OT_SHAPE_FALLBACK_PRIVATE_HH */ diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 6f3426e..80d7da8 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -25,6 +25,7 @@ */ #include "hb-ot-shape-fallback-private.hh" +#include "hb-ot-layout-gsubgpos-private.hh" static unsigned int recategorize_combining_class (hb_codepoint_t u, @@ -34,42 +35,42 @@ recategorize_combining_class (hb_codepoint_t u, return klass; /* Thai / Lao need some per-character work. */ - if ((u & ~0xFF) == 0x0E00) + if ((u & ~0xFF) == 0x0E00u) { if (unlikely (klass == 0)) { switch (u) { - case 0x0E31: - case 0x0E34: - case 0x0E35: - case 0x0E36: - case 0x0E37: - case 0x0E47: - case 0x0E4C: - case 0x0E4D: - case 0x0E4E: + case 0x0E31u: + case 0x0E34u: + case 0x0E35u: + case 0x0E36u: + case 0x0E37u: + case 0x0E47u: + case 0x0E4Cu: + case 0x0E4Du: + case 0x0E4Eu: klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT; break; - case 0x0EB1: - case 0x0EB4: - case 0x0EB5: - case 0x0EB6: - case 0x0EB7: - case 0x0EBB: - case 0x0ECC: - case 0x0ECD: + case 0x0EB1u: + case 0x0EB4u: + case 0x0EB5u: + case 0x0EB6u: + case 0x0EB7u: + case 0x0EBBu: + case 0x0ECCu: + case 0x0ECDu: klass = HB_UNICODE_COMBINING_CLASS_ABOVE; break; - case 0x0EBC: + case 0x0EBCu: klass = HB_UNICODE_COMBINING_CLASS_BELOW; break; } } else { /* Thai virama is below-right */ - if (u == 0x0E3A) + if (u == 0x0E3Au) klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT; } } @@ -166,11 +167,12 @@ _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *pla 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_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { - unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]); - combining_class = recategorize_combining_class (buffer->info[i].codepoint, combining_class); - _hb_glyph_info_set_modified_combining_class (&buffer->info[i], combining_class); + if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { + unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]); + combining_class = recategorize_combining_class (info[i].codepoint, combining_class); + _hb_glyph_info_set_modified_combining_class (&info[i], combining_class); } } @@ -180,8 +182,9 @@ zero_mark_advances (hb_buffer_t *buffer, unsigned int start, unsigned int end) { + hb_glyph_info_t *info = buffer->info; for (unsigned int i = start; i < end; i++) - if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) + if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { buffer->pos[i].x_advance = 0; buffer->pos[i].y_advance = 0; @@ -259,7 +262,13 @@ position_mark (const hb_ot_shape_plan_t *plan, case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: - pos.y_offset += base_extents.y_bearing + base_extents.height - mark_extents.y_bearing; + pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents.y_bearing; + /* Never shift up "below" marks. */ + if ((y_gap > 0) == (pos.y_offset > 0)) + { + base_extents.height -= pos.y_offset; + pos.y_offset = 0; + } base_extents.height += mark_extents.height; break; @@ -273,7 +282,15 @@ position_mark (const hb_ot_shape_plan_t *plan, case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT: - pos.y_offset += base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height); + pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height); + /* Don't shift down "above" marks too much. */ + if ((y_gap > 0) != (pos.y_offset > 0)) + { + unsigned int correction = -pos.y_offset / 2; + base_extents.y_bearing += correction; + base_extents.height -= correction; + pos.y_offset += correction; + } base_extents.y_bearing -= mark_extents.height; base_extents.height += mark_extents.height; break; @@ -299,8 +316,8 @@ position_around_base (const hb_ot_shape_plan_t *plan, base_extents.x_bearing += buffer->pos[base].x_offset; base_extents.y_bearing += buffer->pos[base].y_offset; - unsigned int lig_id = get_lig_id (buffer->info[base]); - unsigned int num_lig_components = get_lig_num_comps (buffer->info[base]); + unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[base]); + unsigned int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]); hb_position_t x_offset = 0, y_offset = 0; if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) { @@ -312,12 +329,13 @@ position_around_base (const hb_ot_shape_plan_t *plan, unsigned int last_lig_component = (unsigned int) -1; unsigned int last_combining_class = 255; hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */ + hb_glyph_info_t *info = buffer->info; for (unsigned int i = base + 1; i < end; i++) - if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i])) + if (_hb_glyph_info_get_modified_combining_class (&info[i])) { if (num_lig_components > 1) { - unsigned int this_lig_id = get_lig_id (buffer->info[i]); - unsigned int this_lig_component = get_lig_comp (buffer->info[i]) - 1; + unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&info[i]); + unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1; /* Conditions for attaching to the last component. */ if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components) this_lig_component = num_lig_components - 1; @@ -340,7 +358,7 @@ position_around_base (const hb_ot_shape_plan_t *plan, } } - unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]); + unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]); if (last_combining_class != this_combining_class) { last_combining_class = this_combining_class; @@ -376,13 +394,14 @@ position_cluster (const hb_ot_shape_plan_t *plan, return; /* Find the base glyph */ + hb_glyph_info_t *info = buffer->info; for (unsigned int i = start; i < end; i++) - if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i]))) + if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))) { /* Find mark glyphs */ unsigned int j; for (j = i + 1; j < end; j++) - if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[j]))) + if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[j]))) break; position_around_base (plan, font, buffer, i, j); @@ -396,6 +415,8 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { + _hb_buffer_assert_gsubgpos_vars (buffer); + unsigned int start = 0; unsigned int last_cluster = buffer->info[0].cluster; unsigned int count = buffer->len; @@ -407,3 +428,56 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, } position_cluster (plan, font, buffer, start, count); } + + +/* Performs old-style TrueType kerning. */ +void +_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + if (!plan->has_kern) return; + + OT::hb_apply_context_t c (1, font, buffer); + c.set_lookup_mask (plan->kern_mask); + c.set_lookup_props (OT::LookupFlag::IgnoreMarks); + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int idx = 0; idx < count;) + { + OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1); + if (!skippy_iter.next ()) + { + idx++; + continue; + } + + hb_position_t x_kern, y_kern; + font->get_glyph_kerning_for_direction (info[idx].codepoint, + info[skippy_iter.idx].codepoint, + buffer->props.direction, + &x_kern, &y_kern); + + if (x_kern) + { + hb_position_t kern1 = x_kern >> 1; + hb_position_t kern2 = x_kern - kern1; + pos[idx].x_advance += kern1; + pos[skippy_iter.idx].x_advance += kern2; + pos[skippy_iter.idx].x_offset += kern2; + } + + if (y_kern) + { + hb_position_t kern1 = y_kern >> 1; + hb_position_t kern2 = y_kern - kern1; + pos[idx].y_advance += kern1; + pos[skippy_iter.idx].y_advance += kern2; + pos[skippy_iter.idx].y_offset += kern2; + } + + idx = skippy_iter.idx; + } +} diff --git a/src/hb-ot-shape-normalize-private.hh b/src/hb-ot-shape-normalize-private.hh index 8112f03..c744e26 100644 --- a/src/hb-ot-shape-normalize-private.hh +++ b/src/hb-ot-shape-normalize-private.hh @@ -29,8 +29,6 @@ #include "hb-private.hh" -#include "hb-font.h" -#include "hb-buffer.h" /* buffer var allocations, used during the normalization process */ #define glyph_index() var1.u32 @@ -38,10 +36,10 @@ struct hb_ot_shape_plan_t; enum hb_ot_shape_normalization_mode_t { + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED, HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL, /* including base-to-base composition */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS }; diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index c5325e4..4287253 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -132,17 +132,19 @@ static inline unsigned int decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab) { hb_codepoint_t a, b, a_glyph, b_glyph; + hb_buffer_t * const buffer = c->buffer; + hb_font_t * const font = c->font; if (!c->decompose (c, ab, &a, &b) || - (b && !c->font->get_glyph (b, 0, &b_glyph))) + (b && !font->get_glyph (b, 0, &b_glyph))) return 0; - bool has_a = c->font->get_glyph (a, 0, &a_glyph); + bool has_a = font->get_glyph (a, 0, &a_glyph); if (shortest && has_a) { /* Output a and b */ - output_char (c->buffer, a, a_glyph); + output_char (buffer, a, a_glyph); if (likely (b)) { - output_char (c->buffer, b, b_glyph); + output_char (buffer, b, b_glyph); return 2; } return 1; @@ -151,16 +153,16 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint unsigned int ret; if ((ret = decompose (c, shortest, a))) { if (b) { - output_char (c->buffer, b, b_glyph); + output_char (buffer, b, b_glyph); return ret + 1; } return ret; } if (has_a) { - output_char (c->buffer, a, a_glyph); + output_char (buffer, a, a_glyph); if (likely (b)) { - output_char (c->buffer, b, b_glyph); + output_char (buffer, b, b_glyph); return 2; } return 1; @@ -170,7 +172,7 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint } /* Returns 0 if didn't decompose, number of resulting characters otherwise. */ -static inline bool +static inline unsigned int decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t u) { unsigned int len, i; @@ -191,79 +193,84 @@ decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_ return len; } -/* Returns true if recomposition may be benefitial. */ -static inline bool +static inline void decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest) { hb_buffer_t * const buffer = c->buffer; hb_codepoint_t glyph; - unsigned int len = 1; /* Kind of a cute waterfall here... */ if (shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph)) next_char (buffer, glyph); - else if ((len = decompose (c, shortest, buffer->cur().codepoint))) + else if (decompose (c, shortest, buffer->cur().codepoint)) skip_char (buffer); else if (!shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph)) next_char (buffer, glyph); - else if ((len = decompose_compatibility (c, buffer->cur().codepoint))) + else if (decompose_compatibility (c, buffer->cur().codepoint)) skip_char (buffer); else next_char (buffer, glyph); /* glyph is initialized in earlier branches. */ - - /* - * A recomposition would only be useful if we decomposed into at least three - * characters... - */ - return len > 2; } static inline void -handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end) +handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit) { + /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */ hb_buffer_t * const buffer = c->buffer; + hb_font_t * const font = c->font; for (; buffer->idx < end - 1;) { if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { /* The next two lines are some ugly lines... But work. */ - c->font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()); - buffer->replace_glyphs (2, 1, &buffer->cur().codepoint); + if (font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) + { + buffer->replace_glyphs (2, 1, &buffer->cur().codepoint); + } + else + { + /* Just pass on the two characters separately, let GSUB do its magic. */ + set_glyph (buffer->cur(), font); + buffer->next_glyph (); + set_glyph (buffer->cur(), font); + buffer->next_glyph (); + } + /* Skip any further variation selectors. */ + while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint))) + { + set_glyph (buffer->cur(), font); + buffer->next_glyph (); + } } else { - set_glyph (buffer->cur(), c->font); + set_glyph (buffer->cur(), font); buffer->next_glyph (); } } if (likely (buffer->idx < end)) { - set_glyph (buffer->cur(), c->font); + set_glyph (buffer->cur(), font); buffer->next_glyph (); } } -/* Returns true if recomposition may be benefitial. */ -static inline bool -decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end) +static inline void +decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit) { hb_buffer_t * const buffer = c->buffer; - /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */ for (unsigned int i = buffer->idx; i < end; i++) if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) { - handle_variation_selector_cluster (c, end); - return false; + handle_variation_selector_cluster (c, end, short_circuit); + return; } while (buffer->idx < end) - decompose_current_character (c, false); - /* We can be smarter here and only return true if there are at least two ccc!=0 marks. - * But does not matter. */ - return true; + decompose_current_character (c, short_circuit); } -static inline bool -decompose_cluster (const hb_ot_shape_normalize_context_t *c, bool short_circuit, unsigned int end) +static inline void +decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit) { if (likely (c->buffer->idx + 1 == end)) - return decompose_current_character (c, short_circuit); + decompose_current_character (c, might_short_circuit); else - return decompose_multi_char_cluster (c, end); + decompose_multi_char_cluster (c, end, always_short_circuit); } @@ -282,9 +289,9 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font) { - hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference ? - plan->shaper->normalization_preference (&buffer->props) : - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT; + _hb_buffer_assert_unicode_vars (buffer); + + hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference; const hb_ot_shape_normalize_context_t c = { plan, buffer, @@ -294,9 +301,10 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, plan->shaper->compose ? plan->shaper->compose : compose_unicode }; - bool short_circuit = mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED && - mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT; - bool can_use_recompose = false; + bool always_short_circuit = mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE; + bool might_short_circuit = always_short_circuit || + (mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED && + mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT); unsigned int count; /* We do a fairly straightforward yet custom normalization process in three @@ -317,15 +325,11 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, if (buffer->cur().cluster != buffer->info[end].cluster) break; - can_use_recompose = decompose_cluster (&c, short_circuit, end) || can_use_recompose; + decompose_cluster (&c, end, might_short_circuit, always_short_circuit); } buffer->swap_buffers (); - if (mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL && !can_use_recompose) - return; /* Done! */ - - /* Second round, reorder (inplace) */ count = buffer->len; @@ -353,7 +357,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, } - if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED) + if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE || + mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED) return; /* Third round, recompose */ @@ -368,10 +373,11 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, while (buffer->idx < count) { hb_codepoint_t composed, glyph; - if (/* If mode is NOT COMPOSED_FULL (ie. it's COMPOSED_DIACRITICS), we don't try to - * compose a CCC=0 character with it's preceding starter. */ - (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL || - _hb_glyph_info_get_modified_combining_class (&buffer->cur()) != 0) && + if (/* We don't try to compose a non-mark character with it's preceding starter. + * This is both an optimization to avoid trying to compose every two neighboring + * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul + * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */ + HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) && /* If there's anything between the starter and this char, they should have CCC * smaller than this character's. */ (starter == buffer->out_len - 1 || @@ -390,8 +396,9 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, return; buffer->merge_out_clusters (starter, buffer->out_len); buffer->out_len--; /* Remove the second composable. */ - buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */ - set_glyph (buffer->out_info[starter], font); + /* Modify starter and carry on. */ + buffer->out_info[starter].codepoint = composed; + buffer->out_info[starter].glyph_index() = glyph; _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode); continue; diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh index 23e80b7..54ac2c3 100644 --- a/src/hb-ot-shape-private.hh +++ b/src/hb-ot-shape-private.hh @@ -30,12 +30,7 @@ #include "hb-private.hh" #include "hb-ot-map-private.hh" - - - -/* buffer var allocations, used during the entire shaping process */ -#define unicode_props0() var2.u8[0] -#define unicode_props1() var2.u8[1] +#include "hb-ot-layout-private.hh" @@ -45,6 +40,11 @@ struct hb_ot_shape_plan_t const struct hb_ot_complex_shaper_t *shaper; hb_ot_map_t map; const void *data; + hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask; + hb_mask_t kern_mask; + unsigned int has_frac : 1; + unsigned int has_kern : 1; + unsigned int has_mark : 1; inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const { @@ -71,7 +71,7 @@ struct hb_ot_shape_planner_t hb_ot_map_builder_t map; hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) : - face (master_plan->face), + face (master_plan->face_unsafe), props (master_plan->props), shaper (NULL), map (face, &props) {} @@ -82,6 +82,18 @@ struct hb_ot_shape_planner_t plan.props = props; plan.shaper = shaper; map.compile (plan.map); + + plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m')); + plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); + plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r')); + plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m')); + + plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ? + HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n')); + + plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask); + plan.has_kern = !!plan.kern_mask; + plan.has_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); } private: @@ -89,37 +101,4 @@ struct hb_ot_shape_planner_t }; - -inline void -_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) -{ - info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) | - (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0); - info->unicode_props1() = unicode->modified_combining_class (info->codepoint); -} - -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_props0() & 0x7F); -} - -inline void -_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class) -{ - info->unicode_props1() = modified_class; -} - -inline unsigned int -_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) -{ - return info->unicode_props1(); -} - -inline hb_bool_t -_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) -{ - return !!(info->unicode_props0() & 0x80); -} - #endif /* HB_OT_SHAPE_PRIVATE_HH */ diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 96461d7..a0b503a 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -37,12 +37,12 @@ #include "hb-ot-shape-normalize-private.hh" #include "hb-ot-layout-private.hh" +#include "hb-unicode-private.hh" #include "hb-set-private.hh" static hb_tag_t common_features[] = { HB_TAG('c','c','m','p'), - HB_TAG('l','i','g','a'), HB_TAG('l','o','c','l'), HB_TAG('m','a','r','k'), HB_TAG('m','k','m','k'), @@ -55,20 +55,12 @@ static hb_tag_t horizontal_features[] = { HB_TAG('c','l','i','g'), HB_TAG('c','u','r','s'), HB_TAG('k','e','r','n'), + HB_TAG('l','i','g','a'), HB_TAG('r','c','l','t'), }; -/* Note: - * Technically speaking, vrt2 and vert are mutually exclusive. - * According to the spec, valt and vpal are also mutually exclusive. - * But we apply them all for now. - */ static hb_tag_t vertical_features[] = { - HB_TAG('v','a','l','t'), HB_TAG('v','e','r','t'), - HB_TAG('v','k','r','n'), - HB_TAG('v','p','a','l'), - HB_TAG('v','r','t','2'), }; @@ -83,12 +75,12 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, switch (props->direction) { case HB_DIRECTION_LTR: - map->add_bool_feature (HB_TAG ('l','t','r','a')); - map->add_bool_feature (HB_TAG ('l','t','r','m')); + map->add_global_bool_feature (HB_TAG ('l','t','r','a')); + map->add_global_bool_feature (HB_TAG ('l','t','r','m')); break; case HB_DIRECTION_RTL: - map->add_bool_feature (HB_TAG ('r','t','l','a')); - map->add_bool_feature (HB_TAG ('r','t','l','m'), false); + map->add_global_bool_feature (HB_TAG ('r','t','l','a')); + map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE); break; case HB_DIRECTION_TTB: case HB_DIRECTION_BTT: @@ -97,30 +89,35 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, break; } -#define ADD_FEATURES(array) \ - HB_STMT_START { \ - for (unsigned int i = 0; i < ARRAY_LENGTH (array); i++) \ - map->add_bool_feature (array[i]); \ - } HB_STMT_END + map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE); + map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE); + map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE); if (planner->shaper->collect_features) planner->shaper->collect_features (planner); - ADD_FEATURES (common_features); + for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) + map->add_global_bool_feature (common_features[i]); if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) - ADD_FEATURES (horizontal_features); + for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++) + map->add_feature (horizontal_features[i], 1, F_GLOBAL | + (horizontal_features[i] == HB_TAG('k','e','r','n') ? + F_HAS_FALLBACK : F_NONE)); else - ADD_FEATURES (vertical_features); + for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++) + map->add_feature (vertical_features[i], 1, F_GLOBAL | + (vertical_features[i] == HB_TAG('v','k','r','n') ? + F_HAS_FALLBACK : F_NONE)); if (planner->shaper->override_features) planner->shaper->override_features (planner); -#undef ADD_FEATURES - for (unsigned int i = 0; i < num_user_features; i++) { const hb_feature_t *feature = &user_features[i]; - map->add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1)); + map->add_feature (feature->tag, feature->value, + (feature->start == 0 && feature->end == (unsigned int) -1) ? + F_GLOBAL : F_NONE); } } @@ -230,24 +227,25 @@ static void hb_set_unicode_props (hb_buffer_t *buffer) { unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode); + _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode); } static void hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) { if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || + buffer->context_len[0] || _hb_glyph_info_get_general_category (&buffer->info[0]) != HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) return; - hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph)) + if (!font->has_glyph (0x25CCu)) return; - hb_glyph_info_t dottedcircle; - dottedcircle.codepoint = 0x25CC; + hb_glyph_info_t dottedcircle = {0}; + dottedcircle.codepoint = 0x25CCu; _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); buffer->clear_output (); @@ -267,8 +265,9 @@ static void hb_form_clusters (hb_buffer_t *buffer) { unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i]))) + if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))) buffer->merge_clusters (i - 1, i + 1); } @@ -298,29 +297,77 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) if (HB_DIRECTION_IS_FORWARD (c->target_direction)) return; - hb_unicode_funcs_t *unicode = c->buffer->unicode; - hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m')); + hb_buffer_t *buffer = c->buffer; + hb_unicode_funcs_t *unicode = buffer->unicode; + hb_mask_t rtlm_mask = c->plan->rtlm_mask; - unsigned int count = c->buffer->len; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) { - hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint); - if (likely (codepoint == c->buffer->info[i].codepoint)) - c->buffer->info[i].mask |= rtlm_mask; + hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); + if (likely (codepoint == info[i].codepoint)) + info[i].mask |= rtlm_mask; else - c->buffer->info[i].codepoint = codepoint; + info[i].codepoint = codepoint; } } static inline void -hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) +hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) +{ + if (!c->plan->has_frac) + return; + + hb_buffer_t *buffer = c->buffer; + + /* TODO look in pre/post context text also. */ + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + { + if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */ + { + unsigned int start = i, end = i + 1; + while (start && + _hb_glyph_info_get_general_category (&info[start - 1]) == + HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + start--; + while (end < count && + _hb_glyph_info_get_general_category (&info[end]) == + HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + end++; + + for (unsigned int j = start; j < i; j++) + info[j].mask |= c->plan->numr_mask | c->plan->frac_mask; + info[i].mask |= c->plan->frac_mask; + for (unsigned int j = i + 1; j < end; j++) + info[j].mask |= c->plan->frac_mask | c->plan->dnom_mask; + + i = end - 1; + } + } +} + +static inline void +hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) { hb_ot_map_t *map = &c->plan->map; + hb_buffer_t *buffer = c->buffer; hb_mask_t global_mask = map->get_global_mask (); - c->buffer->reset_masks (global_mask); + buffer->reset_masks (global_mask); +} + +static inline void +hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) +{ + hb_ot_map_t *map = &c->plan->map; + hb_buffer_t *buffer = c->buffer; + + hb_ot_shape_setup_masks_fraction (c); if (c->plan->shaper->setup_masks) - c->plan->shaper->setup_masks (c->plan, c->buffer, c->font); + c->plan->shaper->setup_masks (c->plan, buffer, c->font); for (unsigned int i = 0; i < c->num_user_features; i++) { @@ -328,7 +375,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { unsigned int shift; hb_mask_t mask = map->get_mask (feature->tag, &shift); - c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end); + buffer->set_masks (feature->value << shift, mask, feature->start, feature->end); } } } @@ -338,54 +385,78 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer) { /* Normalization process sets up glyph_index(), we just copy it. */ unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - buffer->info[i].codepoint = buffer->info[i].glyph_index(); + info[i].codepoint = info[i].glyph_index(); } static inline void hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) { unsigned int count = c->buffer->len; + hb_glyph_info_t *info = c->buffer->info; for (unsigned int i = 0; i < count; i++) - c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ? - HB_OT_LAYOUT_GLYPH_PROPS_MARK : - HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH; + { + hb_ot_layout_glyph_class_mask_t klass; + + /* Never mark default-ignorables as marks. + * They won't get in the way of lookups anyway, + * but having them as mark will cause them to be skipped + * over if the lookup-flag says so, but at least for the + * Mongolian variation selectors, looks like Uniscribe + * marks them as non-mark. Some Mongolian fonts without + * GDEF rely on this. Another notable character that + * this applies to is COMBINING GRAPHEME JOINER. */ + klass = (_hb_glyph_info_get_general_category (&info[i]) != + HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK || + _hb_glyph_info_is_default_ignorable (&info[i])) ? + HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : + HB_OT_LAYOUT_GLYPH_PROPS_MARK; + _hb_glyph_info_set_glyph_props (&info[i], klass); + } } static inline void hb_ot_substitute_default (hb_ot_shape_context_t *c) { + hb_buffer_t *buffer = c->buffer; + if (c->plan->shaper->preprocess_text) - c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); + c->plan->shaper->preprocess_text (c->plan, buffer, c->font); + + hb_ot_shape_initialize_masks (c); hb_ot_mirror_chars (c); - HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index); + HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); - _hb_ot_shape_normalize (c->plan, c->buffer, c->font); + _hb_ot_shape_normalize (c->plan, buffer, c->font); hb_ot_shape_setup_masks (c); /* This is unfortunate to go here, but necessary... */ if (!hb_ot_layout_has_positioning (c->face)) - _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buffer); + _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); - hb_ot_map_glyphs_fast (c->buffer); + hb_ot_map_glyphs_fast (buffer); - HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index); + HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); } static inline void hb_ot_substitute_complex (hb_ot_shape_context_t *c) { - hb_ot_layout_substitute_start (c->font, c->buffer); + hb_buffer_t *buffer = c->buffer; + + _hb_buffer_allocate_gsubgpos_vars (buffer); + hb_ot_layout_substitute_start (c->font, buffer); if (!hb_ot_layout_has_glyph_classes (c->face)) hb_synthesize_glyph_classes (c); - c->plan->substitute (c->font, c->buffer); + c->plan->substitute (c->font, buffer); - hb_ot_layout_substitute_finish (c->font, c->buffer); + hb_ot_layout_substitute_finish (c->font, buffer); return; } @@ -400,20 +471,65 @@ hb_ot_substitute (hb_ot_shape_context_t *c) /* Position */ static inline void -hb_ot_position_default (hb_ot_shape_context_t *c) +adjust_mark_offsets (hb_glyph_position_t *pos) { - hb_ot_layout_position_start (c->font, c->buffer); + pos->x_offset -= pos->x_advance; + pos->y_offset -= pos->y_advance; +} + +static inline void +zero_mark_width (hb_glyph_position_t *pos) +{ + pos->x_advance = 0; + pos->y_advance = 0; +} + +static inline void +zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) +{ + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) + { + if (adjust_offsets) + adjust_mark_offsets (&buffer->pos[i]); + zero_mark_width (&buffer->pos[i]); + } +} +static inline void +zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) +{ + 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_mark (&info[i])) + { + if (adjust_offsets) + adjust_mark_offsets (&buffer->pos[i]); + zero_mark_width (&buffer->pos[i]); + } +} + +static inline void +hb_ot_position_default (hb_ot_shape_context_t *c) +{ + hb_direction_t direction = c->buffer->props.direction; unsigned int count = c->buffer->len; - for (unsigned int i = 0; i < count; i++) { - c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint, - c->buffer->props.direction, - &c->buffer->pos[i].x_advance, - &c->buffer->pos[i].y_advance); - c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint, - c->buffer->props.direction, - &c->buffer->pos[i].x_offset, - &c->buffer->pos[i].y_offset); + hb_glyph_info_t *info = c->buffer->info; + hb_glyph_position_t *pos = c->buffer->pos; + for (unsigned int i = 0; i < count; i++) + { + c->font->get_glyph_advance_for_direction (info[i].codepoint, + direction, + &pos[i].x_advance, + &pos[i].y_advance); + c->font->subtract_glyph_origin_for_direction (info[i].codepoint, + direction, + &pos[i].x_offset, + &pos[i].y_offset); + } } @@ -421,68 +537,96 @@ static inline bool hb_ot_position_complex (hb_ot_shape_context_t *c) { bool ret = false; + unsigned int count = c->buffer->len; + bool has_positioning = hb_ot_layout_has_positioning (c->face); + /* If the font has no GPOS, AND, no fallback positioning will + * happen, AND, direction is forward, then when zeroing mark + * widths, we shift the mark with it, such that the mark + * is positioned hanging over the previous glyph. When + * direction is backward we don't shift and it will end up + * hanging over the next glyph after the final reordering. + * If fallback positinoing happens or GPOS is present, we don't + * care. + */ + bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position || + HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)); + + switch (c->plan->shaper->zero_width_marks) + { + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: + zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); + break; + + /* Not currently used for any shaper: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: + zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); + break; + */ + + default: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: + break; + } - if (hb_ot_layout_has_positioning (c->face)) + if (has_positioning) { + hb_glyph_info_t *info = c->buffer->info; + hb_glyph_position_t *pos = c->buffer->pos; + /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ - unsigned int count = c->buffer->len; for (unsigned int i = 0; i < count; i++) { - c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint, + c->font->add_glyph_origin_for_direction (info[i].codepoint, HB_DIRECTION_LTR, - &c->buffer->pos[i].x_offset, - &c->buffer->pos[i].y_offset); + &pos[i].x_offset, + &pos[i].y_offset); } c->plan->position (c->font, c->buffer); for (unsigned int i = 0; i < count; i++) { - c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint, + c->font->subtract_glyph_origin_for_direction (info[i].codepoint, HB_DIRECTION_LTR, - &c->buffer->pos[i].x_offset, - &c->buffer->pos[i].y_offset); + &pos[i].x_offset, + &pos[i].y_offset); } ret = true; } - hb_ot_layout_position_finish (c->font, c->buffer, c->plan->shaper->zero_width_attached_marks); + switch (c->plan->shaper->zero_width_marks) + { + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: + zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); + break; - return ret; -} + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: + zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); + break; -static inline void -hb_ot_truetype_kern (hb_ot_shape_context_t *c) -{ - /* TODO Check for kern=0 */ - unsigned int count = c->buffer->len; - for (unsigned int i = 1; i < count; i++) { - hb_position_t x_kern, y_kern, kern1, kern2; - c->font->get_glyph_kerning_for_direction (c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint, - c->buffer->props.direction, - &x_kern, &y_kern); - - kern1 = x_kern >> 1; - kern2 = x_kern - kern1; - c->buffer->pos[i - 1].x_advance += kern1; - c->buffer->pos[i].x_advance += kern2; - c->buffer->pos[i].x_offset += kern2; - - kern1 = y_kern >> 1; - kern2 = y_kern - kern1; - c->buffer->pos[i - 1].y_advance += kern1; - c->buffer->pos[i].y_advance += kern2; - c->buffer->pos[i].y_offset += kern2; + default: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: + //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: + break; } + + return ret; } static inline void hb_ot_position (hb_ot_shape_context_t *c) { + hb_ot_layout_position_start (c->font, c->buffer); + hb_ot_position_default (c); hb_bool_t fallback = !hb_ot_position_complex (c); + hb_ot_layout_position_finish (c->font, c->buffer); + if (fallback && c->plan->shaper->fallback_position) _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); @@ -492,7 +636,9 @@ hb_ot_position (hb_ot_shape_context_t *c) /* Visual fallback goes here. */ if (fallback) - hb_ot_truetype_kern (c); + _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); + + _hb_buffer_deallocate_gsubgpos_vars (c->buffer); } @@ -504,22 +650,42 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) return; - hb_codepoint_t space = 0; + hb_codepoint_t space; + enum { + SPACE_DONT_KNOW, + SPACE_AVAILABLE, + SPACE_UNAVAILABLE + } space_status = SPACE_DONT_KNOW; unsigned int count = c->buffer->len; + hb_glyph_info_t *info = c->buffer->info; + hb_glyph_position_t *pos = c->buffer->pos; + unsigned int j = 0; for (unsigned int i = 0; i < count; i++) - if (unlikely (!is_a_ligature (c->buffer->info[i]) && - _hb_glyph_info_is_default_ignorable (&c->buffer->info[i]))) + { + if (unlikely (!_hb_glyph_info_ligated (&info[i]) && + _hb_glyph_info_is_default_ignorable (&info[i]))) { - if (!space) { - /* We assume that the space glyph is not gid0. */ - if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space) - return; /* No point! */ + if (space_status == SPACE_DONT_KNOW) + space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE; + + if (space_status == SPACE_AVAILABLE) + { + info[i].codepoint = space; + pos[i].x_advance = 0; + pos[i].y_advance = 0; } - c->buffer->info[i].codepoint = space; - c->buffer->pos[i].x_advance = 0; - c->buffer->pos[i].y_advance = 0; + else + continue; /* Delete it. */ + } + if (j != i) + { + info[j] = info[i]; + pos[j] = pos[i]; } + j++; + } + c->buffer->len = j; } @@ -533,8 +699,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) /* Save the original direction, we use it later. */ c->target_direction = c->buffer->props.direction; - HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0); - HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1); + _hb_buffer_allocate_unicode_vars (c->buffer); c->buffer->clear_output (); @@ -549,8 +714,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ot_hide_default_ignorables (c); - HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1); - HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0); + _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; @@ -611,8 +775,6 @@ hb_ot_shape_glyphs_closure (hb_font_t *font, { hb_ot_shape_plan_t plan; - buffer->guess_segment_properties (); - const char *shapers[] = {"ot", NULL}; hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shapers); @@ -620,8 +782,9 @@ hb_ot_shape_glyphs_closure (hb_font_t *font, bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL; unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs); + add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs); hb_set_t lookups; lookups.init (); diff --git a/src/hb-ot-shape.h b/src/hb-ot-shape.h new file mode 100644 index 0000000..1402f54 --- /dev/null +++ b/src/hb-ot-shape.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2013 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_SHAPE_H +#define HB_OT_SHAPE_H + +#include "hb.h" + +HB_BEGIN_DECLS + +/* TODO port to shape-plan / set. */ +void +hb_ot_shape_glyphs_closure (hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features, + hb_set_t *glyphs); + +void +hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, + hb_tag_t table_tag, + hb_set_t *lookup_indexes /* OUT */); + +HB_END_DECLS + +#endif /* HB_OT_SHAPE_H */ diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index 91ebec7..878dd79 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -27,7 +27,6 @@ */ #include "hb-private.hh" -#include "hb-ot.h" #include <string.h> @@ -58,7 +57,7 @@ hb_ot_old_tag_from_script (hb_script_t script) } /* Else, just change first char to lowercase and return */ - return ((hb_tag_t) script) | 0x20000000; + return ((hb_tag_t) script) | 0x20000000u; } static hb_script_t @@ -71,13 +70,13 @@ hb_ot_old_tag_to_script (hb_tag_t tag) /* Any spaces at the end of the tag are replaced by repeating the last * letter. Eg 'nko ' -> 'Nkoo' */ - if (unlikely ((tag & 0x0000FF00) == 0x00002000)) - tag |= (tag >> 8) & 0x0000FF00; /* Copy second letter to third */ - if (unlikely ((tag & 0x000000FF) == 0x00000020)) - tag |= (tag >> 8) & 0x000000FF; /* Copy third letter to fourth */ + if (unlikely ((tag & 0x0000FF00u) == 0x00002000u)) + tag |= (tag >> 8) & 0x0000FF00u; /* Copy second letter to third */ + if (unlikely ((tag & 0x000000FFu) == 0x00000020u)) + tag |= (tag >> 8) & 0x000000FFu; /* Copy third letter to fourth */ /* Change first char to uppercase and return */ - return (hb_script_t) (tag & ~0x20000000); + return (hb_script_t) (tag & ~0x20000000u); } static hb_tag_t @@ -147,7 +146,7 @@ hb_ot_tags_from_script (hb_script_t script, hb_script_t hb_ot_tag_to_script (hb_tag_t tag) { - if (unlikely ((tag & 0x000000FF) == '2')) + if (unlikely ((tag & 0x000000FFu) == '2')) return hb_ot_new_tag_to_script (tag); return hb_ot_old_tag_to_script (tag); @@ -157,7 +156,7 @@ hb_ot_tag_to_script (hb_tag_t tag) /* hb_language_t */ typedef struct { - char language[6]; + char language[4]; hb_tag_t tag; } LangTag; @@ -167,9 +166,12 @@ typedef struct { * * Generated by intersecting the OpenType language tag list from * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from - * 2008/08/04, matching on name, and finally adjusted manually. + * 2008-08-04, matching on name, and finally adjusted manually. * - * Updated on 2012/12/07 with more research into remaining codes. + * Updated on 2012-12-07 with more research into remaining codes. + * + * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts, + * the new proposal from Microsoft, and latest ISO 639-3 names. * * Some items still missing. Those are commented out at the end. * Keep sorted for bsearch. @@ -179,57 +181,90 @@ static const LangTag ot_languages[] = { {"aa", HB_TAG('A','F','R',' ')}, /* Afar */ {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */ {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */ + {"ach", HB_TAG('A','C','H',' ')}, /* Acoli */ {"ada", HB_TAG('D','N','G',' ')}, /* Dangme */ {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */ {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */ {"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */ + {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */ {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */ + {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] */ {"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */ {"am", HB_TAG('A','M','H',' ')}, /* Amharic */ {"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */ - {"ar", HB_TAG('A','R','A',' ')}, /* Arabic */ + {"an", HB_TAG('A','R','G',' ')}, /* Aragonese */ + {"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) */ + {"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */ + {"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic */ {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */ + {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic */ {"as", HB_TAG('A','S','M',' ')}, /* Assamese */ + {"ast", HB_TAG('A','S','T',' ')}, /* Asturian/Asturleonese/Bable/Leonese */ {"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */ {"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */ {"av", HB_TAG('A','V','R',' ')}, /* Avaric */ {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */ - {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */ - {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */ + {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */ + {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */ + {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani */ + {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani */ {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */ - {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */ - {"bci", HB_TAG('B','A','U',' ')}, /* Baule */ + {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolangauge] */ + {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */ + {"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */ + {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */ + {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */ + {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ - {"be", HB_TAG('B','E','L',' ')}, /* Belarussian */ + {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */ {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */ {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */ {"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */ {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */ + {"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */ + {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */ {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */ + {"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) */ {"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */ - {"bik", HB_TAG('B','I','K',' ')}, /* Bikol */ + {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */ + {"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */ {"bin", HB_TAG('E','D','O',' ')}, /* Bini */ + {"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */ {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */ {"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */ {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */ + {"blk", HB_TAG('B','L','K',' ')}, /* Pa'O/Pa'o Karen */ + {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol */ {"bm", HB_TAG('B','M','B',' ')}, /* Bambara */ {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */ {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */ + {"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya */ + {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari */ {"br", HB_TAG('B','R','E',' ')}, /* Breton */ {"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */ {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */ + {"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */ {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */ {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */ + {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol */ + {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */ + {"bug", HB_TAG('B','U','G',' ')}, /* Buginese */ {"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */ {"byn", HB_TAG('B','I','L',' ')}, /* Bilen */ {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */ + {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */ {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */ {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */ + {"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */ + {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */ + {"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */ {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */ {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */ + {"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */ + {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */ {"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */ {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */ {"cr", HB_TAG('C','R','E',' ')}, /* Cree */ @@ -239,6 +274,9 @@ static const LangTag ot_languages[] = { {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */ {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */ {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */ + {"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */ + {"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */ + {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */ {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */ {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */ {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */ @@ -247,34 +285,42 @@ static const LangTag ot_languages[] = { {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */ {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */ {"de", HB_TAG('D','E','U',' ')}, /* German */ - {"din", HB_TAG('D','N','K',' ')}, /* Dinka */ - {"dje", HB_TAG('D','J','R',' ')}, /* Djerma */ + {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */ + {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari */ + {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */ + {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */ + {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */ {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */ - {"doi", HB_TAG('D','G','R',' ')}, /* Dogri */ + {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */ {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */ - {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */ + {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi/Divehi/Maldivian */ {"dyu", HB_TAG('J','U','L',' ')}, /* Jula */ {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */ {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */ {"efi", HB_TAG('E','F','I',' ')}, /* Efik */ + {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian */ {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */ + {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan */ {"en", HB_TAG('E','N','G',' ')}, /* English */ {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */ {"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */ {"es", HB_TAG('E','S','P',' ')}, /* Spanish */ - {"et", HB_TAG('E','T','I',' ')}, /* Estonian */ + {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */ {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */ {"eve", HB_TAG('E','V','N',' ')}, /* Even */ {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */ - {"fa", HB_TAG('F','A','R',' ')}, /* Persian */ - {"ff", HB_TAG('F','U','L',' ')}, /* Fulah */ + {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */ + {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */ {"fi", HB_TAG('F','I','N',' ')}, /* Finnish */ {"fil", HB_TAG('P','I','L',' ')}, /* Filipino */ {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */ {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */ {"fon", HB_TAG('F','O','N',' ')}, /* Fon */ {"fr", HB_TAG('F','R','A',' ')}, /* French */ + {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */ + {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan/Francoprovençal */ {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */ + {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */ {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */ {"ga", HB_TAG('I','R','I',' ')}, /* Irish */ {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */ @@ -282,113 +328,167 @@ static const LangTag ot_languages[] = { {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */ {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */ {"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */ + {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi */ {"gl", HB_TAG('G','A','L',' ')}, /* Galician */ {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */ - {"gn", HB_TAG('G','U','A',' ')}, /* Guarani */ - {"gon", HB_TAG('G','O','N',' ')}, /* Gondi */ + {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */ + {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ + {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi */ + {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */ + {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */ {"grt", HB_TAG('G','R','O',' ')}, /* Garo */ {"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */ {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */ + {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */ {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */ - {"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */ +/*{"guk", HB_TAG('G','U','K',' ')},*/ /* Gumuz (in SIL fonts) */ + {"guz", HB_TAG('G','U','Z',' ')}, /* Ekegusii/Gusii */ + {"gv", HB_TAG('M','N','X',' ')}, /* Manx */ {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */ {"har", HB_TAG('H','R','I',' ')}, /* Harari */ - {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiin */ + {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */ + {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ + {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ + {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */ {"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */ {"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */ {"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */ + {"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */ {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */ {"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */ {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */ {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */ - {"ht", HB_TAG('H','A','I',' ')}, /* Haitian */ + {"ht", HB_TAG('H','A','I',' ')}, /* Haitian/Haitian Creole */ {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */ {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */ + {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ + {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */ + {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */ {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */ + {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue/Occidental */ {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */ {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */ + {"ijc", HB_TAG('I','J','O',' ')}, /* Izon */ {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */ + {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] */ {"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */ {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */ + {"io", HB_TAG('I','D','O',' ')}, /* Ido */ {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */ {"it", HB_TAG('I','T','A',' ')}, /* Italian */ - {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */ + {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */ {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */ + {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English */ + {"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */ {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */ {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */ {"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */ + {"kab", HB_TAG('K','A','B',' ')}, /* Kabyle */ {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */ {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */ + {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */ {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */ {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */ {"kex", HB_TAG('K','K','N',' ')}, /* Kokni */ {"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */ {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */ + {"kg", HB_TAG('K','O','N',' ')}, /* Kongo [macrolanguage] */ {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */ - {"khb", HB_TAG('X','B','D',' ')}, /* Tai Lue */ + {"khb", HB_TAG('X','B','D',' ')}, /* Lü */ + {"kht", HB_TAG('K','H','N',' ')}, /* Khamti (Microsoft fonts) */ +/*{"kht", HB_TAG('K','H','T',' ')},*/ /* Khamti (OpenType spec and SIL fonts) */ {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */ - {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */ + {"ki", HB_TAG('K','I','K',' ')}, /* Gikuyu/Kikuyu */ + {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama/Kwanyama */ {"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */ + {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen */ {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */ {"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */ {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */ {"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */ - {"kmb", HB_TAG('M','B','N',' ')}, /* [North] Mbundu */ + {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu */ {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */ {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */ + {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */ {"ko", HB_TAG('K','O','R',' ')}, /* Korean */ {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */ - {"kok", HB_TAG('K','O','K',' ')}, /* Konkani */ - {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */ + {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */ + {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */ {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */ {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */ {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */ - {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */ + {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */ {"kri", HB_TAG('K','R','I',' ')}, /* Krio */ {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */ {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */ {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */ - {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */ + {"ksh", HB_TAG('K','S','H',' ')}, /* Kölsch */ +/*{"ksw", HB_TAG('K','R','N',' ')},*/ /* S'gaw Karen (Microsoft fonts?) */ + {"ksw", HB_TAG('K','S','W',' ')}, /* S'gaw Karen (OpenType spec and SIL fonts) */ + {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */ {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */ + {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */ {"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */ + {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */ {"kxc", HB_TAG('K','M','S',' ')}, /* Komso */ {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */ - {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */ + {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz/Kyrgyz */ + {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */ {"la", HB_TAG('L','A','T',' ')}, /* Latin */ {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */ {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */ {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */ {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */ {"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */ - {"lg", HB_TAG('L','U','G',' ')}, /* Luganda */ + {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */ + {"li", HB_TAG('L','I','M',' ')}, /* Limburgan/Limburger/Limburgish */ {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */ + {"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */ + {"lis", HB_TAG('L','I','S',' ')}, /* Lisu */ + {"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api */ + {"lki", HB_TAG('L','K','I',' ')}, /* Laki */ {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */ {"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */ + {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */ {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */ {"lo", HB_TAG('L','A','O',' ')}, /* Lao */ + {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri */ {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */ {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */ {"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */ {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */ {"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */ - {"luy", HB_TAG('L','U','H',' ')}, /* Luhya [macrolanguage] */ + {"luy", HB_TAG('L','U','H',' ')}, /* Luyia/Oluluyia [macrolanguage] */ + {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri */ {"lv", HB_TAG('L','V','I',' ')}, /* Latvian */ {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */ + {"mad", HB_TAG('M','A','D',' ')}, /* Madurese */ + {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */ {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */ + {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */ + {"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */ {"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */ {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */ + {"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */ {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */ {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ - {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */ + {"mer", HB_TAG('M','E','R',' ')}, /* Meru */ + {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */ + {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */ + {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */ {"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */ {"mi", HB_TAG('M','R','I',' ')}, /* Maori */ + {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */ {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */ + {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka */ + {"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */ {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */ - {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */ + {"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan */ + {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */ {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */ {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */ {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */ @@ -396,72 +496,119 @@ static const LangTag ot_languages[] = { {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */ {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */ + {"mos", HB_TAG('M','O','S',' ')}, /* Mossi */ {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */ {"mr", HB_TAG('M','A','R',' ')}, /* Marathi */ {"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */ - {"ms", HB_TAG('M','L','Y',' ')}, /* Malay */ + {"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */ + {"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka */ {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */ - {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */ + {"mtr", HB_TAG('M','A','W',' ')}, /* Mewari */ + {"mus", HB_TAG('M','U','S',' ')}, /* Creek */ + {"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */ + {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan */ + {"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */ + {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */ + {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */ {"my", HB_TAG('B','R','M',' ')}, /* Burmese */ {"mym", HB_TAG('M','E','N',' ')}, /* Me'en */ + {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) */ {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */ + {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */ + {"na", HB_TAG('N','A','U',' ')}, /* Nauru */ {"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */ + {"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */ + {"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */ {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */ {"nco", HB_TAG('S','I','B',' ')}, /* Sibe */ {"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */ + {"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */ + {"nds", HB_TAG('N','D','S',' ')}, /* Low German/Low Saxon */ {"ne", HB_TAG('N','E','P',' ')}, /* Nepali */ {"new", HB_TAG('N','E','W',' ')}, /* Newari */ {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */ + {"nga", HB_TAG('N','G','A',' ')}, /* Ngabaka */ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */ {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */ {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */ {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */ {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */ - {"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */ - {"nod", HB_TAG('N','T','A',' ')}, /* Northern Tai */ + {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */ + {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai */ + {"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */ {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */ + {"nov", HB_TAG('N','O','V',' ')}, /* Novial */ {"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */ {"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */ {"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */ - {"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */ - {"nyn", HB_TAG('N','K','L',' ')}, /* Nkole */ + {"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */ + {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */ + {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */ {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ - {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */ + {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] */ {"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */ - {"om", HB_TAG('O','R','O',' ')}, /* Oromo */ + {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ {"or", HB_TAG('O','R','I',' ')}, /* Oriya */ {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */ {"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */ + {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */ + {"pam", HB_TAG('P','A','M',' ')}, /* Kapampangan/Pampanga */ + {"pap", HB_TAG('P','A','P',' ')}, /* Papiamento */ + {"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */ + {"pcd", HB_TAG('P','C','D',' ')}, /* Picard */ {"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */ + {"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */ + {"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian */ + {"phk", HB_TAG('P','H','K',' ')}, /* Phake */ {"pi", HB_TAG('P','A','L',' ')}, /* Pali */ + {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk */ {"pl", HB_TAG('P','L','K',' ')}, /* Polish */ {"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */ {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */ - {"prs", HB_TAG('D','R','I',' ')}, /* Dari */ - {"ps", HB_TAG('P','A','S',' ')}, /* Pushto */ + {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */ + {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */ + {"prs", HB_TAG('D','R','I',' ')}, /* Afghan Persian/Dari */ + {"ps", HB_TAG('P','A','S',' ')}, /* Pashto/Pushto [macrolanguage] */ {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */ - {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */ - {"rbb", HB_TAG('P','L','G',' ')}, /* [Rumai] Palaung */ + {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen */ + {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */ + {"quc", HB_TAG('Q','U','C',' ')}, /* K'iche'/Quiché */ + {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua */ + {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */ + {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung */ + {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */ {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */ {"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */ - {"rki", HB_TAG('A','R','K',' ')}, /* Arakanese */ - {"rm", HB_TAG('R','M','S',' ')}, /* Rhaeto-Romanic */ + {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */ + {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */ + {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */ + {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */ {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */ - {"rom", HB_TAG('R','O','Y',' ')}, /* Romany */ + {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */ {"ru", HB_TAG('R','U','S',' ')}, /* Russian */ {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */ - {"rw", HB_TAG('R','U','A',' ')}, /* Ruanda */ + {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian/Arumanian/Macedo-Romanian */ + {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ + {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */ {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */ {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */ + {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */ {"sat", HB_TAG('S','A','T',' ')}, /* Santali */ {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */ + {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ + {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */ + {"sco", HB_TAG('S','C','O',' ')}, /* Scots */ {"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */ {"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */ {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */ {"seh", HB_TAG('S','N','A',' ')}, /* Sena */ {"sel", HB_TAG('S','E','L',' ')}, /* Selkup */ {"sg", HB_TAG('S','G','O',' ')}, /* Sango */ + {"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */ + {"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */ + {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage */ +/*{"sgw", HB_TAG('S','G','W',' ')},*/ /* Sebat Bet Gurage (in SIL fonts) */ {"shn", HB_TAG('S','H','N',' ')}, /* Shan */ {"si", HB_TAG('S','N','H',' ')}, /* Sinhala */ {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */ @@ -474,60 +621,98 @@ static const LangTag ot_languages[] = { {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */ {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */ {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */ + {"sn", HB_TAG('S','N','A',' ')}, /* Shona */ {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */ {"so", HB_TAG('S','M','L',' ')}, /* Somali */ - {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */ + {"sop", HB_TAG('S','O','P',' ')}, /* Songe */ + {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */ {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */ {"srr", HB_TAG('S','R','R',' ')}, /* Serer */ - {"ss", HB_TAG('S','W','Z',' ')}, /* Swazi */ + {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */ {"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */ + {"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch */ + {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e */ + {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */ + {"suk", HB_TAG('S','U','K',' ')}, /* Sukama */ {"suq", HB_TAG('S','U','R',' ')}, /* Suri */ {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */ {"sva", HB_TAG('S','V','A',' ')}, /* Svan */ - {"sw", HB_TAG('S','W','K',' ')}, /* Swahili */ + {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */ {"swb", HB_TAG('C','M','R',' ')}, /* Comorian */ - {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */ + {"swh", HB_TAG('S','W','K',' ')}, /* Kiswahili/Swahili */ + {"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati */ + {"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */ + {"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */ + {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */ + {"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */ {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */ {"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */ {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */ + {"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa */ {"te", HB_TAG('T','E','L',' ')}, /* Telugu */ {"tem", HB_TAG('T','M','N',' ')}, /* Temne */ + {"tet", HB_TAG('T','E','T',' ')}, /* Tetum */ {"tg", HB_TAG('T','A','J',' ')}, /* Tajik */ {"th", HB_TAG('T','H','A',' ')}, /* Thai */ {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */ + {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ + {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */ + {"tmh", HB_TAG('t','m','h',' ')}, /* Tamashek [macrolanguage] */ {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */ {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */ + {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */ {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */ {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */ {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */ {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */ + {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka */ {"tw", HB_TAG('T','W','I',' ')}, /* Twi */ {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */ {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */ + {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */ + {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight */ {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */ {"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */ {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */ - {"umb", HB_TAG('M','B','N',' ')}, /* [South] Mbundu */ + {"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */ {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */ {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */ - {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */ + {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */ + {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek */ + {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek */ {"ve", HB_TAG('V','E','N',' ')}, /* Venda */ + {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */ + {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */ {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */ - {"vmw", HB_TAG('M','A','K',' ')}, /* Makua */ + {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */ + {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */ + {"vro", HB_TAG('V','R','O',' ')}, /* Võro */ + {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */ + {"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) */ {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */ + {"wle", HB_TAG('S','I','G',' ')}, /* Wolane */ + {"wry", HB_TAG('M','A','W',' ')}, /* Merwari */ + {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */ {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */ {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */ {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */ + {"xog", HB_TAG('X','O','G',' ')}, /* Soga */ {"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */ {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */ - {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */ + {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) */ + {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat (Todo) */ + {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */ + {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */ {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */ {"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */ + {"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */ + {"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */ {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */ - {"zu", HB_TAG('Z','U','L',' ')} /* Zulu */ + {"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */ + {"zum", HB_TAG('L','R','C',' ')} /* Kumzari */ /* The corresponding languages IDs for the following IDs are unclear, * overlap, or are architecturally weird. Needs more research. */ @@ -536,13 +721,13 @@ static const LangTag ot_languages[] = { /*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */ /*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */ /*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */ -/*{"sgw?", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */ +/*{"zh?", HB_TAG('C','H','N',' ')},*/ /* Chinese (seen in Microsoft fonts) */ /*{"acf/gcf?", HB_TAG('F','A','N',' ')},*/ /* French Antillean */ -/*{"vls/nl-be", HB_TAG('F','L','E',' ')},*/ /* Flemish */ /*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */ /*{"fuf?", HB_TAG('F','T','A',' ')},*/ /* Futa */ /*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */ /*{"cfm/rnl?", HB_TAG('H','A','L',' ')},*/ /* Halam */ +/*{"fonipa", HB_TAG('I','P','P','H')},*/ /* Phonetic transcription—IPA conventions */ /*{"ga-Latg?/Latg?", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */ /*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */ /*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/ /* Kebena */ @@ -559,8 +744,6 @@ static const LangTag ot_languages[] = { /*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */ /*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */ /*{"mnk?/mlq?/...", HB_TAG('M','L','N',' ')},*/ /* Malinke */ -/*{"man?/myq?/mku?/msc?/...", HB_TAG('M','N','K',' ')},*/ /* Maninka */ -/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */ /*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */ /*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */ /*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */ @@ -569,25 +752,29 @@ static const LangTag ot_languages[] = { /*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */ /*{"chp?", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */ /*{"xan?", HB_TAG('S','E','K',' ')},*/ /* Sekota */ -/*{"stv/wle?/xst?", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */ /*{"ngo?", HB_TAG('S','X','T',' ')},*/ /* Sutu */ /*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */ /*{"tnz?/tog?/toi?", HB_TAG('T','N','G',' ')},*/ /* Tonga */ /*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */ -/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */ /*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */ -/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */ +/*{"cre?", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */ /*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */ /*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */ /*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */ }; -static const LangTag ot_languages_zh[] = { +typedef struct { + char language[8]; + hb_tag_t tag; +} LangTagLong; +static const LangTagLong ot_languages_zh[] = { {"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */ {"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */ {"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */ {"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */ - {"zh-tw", HB_TAG('Z','H','T',' ')} /* Chinese (Taiwan) */ + {"zh-tw", HB_TAG('Z','H','T',' ')}, /* Chinese (Taiwan) */ + {"zh-hans", HB_TAG('Z','H','S',' ')}, /* Chinese (Simplified) */ + {"zh-hant", HB_TAG('Z','H','T',' ')}, /* Chinese (Traditional) */ }; static int @@ -619,7 +806,6 @@ hb_tag_t hb_ot_tag_from_language (hb_language_t language) { const char *lang_str, *s; - const LangTag *lang_tag; if (language == HB_LANGUAGE_INVALID) return HB_OT_TAG_DEFAULT_LANGUAGE; @@ -641,11 +827,14 @@ hb_ot_tag_from_language (hb_language_t language) } /* Find a language matching in the first component */ - lang_tag = (LangTag *) bsearch (lang_str, ot_languages, - ARRAY_LENGTH (ot_languages), sizeof (LangTag), - (hb_compare_func_t) lang_compare_first_component); - if (lang_tag) - return lang_tag->tag; + { + const LangTag *lang_tag; + lang_tag = (LangTag *) bsearch (lang_str, ot_languages, + ARRAY_LENGTH (ot_languages), sizeof (LangTag), + (hb_compare_func_t) lang_compare_first_component); + if (lang_tag) + return lang_tag->tag; + } /* Otherwise, check the Chinese ones */ if (0 == lang_compare_first_component (lang_str, "zh")) @@ -654,8 +843,9 @@ hb_ot_tag_from_language (hb_language_t language) for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++) { + const LangTagLong *lang_tag; lang_tag = &ot_languages_zh[i]; - if (lang_matches (lang_tag->language, lang_str)) + if (lang_matches (lang_str, lang_tag->language)) return lang_tag->tag; } @@ -668,7 +858,7 @@ hb_ot_tag_from_language (hb_language_t language) s = lang_str + strlen (lang_str); if (s - lang_str == 3) { /* Assume it's ISO-639-3 and upper-case and use it. */ - return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000; + return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u; } return HB_OT_TAG_DEFAULT_LANGUAGE; @@ -687,21 +877,12 @@ hb_ot_tag_to_language (hb_tag_t tag) return hb_language_from_string (ot_languages[i].language, -1); /* If tag starts with ZH, it's Chinese */ - if ((tag & 0xFFFF0000) == 0x5A480000) { + if ((tag & 0xFFFF0000u) == 0x5A480000u) { switch (tag) { case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */ - default: { - /* Encode the tag... */ - unsigned char buf[14] = "zh-x-hbot"; - buf[9] = tag >> 24; - buf[10] = (tag >> 16) & 0xFF; - buf[11] = (tag >> 8) & 0xFF; - buf[12] = tag & 0xFF; - if (buf[12] == 0x20) - buf[12] = '\0'; - buf[13] = '\0'; - return hb_language_from_string ((char *) buf, -1); - } + case HB_TAG('Z','H','S',' '): return hb_language_from_string ("zh-Hans", -1); /* Simplified */ + case HB_TAG('Z','H','T',' '): return hb_language_from_string ("zh-Hant", -1); /* Traditional */ + default: break; /* Fall through */ } } diff --git a/src/hb-ot.h b/src/hb-ot.h index 8073906..47c92a5 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -30,19 +30,13 @@ #include "hb.h" +#include "hb-ot-font.h" #include "hb-ot-layout.h" #include "hb-ot-tag.h" +#include "hb-ot-shape.h" HB_BEGIN_DECLS -/* TODO remove */ -void -hb_ot_shape_glyphs_closure (hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features, - hb_set_t *glyphs); - HB_END_DECLS #undef HB_OT_H_IN diff --git a/src/hb-private.hh b/src/hb-private.hh index be0d505..80fd6c4 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -54,23 +54,125 @@ #include <stdarg.h> +/* Compiler attributes */ -/* Essentials */ -#ifndef NULL -# define NULL ((void *) 0) +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) +#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) +#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) +#else +#define likely(expr) (expr) +#define unlikely(expr) (expr) #endif +#ifndef __GNUC__ +#undef __attribute__ +#define __attribute__(x) +#endif -/* Void! */ -struct _hb_void_t {}; -typedef const _hb_void_t &hb_void_t; -#define HB_VOID (* (const _hb_void_t *) NULL) +#if __GNUC__ >= 3 +#define HB_PURE_FUNC __attribute__((pure)) +#define HB_CONST_FUNC __attribute__((const)) +#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) +#else +#define HB_PURE_FUNC +#define HB_CONST_FUNC +#define HB_PRINTF_FUNC(format_idx, arg_idx) +#endif +#if __GNUC__ >= 4 +#define HB_UNUSED __attribute__((unused)) +#else +#define HB_UNUSED +#endif + +#ifndef HB_INTERNAL +# if !defined(__MINGW32__) && !defined(__CYGWIN__) +# define HB_INTERNAL __attribute__((__visibility__("hidden"))) +# else +# define HB_INTERNAL +# endif +#endif + +#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) +#define snprintf _snprintf +/* Windows CE only has _strdup, while rest of Windows has both. */ +#define strdup _strdup +#endif + +#ifdef _MSC_VER +#undef inline +#define inline __inline +#endif + +#ifdef __STRICT_ANSI__ +#undef inline +#define inline __inline__ +#endif + +#if __GNUC__ >= 3 +#define HB_FUNC __PRETTY_FUNCTION__ +#elif defined(_MSC_VER) +#define HB_FUNC __FUNCSIG__ +#else +#define HB_FUNC __func__ +#endif +#if defined(_WIN32) || defined(__CYGWIN__) + /* We need Windows Vista for both Uniscribe backend and for + * MemoryBarrier. We don't support compiling on Windows XP, + * though we run on it fine. */ +# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 +# undef _WIN32_WINNT +# endif +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0600 +# endif +# define WIN32_LEAN_AND_MEAN +# define STRICT +#endif + +#ifdef _WIN32_WCE +/* Some things not defined on Windows CE. */ +#define MemoryBarrier() +#define getenv(Name) NULL +#define setlocale(Category, Locale) "C" +static int errno = 0; /* Use something better? */ +#endif + +#if HAVE_ATEXIT +/* atexit() is only safe to be called from shared libraries on certain + * platforms. Whitelist. + * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */ +# if defined(__linux) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2,3) +/* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */ +# define HB_USE_ATEXIT 1 +# endif +# elif defined(_MSC_VER) || defined(__MINGW32__) +/* For MSVC: + * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx + * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx + * mingw32 headers say atexit is safe to use in shared libraries. + */ +# define HB_USE_ATEXIT 1 +# elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +/* This was fixed in Android NKD r8 or r8b: + * https://code.google.com/p/android/issues/detail?id=6455 + * which introduced GCC 4.6: + * https://developer.android.com/tools/sdk/ndk/index.html + */ +# define HB_USE_ATEXIT 1 +# endif +#endif /* Basics */ +#ifndef NULL +# define NULL ((void *) 0) +#endif + #undef MIN template <typename Type> static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } @@ -79,6 +181,9 @@ static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } template <typename Type> static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } +static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b) +{ return (a + (b - 1)) / b; } + #undef ARRAY_LENGTH template <typename Type, unsigned int n> @@ -89,7 +194,7 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } #define HB_STMT_START do #define HB_STMT_END while (0) -#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] +#define _ASSERT_STATIC1(_line, _cond) HB_UNUSED typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] #define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) #define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) @@ -136,7 +241,7 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4); /* Check _assertion in a method environment */ #define _ASSERT_POD1(_line) \ - inline void _static_assertion_on_line_##_line (void) const \ + HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \ { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ } # define _ASSERT_POD0(_line) _ASSERT_POD1 (_line) # define ASSERT_POD() _ASSERT_POD0 (__LINE__) @@ -145,68 +250,10 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4); /* Misc */ - -#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) -#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) -#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) -#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) -#else -#define likely(expr) (expr) -#define unlikely(expr) (expr) -#endif - -#ifndef __GNUC__ -#undef __attribute__ -#define __attribute__(x) -#endif - -#if __GNUC__ >= 3 -#define HB_PURE_FUNC __attribute__((pure)) -#define HB_CONST_FUNC __attribute__((const)) -#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) -#else -#define HB_PURE_FUNC -#define HB_CONST_FUNC -#define HB_PRINTF_FUNC(format_idx, arg_idx) -#endif -#if __GNUC__ >= 4 -#define HB_UNUSED __attribute__((unused)) -#else -#define HB_UNUSED -#endif - -#ifndef HB_INTERNAL -# ifndef __MINGW32__ -# define HB_INTERNAL __attribute__((__visibility__("hidden"))) -# else -# define HB_INTERNAL -# endif -#endif - - -#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) -#define snprintf _snprintf -#endif - -#ifdef _MSC_VER -#undef inline -#define inline __inline -#endif - -#ifdef __STRICT_ANSI__ -#undef inline -#define inline __inline__ -#endif - - -#if __GNUC__ >= 3 -#define HB_FUNC __PRETTY_FUNCTION__ -#elif defined(_MSC_VER) -#define HB_FUNC __FUNCSIG__ -#else -#define HB_FUNC __func__ -#endif - +/* Void! */ +struct _hb_void_t {}; +typedef const _hb_void_t &hb_void_t; +#define HB_VOID (* (const _hb_void_t *) NULL) /* Return the number of 1 bits in mask. */ static inline HB_CONST_FUNC unsigned int @@ -216,7 +263,7 @@ _hb_popcount32 (uint32_t mask) return __builtin_popcount (mask); #else /* "HACKMEM 169" */ - register uint32_t y; + uint32_t y; y = (mask >> 1) &033333333333; y = mask - y - ((y >>1) & 033333333333); return (((y + (y >> 3)) & 030707070707) % 077); @@ -230,7 +277,7 @@ _hb_bit_storage (unsigned int number) #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0; #else - register unsigned int n_bits = 0; + unsigned int n_bits = 0; while (number) { n_bits++; number >>= 1; @@ -246,7 +293,7 @@ _hb_ctz (unsigned int number) #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) return likely (number) ? __builtin_ctz (number) : 0; #else - register unsigned int n_bits = 0; + unsigned int n_bits = 0; if (unlikely (!number)) return 0; while (!(number & 1)) { n_bits++; @@ -272,8 +319,8 @@ typedef int (*hb_compare_func_t) (const void *, const void *); /* arrays and maps */ -#define HB_PREALLOCED_ARRAY_INIT {0} -template <typename Type, unsigned int StaticSize> +#define HB_PREALLOCED_ARRAY_INIT {0, 0, NULL} +template <typename Type, unsigned int StaticSize=16> struct hb_prealloced_array_t { unsigned int len; @@ -321,14 +368,22 @@ struct hb_prealloced_array_t inline void pop (void) { len--; - /* TODO: shrink array if needed */ + } + + inline void remove (unsigned int i) + { + if (unlikely (i >= len)) + return; + memmove (static_cast<void *> (&array[i]), + static_cast<void *> (&array[i + 1]), + (len - i - 1) * sizeof (Type)); + len--; } inline void shrink (unsigned int l) { if (l < len) len = l; - /* TODO: shrink array if needed */ } template <typename T> @@ -346,14 +401,14 @@ struct hb_prealloced_array_t return NULL; } - inline void sort (void) + inline void qsort (void) { - qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); + ::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); } - inline void sort (unsigned int start, unsigned int end) + inline void qsort (unsigned int start, unsigned int end) { - qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp); + ::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp); } template <typename T> @@ -376,6 +431,13 @@ struct hb_prealloced_array_t } }; +template <typename Type> +struct hb_auto_array_t : hb_prealloced_array_t <Type> +{ + hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); } + ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); } +}; + #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} template <typename item_t, typename lock_t> @@ -509,17 +571,19 @@ static inline uint32_t hb_uint32_swap (const uint32_t v) #define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3]) #define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]) -#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] (V); } HB_STMT_END +#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] = (V); } HB_STMT_END #define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2]) #define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) /* ASCII tag/character handling */ -static inline unsigned char ISALPHA (unsigned char c) +static inline bool ISALPHA (unsigned char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } -static inline unsigned char ISALNUM (unsigned char c) +static inline bool ISALNUM (unsigned char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } +static inline bool ISSPACE (unsigned char c) +{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; } static inline unsigned char TOUPPER (unsigned char c) { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } static inline unsigned char TOLOWER (unsigned char c) @@ -553,8 +617,8 @@ _hb_debug (unsigned int level, return level < max_level; } -#define DEBUG_LEVEL(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) -#define DEBUG(WHAT) (DEBUG_LEVEL (WHAT, 0)) +#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) +#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0)) template <int max_level> static inline void _hb_debug_msg_va (const char *what, @@ -564,6 +628,15 @@ _hb_debug_msg_va (const char *what, unsigned int level, int level_dir, const char *message, + va_list ap) HB_PRINTF_FUNC(7, 0); +template <int max_level> static inline void +_hb_debug_msg_va (const char *what, + const void *obj, + const char *func, + bool indented, + unsigned int level, + int level_dir, + const char *message, va_list ap) { if (!_hb_debug (level, max_level)) @@ -585,7 +658,7 @@ _hb_debug_msg_va (const char *what, #define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */ #define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */ static const char bars[] = VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR; - fprintf (stderr, "%2d %s" VRBAR "%s", + fprintf (stderr, "%2u %s" VRBAR "%s", level, bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars), (unsigned int) (sizeof (VBAR) - 1) * level), level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR); @@ -594,6 +667,8 @@ _hb_debug_msg_va (const char *what, if (func) { + unsigned int func_len = strlen (func); +#ifndef HB_DEBUG_VERBOSE /* Skip "typename" */ if (0 == strncmp (func, "typename ", 9)) func += 9; @@ -603,7 +678,9 @@ _hb_debug_msg_va (const char *what, func = space + 1; /* Skip parameter list */ const char *paren = strchr (func, '('); - unsigned int func_len = paren ? paren - func : strlen (func); + if (paren) + func_len = paren - func; +#endif fprintf (stderr, "%.*s: ", func_len, func); } @@ -700,7 +777,7 @@ static inline void _hb_warn_no_return (bool returned) } } template <> -inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) +/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) {} template <int max_level, typename ret_t> @@ -766,20 +843,31 @@ struct hb_auto_trace_t<0, ret_t> { /* Misc */ +template <typename T> class hb_assert_unsigned_t; +template <> class hb_assert_unsigned_t<unsigned char> {}; +template <> class hb_assert_unsigned_t<unsigned short> {}; +template <> class hb_assert_unsigned_t<unsigned int> {}; +template <> class hb_assert_unsigned_t<unsigned long> {}; -/* Pre-mature optimization: - * Checks for lo <= u <= hi but with an optimization if lo and hi - * are only different in a contiguous set of lower-most bits. - */ template <typename T> static inline bool hb_in_range (T u, T lo, T hi) { - if ( ((lo^hi) & lo) == 0 && - ((lo^hi) & hi) == (lo^hi) && - ((lo^hi) & ((lo^hi) + 1)) == 0 ) - return (u & ~(lo^hi)) == lo; - else - return lo <= u && u <= hi; + /* The sizeof() is here to force template instantiation. + * I'm sure there are better ways to do this but can't think of + * one right now. Declaring a variable won't work as HB_UNUSED + * is unsable on some platforms and unused types are less likely + * to generate a warning than unused variables. */ + ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0); + + /* The casts below are important as if T is smaller than int, + * the subtract results will become a signed int! */ + return (T)(u - lo) <= (T)(hi - lo); +} + +template <typename T> static inline bool +hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) +{ + return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); } template <typename T> static inline bool @@ -841,8 +929,9 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o { /* Pain because we don't know whether s is nul-terminated. */ char buf[64]; - strncpy (buf, s, MIN (ARRAY_LENGTH (buf) - 1, len)); - buf[MIN (ARRAY_LENGTH (buf) - 1, len)] = '\0'; + len = MIN (ARRAY_LENGTH (buf) - 1, len); + strncpy (buf, s, len); + buf[len] = '\0'; char *end; errno = 0; @@ -854,4 +943,33 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o } +/* Global runtime options. */ + +struct hb_options_t +{ + int initialized : 1; + int uniscribe_bug_compatible : 1; +}; + +union hb_options_union_t { + int i; + hb_options_t opts; +}; +ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t)); + +HB_INTERNAL void +_hb_options_init (void); + +extern HB_INTERNAL hb_options_union_t _hb_options; + +static inline hb_options_t +hb_options (void) +{ + if (unlikely (!_hb_options.i)) + _hb_options_init (); + + return _hb_options.opts; +} + + #endif /* HB_PRIVATE_HH */ diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index 5e30a7e..705f554 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -28,51 +28,34 @@ #define HB_SET_PRIVATE_HH #include "hb-private.hh" -#include "hb-set.h" #include "hb-object-private.hh" -struct hb_set_digest_common_bits_t -{ - ASSERT_POD (); - - typedef unsigned int mask_t; - - inline void init (void) { - mask = ~0; - value = (mask_t) -1; - } - - inline void add (hb_codepoint_t g) { - if (unlikely (value == (mask_t) -1)) { - value = g; - return; - } - - mask ^= (g & mask) ^ value; - value &= mask; - } - - inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { - /* The negation here stands for ~(x-1). */ - mask &= -(1 << _hb_bit_storage (a ^ b)); - value &= mask; - } - - inline bool may_have (hb_codepoint_t g) const { - return (g & mask) == value; - } - - private: - mask_t mask; - mask_t value; -}; +/* + * The set digests here implement various "filters" that support + * "approximate member query". Conceptually these are like Bloom + * Filter and Quotient Filter, however, much smaller, faster, and + * designed to fit the requirements of our uses for glyph coverage + * queries. As a result, our filters have much higher. + */ +template <typename mask_t, unsigned int shift> struct hb_set_digest_lowest_bits_t { ASSERT_POD (); - typedef unsigned long mask_t; + static const unsigned int mask_bytes = sizeof (mask_t); + static const unsigned int mask_bits = sizeof (mask_t) * 8; + static const unsigned int num_bits = 0 + + (mask_bytes >= 1 ? 3 : 0) + + (mask_bytes >= 2 ? 1 : 0) + + (mask_bytes >= 4 ? 1 : 0) + + (mask_bytes >= 8 ? 1 : 0) + + (mask_bytes >= 16? 1 : 0) + + 0; + + ASSERT_STATIC (shift < sizeof (hb_codepoint_t) * 8); + ASSERT_STATIC (shift + num_bits <= sizeof (hb_codepoint_t) * 8); inline void init (void) { mask = 0; @@ -83,7 +66,7 @@ struct hb_set_digest_lowest_bits_t } inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { - if (b - a >= sizeof (mask_t) * 8 - 1) + if ((b >> shift) - (a >> shift) >= mask_bits - 1) mask = (mask_t) -1; else { mask_t ma = mask_for (a); @@ -98,39 +81,66 @@ struct hb_set_digest_lowest_bits_t private: - static inline mask_t mask_for (hb_codepoint_t g) { return ((mask_t) 1) << (g & (sizeof (mask_t) * 8 - 1)); } + static inline mask_t mask_for (hb_codepoint_t g) { + return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); + } mask_t mask; }; -struct hb_set_digest_t +template <typename head_t, typename tail_t> +struct hb_set_digest_combiner_t { ASSERT_POD (); inline void init (void) { - digest1.init (); - digest2.init (); + head.init (); + tail.init (); } inline void add (hb_codepoint_t g) { - digest1.add (g); - digest2.add (g); + head.add (g); + tail.add (g); } inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { - digest1.add_range (a, b); - digest2.add_range (a, b); + head.add_range (a, b); + tail.add_range (a, b); } inline bool may_have (hb_codepoint_t g) const { - return digest1.may_have (g) && digest2.may_have (g); + return head.may_have (g) && tail.may_have (g); } private: - hb_set_digest_common_bits_t digest1; - hb_set_digest_lowest_bits_t digest2; + head_t head; + tail_t tail; }; +/* + * hb_set_digest_t + * + * This is a combination of digests that performs "best". + * There is not much science to this: it's a result of intuition + * and testing. + */ +typedef hb_set_digest_combiner_t +< + hb_set_digest_lowest_bits_t<unsigned long, 4>, + hb_set_digest_combiner_t + < + hb_set_digest_lowest_bits_t<unsigned long, 0>, + hb_set_digest_lowest_bits_t<unsigned long, 9> + > +> hb_set_digest_t; + + + +/* + * hb_set_t + */ + + /* TODO Make this faster and memmory efficient. */ struct hb_set_t @@ -160,7 +170,7 @@ struct hb_set_t inline void add (hb_codepoint_t g) { if (unlikely (in_error)) return; - if (unlikely (g == SENTINEL)) return; + if (unlikely (g == INVALID)) return; if (unlikely (g > MAX_G)) return; elt (g) |= mask (g); } @@ -245,19 +255,22 @@ struct hb_set_t } inline bool next (hb_codepoint_t *codepoint) const { - if (unlikely (*codepoint == SENTINEL)) { + if (unlikely (*codepoint == INVALID)) { hb_codepoint_t i = get_min (); - if (i != SENTINEL) { + if (i != INVALID) { *codepoint = i; return true; - } else + } else { + *codepoint = INVALID; return false; + } } for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++) if (has (i)) { *codepoint = i; return true; } + *codepoint = INVALID; return false; } inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const @@ -266,7 +279,10 @@ struct hb_set_t i = *last; if (!next (&i)) + { + *last = *first = INVALID; return false; + } *last = *first = i; while (next (&i) && i == *last + 1) @@ -286,10 +302,10 @@ struct hb_set_t { for (unsigned int i = 0; i < ELTS; i++) if (elts[i]) - for (unsigned int j = 0; i < BITS; j++) + for (unsigned int j = 0; j < BITS; j++) if (elts[i] & (1 << j)) return i * BITS + j; - return SENTINEL; + return INVALID; } inline hb_codepoint_t get_max (void) const { @@ -298,7 +314,7 @@ struct hb_set_t for (unsigned int j = BITS; j; j--) if (elts[i - 1] & (1 << (j - 1))) return (i - 1) * BITS + (j - 1); - return SENTINEL; + return INVALID; } typedef uint32_t elt_t; @@ -307,7 +323,7 @@ struct hb_set_t static const unsigned int BITS = (1 << SHIFT); static const unsigned int MASK = BITS - 1; static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS; - static const hb_codepoint_t SENTINEL = (hb_codepoint_t) -1; + static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; } elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; } diff --git a/src/hb-set.cc b/src/hb-set.cc index 5f427a5..59a0af4 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -27,10 +27,16 @@ #include "hb-set-private.hh" - /* Public API */ +/** + * hb_set_create: (Xconstructor) + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_set_t * hb_set_create (void) { @@ -44,6 +50,13 @@ hb_set_create (void) return set; } +/** + * hb_set_get_empty: + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_set_t * hb_set_get_empty (void) { @@ -57,12 +70,26 @@ hb_set_get_empty (void) return const_cast<hb_set_t *> (&_hb_set_nil); } +/** + * hb_set_reference: (skip) + * @set: a set. + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_set_t * hb_set_reference (hb_set_t *set) { return hb_object_reference (set); } +/** + * hb_set_destroy: (skip) + * @set: a set. + * + * Since: 1.0 + **/ void hb_set_destroy (hb_set_t *set) { @@ -73,6 +100,18 @@ hb_set_destroy (hb_set_t *set) free (set); } +/** + * hb_set_set_user_data: (skip) + * @set: a set. + * @key: + * @data: + * @destroy (closure data): + * @replace: + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_set_set_user_data (hb_set_t *set, hb_user_data_key_t *key, @@ -83,6 +122,15 @@ hb_set_set_user_data (hb_set_t *set, return hb_object_set_user_data (set, key, data, destroy, replace); } +/** + * hb_set_get_user_data: (skip) + * @set: a set. + * @key: + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ void * hb_set_get_user_data (hb_set_t *set, hb_user_data_key_t *key) @@ -91,24 +139,63 @@ hb_set_get_user_data (hb_set_t *set, } +/** + * hb_set_allocation_successful: + * @set: a set. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_set_allocation_successful (const hb_set_t *set HB_UNUSED) { return !set->in_error; } +/** + * hb_set_clear: + * @set: a set. + * + * + * + * Since: 1.0 + **/ void hb_set_clear (hb_set_t *set) { set->clear (); } +/** + * hb_set_is_empty: + * @set: a set. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_set_is_empty (const hb_set_t *set) { return set->is_empty (); } +/** + * hb_set_has: + * @set: a set. + * @codepoint: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_set_has (const hb_set_t *set, hb_codepoint_t codepoint) @@ -116,6 +203,15 @@ hb_set_has (const hb_set_t *set, return set->has (codepoint); } +/** + * hb_set_add: + * @set: a set. + * @codepoint: + * + * + * + * Since: 1.0 + **/ void hb_set_add (hb_set_t *set, hb_codepoint_t codepoint) @@ -123,6 +219,16 @@ hb_set_add (hb_set_t *set, set->add (codepoint); } +/** + * hb_set_add_range: + * @set: a set. + * @first: + * @last: + * + * + * + * Since: 1.0 + **/ void hb_set_add_range (hb_set_t *set, hb_codepoint_t first, @@ -131,6 +237,15 @@ hb_set_add_range (hb_set_t *set, set->add_range (first, last); } +/** + * hb_set_del: + * @set: a set. + * @codepoint: + * + * + * + * Since: 1.0 + **/ void hb_set_del (hb_set_t *set, hb_codepoint_t codepoint) @@ -138,6 +253,16 @@ hb_set_del (hb_set_t *set, set->del (codepoint); } +/** + * hb_set_del_range: + * @set: a set. + * @first: + * @last: + * + * + * + * Since: 1.0 + **/ void hb_set_del_range (hb_set_t *set, hb_codepoint_t first, @@ -146,6 +271,17 @@ hb_set_del_range (hb_set_t *set, set->del_range (first, last); } +/** + * hb_set_is_equal: + * @set: a set. + * @other: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_set_is_equal (const hb_set_t *set, const hb_set_t *other) @@ -153,6 +289,15 @@ hb_set_is_equal (const hb_set_t *set, return set->is_equal (other); } +/** + * hb_set_set: + * @set: a set. + * @other: + * + * + * + * Since: 1.0 + **/ void hb_set_set (hb_set_t *set, const hb_set_t *other) @@ -160,6 +305,15 @@ hb_set_set (hb_set_t *set, set->set (other); } +/** + * hb_set_union: + * @set: a set. + * @other: + * + * + * + * Since: 1.0 + **/ void hb_set_union (hb_set_t *set, const hb_set_t *other) @@ -167,6 +321,15 @@ hb_set_union (hb_set_t *set, set->union_ (other); } +/** + * hb_set_intersect: + * @set: a set. + * @other: + * + * + * + * Since: 1.0 + **/ void hb_set_intersect (hb_set_t *set, const hb_set_t *other) @@ -174,6 +337,15 @@ hb_set_intersect (hb_set_t *set, set->intersect (other); } +/** + * hb_set_subtract: + * @set: a set. + * @other: + * + * + * + * Since: 1.0 + **/ void hb_set_subtract (hb_set_t *set, const hb_set_t *other) @@ -181,6 +353,15 @@ hb_set_subtract (hb_set_t *set, set->subtract (other); } +/** + * hb_set_symmetric_difference: + * @set: a set. + * @other: + * + * + * + * Since: 1.0 + **/ void hb_set_symmetric_difference (hb_set_t *set, const hb_set_t *other) @@ -188,30 +369,79 @@ hb_set_symmetric_difference (hb_set_t *set, set->symmetric_difference (other); } +/** + * hb_set_invert: + * @set: a set. + * + * + * + * Since: 1.0 + **/ void hb_set_invert (hb_set_t *set) { set->invert (); } +/** + * hb_set_get_population: + * @set: a set. + * + * Returns the number of numbers in the set. + * + * Return value: set population. + * + * Since: 1.0 + **/ unsigned int hb_set_get_population (const hb_set_t *set) { return set->get_population (); } +/** + * hb_set_get_min: + * @set: a set. + * + * Finds the minimum number in the set. + * + * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. + * + * Since: 1.0 + **/ hb_codepoint_t hb_set_get_min (const hb_set_t *set) { return set->get_min (); } +/** + * hb_set_get_max: + * @set: a set. + * + * Finds the maximum number in the set. + * + * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. + * + * Since: 1.0 + **/ hb_codepoint_t hb_set_get_max (const hb_set_t *set) { return set->get_max (); } +/** + * hb_set_next: + * @set: a set. + * @codepoint: (inout): + * + * + * + * Return value: whether there was a next value. + * + * Since: 1.0 + **/ hb_bool_t hb_set_next (const hb_set_t *set, hb_codepoint_t *codepoint) @@ -219,6 +449,19 @@ hb_set_next (const hb_set_t *set, return set->next (codepoint); } +/** + * hb_set_next_range: + * @set: a set. + * @first: (out): output first codepoint in the range. + * @last: (inout): input current last and output last codepoint in the range. + * + * Gets the next consecutive range of numbers in @set that + * are greater than current value of @last. + * + * Return value: whether there was a next range. + * + * Since: 1.0 + **/ hb_bool_t hb_set_next_range (const hb_set_t *set, hb_codepoint_t *first, diff --git a/src/hb-set.h b/src/hb-set.h index 291e249..bafdae9 100644 --- a/src/hb-set.h +++ b/src/hb-set.h @@ -36,6 +36,8 @@ HB_BEGIN_DECLS +#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1) + typedef struct hb_set_t hb_set_t; diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh index dd014e3..607da5e 100644 --- a/src/hb-shape-plan-private.hh +++ b/src/hb-shape-plan-private.hh @@ -28,7 +28,6 @@ #define HB_SHAPE_PLAN_PRIVATE_HH #include "hb-private.hh" -#include "hb-shape-plan.h" #include "hb-object-private.hh" #include "hb-shaper-private.hh" @@ -39,12 +38,15 @@ struct hb_shape_plan_t ASSERT_POD (); hb_bool_t default_shaper_list; - hb_face_t *face; + hb_face_t *face_unsafe; /* We don't carry a reference to face. */ hb_segment_properties_t props; hb_shape_func_t *shaper_func; const char *shaper_name; + hb_feature_t *user_features; + unsigned int num_user_features; + struct hb_shaper_data_t shaper_data; }; diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 22a226f..2166173 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -27,6 +27,13 @@ #include "hb-shape-plan-private.hh" #include "hb-shaper-private.hh" #include "hb-font-private.hh" +#include "hb-buffer-private.hh" + + +#ifndef HB_DEBUG_SHAPE_PLAN +#define HB_DEBUG_SHAPE_PLAN (HB_DEBUG+0) +#endif + #define HB_SHAPER_IMPLEMENT(shaper) \ HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \ @@ -41,11 +48,16 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, unsigned int num_user_features, const char * const *shaper_list) { + DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, + "num_features=%d shaper_list=%p", + num_user_features, + shaper_list); + const hb_shaper_pair_t *shapers = _hb_shapers_get (); #define HB_SHAPER_PLAN(shaper) \ HB_STMT_START { \ - if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \ + if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \ HB_SHAPER_DATA (shaper, shape_plan) = \ HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \ shape_plan->shaper_func = _hb_##shaper##_shape; \ @@ -82,6 +94,20 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, * hb_shape_plan_t */ +/** + * hb_shape_plan_create: (Xconstructor) + * @face: + * @props: + * @user_features: (array length=num_user_features): + * @num_user_features: + * @shaper_list: (array zero-terminated=1): + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_shape_plan_t * hb_shape_plan_create (hb_face_t *face, const hb_segment_properties_t *props, @@ -89,27 +115,51 @@ hb_shape_plan_create (hb_face_t *face, unsigned int num_user_features, const char * const *shaper_list) { - assert (props->direction != HB_DIRECTION_INVALID); + DEBUG_MSG_FUNC (SHAPE_PLAN, NULL, + "face=%p num_features=%d shaper_list=%p", + face, + num_user_features, + shaper_list); hb_shape_plan_t *shape_plan; + hb_feature_t *features = NULL; if (unlikely (!face)) face = hb_face_get_empty (); if (unlikely (!props || hb_object_is_inert (face))) return hb_shape_plan_get_empty (); - if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) + if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t)))) + return hb_shape_plan_get_empty (); + if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) { + free (features); return hb_shape_plan_get_empty (); + } + + assert (props->direction != HB_DIRECTION_INVALID); hb_face_make_immutable (face); shape_plan->default_shaper_list = shaper_list == NULL; - shape_plan->face = hb_face_reference (face); + shape_plan->face_unsafe = face; shape_plan->props = *props; + shape_plan->num_user_features = num_user_features; + shape_plan->user_features = features; + if (num_user_features) + memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list); return shape_plan; } +/** + * hb_shape_plan_get_empty: + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_shape_plan_t * hb_shape_plan_get_empty (void) { @@ -123,6 +173,9 @@ hb_shape_plan_get_empty (void) NULL, /* shaper_func */ NULL, /* shaper_name */ + NULL, /* user_features */ + 0, /* num_user_featurs */ + { #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, #include "hb-shaper-list.hh" @@ -133,12 +186,30 @@ hb_shape_plan_get_empty (void) return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil); } +/** + * hb_shape_plan_reference: (skip) + * @shape_plan: a shape plan. + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_shape_plan_t * hb_shape_plan_reference (hb_shape_plan_t *shape_plan) { return hb_object_reference (shape_plan); } +/** + * hb_shape_plan_destroy: (skip) + * @shape_plan: a shape plan. + * + * + * + * Since: 1.0 + **/ void hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) { @@ -148,11 +219,25 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT - hb_face_destroy (shape_plan->face); + free (shape_plan->user_features); free (shape_plan); } +/** + * hb_shape_plan_set_user_data: (skip) + * @shape_plan: a shape plan. + * @key: + * @data: + * @destroy: + * @replace: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, hb_user_data_key_t *key, @@ -163,6 +248,17 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, return hb_object_set_user_data (shape_plan, key, data, destroy, replace); } +/** + * hb_shape_plan_get_user_data: (skip) + * @shape_plan: a shape plan. + * @key: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ void * hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, hb_user_data_key_t *key) @@ -171,6 +267,20 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, } +/** + * hb_shape_plan_execute: + * @shape_plan: a shape plan. + * @font: a font. + * @buffer: a buffer. + * @features: (array length=num_features): + * @num_features: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_shape_plan_execute (hb_shape_plan_t *shape_plan, hb_font_t *font, @@ -178,9 +288,19 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, const hb_feature_t *features, unsigned int num_features) { - if (unlikely (shape_plan->face != font->face)) + DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, + "num_features=%d shaper_func=%p", + num_features, + shape_plan->shaper_func); + + if (unlikely (hb_object_is_inert (shape_plan) || + hb_object_is_inert (font) || + hb_object_is_inert (buffer))) return false; + assert (shape_plan->face_unsafe == font->face); + assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props)); + #define HB_SHAPER_EXECUTE(shaper) \ HB_STMT_START { \ return HB_SHAPER_DATA (shaper, shape_plan) && \ @@ -215,23 +335,69 @@ hb_shape_plan_hash (const hb_shape_plan_t *shape_plan) } #endif -/* TODO no user-feature caching for now. */ +/* User-feature caching is currently somewhat dumb: + * it only finds matches where the feature array is identical, + * not cases where the feature lists would be compatible for plan purposes + * but have different ranges, for example. + */ struct hb_shape_plan_proposal_t { const hb_segment_properties_t props; const char * const *shaper_list; + const hb_feature_t *user_features; + unsigned int num_user_features; hb_shape_func_t *shaper_func; }; +static inline hb_bool_t +hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan, + const hb_shape_plan_proposal_t *proposal) +{ + if (proposal->num_user_features != shape_plan->num_user_features) return false; + for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++) + if (proposal->user_features[i].tag != shape_plan->user_features[i].tag || + proposal->user_features[i].value != shape_plan->user_features[i].value || + proposal->user_features[i].start != shape_plan->user_features[i].start || + proposal->user_features[i].end != shape_plan->user_features[i].end) return false; + return true; +} + static hb_bool_t hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, const hb_shape_plan_proposal_t *proposal) { return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && + hb_shape_plan_user_features_match (shape_plan, proposal) && ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) || (shape_plan->shaper_func == proposal->shaper_func)); } +static inline hb_bool_t +hb_non_global_user_features_present (const hb_feature_t *user_features, + unsigned int num_user_features) +{ + while (num_user_features) + if (user_features->start != 0 || user_features->end != (unsigned int) -1) + return true; + else + num_user_features--, user_features++; + return false; +} + +/** + * hb_shape_plan_create_cached: + * @face: + * @props: + * @user_features: (array length=num_user_features): + * @num_user_features: + * @shaper_list: (array zero-terminated=1): + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_shape_plan_t * hb_shape_plan_create_cached (hb_face_t *face, const hb_segment_properties_t *props, @@ -239,35 +405,37 @@ hb_shape_plan_create_cached (hb_face_t *face, unsigned int num_user_features, const char * const *shaper_list) { - if (num_user_features) - return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list); + DEBUG_MSG_FUNC (SHAPE_PLAN, NULL, + "face=%p num_features=%d shaper_list=%p", + face, + num_user_features, + shaper_list); hb_shape_plan_proposal_t proposal = { *props, shaper_list, + user_features, + num_user_features, NULL }; if (shaper_list) { - /* Choose shaper. Adapted from hb_shape_plan_plan(). */ -#define HB_SHAPER_PLAN(shaper) \ - HB_STMT_START { \ - if (hb_##shaper##_shaper_face_data_ensure (face)) \ - proposal.shaper_func = _hb_##shaper##_shape; \ - } HB_STMT_END - + /* Choose shaper. Adapted from hb_shape_plan_plan(). + * Must choose shaper exactly the same way as that function. */ for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++) if (0) ; #define HB_SHAPER_IMPLEMENT(shaper) \ - else if (0 == strcmp (*shaper_item, #shaper)) \ - HB_SHAPER_PLAN (shaper); + else if (0 == strcmp (*shaper_item, #shaper) && \ + hb_##shaper##_shaper_face_data_ensure (face)) \ + { \ + proposal.shaper_func = _hb_##shaper##_shape; \ + break; \ + } #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT -#undef HB_SHAPER_PLAN - - if (unlikely (!proposal.shaper_list)) + if (unlikely (!proposal.shaper_func)) return hb_shape_plan_get_empty (); } @@ -276,12 +444,20 @@ retry: hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atomic_ptr_get (&face->shape_plans); for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next) if (hb_shape_plan_matches (node->shape_plan, &proposal)) + { + DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache"); return hb_shape_plan_reference (node->shape_plan); + } /* Not found. */ hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list); + /* Don't add the plan to the cache if there were user features with non-global ranges */ + + if (hb_non_global_user_features_present (user_features, num_user_features)) + return shape_plan; + hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t)); if (unlikely (!node)) return shape_plan; @@ -294,13 +470,21 @@ retry: free (node); goto retry; } - - /* Release our reference on face. */ - hb_face_destroy (face); + DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "inserted into cache"); return hb_shape_plan_reference (shape_plan); } +/** + * hb_shape_plan_get_shaper: + * @shape_plan: a shape plan. + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ const char * hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) { diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 389ce3e..74747f8 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -34,17 +34,15 @@ #include "hb-font-private.hh" -static void +static bool parse_space (const char **pp, const char *end) { - char c; -#define ISSPACE(c) ((c)==' '||(c)=='\f'||(c)=='\n'||(c)=='\r'||(c)=='\t'||(c)=='\v') - while (*pp < end && (c = **pp, ISSPACE (c))) + while (*pp < end && ISSPACE (**pp)) (*pp)++; -#undef ISSPACE + return true; } -static hb_bool_t +static bool parse_char (const char **pp, const char *end, char c) { parse_space (pp, end); @@ -56,20 +54,23 @@ parse_char (const char **pp, const char *end, char c) return true; } -static hb_bool_t +static bool parse_uint (const char **pp, const char *end, unsigned int *pv) { char buf[32]; - strncpy (buf, *pp, end - *pp); - buf[ARRAY_LENGTH (buf) - 1] = '\0'; + 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; unsigned int v; + /* Intentionally use strtol instead of strtoul, such that + * -1 turns into "big number"... */ + errno = 0; v = strtol (p, &pend, 0); - - if (p == pend) + if (errno || p == pend) return false; *pv = v; @@ -77,7 +78,27 @@ parse_uint (const char **pp, const char *end, unsigned int *pv) return true; } -static hb_bool_t +static bool +parse_bool (const char **pp, const char *end, unsigned int *pv) +{ + parse_space (pp, end); + + const char *p = *pp; + while (*pp < end && ISALPHA(**pp)) + (*pp)++; + + /* CSS allows on/off as aliases 1/0. */ + if (*pp - p == 2 || 0 == strncmp (p, "on", 2)) + *pv = 1; + else if (*pp - p == 3 || 0 == strncmp (p, "off", 2)) + *pv = 0; + else + return false; + + return true; +} + +static bool parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature) { if (parse_char (pp, end, '-')) @@ -90,32 +111,48 @@ parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feat return true; } -static hb_bool_t +static bool parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature) { - const char *p = *pp; - char c; - parse_space (pp, end); -#define ISALNUM(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '9')) - while (*pp < end && (c = **pp, ISALNUM(c))) + char quote = 0; + + if (*pp < end && (**pp == '\'' || **pp == '"')) + { + quote = **pp; (*pp)++; -#undef ISALNUM + } - if (p == *pp) + const char *p = *pp; + while (*pp < end && ISALNUM(**pp)) + (*pp)++; + + if (p == *pp || *pp - p > 4) return false; feature->tag = hb_tag_from_string (p, *pp - p); + + if (quote) + { + /* CSS expects exactly four bytes. And we only allow quotations for + * CSS compatibility. So, enforce the length. */ + if (*pp - p != 4) + return false; + if (*pp == end || **pp != quote) + return false; + (*pp)++; + } + return true; } -static hb_bool_t +static bool parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature) { parse_space (pp, end); - hb_bool_t has_start; + bool has_start; feature->start = 0; feature->end = (unsigned int) -1; @@ -135,33 +172,73 @@ parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature) return parse_char (pp, end, ']'); } -static hb_bool_t +static bool parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature) { - return !parse_char (pp, end, '=') || parse_uint (pp, end, &feature->value); + bool had_equal = parse_char (pp, end, '='); + bool had_value = parse_uint (pp, end, &feature->value) || + parse_bool (pp, end, &feature->value); + /* CSS doesn't use equal-sign between tag and value. + * If there was an equal-sign, then there *must* be a value. + * A value without an eqaul-sign is ok, but not required. */ + return !had_equal || had_value; } -static hb_bool_t +static bool parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) { return parse_feature_value_prefix (pp, end, feature) && parse_feature_tag (pp, end, feature) && parse_feature_indices (pp, end, feature) && parse_feature_value_postfix (pp, end, feature) && + parse_space (pp, end) && *pp == end; } +/** + * hb_feature_from_string: + * @str: (array length=len): + * @len: + * @feature: (out) (allow-none): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_feature_from_string (const char *str, int len, hb_feature_t *feature) { + hb_feature_t feat; + if (len < 0) len = strlen (str); - return parse_one_feature (&str, str + len, feature); + if (likely (parse_one_feature (&str, str + len, &feat))) + { + if (feature) + *feature = feat; + return true; + } + + if (feature) + memset (feature, 0, sizeof (*feature)); + return false; } +/** + * hb_feature_to_string: + * @feature: + * @buf: (array length=size): + * @size: + * + * + * + * Since: 1.0 + **/ void hb_feature_to_string (hb_feature_t *feature, char *buf, unsigned int size) @@ -180,34 +257,43 @@ hb_feature_to_string (hb_feature_t *feature, { s[len++] = '['; if (feature->start) - len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->start); + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start)); if (feature->end != feature->start + 1) { s[len++] = ':'; if (feature->end != (unsigned int) -1) - len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->end); + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end)); } s[len++] = ']'; } if (feature->value > 1) { s[len++] = '='; - len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->value); + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); } assert (len < ARRAY_LENGTH (s)); len = MIN (len, size - 1); memcpy (buf, s, len); - s[len] = '\0'; + buf[len] = '\0'; } static const char **static_shaper_list; -static +static inline void free_static_shaper_list (void) { free (static_shaper_list); } +/** + * hb_shape_list_shapers: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ const char ** hb_shape_list_shapers (void) { @@ -234,7 +320,7 @@ retry: goto retry; } -#ifdef HAVE_ATEXIT +#ifdef HB_USE_ATEXIT atexit (free_static_shaper_list); /* First person registers atexit() callback. */ #endif } @@ -243,6 +329,20 @@ retry: } +/** + * hb_shape_full: + * @font: a font. + * @buffer: a buffer. + * @features: (array length=num_features): + * @num_features: + * @shaper_list: (array zero-terminated=1): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_shape_full (hb_font_t *font, hb_buffer_t *buffer, @@ -255,8 +355,6 @@ hb_shape_full (hb_font_t *font, assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE); - buffer->guess_segment_properties (); - hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list); hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); hb_shape_plan_destroy (shape_plan); @@ -266,6 +364,17 @@ hb_shape_full (hb_font_t *font, return res; } +/** + * hb_shape: + * @font: a font. + * @buffer: a buffer. + * @features: (array length=num_features): + * @num_features: + * + * + * + * Since: 1.0 + **/ void hb_shape (hb_font_t *font, hb_buffer_t *buffer, diff --git a/src/hb-shaper-list.hh b/src/hb-shaper-list.hh index b9c029e..6c537d4 100644 --- a/src/hb-shaper-list.hh +++ b/src/hb-shaper-list.hh @@ -34,17 +34,15 @@ /* Only picks up fonts that have a "Silf" table. */ HB_SHAPER_IMPLEMENT (graphite2) #endif +#ifdef HAVE_CORETEXT +/* Only picks up fonts that have a "mort" or "morx" table. */ +HB_SHAPER_IMPLEMENT (coretext_aat) +#endif #ifdef HAVE_OT HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */ #endif -#ifdef HAVE_HB_OLD -HB_SHAPER_IMPLEMENT (old) -#endif -#ifdef HAVE_ICU_LE -HB_SHAPER_IMPLEMENT (icu_le) -#endif #ifdef HAVE_UNISCRIBE HB_SHAPER_IMPLEMENT (uniscribe) #endif @@ -52,4 +50,6 @@ HB_SHAPER_IMPLEMENT (uniscribe) HB_SHAPER_IMPLEMENT (coretext) #endif +#ifdef HAVE_FALLBACK HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */ +#endif diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc index 1c1aed9..6ae2601 100644 --- a/src/hb-shaper.cc +++ b/src/hb-shaper.cc @@ -40,7 +40,7 @@ static const hb_shaper_pair_t all_shapers[] = { static const hb_shaper_pair_t *static_shapers; -static +static inline void free_static_shapers (void) { if (unlikely (static_shapers != all_shapers)) @@ -100,7 +100,7 @@ retry: goto retry; } -#ifdef HAVE_ATEXIT +#ifdef HB_USE_ATEXIT atexit (free_static_shapers); /* First person registers atexit() callback. */ #endif } diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index 61e6ad3..5b53821 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -49,7 +49,7 @@ static const hb_script_t ucdn_script_translate[] = HB_SCRIPT_HANGUL, HB_SCRIPT_ETHIOPIC, HB_SCRIPT_CHEROKEE, - HB_SCRIPT_CANADIAN_ABORIGINAL, + HB_SCRIPT_CANADIAN_SYLLABICS, HB_SCRIPT_OGHAM, HB_SCRIPT_RUNIC, HB_SCRIPT_KHMER, @@ -125,6 +125,29 @@ static const hb_script_t ucdn_script_translate[] = HB_SCRIPT_SORA_SOMPENG, HB_SCRIPT_TAKRI, HB_SCRIPT_UNKNOWN, + HB_SCRIPT_BASSA_VAH, + HB_SCRIPT_CAUCASIAN_ALBANIAN, + HB_SCRIPT_DUPLOYAN, + HB_SCRIPT_ELBASAN, + HB_SCRIPT_GRANTHA, + HB_SCRIPT_KHOJKI, + HB_SCRIPT_KHUDAWADI, + HB_SCRIPT_LINEAR_A, + HB_SCRIPT_MAHAJANI, + HB_SCRIPT_MANICHAEAN, + HB_SCRIPT_MENDE_KIKAKUI, + HB_SCRIPT_MODI, + HB_SCRIPT_MRO, + HB_SCRIPT_NABATAEAN, + HB_SCRIPT_OLD_NORTH_ARABIAN, + HB_SCRIPT_OLD_PERMIC, + HB_SCRIPT_PAHAWH_HMONG, + HB_SCRIPT_PALMYRENE, + HB_SCRIPT_PAU_CIN_HAU, + HB_SCRIPT_PSALTER_PAHLAVI, + HB_SCRIPT_SIDDHAM, + HB_SCRIPT_TIRHUTA, + HB_SCRIPT_WARANG_CITI, }; static hb_unicode_combining_class_t diff --git a/src/hb-ucdn/Makefile.am b/src/hb-ucdn/Makefile.am index 40d6055..0670b5c 100644 --- a/src/hb-ucdn/Makefile.am +++ b/src/hb-ucdn/Makefile.am @@ -7,7 +7,7 @@ libhb_ucdn_la_SOURCES = \ ucdn.h \ ucdn.c \ unicodedata_db.h -libhb_ucdn_CPPFLAGS = \ +libhb_ucdn_la_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ -I$(top_builddir)/src diff --git a/src/hb-ucdn/Makefile.in b/src/hb-ucdn/Makefile.in index 64e16d2..95f8ac6 100644 --- a/src/hb-ucdn/Makefile.in +++ b/src/hb-ucdn/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,6 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -35,14 +79,14 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/hb-ucdn -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - COPYING +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp COPYING README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -51,11 +95,24 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhb_ucdn_la_DEPENDENCIES = -am_libhb_ucdn_la_OBJECTS = ucdn.lo +am_libhb_ucdn_la_OBJECTS = libhb_ucdn_la-ucdn.lo libhb_ucdn_la_OBJECTS = $(am_libhb_ucdn_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -68,22 +125,40 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(libhb_ucdn_la_SOURCES) DIST_SOURCES = $(libhb_ucdn_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -124,6 +199,7 @@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ FREETYPE_LIBS = @FREETYPE_LIBS@ +GIT = @GIT@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GLIB_MKENUMS = @GLIB_MKENUMS@ @@ -132,22 +208,34 @@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRAPHITE2_CFLAGS = @GRAPHITE2_CFLAGS@ GRAPHITE2_LIBS = @GRAPHITE2_LIBS@ GREP = @GREP@ -GTHREAD_CFLAGS = @GTHREAD_CFLAGS@ -GTHREAD_LIBS = @GTHREAD_LIBS@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@ HB_VERSION = @HB_VERSION@ HB_VERSION_MAJOR = @HB_VERSION_MAJOR@ HB_VERSION_MICRO = @HB_VERSION_MICRO@ HB_VERSION_MINOR = @HB_VERSION_MINOR@ +HTML_DIR = @HTML_DIR@ ICU_CFLAGS = @ICU_CFLAGS@ -ICU_LE_CFLAGS = @ICU_LE_CFLAGS@ -ICU_LE_LIBS = @ICU_LE_LIBS@ +ICU_CONFIG = @ICU_CONFIG@ ICU_LIBS = @ICU_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ @@ -177,6 +265,7 @@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ +RAGEL = @RAGEL@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -245,7 +334,7 @@ libhb_ucdn_la_SOURCES = \ ucdn.c \ unicodedata_db.h -libhb_ucdn_CPPFLAGS = \ +libhb_ucdn_la_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ -I$(top_builddir)/src @@ -289,12 +378,15 @@ $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + libhb-ucdn.la: $(libhb_ucdn_la_OBJECTS) $(libhb_ucdn_la_DEPENDENCIES) $(EXTRA_libhb_ucdn_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhb_ucdn_la_OBJECTS) $(libhb_ucdn_la_LIBADD) $(LIBS) @@ -304,21 +396,21 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucdn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_ucdn_la-ucdn.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -327,32 +419,28 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +libhb_ucdn_la-ucdn.lo: ucdn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_ucdn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_ucdn_la-ucdn.lo -MD -MP -MF $(DEPDIR)/libhb_ucdn_la-ucdn.Tpo -c -o libhb_ucdn_la-ucdn.lo `test -f 'ucdn.c' || echo '$(srcdir)/'`ucdn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_ucdn_la-ucdn.Tpo $(DEPDIR)/libhb_ucdn_la-ucdn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ucdn.c' object='libhb_ucdn_la-ucdn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_ucdn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_ucdn_la-ucdn.lo `test -f 'ucdn.c' || echo '$(srcdir)/'`ucdn.c + mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -364,15 +452,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -381,6 +465,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -522,18 +621,19 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am -include $(top_srcdir)/git.mk diff --git a/src/hb-ucdn/README b/src/hb-ucdn/README index fcb97b9..2f3c552 100644 --- a/src/hb-ucdn/README +++ b/src/hb-ucdn/README @@ -1,6 +1,7 @@ Contents of this directory are derived from UCDN: https://github.com/grigorig/ucdn + https://github.com/behdad/ucdn The original README follows: diff --git a/src/hb-ucdn/ucdn.c b/src/hb-ucdn/ucdn.c index b61e34a..d1a4195 100644 --- a/src/hb-ucdn/ucdn.c +++ b/src/hb-ucdn/ucdn.c @@ -16,7 +16,6 @@ #include <stdio.h> #include <stdlib.h> -#include <stdint.h> #include "ucdn.h" typedef struct { @@ -34,7 +33,7 @@ typedef struct { } MirrorPair; typedef struct { - int start; + unsigned int start; short count, index; } Reindex; diff --git a/src/hb-ucdn/ucdn.h b/src/hb-ucdn/ucdn.h index 802f044..ec8085b 100644 --- a/src/hb-ucdn/ucdn.h +++ b/src/hb-ucdn/ucdn.h @@ -34,7 +34,29 @@ HB_BEGIN_HEADER -#include <stdint.h> +#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 #define UCDN_EAST_ASIAN_F 0 #define UCDN_EAST_ASIAN_H 1 @@ -146,6 +168,29 @@ HB_BEGIN_HEADER #define UCDN_SCRIPT_SORA_SOMPENG 100 #define UCDN_SCRIPT_TAKRI 101 #define UCDN_SCRIPT_UNKNOWN 102 +#define UCDN_SCRIPT_BASSA_VAH 103 +#define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104 +#define UCDN_SCRIPT_DUPLOYAN 105 +#define UCDN_SCRIPT_ELBASAN 106 +#define UCDN_SCRIPT_GRANTHA 107 +#define UCDN_SCRIPT_KHOJKI 108 +#define UCDN_SCRIPT_KHUDAWADI 109 +#define UCDN_SCRIPT_LINEAR_A 110 +#define UCDN_SCRIPT_MAHAJANI 111 +#define UCDN_SCRIPT_MANICHAEAN 112 +#define UCDN_SCRIPT_MENDE_KIKAKUI 113 +#define UCDN_SCRIPT_MODI 114 +#define UCDN_SCRIPT_MRO 115 +#define UCDN_SCRIPT_NABATAEAN 116 +#define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117 +#define UCDN_SCRIPT_OLD_PERMIC 118 +#define UCDN_SCRIPT_PAHAWH_HMONG 119 +#define UCDN_SCRIPT_PALMYRENE 120 +#define UCDN_SCRIPT_PAU_CIN_HAU 121 +#define UCDN_SCRIPT_PSALTER_PAHLAVI 122 +#define UCDN_SCRIPT_SIDDHAM 123 +#define UCDN_SCRIPT_TIRHUTA 124 +#define UCDN_SCRIPT_WARANG_CITI 125 #define UCDN_GENERAL_CATEGORY_CC 0 #define UCDN_GENERAL_CATEGORY_CF 1 @@ -197,6 +242,10 @@ HB_BEGIN_HEADER #define UCDN_BIDI_CLASS_S 16 #define UCDN_BIDI_CLASS_WS 17 #define UCDN_BIDI_CLASS_ON 18 +#define UCDN_BIDI_CLASS_LRI 19 +#define UCDN_BIDI_CLASS_RLI 20 +#define UCDN_BIDI_CLASS_FSI 21 +#define UCDN_BIDI_CLASS_PDI 22 /** * Return version of the Unicode database. diff --git a/src/hb-ucdn/unicodedata_db.h b/src/hb-ucdn/unicodedata_db.h index 20244ac..a78d2e6 100644 --- a/src/hb-ucdn/unicodedata_db.h +++ b/src/hb-ucdn/unicodedata_db.h @@ -1,6 +1,6 @@ /* this file was generated by makeunicodedata.py 3.2 */ -#define UNIDATA_VERSION "6.2.0" +#define UNIDATA_VERSION "7.0.0" /* a list of unique database records */ static const UCDRecord ucd_records[] = { {2, 0, 18, 0, 5, 0, 102}, @@ -89,6 +89,7 @@ static const UCDRecord ucd_records[] = { {5, 0, 0, 0, 5, 0, 4}, {21, 0, 0, 0, 5, 0, 0}, {17, 0, 18, 0, 5, 0, 4}, + {26, 0, 18, 0, 5, 0, 4}, {23, 0, 10, 0, 5, 0, 4}, {12, 220, 13, 0, 5, 0, 5}, {12, 230, 13, 0, 5, 0, 5}, @@ -114,6 +115,7 @@ static const UCDRecord ucd_records[] = { {12, 25, 13, 0, 5, 0, 5}, {7, 0, 3, 0, 5, 0, 5}, {1, 0, 11, 0, 5, 0, 6}, + {1, 0, 11, 0, 5, 0, 0}, {25, 0, 18, 0, 5, 0, 6}, {25, 0, 4, 0, 5, 0, 6}, {21, 0, 10, 0, 5, 0, 6}, @@ -126,6 +128,7 @@ static const UCDRecord ucd_records[] = { {12, 31, 13, 0, 5, 0, 6}, {12, 32, 13, 0, 5, 0, 6}, {21, 0, 4, 0, 5, 0, 0}, + {1, 0, 4, 0, 5, 0, 0}, {7, 0, 4, 0, 5, 0, 6}, {6, 0, 4, 0, 5, 0, 0}, {12, 27, 13, 0, 5, 0, 40}, @@ -141,7 +144,6 @@ static const UCDRecord ucd_records[] = { {13, 0, 11, 0, 5, 0, 0}, {21, 0, 11, 0, 5, 0, 6}, {12, 35, 13, 0, 5, 0, 40}, - {1, 0, 11, 0, 5, 0, 0}, {6, 0, 4, 0, 5, 0, 6}, {13, 0, 8, 0, 5, 0, 6}, {26, 0, 4, 0, 5, 0, 6}, @@ -179,9 +181,9 @@ static const UCDRecord ucd_records[] = { {13, 0, 0, 0, 5, 0, 9}, {21, 0, 0, 0, 5, 0, 9}, {6, 0, 0, 0, 5, 0, 9}, + {7, 0, 0, 0, 5, 0, 10}, {12, 0, 13, 0, 5, 0, 10}, {10, 0, 0, 0, 5, 0, 10}, - {7, 0, 0, 0, 5, 0, 10}, {12, 7, 13, 0, 5, 0, 10}, {12, 9, 13, 0, 5, 0, 10}, {13, 0, 0, 0, 5, 0, 10}, @@ -218,25 +220,25 @@ static const UCDRecord ucd_records[] = { {15, 0, 0, 0, 5, 0, 14}, {26, 0, 18, 0, 5, 0, 14}, {23, 0, 10, 0, 5, 0, 14}, + {12, 0, 13, 0, 5, 0, 15}, {10, 0, 0, 0, 5, 0, 15}, {7, 0, 0, 0, 5, 0, 15}, - {12, 0, 13, 0, 5, 0, 15}, {12, 9, 13, 0, 5, 0, 15}, {12, 84, 13, 0, 5, 0, 15}, {12, 91, 13, 0, 5, 0, 15}, {13, 0, 0, 0, 5, 0, 15}, {15, 0, 18, 0, 5, 0, 15}, {26, 0, 0, 0, 5, 0, 15}, + {12, 0, 13, 0, 5, 0, 16}, {10, 0, 0, 0, 5, 0, 16}, {7, 0, 0, 0, 5, 0, 16}, {12, 7, 13, 0, 5, 0, 16}, {12, 0, 0, 0, 5, 0, 16}, - {12, 0, 13, 0, 5, 0, 16}, {12, 9, 13, 0, 5, 0, 16}, {13, 0, 0, 0, 5, 0, 16}, + {12, 0, 13, 0, 5, 0, 17}, {10, 0, 0, 0, 5, 0, 17}, {7, 0, 0, 0, 5, 0, 17}, - {12, 0, 13, 0, 5, 0, 17}, {12, 9, 13, 0, 5, 0, 17}, {13, 0, 0, 0, 5, 0, 17}, {15, 0, 0, 0, 5, 0, 17}, @@ -245,6 +247,7 @@ static const UCDRecord ucd_records[] = { {7, 0, 0, 0, 5, 0, 18}, {12, 9, 13, 0, 5, 0, 18}, {12, 0, 13, 0, 5, 0, 18}, + {13, 0, 0, 0, 5, 0, 18}, {21, 0, 0, 0, 5, 0, 18}, {7, 0, 0, 0, 5, 0, 19}, {12, 0, 13, 0, 5, 0, 19}, @@ -330,7 +333,7 @@ static const UCDRecord ucd_records[] = { {21, 0, 18, 0, 5, 0, 31}, {17, 0, 18, 0, 5, 0, 31}, {12, 0, 13, 0, 5, 0, 31}, - {29, 0, 17, 0, 5, 0, 31}, + {1, 0, 14, 0, 5, 0, 31}, {13, 0, 0, 0, 5, 0, 31}, {7, 0, 0, 0, 5, 0, 31}, {6, 0, 0, 0, 5, 0, 31}, @@ -355,6 +358,7 @@ static const UCDRecord ucd_records[] = { {12, 230, 13, 0, 5, 0, 53}, {12, 220, 13, 0, 5, 0, 53}, {10, 0, 0, 0, 5, 0, 53}, + {12, 0, 13, 0, 5, 0, 53}, {21, 0, 0, 0, 5, 0, 53}, {7, 0, 0, 0, 5, 0, 77}, {10, 0, 0, 0, 5, 0, 77}, @@ -365,6 +369,7 @@ static const UCDRecord ucd_records[] = { {13, 0, 0, 0, 5, 0, 77}, {21, 0, 0, 0, 5, 0, 77}, {6, 0, 0, 0, 5, 0, 77}, + {11, 0, 13, 0, 5, 0, 40}, {12, 0, 13, 0, 5, 0, 61}, {10, 0, 0, 0, 5, 0, 61}, {7, 0, 0, 0, 5, 0, 61}, @@ -432,11 +437,14 @@ static const UCDRecord ucd_records[] = { {22, 0, 18, 1, 5, 0, 0}, {18, 0, 18, 1, 5, 0, 0}, {25, 0, 18, 0, 5, 0, 0}, + {1, 0, 19, 0, 5, 0, 0}, + {1, 0, 20, 0, 5, 0, 0}, + {1, 0, 21, 0, 5, 0, 0}, + {1, 0, 22, 0, 5, 0, 0}, {15, 0, 8, 0, 5, 0, 0}, {25, 0, 9, 0, 5, 0, 0}, {6, 0, 0, 0, 4, 0, 1}, {23, 0, 10, 0, 1, 0, 0}, - {11, 0, 13, 0, 5, 0, 40}, {9, 0, 0, 0, 5, 0, 0}, {5, 0, 0, 0, 4, 0, 0}, {26, 0, 10, 0, 5, 0, 0}, @@ -541,14 +549,13 @@ static const UCDRecord ucd_records[] = { {12, 7, 13, 0, 5, 0, 84}, {10, 9, 0, 0, 5, 0, 84}, {21, 0, 0, 0, 5, 0, 84}, - {6, 0, 0, 0, 5, 0, 84}, {13, 0, 0, 0, 5, 0, 84}, + {6, 0, 0, 0, 5, 0, 22}, {7, 0, 0, 0, 5, 0, 76}, {12, 0, 13, 0, 5, 0, 76}, {10, 0, 0, 0, 5, 0, 76}, {13, 0, 0, 0, 5, 0, 76}, {21, 0, 0, 0, 5, 0, 76}, - {6, 0, 0, 0, 5, 0, 22}, {7, 0, 0, 0, 5, 0, 78}, {12, 230, 13, 0, 5, 0, 78}, {12, 220, 13, 0, 5, 0, 78}, @@ -612,6 +619,8 @@ static const UCDRecord ucd_records[] = { {15, 0, 0, 0, 5, 0, 37}, {7, 0, 0, 0, 5, 0, 38}, {14, 0, 0, 0, 5, 0, 38}, + {7, 0, 0, 0, 5, 0, 118}, + {12, 230, 13, 0, 5, 0, 118}, {7, 0, 0, 0, 5, 0, 48}, {21, 0, 0, 0, 5, 0, 48}, {7, 0, 0, 0, 5, 0, 59}, @@ -622,10 +631,19 @@ static const UCDRecord ucd_records[] = { {7, 0, 0, 0, 5, 0, 49}, {7, 0, 0, 0, 5, 0, 50}, {13, 0, 0, 0, 5, 0, 50}, + {7, 0, 0, 0, 5, 0, 106}, + {7, 0, 0, 0, 5, 0, 104}, + {21, 0, 0, 0, 5, 0, 104}, + {7, 0, 0, 0, 5, 0, 110}, {7, 0, 3, 0, 5, 0, 51}, {7, 0, 3, 0, 5, 0, 86}, {21, 0, 3, 0, 5, 0, 86}, {15, 0, 3, 0, 5, 0, 86}, + {7, 0, 3, 0, 5, 0, 120}, + {26, 0, 3, 0, 5, 0, 120}, + {15, 0, 3, 0, 5, 0, 120}, + {7, 0, 3, 0, 5, 0, 116}, + {15, 0, 3, 0, 5, 0, 116}, {7, 0, 3, 0, 5, 0, 63}, {15, 0, 3, 0, 5, 0, 63}, {21, 0, 18, 0, 5, 0, 63}, @@ -644,12 +662,23 @@ static const UCDRecord ucd_records[] = { {7, 0, 3, 0, 5, 0, 87}, {15, 0, 3, 0, 5, 0, 87}, {21, 0, 3, 0, 5, 0, 87}, + {7, 0, 3, 0, 5, 0, 117}, + {15, 0, 3, 0, 5, 0, 117}, + {7, 0, 3, 0, 5, 0, 112}, + {26, 0, 3, 0, 5, 0, 112}, + {12, 230, 13, 0, 5, 0, 112}, + {12, 220, 13, 0, 5, 0, 112}, + {15, 0, 3, 0, 5, 0, 112}, + {21, 0, 3, 0, 5, 0, 112}, {7, 0, 3, 0, 5, 0, 79}, {21, 0, 18, 0, 5, 0, 79}, {7, 0, 3, 0, 5, 0, 88}, {15, 0, 3, 0, 5, 0, 88}, {7, 0, 3, 0, 5, 0, 89}, {15, 0, 3, 0, 5, 0, 89}, + {7, 0, 3, 0, 5, 0, 122}, + {21, 0, 3, 0, 5, 0, 122}, + {15, 0, 3, 0, 5, 0, 122}, {7, 0, 3, 0, 5, 0, 90}, {15, 0, 11, 0, 5, 0, 6}, {10, 0, 0, 0, 5, 0, 93}, @@ -675,31 +704,99 @@ static const UCDRecord ucd_records[] = { {12, 9, 13, 0, 5, 0, 95}, {13, 0, 0, 0, 5, 0, 95}, {21, 0, 0, 0, 5, 0, 95}, + {7, 0, 0, 0, 5, 0, 111}, + {12, 7, 13, 0, 5, 0, 111}, + {21, 0, 0, 0, 5, 0, 111}, {12, 0, 13, 0, 5, 0, 99}, {10, 0, 0, 0, 5, 0, 99}, {7, 0, 0, 0, 5, 0, 99}, {10, 9, 0, 0, 5, 0, 99}, {21, 0, 0, 0, 5, 0, 99}, {13, 0, 0, 0, 5, 0, 99}, + {15, 0, 0, 0, 5, 0, 18}, + {7, 0, 0, 0, 5, 0, 108}, + {10, 0, 0, 0, 5, 0, 108}, + {12, 0, 13, 0, 5, 0, 108}, + {10, 9, 0, 0, 5, 0, 108}, + {12, 7, 13, 0, 5, 0, 108}, + {21, 0, 0, 0, 5, 0, 108}, + {7, 0, 0, 0, 5, 0, 109}, + {12, 0, 13, 0, 5, 0, 109}, + {10, 0, 0, 0, 5, 0, 109}, + {12, 7, 13, 0, 5, 0, 109}, + {12, 9, 13, 0, 5, 0, 109}, + {13, 0, 0, 0, 5, 0, 109}, + {12, 0, 13, 0, 5, 0, 107}, + {10, 0, 0, 0, 5, 0, 107}, + {7, 0, 0, 0, 5, 0, 107}, + {12, 7, 13, 0, 5, 0, 107}, + {10, 9, 0, 0, 5, 0, 107}, + {12, 230, 13, 0, 5, 0, 107}, + {7, 0, 0, 0, 5, 0, 124}, + {10, 0, 0, 0, 5, 0, 124}, + {12, 0, 13, 0, 5, 0, 124}, + {12, 9, 13, 0, 5, 0, 124}, + {12, 7, 13, 0, 5, 0, 124}, + {21, 0, 0, 0, 5, 0, 124}, + {13, 0, 0, 0, 5, 0, 124}, + {7, 0, 0, 0, 5, 0, 123}, + {10, 0, 0, 0, 5, 0, 123}, + {12, 0, 13, 0, 5, 0, 123}, + {12, 9, 13, 0, 5, 0, 123}, + {12, 7, 13, 0, 5, 0, 123}, + {21, 0, 0, 0, 5, 0, 123}, + {7, 0, 0, 0, 5, 0, 114}, + {10, 0, 0, 0, 5, 0, 114}, + {12, 0, 13, 0, 5, 0, 114}, + {12, 9, 13, 0, 5, 0, 114}, + {21, 0, 0, 0, 5, 0, 114}, + {13, 0, 0, 0, 5, 0, 114}, {7, 0, 0, 0, 5, 0, 101}, {12, 0, 13, 0, 5, 0, 101}, {10, 0, 0, 0, 5, 0, 101}, {10, 9, 0, 0, 5, 0, 101}, {12, 7, 13, 0, 5, 0, 101}, {13, 0, 0, 0, 5, 0, 101}, + {9, 0, 0, 0, 5, 0, 125}, + {5, 0, 0, 0, 5, 0, 125}, + {13, 0, 0, 0, 5, 0, 125}, + {15, 0, 0, 0, 5, 0, 125}, + {7, 0, 0, 0, 5, 0, 125}, + {7, 0, 0, 0, 5, 0, 121}, {7, 0, 0, 0, 5, 0, 62}, {14, 0, 0, 0, 5, 0, 62}, {21, 0, 0, 0, 5, 0, 62}, {7, 0, 0, 0, 5, 0, 80}, + {7, 0, 0, 0, 5, 0, 115}, + {13, 0, 0, 0, 5, 0, 115}, + {21, 0, 0, 0, 5, 0, 115}, + {7, 0, 0, 0, 5, 0, 103}, + {12, 1, 13, 0, 5, 0, 103}, + {21, 0, 0, 0, 5, 0, 103}, + {7, 0, 0, 0, 5, 0, 119}, + {12, 230, 13, 0, 5, 0, 119}, + {21, 0, 0, 0, 5, 0, 119}, + {26, 0, 0, 0, 5, 0, 119}, + {6, 0, 0, 0, 5, 0, 119}, + {13, 0, 0, 0, 5, 0, 119}, + {15, 0, 0, 0, 5, 0, 119}, {7, 0, 0, 0, 5, 0, 98}, {10, 0, 0, 0, 5, 0, 98}, {12, 0, 13, 0, 5, 0, 98}, {6, 0, 0, 0, 5, 0, 98}, + {7, 0, 0, 0, 5, 0, 105}, + {26, 0, 0, 0, 5, 0, 105}, + {12, 0, 13, 0, 5, 0, 105}, + {12, 1, 13, 0, 5, 0, 105}, + {21, 0, 0, 0, 5, 0, 105}, {10, 216, 0, 0, 5, 0, 0}, {10, 226, 0, 0, 5, 0, 0}, {12, 230, 13, 0, 5, 0, 2}, {25, 0, 0, 0, 5, 0, 0}, {13, 0, 8, 0, 5, 0, 0}, + {7, 0, 3, 0, 5, 0, 113}, + {15, 0, 3, 0, 5, 0, 113}, + {12, 220, 13, 0, 5, 0, 113}, {26, 0, 0, 0, 2, 0, 32}, }; @@ -1072,8 +1169,8 @@ static const MirrorPair mirror_pairs[] = { }; /* Reindexing of NFC first characters. */ -#define TOTAL_FIRST 372 -#define TOTAL_LAST 56 +#define TOTAL_FIRST 376 +#define TOTAL_LAST 62 static const Reindex nfc_first[] = { { 60, 2, 0}, { 65, 15, 3}, @@ -1282,6 +1379,9 @@ static const Reindex nfc_first[] = { { 69787, 0, 368}, { 69797, 0, 369}, { 69937, 1, 370}, + { 70471, 0, 372}, + { 70841, 0, 373}, + { 71096, 1, 374}, {0,0,0} }; @@ -1319,6 +1419,12 @@ static const Reindex nfc_last[] = { { 12441, 1, 52}, { 69818, 0, 54}, { 69927, 0, 55}, + { 70462, 0, 56}, + { 70487, 0, 57}, + { 70832, 0, 58}, + { 70842, 0, 59}, + { 70845, 0, 60}, + { 71087, 0, 61}, {0,0,0} }; @@ -1432,6 +1538,29 @@ static const Reindex nfc_last[] = { #define UCDN_SCRIPT_SORA_SOMPENG 100 #define UCDN_SCRIPT_TAKRI 101 #define UCDN_SCRIPT_UNKNOWN 102 +#define UCDN_SCRIPT_BASSA_VAH 103 +#define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104 +#define UCDN_SCRIPT_DUPLOYAN 105 +#define UCDN_SCRIPT_ELBASAN 106 +#define UCDN_SCRIPT_GRANTHA 107 +#define UCDN_SCRIPT_KHOJKI 108 +#define UCDN_SCRIPT_KHUDAWADI 109 +#define UCDN_SCRIPT_LINEAR_A 110 +#define UCDN_SCRIPT_MAHAJANI 111 +#define UCDN_SCRIPT_MANICHAEAN 112 +#define UCDN_SCRIPT_MENDE_KIKAKUI 113 +#define UCDN_SCRIPT_MODI 114 +#define UCDN_SCRIPT_MRO 115 +#define UCDN_SCRIPT_NABATAEAN 116 +#define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117 +#define UCDN_SCRIPT_OLD_PERMIC 118 +#define UCDN_SCRIPT_PAHAWH_HMONG 119 +#define UCDN_SCRIPT_PALMYRENE 120 +#define UCDN_SCRIPT_PAU_CIN_HAU 121 +#define UCDN_SCRIPT_PSALTER_PAHLAVI 122 +#define UCDN_SCRIPT_SIDDHAM 123 +#define UCDN_SCRIPT_TIRHUTA 124 +#define UCDN_SCRIPT_WARANG_CITI 125 #define UCDN_GENERAL_CATEGORY_CC 0 #define UCDN_GENERAL_CATEGORY_CF 1 @@ -1483,6 +1612,10 @@ static const Reindex nfc_last[] = { #define UCDN_BIDI_CLASS_S 16 #define UCDN_BIDI_CLASS_WS 17 #define UCDN_BIDI_CLASS_ON 18 +#define UCDN_BIDI_CLASS_LRI 19 +#define UCDN_BIDI_CLASS_RLI 20 +#define UCDN_BIDI_CLASS_FSI 21 +#define UCDN_BIDI_CLASS_PDI 22 /* index tables for the database records */ #define SHIFT1 5 @@ -1502,21 +1635,21 @@ static const unsigned char index0[] = { 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 69, 70, 70, 71, 69, 70, 70, 72, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 70, 70, 70, 88, 89, 90, 91, 92, 70, 93, 70, 94, - 95, 70, 70, 70, 70, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 97, 97, 97, - 98, 99, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 100, 100, 100, 100, - 101, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 70, 96, 70, 97, + 98, 99, 100, 101, 102, 103, 70, 104, 70, 105, 70, 70, 70, 70, 70, 106, + 106, 106, 107, 108, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 109, 109, + 109, 109, 110, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 102, 102, - 103, 70, 70, 70, 70, 104, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 111, 111, 112, 113, 70, 70, 70, 114, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 105, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 106, 107, 108, 109, 110, - 111, 112, 113, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 114, 70, 115, 116, 117, 118, 119, 120, - 121, 122, 70, 70, 70, 70, 70, 70, 70, 70, 52, 53, 53, 53, 53, 53, 53, 53, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 115, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 116, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 117, 118, + 119, 120, 121, 122, 123, 124, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 125, 70, 70, 70, 70, 70, 126, 70, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 70, 70, 70, 70, 70, 70, 70, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, @@ -1525,32 +1658,32 @@ static const unsigned char index0[] = { 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 123, 52, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 124, 125, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 76, 76, 127, 126, 126, 126, 126, 128, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 128, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 136, + 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 137, 138, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 76, 76, 140, 139, 139, 139, 139, 141, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 141, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, @@ -1692,7 +1825,7 @@ static const unsigned char index0[] = { 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 129, 130, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 142, 143, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, @@ -1706,7 +1839,8 @@ static const unsigned char index0[] = { 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 73, 74, 74, 74, 74, 74, 74, 74, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 73, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, @@ -1719,8 +1853,8 @@ static const unsigned char index0[] = { 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 144, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 131, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, @@ -1734,7 +1868,7 @@ static const unsigned char index0[] = { 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 131, + 74, 74, 144, }; static const unsigned short index1[] = { @@ -1747,299 +1881,332 @@ static const unsigned short index1[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 97, 97, 97, 98, 98, 98, 98, 99, 100, 101, 101, 101, 101, 102, 103, 101, 101, 101, 101, 101, 101, 104, 105, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 106, 107, 108, 108, 108, 109, 110, 111, 112, - 112, 112, 112, 113, 114, 115, 116, 117, 118, 119, 120, 106, 121, 121, - 121, 122, 123, 106, 124, 125, 126, 127, 128, 128, 128, 128, 129, 130, + 101, 101, 101, 101, 101, 101, 106, 107, 107, 107, 108, 109, 110, 111, + 111, 111, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 121, + 121, 122, 123, 120, 124, 125, 126, 127, 128, 128, 128, 128, 129, 130, 131, 132, 133, 134, 135, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 145, 145, 146, 147, 148, 149, 128, 128, 128, 128, 128, 128, 150, 150, 150, 150, - 151, 152, 153, 106, 154, 155, 156, 156, 156, 157, 158, 159, 160, 160, - 161, 162, 163, 164, 165, 166, 167, 167, 167, 168, 106, 106, 106, 106, - 106, 106, 106, 106, 169, 170, 106, 106, 106, 106, 106, 106, 171, 172, - 173, 174, 175, 176, 176, 176, 176, 176, 176, 177, 178, 179, 180, 176, - 181, 182, 183, 184, 185, 186, 187, 188, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 106, 214, 215, 216, 217, 217, 218, - 219, 220, 221, 222, 223, 106, 224, 225, 226, 106, 227, 228, 229, 230, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 106, 241, 242, - 243, 244, 245, 242, 246, 247, 248, 249, 250, 106, 251, 252, 253, 254, - 255, 256, 257, 258, 258, 257, 259, 260, 261, 262, 263, 264, 265, 266, - 106, 267, 268, 269, 270, 271, 271, 270, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 106, 281, 282, 283, 284, 284, 284, 284, 285, 286, 287, - 288, 106, 289, 290, 291, 292, 293, 294, 295, 296, 294, 294, 297, 298, - 295, 299, 300, 301, 106, 106, 302, 106, 303, 304, 304, 304, 304, 304, - 305, 306, 307, 308, 309, 310, 106, 106, 106, 106, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 106, 106, 106, 106, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 331, 331, 331, 333, 334, 335, - 336, 337, 338, 339, 338, 338, 338, 340, 341, 342, 343, 344, 106, 106, - 106, 106, 345, 345, 345, 345, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 345, 356, 357, 349, 358, 359, 359, 359, 359, 360, 361, - 362, 362, 362, 362, 362, 363, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 366, 366, 366, 366, - 366, 366, 366, 366, 366, 367, 368, 367, 366, 366, 366, 366, 366, 367, - 366, 366, 366, 366, 367, 368, 367, 366, 368, 366, 366, 366, 366, 366, - 366, 366, 367, 366, 366, 366, 366, 366, 366, 366, 366, 369, 370, 371, - 372, 373, 366, 366, 374, 375, 376, 376, 376, 376, 376, 376, 376, 376, - 376, 376, 377, 106, 378, 379, 379, 379, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 380, 379, 379, - 381, 382, 382, 383, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, - 386, 106, 387, 388, 389, 106, 390, 390, 391, 106, 392, 392, 393, 106, - 394, 395, 396, 106, 397, 397, 397, 397, 397, 397, 398, 399, 400, 401, + 151, 152, 153, 120, 154, 155, 156, 156, 156, 157, 158, 159, 160, 160, + 161, 162, 163, 164, 165, 166, 167, 167, 167, 168, 120, 120, 120, 120, + 120, 120, 120, 120, 128, 128, 169, 120, 120, 120, 120, 120, 170, 171, + 172, 173, 174, 175, 175, 175, 175, 175, 175, 176, 177, 178, 179, 175, + 180, 181, 182, 175, 183, 184, 185, 186, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 120, 212, 213, 214, 215, 215, 216, + 217, 218, 219, 220, 221, 120, 222, 223, 224, 120, 225, 226, 227, 228, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 120, 239, 240, + 241, 242, 243, 240, 244, 245, 246, 247, 248, 120, 249, 250, 251, 252, + 253, 254, 255, 256, 256, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 120, 264, 265, 266, 267, 268, 268, 267, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 120, 278, 279, 280, 281, 281, 281, 281, 282, 283, 284, + 285, 120, 286, 287, 288, 289, 290, 291, 292, 293, 291, 291, 294, 295, + 292, 296, 297, 298, 299, 300, 301, 120, 302, 303, 303, 303, 303, 303, + 304, 305, 306, 307, 308, 309, 120, 120, 120, 120, 310, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, 120, 120, 120, 120, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 331, 330, 330, 330, 332, 333, 334, + 335, 336, 337, 338, 337, 337, 337, 339, 340, 341, 342, 343, 120, 120, + 120, 120, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 344, 355, 356, 348, 357, 358, 358, 358, 358, 359, 360, + 361, 361, 361, 361, 361, 362, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 366, 367, 366, 365, 365, 365, 365, 365, 366, + 365, 365, 365, 365, 366, 367, 366, 365, 367, 365, 365, 365, 365, 365, + 365, 365, 366, 365, 365, 365, 365, 365, 365, 365, 365, 368, 369, 370, + 371, 372, 365, 365, 373, 374, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 376, 120, 377, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 379, 378, 378, + 380, 381, 381, 382, 383, 383, 383, 383, 383, 383, 383, 383, 383, 384, + 385, 386, 387, 388, 389, 120, 390, 390, 391, 120, 392, 392, 393, 120, + 394, 395, 396, 120, 397, 397, 397, 397, 397, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 412, 412, 412, - 413, 412, 412, 412, 412, 412, 412, 106, 412, 412, 412, 412, 412, 414, - 379, 379, 379, 379, 379, 379, 379, 379, 415, 106, 416, 416, 416, 417, - 418, 419, 420, 421, 422, 423, 424, 424, 424, 425, 426, 106, 427, 427, + 413, 412, 412, 412, 412, 412, 412, 120, 412, 412, 412, 412, 412, 414, + 378, 378, 378, 378, 378, 378, 378, 378, 415, 120, 416, 416, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 424, 424, 425, 426, 120, 427, 427, 427, 427, 427, 428, 429, 429, 430, 431, 432, 433, 434, 434, 434, 434, 435, 435, 436, 437, 438, 438, 438, 438, 438, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 445, 446, 447, 448, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 449, 450, 450, 450, 450, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 462, 462, 463, 464, 465, 466, - 467, 467, 467, 467, 468, 469, 470, 471, 472, 472, 472, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 481, 481, 482, 106, 106, 106, 106, - 106, 106, 106, 106, 483, 106, 484, 485, 486, 487, 488, 106, 54, 54, 54, - 54, 489, 490, 56, 56, 56, 56, 56, 491, 492, 493, 54, 494, 54, 54, 54, - 495, 56, 56, 56, 496, 497, 498, 499, 500, 501, 106, 106, 502, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 503, 504, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 505, 506, 507, 508, 505, 506, - 505, 506, 507, 508, 505, 509, 505, 506, 505, 507, 505, 510, 505, 510, - 505, 510, 511, 512, 513, 514, 515, 516, 505, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, - 536, 537, 56, 538, 539, 540, 539, 541, 106, 106, 542, 543, 544, 545, 546, - 106, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, - 560, 559, 561, 562, 563, 564, 565, 566, 567, 568, 569, 568, 570, 571, - 568, 572, 568, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 583, 583, 589, 590, 591, 592, 593, 583, 583, - 594, 574, 595, 596, 583, 583, 597, 583, 583, 568, 598, 599, 568, 600, - 601, 602, 603, 603, 603, 603, 603, 603, 603, 603, 604, 568, 568, 605, - 606, 574, 574, 607, 568, 568, 568, 568, 573, 608, 568, 609, 106, 568, - 568, 568, 568, 610, 106, 106, 106, 568, 611, 106, 106, 612, 612, 612, - 612, 612, 613, 613, 614, 615, 615, 615, 615, 615, 615, 615, 615, 615, - 616, 612, 612, 617, 617, 617, 617, 617, 617, 617, 617, 617, 618, 617, - 617, 617, 617, 618, 568, 617, 617, 619, 568, 620, 569, 621, 622, 623, - 624, 569, 568, 619, 572, 568, 574, 625, 626, 622, 627, 568, 568, 568, - 568, 628, 568, 568, 568, 629, 630, 568, 568, 568, 568, 568, 631, 568, - 632, 568, 631, 633, 634, 617, 617, 635, 617, 617, 617, 636, 568, 568, - 568, 568, 568, 568, 637, 568, 568, 572, 568, 568, 638, 639, 612, 640, - 640, 641, 568, 568, 568, 568, 568, 642, 643, 644, 645, 646, 647, 574, - 574, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, - 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, - 648, 648, 648, 648, 648, 574, 574, 574, 574, 574, 574, 574, 574, 574, - 574, 574, 574, 574, 574, 574, 574, 649, 650, 650, 651, 583, 583, 574, - 652, 597, 653, 654, 655, 656, 657, 658, 659, 574, 660, 583, 661, 662, - 663, 664, 645, 574, 574, 586, 652, 664, 665, 666, 667, 583, 583, 583, - 583, 668, 669, 583, 583, 583, 583, 670, 671, 672, 645, 673, 674, 568, - 568, 568, 568, 568, 568, 574, 574, 675, 676, 677, 678, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 679, 679, 679, 679, 679, 680, 681, 681, 681, 681, 681, - 682, 683, 684, 685, 686, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 687, 688, 689, 690, 691, 691, 691, 691, 692, 693, 694, 694, 694, 694, - 694, 694, 694, 695, 696, 697, 366, 366, 368, 106, 368, 368, 368, 368, - 368, 368, 368, 368, 698, 698, 698, 698, 699, 700, 701, 702, 703, 704, - 529, 705, 106, 106, 106, 106, 106, 106, 106, 106, 706, 706, 706, 707, - 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 708, 106, 706, 706, - 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, - 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 709, 106, 106, 106, - 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 721, 721, - 721, 721, 721, 721, 721, 721, 722, 723, 724, 725, 725, 725, 725, 725, - 725, 725, 725, 725, 725, 726, 727, 728, 728, 728, 728, 729, 730, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 731, 732, 733, 728, 728, - 728, 734, 710, 710, 710, 710, 711, 106, 725, 725, 735, 735, 735, 736, - 737, 738, 733, 733, 733, 739, 740, 741, 735, 735, 735, 742, 737, 738, - 733, 733, 733, 733, 743, 741, 733, 744, 745, 745, 745, 745, 745, 746, - 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 733, 733, 733, - 747, 748, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 749, - 733, 733, 733, 747, 750, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 752, 753, 568, 568, 568, 568, 568, 568, - 568, 568, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 754, - 753, 753, 753, 753, 753, 753, 755, 755, 756, 755, 755, 755, 755, 755, - 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, - 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, - 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, - 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, - 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, - 755, 755, 755, 757, 758, 758, 758, 758, 758, 758, 759, 106, 760, 760, - 760, 760, 760, 761, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 762, 762, 762, 762, 762, 762, 763, 762, 762, 764, 765, - 106, 106, 101, 101, 101, 101, 101, 766, 767, 768, 101, 101, 101, 769, - 770, 770, 770, 770, 770, 770, 770, 770, 771, 772, 773, 106, 64, 64, 774, - 775, 776, 27, 777, 27, 27, 27, 27, 27, 27, 27, 778, 779, 27, 780, 781, - 106, 27, 782, 106, 106, 106, 106, 106, 106, 106, 106, 106, 783, 784, 785, - 786, 786, 787, 788, 789, 790, 791, 791, 791, 791, 791, 791, 792, 106, - 793, 794, 794, 794, 794, 794, 795, 796, 797, 798, 799, 800, 801, 801, - 802, 803, 804, 805, 806, 806, 807, 808, 809, 809, 810, 811, 812, 813, - 364, 364, 364, 814, 815, 816, 816, 816, 816, 816, 817, 818, 819, 820, - 821, 822, 106, 106, 106, 106, 823, 823, 823, 823, 823, 824, 825, 106, - 826, 827, 828, 829, 345, 345, 830, 831, 832, 832, 832, 832, 832, 832, - 833, 834, 835, 106, 106, 836, 837, 838, 839, 106, 840, 840, 840, 106, - 368, 368, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 837, 837, 837, 837, 841, 842, 843, 844, - 845, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, - 847, 106, 365, 365, 848, 849, 365, 365, 365, 365, 365, 850, 851, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 852, 851, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 852, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 852, - 853, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 855, 856, 856, - 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - 856, 857, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - 856, 858, 753, 753, 753, 753, 859, 106, 860, 861, 121, 862, 863, 864, - 865, 121, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 866, 867, 868, 106, 869, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 443, 444, 445, 446, 445, 446, 447, 448, 449, 450, 120, 120, 120, 120, + 120, 120, 120, 120, 451, 452, 452, 452, 452, 452, 453, 454, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 464, 464, 465, 466, 467, 468, + 469, 469, 469, 469, 470, 471, 472, 473, 474, 474, 474, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 483, 483, 484, 120, 120, 120, 120, + 120, 120, 120, 120, 485, 120, 486, 487, 488, 489, 490, 491, 54, 54, 54, + 54, 492, 493, 56, 56, 56, 56, 56, 494, 495, 496, 54, 497, 54, 54, 54, + 498, 56, 56, 56, 499, 500, 501, 502, 503, 503, 503, 504, 505, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 506, 507, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 508, 509, 510, 511, 508, 509, + 508, 509, 510, 511, 508, 512, 508, 509, 508, 510, 508, 513, 508, 513, + 508, 513, 514, 515, 516, 517, 518, 519, 508, 520, 521, 522, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, + 539, 540, 56, 541, 542, 543, 542, 544, 120, 120, 545, 546, 547, 548, 549, + 120, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, + 563, 562, 564, 565, 566, 567, 568, 569, 570, 571, 572, 571, 573, 574, + 571, 575, 571, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, + 587, 588, 589, 590, 591, 586, 586, 592, 593, 594, 595, 596, 586, 586, + 597, 577, 598, 599, 586, 586, 600, 586, 586, 571, 601, 602, 571, 603, + 604, 605, 606, 606, 606, 606, 606, 606, 606, 606, 607, 571, 571, 608, + 609, 577, 577, 610, 571, 571, 571, 571, 576, 611, 571, 571, 612, 571, + 571, 571, 571, 613, 120, 120, 120, 571, 612, 120, 120, 614, 614, 614, + 614, 614, 615, 615, 616, 617, 617, 617, 617, 617, 617, 617, 617, 617, + 618, 614, 614, 619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 619, + 619, 619, 619, 620, 571, 619, 619, 621, 571, 622, 572, 623, 624, 625, + 626, 572, 571, 621, 575, 571, 577, 627, 628, 624, 629, 571, 571, 571, + 571, 630, 571, 571, 571, 631, 632, 571, 571, 571, 571, 571, 633, 571, + 634, 571, 633, 635, 636, 619, 619, 637, 619, 619, 619, 571, 571, 571, + 571, 571, 571, 571, 638, 571, 571, 575, 571, 571, 639, 640, 614, 641, + 641, 642, 571, 571, 571, 571, 571, 643, 644, 645, 646, 647, 648, 577, + 577, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 649, 649, 649, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 650, 651, 651, 652, 586, 586, 577, + 653, 600, 654, 655, 656, 657, 658, 659, 660, 577, 661, 586, 662, 663, + 664, 665, 646, 577, 577, 589, 653, 665, 666, 667, 668, 586, 586, 586, + 586, 669, 670, 586, 586, 586, 586, 671, 672, 673, 646, 674, 675, 571, + 571, 571, 571, 571, 571, 577, 577, 676, 677, 678, 572, 571, 571, 679, + 571, 571, 571, 680, 571, 571, 571, 571, 681, 571, 682, 683, 120, 120, + 120, 120, 120, 684, 684, 684, 684, 684, 685, 686, 686, 686, 686, 686, + 687, 688, 689, 690, 691, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 692, 693, 694, 695, 696, 696, 696, 696, 697, 698, 699, 699, 699, 699, + 699, 699, 699, 700, 701, 702, 365, 365, 367, 120, 367, 367, 367, 367, + 367, 367, 367, 367, 703, 703, 703, 703, 704, 705, 706, 707, 708, 709, + 532, 710, 711, 120, 120, 120, 120, 120, 120, 120, 712, 712, 712, 713, + 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 714, 120, 712, 712, + 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, + 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 715, 120, 120, 120, + 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 727, 727, + 727, 727, 727, 727, 727, 727, 728, 729, 730, 731, 731, 731, 731, 731, + 731, 731, 731, 731, 731, 732, 733, 734, 734, 734, 734, 735, 736, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 737, 738, 739, 734, 734, + 734, 740, 716, 716, 716, 716, 717, 120, 731, 731, 741, 741, 741, 742, + 743, 744, 739, 739, 739, 745, 746, 747, 741, 741, 741, 748, 743, 744, + 739, 739, 739, 739, 749, 747, 739, 750, 751, 751, 751, 751, 751, 752, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 739, 739, 739, + 753, 754, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 755, + 739, 739, 739, 753, 756, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 758, 759, 571, 571, 571, 571, 571, 571, + 571, 571, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 760, + 759, 759, 759, 759, 759, 759, 761, 761, 762, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 763, 764, 764, 764, 764, 764, 764, 765, 120, 766, 766, + 766, 766, 766, 767, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 769, 768, 768, 770, 771, + 120, 120, 101, 101, 101, 101, 101, 772, 773, 774, 101, 101, 101, 775, + 776, 776, 776, 776, 776, 776, 776, 776, 777, 778, 779, 120, 64, 64, 780, + 781, 782, 27, 783, 27, 27, 27, 27, 27, 27, 27, 784, 785, 27, 786, 787, + 27, 27, 788, 789, 120, 120, 120, 120, 120, 120, 120, 790, 791, 792, 793, + 794, 794, 795, 796, 797, 798, 799, 799, 799, 799, 799, 799, 800, 120, + 801, 802, 802, 802, 802, 802, 803, 804, 805, 806, 807, 808, 809, 809, + 810, 811, 812, 813, 814, 814, 815, 816, 817, 817, 818, 819, 820, 821, + 363, 363, 363, 822, 823, 824, 824, 824, 824, 824, 825, 826, 827, 828, + 829, 830, 831, 344, 348, 832, 833, 833, 833, 833, 833, 834, 835, 120, + 836, 837, 838, 839, 344, 344, 840, 841, 842, 842, 842, 842, 842, 842, + 843, 844, 845, 120, 120, 846, 847, 848, 849, 120, 850, 850, 850, 120, + 367, 367, 54, 54, 54, 54, 54, 851, 852, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 847, 847, 847, 847, 853, 854, 855, 856, 857, + 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 859, + 120, 364, 364, 860, 861, 364, 364, 364, 364, 364, 862, 863, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 864, 863, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 864, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 864, 865, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 867, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 869, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 870, 759, 759, 759, 759, 871, 120, 872, 873, 121, 874, 875, 876, 877, + 121, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 878, + 879, 880, 120, 881, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 870, 106, 106, 128, 128, 128, 128, - 128, 128, 128, 128, 871, 128, 128, 128, 128, 128, 128, 106, 106, 106, - 106, 106, 128, 872, 873, 873, 874, 875, 501, 106, 876, 877, 878, 879, - 880, 881, 882, 883, 884, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 885, 886, 887, 888, 889, 890, 891, - 891, 892, 893, 894, 894, 895, 896, 897, 898, 897, 897, 897, 897, 899, - 900, 900, 900, 901, 902, 902, 902, 903, 904, 905, 106, 906, 907, 908, - 907, 907, 909, 907, 907, 910, 907, 911, 907, 911, 106, 106, 106, 106, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 912, 913, 914, 914, 914, 914, 914, 915, 603, 916, 916, 916, 916, - 916, 916, 917, 918, 919, 920, 568, 609, 106, 106, 106, 106, 106, 106, - 603, 603, 603, 603, 603, 921, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 922, 922, 922, 923, 924, 924, - 924, 924, 924, 924, 925, 106, 106, 106, 106, 106, 926, 926, 926, 927, - 928, 106, 929, 929, 930, 931, 106, 106, 106, 106, 106, 106, 932, 932, - 932, 933, 934, 934, 934, 934, 935, 934, 936, 106, 106, 106, 106, 106, - 937, 937, 937, 937, 937, 938, 938, 938, 938, 938, 939, 939, 939, 939, - 939, 939, 940, 940, 940, 941, 942, 943, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 944, 945, 946, 946, 946, 946, 947, 948, 949, 949, - 950, 951, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 952, 952, 953, 954, 955, 955, - 955, 956, 106, 106, 106, 106, 106, 106, 106, 106, 957, 957, 957, 957, - 958, 958, 958, 959, 106, 106, 106, 106, 106, 106, 106, 106, 960, 961, - 962, 963, 964, 964, 965, 966, 967, 106, 968, 969, 970, 970, 970, 971, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 972, 972, 972, 972, 972, 972, 973, 974, 975, 975, 976, 977, - 978, 978, 979, 980, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 981, 981, 981, 981, 981, 981, 981, 981, - 981, 982, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 983, 983, 983, 984, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 985, 986, 986, 986, 986, 986, 986, 987, 988, 989, 990, 991, 992, 993, - 106, 106, 994, 995, 995, 995, 995, 995, 996, 997, 998, 106, 999, 999, - 999, 1000, 1001, 1002, 1003, 1004, 1004, 1004, 1005, 1006, 1007, 1008, - 1009, 106, 106, 106, 106, 106, 106, 106, 1010, 1011, 1011, 1011, 1011, - 1011, 1012, 1013, 1014, 1015, 1016, 1017, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 1018, 1018, 1018, 1018, 1018, 1019, 1020, 106, 1021, 1022, 106, 106, 106, - 106, 106, 106, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, - 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, - 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, - 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, - 1024, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, - 1025, 1025, 1025, 1025, 1026, 106, 1027, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 1028, 1028, 1028, - 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, - 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, - 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1029, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 770, 770, 770, - 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, - 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, - 770, 770, 770, 770, 770, 770, 770, 770, 1030, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, - 1032, 106, 1033, 1034, 1034, 1034, 1034, 1035, 106, 1036, 1037, 1038, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 1039, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, - 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, - 603, 603, 603, 603, 1040, 106, 603, 603, 603, 603, 1041, 1042, 603, 603, - 603, 603, 603, 603, 1043, 1044, 1045, 1046, 1047, 1048, 603, 603, 603, - 1049, 603, 603, 603, 603, 603, 1040, 106, 106, 106, 106, 919, 919, 919, - 919, 919, 919, 919, 919, 1050, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 610, 106, 914, - 914, 1051, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 1052, 1052, 1052, 1053, 1054, 1054, 1055, 1052, - 1052, 1056, 1057, 1054, 1054, 1052, 1052, 1052, 1053, 1054, 1054, 1058, - 1059, 1060, 1056, 1061, 1062, 1054, 1052, 1052, 1052, 1053, 1054, 1054, - 1063, 1064, 1065, 1066, 1054, 1054, 1054, 1067, 1068, 1069, 1070, 1054, - 1054, 1055, 1052, 1052, 1056, 1054, 1054, 1054, 1052, 1052, 1052, 1053, - 1054, 1054, 1055, 1052, 1052, 1056, 1054, 1054, 1054, 1052, 1052, 1052, - 1053, 1054, 1054, 1055, 1052, 1052, 1056, 1054, 1054, 1054, 1052, 1052, - 1052, 1053, 1054, 1054, 1071, 1052, 1052, 1052, 1072, 1054, 1054, 1073, - 1074, 1052, 1052, 1075, 1054, 1054, 1076, 1055, 1052, 1052, 1077, 1054, - 1054, 1078, 1079, 1052, 1052, 1080, 1054, 1054, 1054, 1081, 1052, 1052, - 1052, 1072, 1054, 1054, 1073, 1082, 1083, 1083, 1083, 1083, 1083, 1083, - 1084, 128, 128, 128, 1085, 1086, 1087, 1088, 1089, 1090, 1085, 1091, - 1085, 1087, 1087, 1092, 128, 1093, 128, 1094, 1095, 1093, 128, 1094, 106, - 106, 106, 106, 106, 106, 1096, 106, 568, 568, 568, 568, 568, 609, 568, - 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 609, 106, 568, - 610, 636, 610, 636, 568, 636, 568, 106, 106, 106, 106, 613, 1097, 615, - 615, 615, 1098, 615, 615, 615, 615, 615, 615, 615, 1099, 615, 615, 615, - 615, 615, 1100, 106, 106, 106, 106, 106, 106, 106, 106, 1101, 603, 603, - 603, 1102, 106, 733, 733, 733, 733, 733, 1103, 733, 1104, 1105, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 568, 568, 568, 568, 1106, 106, 1107, 568, 568, - 568, 568, 568, 568, 568, 568, 1108, 568, 568, 609, 106, 568, 568, 568, - 568, 1109, 611, 106, 106, 568, 568, 1106, 106, 568, 568, 568, 568, 568, - 568, 568, 610, 1110, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, - 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 1111, 568, - 568, 568, 568, 568, 568, 568, 1112, 609, 106, 568, 568, 568, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 1113, 568, 568, 568, 568, 568, 568, 568, 568, 1114, 568, 106, - 106, 106, 106, 106, 106, 568, 568, 568, 568, 568, 568, 568, 568, 1112, - 106, 106, 106, 106, 106, 106, 106, 568, 568, 568, 568, 568, 568, 568, - 568, 568, 568, 568, 568, 568, 568, 609, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 1115, 753, 753, 753, 753, - 753, 751, 751, 751, 751, 751, 751, 754, 753, 750, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 752, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 856, - 856, 856, 857, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 1116, 1117, 106, 106, 106, 1118, 1118, - 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, - 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, - 873, 873, 106, 106, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - 854, 854, 854, 854, 854, 854, 854, 1119, + 128, 128, 128, 128, 128, 128, 882, 120, 120, 128, 128, 128, 128, 128, + 128, 128, 128, 883, 128, 128, 128, 128, 128, 128, 120, 120, 120, 120, + 120, 128, 884, 885, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, + 895, 896, 897, 898, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 899, 900, 901, 902, 903, 904, 905, 905, + 906, 907, 908, 908, 909, 910, 911, 912, 911, 911, 911, 911, 913, 914, + 914, 914, 915, 916, 916, 916, 917, 918, 919, 120, 920, 921, 922, 921, + 921, 923, 921, 921, 924, 921, 925, 921, 925, 120, 120, 120, 120, 921, + 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + 926, 927, 928, 928, 928, 928, 928, 929, 606, 930, 930, 930, 930, 930, + 930, 931, 932, 933, 934, 571, 935, 936, 120, 120, 120, 120, 120, 606, + 606, 606, 606, 606, 937, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 938, 938, 938, 939, 940, 940, 940, + 940, 940, 940, 941, 120, 942, 943, 943, 944, 945, 945, 945, 945, 946, + 120, 947, 947, 948, 949, 950, 950, 950, 950, 951, 952, 953, 953, 953, + 954, 955, 955, 955, 955, 956, 955, 957, 120, 120, 120, 120, 120, 958, + 958, 958, 958, 958, 959, 959, 959, 959, 959, 960, 960, 960, 960, 960, + 960, 961, 961, 961, 962, 963, 964, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 965, 965, 965, 965, 965, 120, 966, 966, 966, 966, 966, + 966, 967, 968, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 969, 969, 969, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 969, 969, 970, 120, 969, 969, 971, 120, 969, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 972, 973, 974, 974, 974, 974, 975, 976, 977, 977, 978, 979, 980, + 980, 981, 982, 983, 983, 983, 984, 985, 986, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 987, 987, 988, 989, 990, 990, 990, 991, 120, + 120, 120, 120, 120, 120, 120, 120, 992, 992, 992, 992, 993, 993, 993, + 994, 120, 120, 120, 120, 120, 120, 120, 120, 995, 996, 997, 998, 999, + 999, 1000, 1001, 1002, 120, 1003, 1004, 1005, 1005, 1005, 1006, 1007, + 1007, 1007, 1008, 120, 120, 120, 120, 1009, 1010, 1009, 1009, 1011, 1012, + 1013, 120, 1014, 1014, 1014, 1014, 1014, 1014, 1015, 1016, 1017, 1017, + 1018, 1019, 1020, 1020, 1021, 1022, 1023, 1023, 1024, 1025, 120, 1026, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 1028, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1029, + 1029, 1029, 1030, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 1031, 1032, 1032, 1032, 1032, 1032, 1032, 1033, + 1034, 1035, 1036, 1037, 1038, 1039, 120, 1040, 1041, 1042, 1042, 1042, + 1042, 1042, 1043, 1044, 1045, 120, 1046, 1046, 1046, 1047, 1048, 1049, + 1050, 1051, 1051, 1051, 1052, 1053, 1054, 1055, 1056, 120, 1057, 1057, + 1057, 1057, 1058, 120, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1062, + 1063, 1064, 1065, 1066, 1067, 1068, 1069, 120, 1070, 1070, 1071, 1070, + 1070, 1072, 1073, 1074, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 1075, 1075, 1075, 1075, 1075, 1076, 1077, 1078, 1079, + 1080, 1081, 1082, 1083, 1084, 1084, 1085, 1086, 1087, 1088, 1089, 1090, + 1091, 1092, 1093, 1093, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 1094, 1094, 1094, 1094, + 1094, 1094, 1095, 1096, 1097, 120, 1098, 1099, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 1100, 1100, 1100, 1100, 1100, 1101, 1102, 1103, 1104, 1105, 120, + 120, 120, 120, 120, 120, 1106, 1106, 1106, 1106, 1106, 1106, 1107, 1108, + 1109, 120, 1110, 1111, 120, 120, 120, 120, 1112, 1112, 1112, 1112, 1112, + 1113, 1114, 120, 1115, 1116, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 1117, 1117, 1117, 1117, 1118, 1118, 1118, 1118, 1119, + 1120, 1121, 1122, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1124, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1126, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1127, 1127, 1127, + 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1128, 1129, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1131, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 1132, 1133, 1133, 1133, 1134, 1135, 1136, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 1137, 1137, 1137, 1138, 1139, 120, + 1140, 1140, 1140, 1140, 1140, 1140, 1141, 1142, 1143, 120, 1144, 1145, + 1146, 1140, 1140, 1147, 1140, 1140, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 1148, 1148, 1148, 1148, 1148, 1148, + 1148, 1148, 1149, 120, 1150, 1151, 1151, 1151, 1151, 1152, 120, 1153, + 1154, 1155, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 1156, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, + 1157, 1157, 1157, 1157, 1158, 1157, 1159, 1157, 1160, 1157, 1161, 1162, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 606, 606, 606, + 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 1163, + 120, 606, 606, 606, 606, 1164, 1165, 606, 606, 606, 606, 606, 606, 1166, + 1167, 1168, 1169, 1170, 1171, 606, 606, 606, 1172, 606, 606, 606, 606, + 606, 1163, 120, 120, 120, 120, 933, 933, 933, 933, 933, 933, 933, 933, + 1173, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 613, 120, 928, 928, 1174, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 1175, 1175, 1175, 1176, 1177, 1177, 1178, 1175, 1175, 1179, 1180, 1177, + 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1181, 1182, 1183, 1179, 1184, + 1185, 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1186, 1187, 1188, 1189, + 1177, 1177, 1177, 1190, 1191, 1192, 1193, 1177, 1177, 1178, 1175, 1175, + 1179, 1177, 1177, 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1178, 1175, + 1175, 1179, 1177, 1177, 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1178, + 1175, 1175, 1179, 1177, 1177, 1177, 1175, 1175, 1175, 1176, 1177, 1177, + 1194, 1175, 1175, 1175, 1195, 1177, 1177, 1196, 1197, 1175, 1175, 1198, + 1177, 1177, 1199, 1178, 1175, 1175, 1200, 1177, 1177, 1201, 1202, 1175, + 1175, 1203, 1177, 1177, 1177, 1204, 1175, 1175, 1175, 1195, 1177, 1177, + 1196, 1205, 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1207, 1207, 1207, + 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, + 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1208, 1209, 1210, 120, + 120, 120, 120, 120, 1211, 128, 128, 128, 1212, 1213, 1214, 1215, 1216, + 1217, 1212, 1218, 1212, 1214, 1214, 1219, 128, 1220, 128, 1221, 1222, + 1220, 128, 1221, 120, 120, 120, 120, 120, 120, 1223, 120, 571, 571, 571, + 571, 571, 935, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 935, 120, 571, 613, 1224, 571, 1224, 571, 1224, 571, 571, 571, 680, + 120, 615, 1225, 617, 617, 617, 1226, 617, 617, 617, 617, 617, 617, 617, + 1227, 617, 617, 617, 617, 617, 1228, 120, 120, 120, 120, 120, 120, 120, + 120, 1229, 606, 606, 606, 1230, 120, 739, 739, 739, 739, 739, 1231, 739, + 1232, 1233, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 571, 571, 571, 571, 571, + 1234, 571, 571, 571, 571, 571, 571, 571, 571, 571, 680, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 613, 1235, 571, 571, 571, 571, 120, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 613, 571, 571, 571, 571, 571, 571, 571, 571, 571, 612, 571, + 571, 571, 571, 571, 1236, 571, 571, 571, 571, 1237, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 1238, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 120, 120, 571, 1234, 935, 120, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 935, 120, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 1234, 120, 120, 120, 120, + 120, 571, 935, 571, 571, 571, 571, 571, 571, 571, 120, 571, 683, 571, + 571, 571, 571, 571, 120, 571, 571, 571, 680, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 1239, 759, 759, 759, 759, 759, 757, 757, 757, 757, 757, + 757, 760, 759, 756, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 868, 868, 868, 869, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 1240, 1241, 120, 120, 120, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 120, 120, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 1243, }; static const unsigned short index2[] = { @@ -2077,7 +2244,7 @@ static const unsigned short index2[] = { 53, 51, 51, 51, 51, 51, 51, 51, 51, 57, 51, 53, 53, 53, 51, 51, 51, 53, 53, 58, 51, 51, 51, 53, 53, 53, 53, 51, 52, 53, 53, 51, 59, 60, 60, 59, 60, 60, 59, 51, 51, 51, 51, 51, 61, 62, 61, 62, 45, 63, 61, 62, 64, 64, - 65, 62, 62, 62, 66, 64, 64, 64, 64, 64, 63, 47, 61, 66, 61, 61, 61, 64, + 65, 62, 62, 62, 66, 61, 64, 64, 64, 64, 63, 47, 61, 66, 61, 61, 61, 64, 61, 64, 61, 61, 62, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 67, 67, 67, 67, 67, 67, 67, 61, 61, 62, 62, 62, 62, 62, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, @@ -2089,538 +2256,603 @@ static const unsigned short index2[] = { 74, 74, 74, 74, 75, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 75, 72, 75, 72, 75, 72, 75, 72, 75, 76, 77, 77, 78, 78, 77, 79, 79, 72, 75, 72, 75, 72, 75, 72, 72, 75, 72, 75, 72, 75, 72, 75, 72, - 75, 72, 75, 72, 75, 75, 64, 64, 64, 64, 64, 64, 64, 64, 64, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 64, 64, 81, 82, 82, 82, 82, 82, 82, 64, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 64, 84, 85, 64, 64, 64, 64, 86, 64, 87, - 88, 88, 88, 88, 87, 88, 88, 88, 89, 87, 88, 88, 88, 88, 88, 88, 87, 87, - 87, 87, 87, 87, 88, 88, 87, 88, 88, 89, 90, 88, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 100, 101, 102, 103, 104, 105, 106, 107, 108, 106, 88, - 87, 106, 99, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 64, - 64, 64, 64, 64, 109, 109, 109, 106, 106, 64, 64, 64, 110, 110, 110, 110, - 110, 64, 111, 111, 112, 113, 113, 114, 115, 116, 117, 117, 118, 118, 118, - 118, 118, 118, 118, 118, 119, 120, 121, 122, 64, 64, 116, 122, 123, 123, - 123, 123, 123, 123, 123, 123, 124, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 125, 126, 127, 128, 129, 130, 131, 132, 78, 78, 133, 134, - 118, 118, 118, 118, 118, 134, 118, 118, 134, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 113, 136, 136, 116, 123, 123, 137, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 116, 123, 118, 118, 118, - 118, 118, 118, 118, 138, 117, 118, 118, 118, 118, 134, 118, 139, 139, - 118, 118, 117, 134, 118, 118, 134, 123, 123, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 123, 123, 123, 141, 141, 123, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 64, 143, 144, 145, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 146, 147, 146, 146, 147, 146, 146, 147, 147, 147, 146, 147, 147, 146, - 147, 146, 146, 146, 147, 146, 147, 146, 147, 146, 147, 146, 146, 64, 64, - 144, 144, 144, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 148, 64, 64, 64, 64, 64, 64, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, 152, 153, 152, 154, - 154, 155, 156, 156, 156, 154, 64, 64, 64, 64, 64, 157, 157, 157, 157, - 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 158, 158, 158, 158, - 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, - 159, 158, 158, 158, 158, 158, 64, 64, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, 64, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 162, 162, 162, 64, 64, 163, 64, 123, 64, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 64, 64, 64, 64, 64, 64, 64, 118, - 118, 134, 118, 118, 134, 118, 118, 118, 134, 134, 134, 164, 165, 166, - 118, 118, 118, 134, 118, 118, 134, 134, 118, 118, 118, 118, 64, 167, 167, - 167, 168, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 167, 168, 170, 169, 168, 168, 168, 167, 167, 167, 167, 167, - 167, 167, 167, 168, 168, 168, 168, 171, 168, 168, 169, 78, 133, 172, 172, - 167, 167, 167, 169, 169, 167, 167, 84, 84, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 174, 175, 169, 169, 169, 169, 169, 169, 64, 169, 169, - 169, 169, 169, 169, 169, 64, 176, 177, 177, 64, 178, 178, 178, 178, 178, - 178, 178, 178, 64, 64, 178, 178, 64, 64, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 64, 178, 178, 178, 178, 178, 178, - 178, 64, 178, 64, 64, 64, 178, 178, 178, 178, 64, 64, 179, 178, 177, 177, - 177, 176, 176, 176, 176, 64, 64, 177, 177, 64, 64, 177, 177, 180, 178, - 64, 64, 64, 64, 64, 64, 64, 64, 177, 64, 64, 64, 64, 178, 178, 64, 178, - 178, 178, 176, 176, 64, 64, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 178, 178, 182, 182, 183, 183, 183, 183, 183, 183, 184, 182, 64, 64, - 64, 64, 64, 185, 185, 186, 64, 187, 187, 187, 187, 187, 187, 64, 64, 64, - 64, 187, 187, 64, 64, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 64, 187, 187, 187, 187, 187, 187, 187, 64, 187, 187, - 64, 187, 187, 64, 187, 187, 64, 64, 188, 64, 186, 186, 186, 185, 185, 64, - 64, 64, 64, 185, 185, 64, 64, 185, 185, 189, 64, 64, 64, 185, 64, 64, 64, - 64, 64, 64, 64, 187, 187, 187, 187, 64, 187, 64, 64, 64, 64, 64, 64, 64, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 187, 187, - 187, 185, 64, 64, 64, 191, 191, 192, 64, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 64, 193, 193, 193, 64, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 64, 193, 193, 193, 193, 193, 193, 193, - 64, 193, 193, 64, 193, 193, 193, 193, 193, 64, 64, 194, 193, 192, 192, - 192, 191, 191, 191, 191, 191, 64, 191, 191, 192, 64, 192, 192, 195, 64, - 64, 193, 64, 64, 64, 64, 64, 64, 64, 193, 193, 191, 191, 64, 64, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 197, 198, 64, 64, 64, 64, - 64, 64, 64, 199, 200, 200, 64, 201, 201, 201, 201, 201, 201, 201, 201, - 64, 64, 201, 201, 64, 64, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 201, 201, 201, 201, 64, 201, 201, 201, 201, 201, 201, 201, 64, 201, - 201, 64, 201, 201, 201, 201, 201, 64, 64, 202, 201, 200, 199, 200, 199, - 199, 199, 199, 64, 64, 200, 200, 64, 64, 200, 200, 203, 64, 64, 64, 64, - 64, 64, 64, 64, 199, 200, 64, 64, 64, 64, 201, 201, 64, 201, 201, 201, - 199, 199, 64, 64, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 205, - 201, 206, 206, 206, 206, 206, 206, 64, 64, 207, 208, 64, 208, 208, 208, - 208, 208, 208, 64, 64, 64, 208, 208, 208, 64, 208, 208, 208, 208, 64, 64, - 64, 208, 208, 64, 208, 64, 208, 208, 64, 64, 64, 208, 208, 64, 64, 64, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 64, 64, 64, 64, 209, - 209, 207, 209, 209, 64, 64, 64, 209, 209, 209, 64, 209, 209, 209, 210, - 64, 64, 208, 64, 64, 64, 64, 64, 64, 209, 64, 64, 64, 64, 64, 64, 211, - 211, 211, 211, 211, 211, 211, 211, 211, 211, 212, 212, 212, 213, 213, - 213, 213, 213, 213, 214, 213, 64, 64, 64, 64, 64, 64, 215, 215, 215, 64, - 216, 216, 216, 216, 216, 216, 216, 216, 64, 216, 216, 216, 64, 216, 216, - 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, - 216, 216, 64, 216, 216, 216, 216, 216, 64, 64, 64, 216, 217, 217, 217, - 215, 215, 215, 215, 64, 217, 217, 217, 64, 217, 217, 217, 218, 64, 64, - 64, 64, 64, 64, 64, 219, 220, 64, 216, 216, 64, 64, 64, 64, 64, 64, 216, - 216, 217, 217, 64, 64, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 222, 222, 222, 222, 222, 222, 222, 223, 64, 64, 224, 224, 64, 225, 225, - 225, 225, 225, 225, 225, 225, 64, 225, 225, 225, 64, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 64, - 225, 225, 225, 225, 225, 64, 64, 226, 225, 224, 227, 224, 224, 224, 224, - 224, 64, 227, 224, 224, 64, 224, 224, 228, 229, 64, 64, 64, 64, 64, 64, - 64, 224, 224, 64, 64, 64, 64, 64, 64, 64, 225, 64, 225, 225, 228, 228, - 64, 64, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 64, 225, 225, - 64, 64, 64, 64, 64, 64, 64, 231, 231, 64, 232, 232, 232, 232, 232, 232, - 232, 232, 64, 232, 232, 232, 64, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 64, 64, 232, 231, 231, 231, - 233, 233, 233, 233, 64, 231, 231, 231, 64, 231, 231, 231, 234, 232, 64, - 64, 64, 64, 64, 64, 64, 64, 231, 232, 232, 233, 233, 64, 64, 235, 235, - 235, 235, 235, 235, 235, 235, 235, 235, 236, 236, 236, 236, 236, 236, 64, - 64, 64, 237, 232, 232, 232, 232, 232, 232, 64, 64, 238, 238, 64, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 64, 64, 64, 239, 239, 239, 239, 239, 239, 239, 239, 64, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 64, 239, 64, 64, 64, 64, - 240, 64, 64, 64, 64, 238, 238, 238, 241, 241, 241, 64, 241, 64, 238, 238, - 238, 238, 238, 238, 238, 238, 64, 64, 238, 238, 242, 64, 64, 64, 64, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 244, 243, 243, 244, 244, 244, 244, 245, 245, 246, 64, 64, 64, 64, - 247, 243, 243, 243, 243, 243, 243, 248, 244, 249, 249, 249, 249, 244, - 244, 244, 250, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, - 250, 64, 64, 64, 64, 64, 252, 252, 64, 252, 64, 64, 252, 252, 64, 252, - 64, 64, 252, 64, 64, 64, 64, 64, 64, 252, 252, 252, 252, 64, 252, 252, - 252, 252, 252, 252, 252, 64, 252, 252, 252, 64, 252, 64, 252, 64, 64, - 252, 252, 64, 252, 252, 252, 252, 253, 252, 252, 253, 253, 253, 253, 254, - 254, 64, 253, 253, 252, 64, 64, 252, 252, 252, 252, 252, 64, 255, 64, - 256, 256, 256, 256, 253, 253, 64, 64, 257, 257, 257, 257, 257, 257, 257, - 257, 257, 257, 64, 64, 252, 252, 252, 252, 258, 259, 259, 259, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 259, - 260, 259, 259, 259, 261, 261, 259, 259, 259, 259, 259, 259, 262, 262, - 262, 262, 262, 262, 262, 262, 262, 262, 263, 263, 263, 263, 263, 263, - 263, 263, 263, 263, 259, 261, 259, 261, 259, 264, 265, 266, 265, 266, - 267, 267, 258, 258, 258, 258, 258, 258, 258, 258, 64, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 64, 64, 64, 64, 268, 269, 270, - 271, 270, 270, 270, 270, 270, 269, 269, 269, 269, 270, 267, 269, 270, - 272, 272, 273, 260, 272, 272, 258, 258, 258, 258, 258, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 64, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 64, 259, 259, 259, 259, 259, 259, 259, 259, - 261, 259, 259, 259, 259, 259, 259, 64, 259, 259, 260, 260, 260, 260, 260, - 274, 274, 274, 274, 260, 260, 64, 64, 64, 64, 64, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 276, 276, 277, 277, 277, 277, 276, - 277, 277, 277, 277, 277, 278, 276, 279, 279, 276, 276, 277, 277, 275, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, - 281, 281, 275, 275, 275, 275, 275, 275, 276, 276, 277, 277, 275, 275, - 275, 275, 277, 277, 277, 275, 276, 276, 276, 275, 275, 276, 276, 276, - 276, 276, 276, 276, 275, 275, 275, 277, 277, 277, 277, 275, 275, 275, - 275, 275, 277, 276, 276, 277, 277, 276, 276, 276, 276, 276, 276, 282, - 275, 276, 280, 280, 276, 276, 276, 277, 283, 283, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 64, 284, 64, 64, 64, - 64, 64, 284, 64, 64, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 285, 84, 286, 285, 285, 285, 287, 287, 287, 287, 287, 287, 287, 287, 288, - 288, 288, 288, 288, 288, 288, 288, 289, 289, 289, 289, 289, 289, 289, - 289, 289, 64, 289, 289, 289, 289, 64, 64, 289, 289, 289, 289, 289, 289, - 289, 64, 289, 289, 289, 64, 64, 290, 290, 290, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 64, 64, 64, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 64, 64, 64, 64, 64, 64, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 64, 64, 64, 295, - 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 297, 297, 296, 298, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, - 300, 301, 64, 64, 64, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 84, 84, 84, 303, 303, 303, 64, 64, 64, 64, 64, 64, 64, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 64, 304, 304, 304, - 304, 305, 305, 306, 64, 64, 64, 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 308, 308, 309, 84, 84, 64, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 311, 311, 64, 64, 64, 64, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 64, 312, 312, 312, 64, 313, 313, 64, - 64, 64, 64, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 315, 315, 316, 315, 315, 315, 315, 315, 315, 315, 316, 316, 316, 316, - 316, 316, 316, 316, 315, 316, 316, 315, 315, 315, 315, 315, 315, 315, - 315, 315, 317, 315, 318, 318, 318, 319, 318, 318, 318, 320, 314, 321, 64, - 64, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 64, 64, 64, 64, 64, - 64, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 64, 64, 64, 64, 64, - 64, 324, 324, 66, 66, 324, 66, 325, 324, 324, 324, 324, 326, 326, 326, - 327, 64, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 64, 64, 64, - 64, 64, 64, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 330, - 329, 329, 329, 329, 329, 331, 329, 64, 64, 64, 64, 64, 296, 296, 296, - 296, 296, 296, 64, 64, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, - 332, 332, 332, 64, 64, 64, 333, 333, 333, 334, 334, 334, 334, 333, 333, - 334, 334, 334, 64, 64, 64, 64, 334, 334, 333, 334, 334, 334, 334, 334, - 334, 335, 336, 337, 64, 64, 64, 64, 338, 64, 64, 64, 339, 339, 340, 340, - 340, 340, 340, 340, 340, 340, 340, 340, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 64, 64, 341, 341, 341, 341, 341, - 64, 64, 64, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, - 64, 64, 64, 64, 343, 343, 343, 343, 343, 343, 343, 343, 343, 342, 342, - 342, 342, 342, 342, 342, 343, 343, 64, 64, 64, 64, 64, 64, 344, 344, 344, - 344, 344, 344, 344, 344, 344, 344, 345, 64, 64, 64, 346, 346, 347, 347, - 347, 347, 347, 347, 347, 347, 348, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 348, 348, 348, 348, 349, 350, 351, 351, 351, 64, 64, 352, - 352, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, - 354, 355, 354, 355, 355, 355, 355, 355, 355, 355, 64, 356, 354, 355, 354, - 354, 355, 355, 355, 355, 355, 355, 355, 355, 354, 354, 354, 354, 354, - 354, 355, 355, 357, 357, 357, 357, 357, 357, 357, 357, 64, 64, 358, 359, - 359, 359, 359, 359, 359, 359, 359, 359, 359, 64, 64, 64, 64, 64, 64, 360, - 360, 360, 360, 360, 360, 360, 361, 360, 360, 360, 360, 360, 360, 64, 64, - 362, 362, 362, 362, 363, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 365, 363, 362, 362, 362, 362, 362, 363, - 362, 363, 363, 363, 363, 363, 362, 363, 366, 364, 364, 364, 364, 364, - 364, 364, 64, 64, 64, 64, 367, 367, 367, 367, 367, 367, 367, 367, 367, - 367, 368, 368, 368, 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 370, 371, 370, 370, 370, 370, 370, 370, 370, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 64, 64, 64, 372, 372, 373, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 373, - 372, 372, 372, 372, 373, 373, 372, 372, 375, 376, 373, 373, 374, 374, - 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 374, 374, 374, 374, - 374, 374, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 379, 380, 381, 381, 380, 380, 380, 381, 380, 381, 381, 381, - 382, 382, 64, 64, 64, 64, 64, 64, 64, 64, 383, 383, 383, 383, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 385, 385, 385, - 385, 385, 385, 385, 386, 386, 386, 386, 386, 386, 386, 386, 385, 385, - 386, 387, 64, 64, 64, 388, 388, 388, 388, 388, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 64, 64, 64, 384, 384, 384, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 392, 392, 392, 392, 392, 392, 393, 393, - 394, 394, 394, 394, 394, 394, 394, 394, 78, 78, 78, 84, 395, 133, 133, - 133, 133, 133, 78, 78, 133, 133, 133, 133, 78, 396, 395, 395, 395, 395, - 395, 395, 395, 397, 397, 397, 397, 133, 397, 397, 397, 397, 396, 396, 78, - 397, 397, 64, 41, 41, 41, 41, 41, 41, 62, 62, 62, 62, 62, 75, 44, 44, 44, + 75, 72, 75, 72, 75, 75, 64, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 64, 64, 81, 82, 82, 82, 82, + 82, 82, 64, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 64, 84, 85, 64, 64, 86, 86, 87, 64, 88, 89, 89, 89, 89, 88, 89, 89, 89, + 90, 88, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89, 89, 88, 89, + 89, 90, 91, 89, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 107, 89, 88, 107, 100, 64, 64, 64, 64, 64, + 64, 64, 64, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 64, + 64, 64, 64, 64, 110, 110, 110, 107, 107, 64, 64, 64, 111, 111, 111, 111, + 111, 112, 113, 113, 114, 115, 115, 116, 117, 118, 119, 119, 120, 120, + 120, 120, 120, 120, 120, 120, 121, 122, 123, 124, 125, 64, 118, 124, 126, + 126, 126, 126, 126, 126, 126, 126, 127, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 128, 129, 130, 131, 132, 133, 134, 135, 78, 78, 136, + 137, 120, 120, 120, 120, 120, 137, 120, 120, 137, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 115, 139, 139, 118, 126, 126, 140, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 118, 126, 120, 120, + 120, 120, 120, 120, 120, 112, 119, 120, 120, 120, 120, 137, 120, 141, + 141, 120, 120, 119, 137, 120, 120, 137, 126, 126, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 126, 126, 126, 143, 143, 126, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 64, 145, 146, + 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 148, 149, 148, 148, 149, 148, 148, 149, 149, 149, 148, 149, 149, + 148, 149, 148, 148, 148, 149, 148, 149, 148, 149, 148, 149, 148, 148, 64, + 64, 146, 146, 146, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 150, 64, 64, 64, 64, 64, 64, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 154, 154, 154, 154, 154, 154, 154, 155, 154, 156, + 156, 157, 158, 158, 158, 156, 64, 64, 64, 64, 64, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 160, 160, 160, 160, + 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 160, 160, + 161, 160, 160, 160, 160, 160, 64, 64, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 64, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 164, 164, 164, 64, 64, 165, 64, 126, 126, 126, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 120, 120, 137, 120, 120, 137, 120, 120, 120, 137, + 137, 137, 166, 167, 168, 120, 120, 120, 137, 120, 120, 137, 137, 120, + 120, 120, 120, 120, 169, 169, 169, 170, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 169, 170, 172, 171, 170, 170, + 170, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 173, + 170, 170, 171, 78, 136, 174, 174, 169, 169, 169, 171, 171, 169, 169, 84, + 84, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 177, 171, 171, + 171, 171, 171, 171, 178, 179, 180, 180, 64, 178, 178, 178, 178, 178, 178, + 178, 178, 64, 64, 178, 178, 64, 64, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 64, 178, 178, 178, 178, 178, 178, 178, + 64, 178, 64, 64, 64, 178, 178, 178, 178, 64, 64, 181, 178, 180, 180, 180, + 179, 179, 179, 179, 64, 64, 180, 180, 64, 64, 180, 180, 182, 178, 64, 64, + 64, 64, 64, 64, 64, 64, 180, 64, 64, 64, 64, 178, 178, 64, 178, 178, 178, + 179, 179, 64, 64, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 178, + 178, 184, 184, 185, 185, 185, 185, 185, 185, 186, 184, 64, 64, 64, 64, + 64, 187, 187, 188, 64, 189, 189, 189, 189, 189, 189, 64, 64, 64, 64, 189, + 189, 64, 64, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 64, 189, 189, 189, 189, 189, 189, 189, 64, 189, 189, 64, 189, + 189, 64, 189, 189, 64, 64, 190, 64, 188, 188, 188, 187, 187, 64, 64, 64, + 64, 187, 187, 64, 64, 187, 187, 191, 64, 64, 64, 187, 64, 64, 64, 64, 64, + 64, 64, 189, 189, 189, 189, 64, 189, 64, 64, 64, 64, 64, 64, 64, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 187, 187, 189, 189, 189, + 187, 64, 64, 64, 193, 193, 194, 64, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 64, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195, 64, + 195, 195, 64, 195, 195, 195, 195, 195, 64, 64, 196, 195, 194, 194, 194, + 193, 193, 193, 193, 193, 64, 193, 193, 194, 64, 194, 194, 197, 64, 64, + 195, 64, 64, 64, 64, 64, 64, 64, 195, 195, 193, 193, 64, 64, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, 199, 200, 64, 64, 64, 64, 64, 64, + 64, 201, 202, 202, 64, 203, 203, 203, 203, 203, 203, 203, 203, 64, 64, + 203, 203, 64, 64, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 64, 203, 203, 203, 203, 203, 203, 203, 64, 203, 203, 64, + 203, 203, 203, 203, 203, 64, 64, 204, 203, 202, 201, 202, 201, 201, 201, + 201, 64, 64, 202, 202, 64, 64, 202, 202, 205, 64, 64, 64, 64, 64, 64, 64, + 64, 201, 202, 64, 64, 64, 64, 203, 203, 64, 203, 203, 203, 201, 201, 64, + 64, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 203, 208, 208, + 208, 208, 208, 208, 64, 64, 209, 210, 64, 210, 210, 210, 210, 210, 210, + 64, 64, 64, 210, 210, 210, 64, 210, 210, 210, 210, 64, 64, 64, 210, 210, + 64, 210, 64, 210, 210, 64, 64, 64, 210, 210, 64, 64, 64, 210, 210, 210, + 210, 210, 210, 210, 210, 210, 210, 64, 64, 64, 64, 211, 211, 209, 211, + 211, 64, 64, 64, 211, 211, 211, 64, 211, 211, 211, 212, 64, 64, 210, 64, + 64, 64, 64, 64, 64, 211, 64, 64, 64, 64, 64, 64, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 214, 214, 214, 215, 215, 215, 215, 215, 215, + 216, 215, 64, 64, 64, 64, 64, 217, 218, 218, 218, 64, 219, 219, 219, 219, + 219, 219, 219, 219, 64, 219, 219, 219, 64, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 64, 64, 64, 219, 217, + 217, 217, 218, 218, 218, 218, 64, 217, 217, 217, 64, 217, 217, 217, 220, + 64, 64, 64, 64, 64, 64, 64, 221, 222, 64, 219, 219, 64, 64, 64, 64, 64, + 64, 219, 219, 217, 217, 64, 64, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 224, 224, 224, 224, 224, 224, 224, 225, 64, 226, 227, 227, 64, + 228, 228, 228, 228, 228, 228, 228, 228, 64, 228, 228, 228, 64, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 64, 228, 228, 228, 228, 228, 64, 64, 229, 228, 227, 230, 227, + 227, 227, 227, 227, 64, 230, 227, 227, 64, 227, 227, 226, 231, 64, 64, + 64, 64, 64, 64, 64, 227, 227, 64, 64, 64, 64, 64, 64, 64, 228, 64, 228, + 228, 226, 226, 64, 64, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 64, 228, 228, 64, 64, 64, 64, 64, 64, 233, 234, 234, 64, 235, 235, 235, + 235, 235, 235, 235, 235, 64, 235, 235, 235, 64, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 64, 64, 235, + 234, 234, 234, 233, 233, 233, 233, 64, 234, 234, 234, 64, 234, 234, 234, + 236, 235, 64, 64, 64, 64, 64, 64, 64, 64, 234, 235, 235, 233, 233, 64, + 64, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 238, 238, + 238, 238, 64, 64, 64, 239, 235, 235, 235, 235, 235, 235, 64, 64, 240, + 240, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 64, 64, 64, 241, 241, 241, 241, 241, 241, 241, + 241, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 64, 241, 64, 64, + 64, 64, 242, 64, 64, 64, 64, 240, 240, 240, 243, 243, 243, 64, 243, 64, + 240, 240, 240, 240, 240, 240, 240, 240, 64, 64, 64, 64, 64, 64, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 64, 64, 240, 240, 245, 64, 64, + 64, 64, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 247, 246, 246, 247, 247, 247, 247, 248, 248, 249, 64, 64, + 64, 64, 250, 246, 246, 246, 246, 246, 246, 251, 247, 252, 252, 252, 252, + 247, 247, 247, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 253, 253, 64, 64, 64, 64, 64, 255, 255, 64, 255, 64, 64, 255, 255, 64, + 255, 64, 64, 255, 64, 64, 64, 64, 64, 64, 255, 255, 255, 255, 64, 255, + 255, 255, 255, 255, 255, 255, 64, 255, 255, 255, 64, 255, 64, 255, 64, + 64, 255, 255, 64, 255, 255, 255, 255, 256, 255, 255, 256, 256, 256, 256, + 257, 257, 64, 256, 256, 255, 64, 64, 255, 255, 255, 255, 255, 64, 258, + 64, 259, 259, 259, 259, 256, 256, 64, 64, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 64, 64, 255, 255, 255, 255, 261, 262, 262, 262, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 262, 263, 262, 262, 262, 264, 264, 262, 262, 262, 262, 262, 262, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 262, 264, 262, 264, 262, 267, 268, 269, 268, + 269, 270, 270, 261, 261, 261, 261, 261, 261, 261, 261, 64, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, 261, 64, 64, 64, 64, 271, 272, + 273, 274, 273, 273, 273, 273, 273, 272, 272, 272, 272, 273, 270, 272, + 273, 275, 275, 276, 263, 275, 275, 261, 261, 261, 261, 261, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 64, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 64, 262, 262, 262, 262, 262, 262, 262, + 262, 264, 262, 262, 262, 262, 262, 262, 64, 262, 262, 263, 263, 263, 263, + 263, 277, 277, 277, 277, 263, 263, 64, 64, 64, 64, 64, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280, 280, 280, + 279, 280, 280, 280, 280, 280, 281, 279, 282, 282, 279, 279, 280, 280, + 278, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, 284, 284, + 284, 284, 284, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280, 278, + 278, 278, 278, 280, 280, 280, 278, 279, 279, 279, 278, 278, 279, 279, + 279, 279, 279, 279, 279, 278, 278, 278, 280, 280, 280, 280, 278, 278, + 278, 278, 278, 280, 279, 279, 280, 280, 279, 279, 279, 279, 279, 279, + 285, 278, 279, 283, 283, 279, 279, 279, 280, 286, 286, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 64, 287, 64, 64, + 64, 64, 64, 287, 64, 64, 288, 288, 288, 288, 288, 288, 288, 288, 288, + 288, 288, 84, 289, 288, 288, 288, 290, 290, 290, 290, 290, 290, 290, 290, + 291, 291, 291, 291, 291, 291, 291, 291, 292, 292, 292, 292, 292, 292, + 292, 292, 292, 64, 292, 292, 292, 292, 64, 64, 292, 292, 292, 292, 292, + 292, 292, 64, 292, 292, 292, 64, 64, 293, 293, 293, 294, 294, 294, 294, + 294, 294, 294, 294, 294, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 64, 64, 64, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 64, 64, 64, 64, 64, 64, 297, + 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 64, 64, 64, + 298, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 300, 300, 299, 301, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 303, 304, 64, 64, 64, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 84, 84, 84, 306, 306, 306, 305, 305, 305, 305, 305, 305, 305, + 305, 64, 64, 64, 64, 64, 64, 64, 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 64, 307, 307, 307, 307, 308, 308, 309, 64, 64, + 64, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 311, 311, 312, 84, + 84, 64, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 314, 64, + 64, 64, 64, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 64, 315, 315, 315, 64, 316, 316, 64, 64, 64, 64, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 318, 318, 319, 318, 318, 318, + 318, 318, 318, 318, 319, 319, 319, 319, 319, 319, 319, 319, 318, 319, + 319, 318, 318, 318, 318, 318, 318, 318, 318, 318, 320, 318, 321, 321, + 321, 322, 321, 321, 321, 323, 317, 324, 64, 64, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 64, 64, 64, 64, 64, 64, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 64, 64, 64, 64, 64, 64, 327, 327, 66, 66, 327, + 66, 328, 327, 327, 327, 327, 329, 329, 329, 330, 64, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 64, 64, 64, 64, 64, 64, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 333, 332, 332, 332, 332, 332, 334, + 332, 64, 64, 64, 64, 64, 299, 299, 299, 299, 299, 299, 64, 64, 335, 335, + 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 64, 336, + 336, 336, 337, 337, 337, 337, 336, 336, 337, 337, 337, 64, 64, 64, 64, + 337, 337, 336, 337, 337, 337, 337, 337, 337, 338, 339, 340, 64, 64, 64, + 64, 341, 64, 64, 64, 342, 342, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 64, 64, 344, 344, 344, 344, 344, 64, 64, 64, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, 345, 64, 64, 64, 64, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 345, 345, 345, 345, 345, 345, 345, + 346, 346, 64, 64, 64, 64, 64, 64, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 348, 64, 64, 64, 349, 349, 350, 350, 350, 350, 350, 350, 350, + 350, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 352, 353, 354, 354, 355, 64, 64, 356, 356, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 358, 359, 358, 359, 359, + 359, 359, 359, 359, 359, 64, 360, 358, 359, 358, 358, 359, 359, 359, 359, + 359, 359, 359, 359, 358, 358, 358, 358, 358, 358, 359, 359, 361, 361, + 361, 361, 361, 361, 361, 361, 64, 64, 362, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 64, 64, 64, 64, 64, 64, 364, 364, 364, 364, 364, 364, + 364, 365, 364, 364, 364, 364, 364, 364, 64, 64, 78, 78, 78, 78, 78, 136, + 136, 136, 136, 136, 136, 78, 78, 136, 366, 64, 367, 367, 367, 367, 368, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 370, 368, 367, 367, 367, 367, 367, 368, 367, 368, 368, 368, 368, + 368, 367, 368, 371, 369, 369, 369, 369, 369, 369, 369, 64, 64, 64, 64, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 373, 373, 373, 373, + 373, 373, 373, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 375, + 376, 375, 375, 375, 375, 375, 375, 375, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 64, 64, 64, 377, 377, 378, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 378, 377, 377, 377, 377, 378, + 378, 377, 377, 380, 381, 377, 377, 379, 379, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 379, 379, 379, 379, 379, 379, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 384, 385, 386, + 386, 385, 385, 385, 386, 385, 386, 386, 386, 387, 387, 64, 64, 64, 64, + 64, 64, 64, 64, 388, 388, 388, 388, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 390, 390, 390, 390, 390, 390, 390, 390, 391, + 391, 391, 391, 391, 391, 391, 391, 390, 390, 391, 392, 64, 64, 64, 393, + 393, 393, 393, 393, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 64, + 64, 64, 389, 389, 389, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 397, 397, 397, 397, 397, 397, 398, 398, 399, 399, 399, 399, 399, 399, + 399, 399, 78, 78, 78, 84, 400, 136, 136, 136, 136, 136, 78, 78, 136, 136, + 136, 136, 78, 401, 400, 400, 400, 400, 400, 400, 400, 402, 402, 402, 402, + 136, 402, 402, 402, 402, 401, 401, 78, 402, 402, 64, 78, 78, 64, 64, 64, + 64, 64, 64, 41, 41, 41, 41, 41, 41, 62, 62, 62, 62, 62, 75, 44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 44, 44, 44, 44, 65, 65, 65, - 65, 65, 41, 41, 41, 41, 41, 398, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 78, 78, 133, 78, 78, - 78, 78, 78, 78, 78, 133, 78, 78, 399, 400, 133, 401, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 64, - 64, 64, 64, 64, 402, 133, 78, 133, 37, 41, 37, 41, 37, 41, 41, 41, 41, + 65, 65, 41, 41, 41, 41, 41, 403, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 78, 78, 136, 78, 78, + 78, 78, 78, 78, 78, 136, 78, 78, 404, 405, 136, 406, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 64, 64, + 64, 64, 64, 64, 407, 136, 78, 136, 37, 41, 37, 41, 37, 41, 41, 41, 41, 41, 41, 41, 41, 41, 37, 41, 62, 62, 62, 62, 62, 62, 62, 62, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 64, 64, 61, 61, 61, 61, 61, - 61, 64, 64, 64, 61, 64, 61, 64, 61, 64, 61, 403, 403, 403, 403, 403, 403, - 403, 403, 62, 62, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 403, 63, 62, - 63, 63, 63, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 403, 63, 63, 63, 62, + 61, 64, 64, 64, 61, 64, 61, 64, 61, 64, 61, 408, 408, 408, 408, 408, 408, + 408, 408, 62, 62, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 408, 63, 62, + 63, 63, 63, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 408, 63, 63, 63, 62, 62, 62, 62, 64, 64, 62, 62, 61, 61, 61, 61, 64, 63, 63, 63, 61, 61, 61, - 61, 61, 63, 63, 63, 64, 64, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 403, - 63, 63, 64, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 405, - 406, 406, 407, 408, 409, 410, 410, 409, 409, 409, 22, 66, 411, 412, 413, - 414, 411, 412, 413, 414, 22, 22, 22, 66, 22, 22, 22, 22, 415, 416, 417, - 418, 419, 420, 421, 21, 422, 423, 422, 422, 423, 22, 66, 66, 66, 28, 35, - 22, 66, 66, 22, 424, 424, 66, 66, 66, 425, 426, 427, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 428, 66, 424, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 404, 405, 405, 405, 405, 405, 64, 64, 64, 64, 64, 405, 405, 405, 405, - 405, 405, 429, 44, 64, 64, 33, 429, 429, 429, 429, 429, 430, 430, 428, - 426, 427, 431, 429, 33, 33, 33, 33, 429, 429, 429, 429, 429, 430, 430, - 428, 426, 427, 64, 44, 44, 44, 44, 44, 64, 64, 64, 247, 247, 247, 247, - 247, 247, 247, 247, 247, 432, 247, 247, 23, 247, 247, 247, 247, 247, 247, - 64, 64, 64, 64, 64, 78, 78, 395, 395, 78, 78, 78, 78, 395, 395, 395, 78, - 78, 433, 433, 433, 433, 78, 433, 433, 433, 395, 395, 78, 133, 78, 395, - 395, 133, 133, 133, 133, 78, 64, 64, 64, 64, 64, 64, 64, 26, 26, 434, 30, - 26, 30, 26, 434, 26, 30, 34, 434, 434, 434, 34, 34, 434, 434, 434, 435, - 26, 434, 30, 26, 428, 434, 434, 434, 434, 434, 26, 26, 26, 30, 30, 26, - 434, 26, 67, 26, 434, 26, 37, 38, 434, 434, 436, 34, 434, 434, 37, 434, - 34, 397, 397, 397, 397, 34, 26, 26, 34, 34, 434, 434, 437, 428, 428, 428, - 428, 434, 34, 34, 34, 34, 26, 428, 26, 26, 41, 274, 438, 438, 438, 36, - 36, 438, 438, 438, 438, 438, 438, 36, 36, 36, 36, 438, 439, 439, 439, - 439, 439, 439, 439, 439, 439, 439, 439, 439, 440, 440, 440, 440, 439, - 439, 440, 440, 440, 440, 440, 440, 440, 440, 440, 37, 41, 440, 440, 440, - 440, 36, 64, 64, 64, 64, 64, 64, 39, 39, 39, 39, 39, 30, 30, 30, 30, 30, - 428, 428, 26, 26, 26, 26, 428, 26, 26, 428, 26, 26, 428, 26, 26, 26, 26, - 26, 26, 26, 428, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 428, 428, 26, 26, 39, 26, 39, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 428, 428, 428, 428, - 428, 428, 428, 428, 428, 428, 428, 428, 39, 437, 441, 441, 437, 428, 428, - 39, 441, 437, 437, 441, 437, 437, 428, 39, 428, 441, 430, 442, 428, 441, - 437, 428, 428, 428, 441, 437, 437, 441, 39, 441, 441, 437, 437, 39, 437, - 39, 437, 39, 39, 39, 39, 441, 441, 437, 441, 437, 437, 437, 437, 437, 39, - 39, 39, 39, 428, 437, 428, 437, 441, 441, 437, 437, 437, 437, 437, 437, - 437, 437, 437, 437, 441, 437, 437, 437, 441, 428, 428, 428, 428, 428, - 441, 437, 437, 437, 428, 428, 428, 428, 428, 428, 428, 428, 428, 437, - 441, 39, 437, 428, 441, 441, 441, 441, 437, 437, 441, 441, 428, 428, 441, - 441, 437, 437, 441, 441, 437, 437, 441, 441, 437, 437, 437, 437, 437, - 428, 428, 437, 437, 437, 437, 428, 428, 39, 428, 428, 437, 39, 428, 428, - 428, 428, 428, 428, 428, 428, 437, 437, 428, 39, 437, 437, 437, 428, 428, - 428, 428, 428, 437, 441, 428, 437, 437, 437, 437, 437, 428, 428, 437, - 437, 428, 428, 428, 428, 437, 437, 437, 437, 437, 437, 437, 437, 428, - 428, 437, 437, 437, 437, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, - 437, 437, 26, 26, 26, 26, 26, 26, 26, 443, 444, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 26, 428, 26, 26, 26, 26, 26, 26, 26, 26, 274, 26, 26, 26, - 26, 26, 428, 428, 428, 428, 428, 428, 428, 428, 428, 26, 26, 26, 26, 428, - 428, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 26, 26, 26, - 26, 26, 26, 26, 64, 26, 26, 26, 64, 64, 64, 64, 64, 36, 36, 36, 36, 36, - 36, 36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 445, 445, - 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 438, 36, 36, - 36, 36, 36, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, - 26, 26, 26, 30, 30, 30, 30, 26, 26, 30, 30, 26, 30, 30, 30, 30, 30, 26, - 26, 30, 30, 26, 26, 30, 39, 26, 26, 26, 26, 30, 30, 26, 26, 30, 39, 26, - 26, 26, 26, 30, 30, 30, 26, 26, 30, 26, 26, 30, 30, 26, 26, 26, 26, 26, - 30, 30, 26, 26, 30, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 30, 26, 30, - 26, 30, 26, 30, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30, 30, 26, 30, 30, - 30, 30, 26, 30, 30, 26, 39, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, - 26, 274, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 26, 30, 30, 30, 26, 30, 26, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 30, 26, 26, 426, 427, 426, 427, 426, 427, 426, - 427, 426, 427, 426, 427, 426, 427, 36, 36, 438, 438, 438, 438, 438, 438, - 438, 438, 438, 438, 438, 438, 26, 26, 26, 26, 437, 428, 428, 437, 437, - 426, 427, 428, 437, 437, 428, 437, 437, 437, 428, 428, 428, 428, 428, - 437, 437, 437, 437, 428, 428, 428, 428, 428, 437, 437, 437, 428, 428, - 428, 437, 437, 437, 437, 9, 10, 9, 10, 9, 10, 9, 10, 426, 427, 446, 446, - 446, 446, 446, 446, 446, 446, 428, 428, 428, 426, 427, 9, 10, 426, 427, - 426, 427, 426, 427, 426, 427, 426, 427, 428, 428, 437, 437, 437, 437, - 437, 437, 428, 428, 428, 428, 428, 428, 428, 428, 437, 428, 428, 428, - 428, 437, 437, 437, 437, 437, 428, 437, 437, 428, 428, 426, 427, 426, - 427, 437, 428, 428, 428, 428, 437, 428, 437, 437, 437, 428, 428, 437, - 437, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 437, 437, 437, - 437, 437, 437, 428, 428, 426, 427, 428, 428, 428, 428, 437, 437, 437, - 437, 437, 437, 437, 437, 437, 437, 437, 428, 437, 437, 437, 437, 428, - 428, 437, 428, 437, 428, 428, 437, 428, 437, 437, 437, 437, 428, 428, - 428, 428, 428, 437, 437, 428, 428, 428, 428, 437, 437, 437, 437, 428, - 437, 437, 428, 428, 437, 437, 428, 428, 428, 428, 437, 437, 437, 437, - 437, 437, 437, 437, 437, 437, 437, 428, 428, 437, 437, 437, 437, 437, - 437, 437, 437, 428, 437, 437, 437, 437, 437, 437, 437, 437, 428, 428, - 428, 428, 428, 437, 428, 437, 428, 428, 428, 437, 437, 437, 437, 437, - 428, 428, 428, 428, 437, 428, 428, 428, 437, 437, 437, 437, 437, 428, - 437, 428, 428, 428, 428, 428, 428, 428, 26, 26, 428, 428, 428, 428, 428, - 428, 64, 64, 64, 26, 26, 26, 26, 26, 30, 30, 30, 30, 30, 64, 64, 64, 64, - 64, 64, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, - 447, 447, 64, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, - 448, 448, 448, 64, 37, 41, 37, 37, 37, 41, 41, 37, 41, 37, 41, 37, 41, - 37, 37, 37, 37, 41, 37, 41, 41, 37, 41, 41, 41, 41, 41, 41, 44, 44, 37, - 37, 69, 70, 69, 70, 70, 449, 449, 449, 449, 449, 449, 69, 70, 69, 70, - 450, 450, 450, 69, 70, 64, 64, 64, 64, 64, 451, 451, 451, 451, 452, 451, - 451, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, - 453, 64, 453, 64, 64, 64, 64, 64, 453, 64, 64, 454, 454, 454, 454, 454, - 454, 454, 454, 64, 64, 64, 64, 64, 64, 64, 455, 456, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 457, 77, 77, 77, 77, 77, 77, 77, 77, + 61, 61, 63, 63, 63, 64, 64, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 408, + 63, 63, 64, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 410, + 411, 411, 412, 413, 414, 415, 415, 414, 414, 414, 22, 66, 416, 417, 418, + 419, 416, 417, 418, 419, 22, 22, 22, 66, 22, 22, 22, 22, 420, 421, 422, + 423, 424, 425, 426, 21, 427, 428, 427, 427, 428, 22, 66, 66, 66, 28, 35, + 22, 66, 66, 22, 429, 429, 66, 66, 66, 430, 431, 432, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 433, 66, 429, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 409, 410, 410, 410, 410, 410, 64, 434, 435, 436, 437, 410, 410, 410, + 410, 410, 410, 438, 44, 64, 64, 33, 438, 438, 438, 438, 438, 439, 439, + 433, 431, 432, 440, 438, 33, 33, 33, 33, 438, 438, 438, 438, 438, 439, + 439, 433, 431, 432, 64, 44, 44, 44, 44, 44, 64, 64, 64, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 441, 250, 250, 23, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 64, 64, 78, 78, 400, 400, 78, 78, 78, 78, 400, 400, + 400, 78, 78, 366, 366, 366, 366, 78, 366, 366, 366, 400, 400, 78, 136, + 78, 400, 400, 136, 136, 136, 136, 78, 64, 64, 64, 64, 64, 64, 64, 26, 26, + 442, 30, 26, 30, 26, 442, 26, 30, 34, 442, 442, 442, 34, 34, 442, 442, + 442, 443, 26, 442, 30, 26, 433, 442, 442, 442, 442, 442, 26, 26, 26, 30, + 30, 26, 442, 26, 67, 26, 442, 26, 37, 38, 442, 442, 444, 34, 442, 442, + 37, 442, 34, 402, 402, 402, 402, 34, 26, 26, 34, 34, 442, 442, 445, 433, + 433, 433, 433, 442, 34, 34, 34, 34, 26, 433, 26, 26, 41, 277, 446, 446, + 446, 36, 36, 446, 446, 446, 446, 446, 446, 36, 36, 36, 36, 446, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 448, 448, 448, + 447, 447, 448, 448, 448, 448, 448, 448, 448, 448, 448, 37, 41, 448, 448, + 448, 448, 36, 64, 64, 64, 64, 64, 64, 39, 39, 39, 39, 39, 30, 30, 30, 30, + 30, 433, 433, 26, 26, 26, 26, 433, 26, 26, 433, 26, 26, 433, 26, 26, 26, + 26, 26, 26, 26, 433, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 433, 433, 26, 26, 39, 26, 39, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, 433, 39, 445, 449, 449, 445, 433, + 433, 39, 449, 445, 445, 449, 445, 445, 433, 39, 433, 449, 439, 450, 433, + 449, 445, 433, 433, 433, 449, 445, 445, 449, 39, 449, 449, 445, 445, 39, + 445, 39, 445, 39, 39, 39, 39, 449, 449, 445, 449, 445, 445, 445, 445, + 445, 39, 39, 39, 39, 433, 445, 433, 445, 449, 449, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 449, 445, 445, 445, 449, 433, 433, 433, + 433, 433, 449, 445, 445, 445, 433, 433, 433, 433, 433, 433, 433, 433, + 433, 445, 449, 39, 445, 433, 449, 449, 449, 449, 445, 445, 449, 449, 433, + 433, 449, 449, 445, 445, 449, 449, 445, 445, 449, 449, 445, 445, 445, + 445, 445, 433, 433, 445, 445, 445, 445, 433, 433, 39, 433, 433, 445, 39, + 433, 433, 433, 433, 433, 433, 433, 433, 445, 445, 433, 39, 445, 445, 445, + 433, 433, 433, 433, 433, 445, 449, 433, 445, 445, 445, 445, 445, 433, + 433, 445, 445, 433, 433, 433, 433, 445, 445, 445, 445, 445, 445, 445, + 445, 433, 433, 431, 432, 431, 432, 26, 26, 26, 26, 26, 26, 30, 26, 26, + 26, 26, 26, 445, 445, 26, 26, 26, 26, 26, 26, 26, 451, 452, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 26, 433, 26, 26, 26, 26, 26, 26, 26, 26, 277, + 26, 26, 26, 26, 26, 433, 433, 433, 433, 433, 433, 433, 433, 433, 26, 26, + 26, 26, 433, 433, 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 64, + 26, 26, 26, 26, 26, 26, 26, 64, 36, 36, 36, 36, 36, 36, 36, 36, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 453, 453, 453, 453, 453, 453, + 453, 453, 453, 453, 453, 453, 453, 453, 446, 36, 36, 36, 36, 36, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 30, 30, + 30, 30, 26, 26, 30, 30, 26, 30, 30, 30, 30, 30, 26, 26, 30, 30, 26, 26, + 30, 39, 26, 26, 26, 26, 30, 30, 26, 26, 30, 39, 26, 26, 26, 26, 30, 30, + 30, 26, 26, 30, 26, 26, 30, 30, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, + 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 30, 26, 30, 26, 30, 26, 30, 26, + 26, 26, 26, 26, 30, 30, 26, 30, 30, 30, 26, 30, 30, 30, 30, 26, 30, 30, + 26, 39, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 277, 26, 26, 26, + 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, 30, 30, + 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 431, 432, 431, + 432, 431, 432, 431, 432, 431, 432, 431, 432, 431, 432, 36, 36, 446, 446, + 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 26, 26, 26, 26, 445, + 433, 433, 445, 445, 431, 432, 433, 445, 445, 433, 445, 445, 445, 433, + 433, 433, 433, 433, 445, 445, 445, 445, 433, 433, 433, 433, 433, 445, + 445, 445, 433, 433, 433, 445, 445, 445, 445, 9, 10, 9, 10, 9, 10, 9, 10, + 431, 432, 454, 454, 454, 454, 454, 454, 454, 454, 433, 433, 433, 431, + 432, 9, 10, 431, 432, 431, 432, 431, 432, 431, 432, 431, 432, 433, 433, + 445, 445, 445, 445, 445, 445, 433, 433, 433, 433, 433, 433, 433, 433, + 445, 433, 433, 433, 433, 445, 445, 445, 445, 445, 433, 445, 445, 433, + 433, 431, 432, 431, 432, 445, 433, 433, 433, 433, 445, 433, 445, 445, + 445, 433, 433, 445, 445, 433, 433, 433, 433, 433, 433, 433, 433, 433, + 433, 445, 445, 445, 445, 445, 445, 433, 433, 431, 432, 433, 433, 433, + 433, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 433, 445, + 445, 445, 445, 433, 433, 445, 433, 445, 433, 433, 445, 433, 445, 445, + 445, 445, 433, 433, 433, 433, 433, 445, 445, 433, 433, 433, 433, 445, + 445, 445, 445, 433, 445, 445, 433, 433, 445, 445, 433, 433, 433, 433, + 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 433, 433, 445, + 445, 445, 445, 445, 445, 445, 445, 433, 445, 445, 445, 445, 445, 445, + 445, 445, 433, 433, 433, 433, 433, 445, 433, 445, 433, 433, 433, 445, + 445, 445, 445, 445, 433, 433, 433, 433, 445, 433, 433, 433, 445, 445, + 445, 445, 445, 433, 445, 433, 433, 433, 433, 433, 433, 433, 26, 26, 433, + 433, 433, 433, 433, 433, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 26, + 26, 26, 26, 64, 64, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 26, 26, 64, + 64, 64, 26, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 64, + 64, 64, 64, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 64, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 456, 456, 456, 64, 37, 41, 37, 37, 37, 41, 41, 37, 41, 37, 41, 37, + 41, 37, 37, 37, 37, 41, 37, 41, 41, 37, 41, 41, 41, 41, 41, 41, 44, 44, + 37, 37, 69, 70, 69, 70, 70, 457, 457, 457, 457, 457, 457, 69, 70, 69, 70, + 458, 458, 458, 69, 70, 64, 64, 64, 64, 64, 459, 459, 459, 459, 460, 459, + 459, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, + 461, 64, 461, 64, 64, 64, 64, 64, 461, 64, 64, 462, 462, 462, 462, 462, + 462, 462, 462, 64, 64, 64, 64, 64, 64, 64, 463, 464, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 465, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 28, 35, 28, 35, 66, 66, 66, 28, 35, 66, 28, 35, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 410, 66, 66, 410, 66, 28, 35, 66, 66, 28, 35, 426, - 427, 426, 427, 426, 427, 426, 427, 66, 66, 66, 66, 66, 45, 66, 66, 410, - 410, 64, 64, 64, 64, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, - 64, 458, 458, 458, 458, 458, 458, 458, 458, 458, 64, 64, 64, 64, 458, - 458, 458, 458, 458, 458, 64, 64, 459, 459, 459, 459, 459, 459, 459, 459, - 459, 459, 459, 459, 64, 64, 64, 64, 460, 461, 461, 461, 459, 462, 463, - 464, 443, 444, 443, 444, 443, 444, 443, 444, 443, 444, 459, 459, 443, - 444, 443, 444, 443, 444, 443, 444, 465, 466, 467, 467, 459, 464, 464, - 464, 464, 464, 464, 464, 464, 464, 468, 469, 470, 471, 472, 472, 465, - 473, 473, 473, 473, 473, 459, 459, 464, 464, 464, 462, 463, 461, 459, 26, - 64, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, - 474, 474, 474, 474, 474, 474, 474, 474, 64, 64, 475, 475, 476, 476, 477, - 477, 474, 465, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 461, 473, 479, 479, 478, 64, 64, 64, - 64, 64, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, - 480, 480, 480, 480, 64, 64, 64, 287, 287, 287, 287, 287, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 64, 481, 481, 482, 482, 482, 482, 481, 481, - 481, 481, 481, 481, 481, 481, 481, 481, 480, 480, 480, 64, 64, 64, 64, - 64, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 484, - 484, 64, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 481, 481, 481, - 481, 481, 481, 485, 485, 485, 485, 485, 485, 485, 485, 459, 486, 486, - 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 483, - 483, 483, 483, 484, 484, 484, 481, 481, 486, 486, 486, 486, 486, 486, - 486, 481, 481, 481, 481, 459, 459, 459, 459, 487, 487, 487, 487, 487, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 64, 481, 481, 481, 481, - 481, 481, 481, 459, 459, 459, 459, 481, 481, 481, 481, 481, 481, 481, - 481, 481, 481, 481, 459, 459, 488, 489, 489, 489, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 488, - 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 489, 489, 489, 489, - 488, 490, 490, 490, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, - 491, 491, 491, 492, 491, 491, 491, 491, 491, 491, 491, 64, 64, 64, 493, - 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 64, - 494, 494, 494, 494, 494, 494, 494, 494, 495, 495, 495, 495, 495, 495, - 496, 496, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, - 498, 499, 499, 499, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, - 497, 497, 64, 64, 64, 64, 72, 75, 72, 75, 72, 75, 501, 77, 79, 79, 79, - 502, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 502, 503, 64, 64, 64, 64, - 64, 64, 64, 77, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, - 506, 507, 507, 507, 507, 507, 507, 47, 47, 47, 47, 47, 47, 47, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 47, 47, 37, 41, 37, 41, 37, 41, 41, 41, 37, - 41, 37, 41, 37, 41, 44, 41, 41, 41, 41, 41, 41, 41, 41, 37, 41, 37, 41, - 37, 37, 41, 45, 508, 508, 37, 41, 37, 41, 64, 37, 41, 37, 41, 64, 64, 64, - 64, 37, 41, 37, 64, 64, 64, 64, 64, 44, 44, 41, 42, 42, 42, 42, 42, 509, - 509, 510, 509, 509, 509, 511, 509, 509, 509, 509, 510, 509, 509, 509, - 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 512, 512, - 510, 510, 512, 513, 513, 513, 513, 64, 64, 64, 64, 514, 514, 514, 514, - 514, 514, 274, 274, 247, 436, 64, 64, 64, 64, 64, 64, 515, 515, 515, 515, - 515, 515, 515, 515, 515, 515, 515, 515, 516, 516, 516, 516, 517, 517, - 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, - 518, 518, 518, 518, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - 517, 517, 517, 517, 517, 517, 519, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 520, 520, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 64, 64, 64, - 64, 64, 64, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 169, 169, - 169, 169, 169, 169, 174, 174, 174, 169, 64, 64, 64, 64, 522, 522, 522, - 522, 522, 522, 522, 522, 522, 522, 523, 523, 523, 523, 523, 523, 523, - 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 524, - 524, 524, 524, 524, 525, 525, 525, 526, 526, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 528, 528, 528, 528, - 528, 528, 528, 528, 528, 528, 528, 529, 530, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 531, 287, 287, 287, 287, 287, 64, 64, 64, 532, 532, 532, - 533, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 535, 533, 533, 532, 532, 532, 532, 533, 533, 532, 533, 533, - 533, 536, 537, 537, 537, 537, 537, 537, 537, 537, 537, 537, 537, 537, - 537, 64, 538, 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, 64, 64, - 64, 64, 537, 537, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 541, - 541, 541, 541, 541, 542, 542, 541, 541, 542, 542, 541, 541, 64, 540, 540, - 540, 541, 540, 540, 540, 540, 540, 540, 540, 540, 541, 542, 64, 64, 543, - 543, 543, 543, 543, 543, 543, 543, 543, 543, 64, 64, 544, 544, 544, 544, - 545, 275, 275, 275, 275, 275, 275, 283, 283, 283, 275, 276, 64, 64, 64, - 64, 546, 546, 546, 546, 546, 546, 546, 546, 547, 546, 547, 547, 548, 546, - 546, 547, 547, 546, 546, 546, 546, 546, 547, 547, 546, 547, 546, 64, 64, - 64, 64, 64, 64, 64, 64, 546, 546, 549, 550, 550, 551, 551, 551, 551, 551, - 551, 551, 551, 551, 551, 551, 552, 553, 553, 552, 552, 554, 554, 551, - 555, 555, 552, 556, 64, 64, 289, 289, 289, 289, 289, 289, 64, 551, 551, - 551, 552, 552, 553, 552, 552, 553, 552, 552, 554, 552, 556, 64, 64, 557, - 557, 557, 557, 557, 557, 557, 557, 557, 557, 64, 64, 64, 64, 64, 64, 287, - 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, - 558, 558, 558, 558, 287, 64, 64, 64, 64, 288, 288, 288, 288, 288, 288, - 288, 64, 64, 64, 64, 288, 288, 288, 288, 288, 288, 288, 288, 288, 64, 64, - 64, 64, 559, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 559, - 560, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 561, 561, 561, 561, 561, 560, 488, 488, 488, 488, - 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 490, 490, 488, 488, - 490, 490, 490, 490, 490, 490, 41, 41, 41, 41, 41, 41, 41, 64, 64, 64, 64, - 83, 83, 83, 83, 83, 64, 64, 64, 64, 64, 109, 562, 109, 109, 563, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 64, 109, 109, - 109, 109, 109, 64, 109, 64, 109, 109, 64, 109, 109, 64, 109, 109, 123, - 123, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, - 564, 564, 564, 64, 64, 64, 64, 64, 64, 64, 64, 64, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 413, 565, 64, 64, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 114, 26, 64, 64, 58, 58, 58, 58, 58, 58, - 58, 58, 461, 461, 461, 461, 461, 461, 461, 466, 467, 461, 64, 64, 64, 64, - 64, 64, 461, 465, 465, 566, 566, 466, 467, 466, 467, 466, 467, 466, 467, - 466, 467, 466, 467, 466, 467, 466, 467, 461, 461, 466, 467, 461, 461, - 461, 461, 566, 566, 566, 567, 461, 567, 64, 461, 567, 461, 461, 465, 443, - 444, 443, 444, 443, 444, 568, 461, 461, 569, 570, 571, 571, 572, 64, 461, - 573, 568, 461, 64, 64, 64, 64, 123, 123, 123, 123, 123, 64, 123, 123, - 123, 123, 123, 123, 123, 64, 64, 405, 64, 574, 574, 575, 576, 575, 574, - 574, 577, 578, 574, 579, 580, 581, 580, 580, 582, 582, 582, 582, 582, - 582, 582, 582, 582, 582, 580, 574, 583, 584, 583, 574, 574, 585, 585, - 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, - 585, 585, 577, 574, 578, 586, 587, 586, 588, 588, 588, 588, 588, 588, - 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 577, 584, - 578, 584, 577, 578, 589, 590, 591, 589, 589, 592, 592, 592, 592, 592, - 592, 592, 592, 592, 592, 593, 592, 592, 592, 592, 592, 592, 592, 592, - 592, 592, 592, 592, 592, 593, 593, 594, 594, 594, 594, 594, 594, 594, - 594, 594, 594, 594, 594, 594, 594, 594, 64, 64, 64, 594, 594, 594, 594, - 594, 594, 64, 64, 594, 594, 594, 64, 64, 64, 576, 576, 584, 586, 595, - 576, 576, 64, 596, 597, 597, 597, 597, 596, 596, 64, 64, 598, 598, 598, - 26, 30, 64, 64, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, - 599, 64, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 64, 599, 599, - 599, 64, 599, 599, 64, 599, 599, 599, 599, 599, 599, 599, 64, 64, 599, - 599, 599, 64, 64, 64, 64, 64, 84, 66, 84, 64, 64, 64, 64, 514, 514, 514, - 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 64, 64, 64, 274, 600, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 601, - 601, 601, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, - 602, 602, 602, 602, 602, 601, 64, 64, 64, 64, 64, 274, 274, 274, 274, - 274, 133, 64, 64, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, - 603, 603, 64, 64, 64, 604, 604, 604, 604, 604, 604, 604, 604, 604, 64, - 64, 64, 64, 64, 64, 64, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, - 605, 605, 605, 605, 605, 64, 606, 606, 606, 606, 64, 64, 64, 64, 607, - 607, 607, 607, 607, 607, 607, 607, 607, 608, 607, 607, 607, 607, 607, - 607, 607, 607, 608, 64, 64, 64, 64, 64, 609, 609, 609, 609, 609, 609, - 609, 609, 609, 609, 609, 609, 609, 609, 64, 610, 611, 611, 611, 611, 611, - 611, 611, 611, 611, 611, 611, 611, 64, 64, 64, 64, 612, 613, 613, 613, - 613, 613, 64, 64, 614, 614, 614, 614, 614, 614, 614, 614, 615, 615, 615, - 615, 615, 615, 615, 615, 616, 616, 616, 616, 616, 616, 616, 616, 617, - 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 64, 64, - 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 64, 64, 64, 64, 64, 64, - 619, 619, 619, 619, 619, 619, 64, 64, 619, 64, 619, 619, 619, 619, 619, - 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, - 619, 64, 619, 619, 64, 64, 64, 619, 64, 64, 619, 620, 620, 620, 620, 620, - 620, 620, 620, 620, 620, 620, 620, 620, 620, 64, 621, 622, 622, 622, 622, - 622, 622, 622, 622, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 623, 623, 624, 624, 624, 624, 624, 624, 64, 64, 64, 625, 626, - 626, 626, 626, 626, 626, 626, 626, 626, 626, 64, 64, 64, 64, 64, 627, - 628, 628, 628, 628, 628, 628, 628, 628, 629, 629, 629, 629, 629, 629, - 629, 629, 64, 64, 64, 64, 64, 64, 629, 629, 630, 631, 631, 631, 64, 631, - 631, 64, 64, 64, 64, 64, 631, 632, 631, 633, 630, 630, 630, 630, 64, 630, - 630, 630, 64, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, - 630, 630, 630, 630, 630, 630, 630, 64, 64, 64, 64, 633, 634, 632, 64, 64, - 64, 64, 635, 636, 636, 636, 636, 636, 636, 636, 636, 637, 637, 637, 637, - 637, 637, 637, 637, 637, 64, 64, 64, 64, 64, 64, 64, 638, 638, 638, 638, - 638, 638, 638, 638, 638, 638, 638, 638, 638, 639, 639, 640, 641, 641, - 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, 64, 64, 64, - 642, 642, 642, 642, 642, 642, 642, 643, 643, 643, 643, 643, 643, 643, - 643, 643, 643, 643, 643, 643, 643, 64, 64, 644, 644, 644, 644, 644, 644, - 644, 644, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 64, 64, - 64, 64, 64, 646, 646, 646, 646, 646, 646, 646, 646, 647, 647, 647, 647, - 647, 647, 647, 647, 647, 64, 64, 64, 64, 64, 64, 64, 648, 648, 648, 648, - 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 64, 649, 650, 649, - 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 650, - 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 652, - 653, 653, 653, 653, 653, 653, 653, 64, 64, 64, 64, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, - 654, 654, 655, 655, 655, 655, 655, 655, 655, 655, 655, 655, 656, 656, - 657, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, - 657, 657, 657, 656, 656, 656, 656, 657, 657, 659, 660, 661, 661, 662, - 661, 661, 661, 661, 64, 64, 64, 64, 64, 64, 663, 663, 663, 663, 663, 663, - 663, 663, 663, 64, 64, 64, 64, 64, 64, 64, 664, 664, 664, 664, 664, 664, - 664, 664, 664, 664, 64, 64, 64, 64, 64, 64, 665, 665, 665, 666, 666, 666, - 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 667, 667, 667, 667, 667, 668, 667, 667, 667, 667, 667, - 667, 669, 669, 64, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 671, - 671, 671, 671, 64, 64, 64, 64, 672, 672, 673, 674, 674, 674, 674, 674, - 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 673, 673, 673, - 672, 672, 672, 672, 672, 672, 672, 672, 672, 673, 675, 674, 674, 674, - 674, 676, 676, 676, 676, 64, 64, 64, 64, 64, 64, 64, 677, 677, 677, 677, - 677, 677, 677, 677, 677, 677, 64, 64, 64, 64, 64, 64, 678, 678, 678, 678, - 678, 678, 678, 678, 678, 678, 678, 679, 680, 679, 680, 680, 679, 679, - 679, 679, 679, 679, 681, 682, 683, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 64, 64, 64, 64, 64, 64, 684, 684, 684, 684, 684, 684, 684, 684, - 684, 684, 684, 684, 684, 684, 684, 64, 685, 685, 685, 685, 685, 685, 685, - 685, 685, 685, 685, 64, 64, 64, 64, 64, 686, 686, 686, 686, 64, 64, 64, - 64, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, - 687, 64, 504, 64, 64, 64, 64, 64, 64, 64, 688, 688, 688, 688, 688, 688, - 688, 688, 688, 688, 688, 688, 688, 64, 64, 64, 688, 689, 689, 689, 689, - 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, - 689, 689, 689, 689, 64, 64, 64, 64, 64, 64, 64, 64, 690, 690, 690, 690, - 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 478, - 474, 64, 64, 64, 64, 64, 64, 274, 274, 274, 274, 274, 274, 64, 64, 274, - 274, 274, 274, 274, 274, 274, 64, 64, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 692, 692, 395, 395, 395, 274, 274, 274, 693, - 692, 692, 692, 692, 692, 405, 405, 405, 405, 405, 405, 405, 405, 133, - 133, 133, 133, 133, 133, 133, 133, 274, 274, 78, 78, 78, 78, 78, 133, - 133, 274, 274, 274, 274, 274, 274, 78, 78, 78, 78, 274, 274, 602, 602, - 694, 694, 694, 602, 64, 64, 514, 514, 64, 64, 64, 64, 64, 64, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, 34, - 34, 434, 64, 434, 434, 64, 64, 434, 64, 64, 434, 434, 64, 64, 434, 434, - 434, 434, 64, 434, 434, 34, 34, 64, 34, 64, 34, 34, 34, 34, 34, 34, 34, - 64, 34, 34, 34, 34, 34, 34, 34, 434, 434, 64, 434, 434, 434, 434, 64, 64, - 434, 434, 434, 434, 434, 434, 434, 434, 64, 434, 434, 434, 434, 434, 434, - 434, 64, 34, 34, 434, 434, 64, 434, 434, 434, 434, 64, 434, 434, 434, - 434, 434, 64, 434, 64, 64, 64, 434, 434, 434, 434, 434, 434, 434, 64, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 64, 64, 434, 695, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 437, 34, 34, 34, 34, 34, 34, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 695, 34, 34, 34, 34, 34, 34, 34, 34, 34, 437, - 34, 34, 434, 434, 434, 434, 434, 695, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 437, 34, 34, 34, 34, 34, 34, 434, 434, 434, 434, 434, 434, 434, 434, 434, - 695, 34, 437, 34, 34, 34, 34, 34, 34, 34, 34, 434, 34, 64, 64, 696, 696, - 696, 696, 696, 696, 696, 696, 696, 696, 123, 123, 123, 123, 64, 123, 123, - 123, 64, 123, 123, 64, 123, 64, 64, 123, 64, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 64, 123, 123, 123, 123, 64, 123, 64, 123, 64, - 64, 64, 64, 64, 64, 123, 64, 64, 64, 64, 123, 64, 123, 64, 123, 64, 123, - 123, 123, 64, 123, 64, 123, 64, 123, 64, 123, 64, 123, 123, 123, 123, 64, - 123, 64, 123, 123, 64, 123, 123, 123, 123, 123, 123, 123, 123, 123, 64, - 64, 64, 64, 64, 123, 123, 123, 64, 123, 123, 123, 111, 111, 64, 64, 64, - 64, 64, 64, 33, 33, 33, 64, 64, 64, 64, 64, 445, 445, 445, 445, 445, 445, - 274, 64, 445, 445, 26, 26, 64, 64, 64, 64, 445, 445, 445, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 274, 274, 697, 481, 481, 64, 64, 64, 64, 64, - 481, 481, 481, 64, 64, 64, 64, 64, 481, 64, 64, 64, 64, 64, 64, 64, 481, - 481, 64, 64, 64, 64, 64, 64, 26, 64, 64, 64, 64, 64, 64, 64, 26, 26, 26, - 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 64, 64, 64, 26, 26, 26, 26, 26, - 64, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 64, 26, 26, 26, 26, 64, 64, - 64, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, - 64, 64, 64, 64, 26, 26, 26, 489, 489, 489, 489, 489, 489, 488, 490, 490, - 490, 490, 490, 490, 490, 64, 64, 64, 405, 64, 64, 64, 64, 64, 64, 405, - 405, 405, 405, 405, 405, 405, 405, 561, 561, 561, 561, 561, 560, 64, 64, + 66, 66, 66, 66, 66, 415, 66, 66, 415, 66, 28, 35, 66, 66, 28, 35, 431, + 432, 431, 432, 431, 432, 431, 432, 66, 66, 66, 66, 66, 45, 66, 66, 415, + 415, 66, 66, 66, 66, 415, 66, 418, 64, 64, 64, 64, 64, 466, 466, 466, + 466, 466, 466, 466, 466, 466, 466, 64, 466, 466, 466, 466, 466, 466, 466, + 466, 466, 64, 64, 64, 64, 466, 466, 466, 466, 466, 466, 64, 64, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 64, 64, 64, 64, 468, + 469, 469, 469, 467, 470, 471, 472, 451, 452, 451, 452, 451, 452, 451, + 452, 451, 452, 467, 467, 451, 452, 451, 452, 451, 452, 451, 452, 473, + 474, 475, 475, 467, 472, 472, 472, 472, 472, 472, 472, 472, 472, 476, + 477, 478, 479, 480, 480, 473, 481, 481, 481, 481, 481, 467, 467, 472, + 472, 472, 470, 471, 469, 467, 26, 64, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, + 482, 64, 64, 483, 483, 484, 484, 485, 485, 482, 473, 486, 486, 486, 486, + 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, + 469, 481, 487, 487, 486, 64, 64, 64, 64, 64, 488, 488, 488, 488, 488, + 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 64, 64, 64, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 64, + 489, 489, 490, 490, 490, 490, 489, 489, 489, 489, 489, 489, 489, 489, + 489, 489, 488, 488, 488, 64, 64, 64, 64, 64, 491, 491, 491, 491, 491, + 491, 491, 491, 491, 491, 491, 491, 491, 492, 492, 64, 490, 490, 490, 490, + 490, 490, 490, 490, 490, 490, 489, 489, 489, 489, 489, 489, 493, 493, + 493, 493, 493, 493, 493, 493, 467, 494, 494, 494, 494, 494, 494, 494, + 494, 494, 494, 494, 494, 494, 494, 494, 491, 491, 491, 491, 492, 492, + 492, 489, 489, 494, 494, 494, 494, 494, 494, 494, 489, 489, 489, 489, + 467, 467, 467, 467, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, + 495, 495, 495, 495, 495, 64, 489, 489, 489, 489, 489, 489, 489, 467, 467, + 467, 467, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 467, + 467, 496, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 496, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 497, 497, 497, 497, 496, 498, 498, 498, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 500, 499, + 499, 499, 499, 499, 499, 499, 64, 64, 64, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 64, 502, 502, 502, 502, 502, + 502, 502, 502, 503, 503, 503, 503, 503, 503, 504, 504, 505, 505, 505, + 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 507, 507, 507, 508, + 508, 508, 508, 508, 508, 508, 508, 508, 508, 505, 505, 64, 64, 64, 64, + 72, 75, 72, 75, 72, 75, 509, 77, 79, 79, 79, 510, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 510, 511, 72, 75, 72, 75, 403, 403, 64, 77, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 514, 514, 515, 515, 515, 515, + 515, 515, 47, 47, 47, 47, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 47, 47, 37, 41, 37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 41, 44, 41, + 41, 41, 41, 41, 41, 41, 41, 37, 41, 37, 41, 37, 37, 41, 45, 516, 516, 37, + 41, 37, 41, 64, 37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 37, 37, 37, + 64, 64, 37, 37, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 42, + 44, 44, 41, 42, 42, 42, 42, 42, 517, 517, 518, 517, 517, 517, 519, 517, + 517, 517, 517, 518, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, + 517, 517, 517, 517, 517, 520, 520, 518, 518, 520, 521, 521, 521, 521, 64, + 64, 64, 64, 522, 522, 522, 522, 522, 522, 277, 277, 250, 444, 64, 64, 64, + 64, 64, 64, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, + 524, 524, 524, 524, 525, 525, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 525, 525, 525, 525, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 527, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 528, 528, 529, 529, 529, 529, 529, 529, 529, + 529, 529, 529, 64, 64, 64, 64, 64, 64, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 171, 171, 171, 171, 171, 171, 176, 176, 176, 171, 64, 64, + 64, 64, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 531, 531, 531, + 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, + 531, 531, 531, 532, 532, 532, 532, 532, 533, 533, 533, 84, 534, 535, 535, + 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 537, 538, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 539, 290, 290, 290, 290, 290, 64, 64, 64, + 540, 540, 540, 541, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, + 542, 542, 542, 542, 542, 543, 541, 541, 540, 540, 540, 540, 541, 541, + 540, 541, 541, 541, 544, 545, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 545, 64, 46, 546, 546, 546, 546, 546, 546, 546, 546, 546, + 546, 64, 64, 64, 64, 545, 545, 278, 278, 278, 278, 278, 280, 547, 278, + 283, 283, 278, 278, 278, 278, 278, 64, 548, 548, 548, 548, 548, 548, 548, + 548, 548, 549, 549, 549, 549, 549, 549, 550, 550, 549, 549, 550, 550, + 549, 549, 64, 548, 548, 548, 549, 548, 548, 548, 548, 548, 548, 548, 548, + 549, 550, 64, 64, 551, 551, 551, 551, 551, 551, 551, 551, 551, 551, 64, + 64, 552, 552, 552, 552, 547, 278, 278, 278, 278, 278, 278, 286, 286, 286, + 278, 279, 280, 279, 278, 278, 553, 553, 553, 553, 553, 553, 553, 553, + 554, 553, 554, 554, 555, 553, 553, 554, 554, 553, 553, 553, 553, 553, + 554, 554, 553, 554, 553, 64, 64, 64, 64, 64, 64, 64, 64, 553, 553, 556, + 557, 557, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 559, + 560, 560, 559, 559, 561, 561, 558, 562, 562, 559, 563, 64, 64, 292, 292, + 292, 292, 292, 292, 64, 41, 41, 41, 516, 44, 44, 44, 44, 64, 64, 64, 64, + 41, 62, 64, 64, 558, 558, 558, 559, 559, 560, 559, 559, 560, 559, 559, + 561, 559, 563, 64, 64, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, + 64, 64, 64, 64, 64, 64, 290, 565, 565, 565, 565, 565, 565, 565, 565, 565, + 565, 565, 565, 565, 565, 565, 565, 565, 565, 290, 64, 64, 64, 64, 291, + 291, 291, 291, 291, 291, 291, 64, 64, 64, 64, 291, 291, 291, 291, 291, + 291, 291, 291, 291, 64, 64, 64, 64, 566, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 566, 567, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 567, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 496, 498, 498, 496, 496, 498, 498, 498, 498, 498, 498, 41, 41, 41, 41, + 41, 41, 41, 64, 64, 64, 64, 83, 83, 83, 83, 83, 64, 64, 64, 64, 64, 110, + 569, 110, 110, 570, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 64, 110, 110, 110, 110, 110, 64, 110, 64, 110, 110, 64, + 110, 110, 64, 110, 110, 126, 126, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 572, 418, 64, + 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 116, 119, 64, 64, + 58, 58, 58, 58, 58, 58, 58, 58, 469, 469, 469, 469, 469, 469, 469, 474, + 475, 469, 64, 64, 64, 64, 64, 64, 78, 78, 78, 78, 78, 78, 78, 136, 136, + 136, 136, 136, 136, 136, 64, 64, 469, 473, 473, 573, 573, 474, 475, 474, + 475, 474, 475, 474, 475, 474, 475, 474, 475, 474, 475, 474, 475, 469, + 469, 474, 475, 469, 469, 469, 469, 573, 573, 573, 574, 469, 574, 64, 469, + 574, 469, 469, 473, 451, 452, 451, 452, 451, 452, 575, 469, 469, 576, + 577, 578, 578, 579, 64, 469, 580, 575, 469, 64, 64, 64, 64, 126, 126, + 126, 126, 126, 64, 126, 126, 126, 126, 126, 126, 126, 64, 64, 410, 64, + 581, 581, 582, 583, 582, 581, 581, 584, 585, 581, 586, 587, 588, 587, + 587, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 587, 581, 590, + 591, 590, 581, 581, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 592, 592, 592, 584, 581, 585, 593, 594, 593, + 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + 595, 595, 595, 595, 584, 591, 585, 591, 584, 585, 596, 597, 598, 596, + 596, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 600, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 600, 600, 601, + 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 64, + 64, 64, 601, 601, 601, 601, 601, 601, 64, 64, 601, 601, 601, 64, 64, 64, + 583, 583, 591, 593, 602, 583, 583, 64, 603, 604, 604, 604, 604, 603, 603, + 64, 64, 605, 605, 605, 26, 30, 64, 64, 606, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 606, 606, 64, 606, 606, 606, 606, 606, 606, 606, 606, 606, + 606, 64, 606, 606, 606, 64, 606, 606, 64, 606, 606, 606, 606, 606, 606, + 606, 64, 64, 606, 606, 606, 64, 64, 64, 64, 64, 84, 66, 84, 64, 64, 64, + 64, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 64, + 64, 64, 277, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, + 607, 608, 608, 608, 608, 609, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 608, 608, 609, 64, 64, 64, 26, + 26, 26, 26, 64, 64, 64, 64, 609, 64, 64, 64, 64, 64, 64, 64, 277, 277, + 277, 277, 277, 136, 64, 64, 610, 610, 610, 610, 610, 610, 610, 610, 610, + 610, 610, 610, 610, 64, 64, 64, 611, 611, 611, 611, 611, 611, 611, 611, + 611, 64, 64, 64, 64, 64, 64, 64, 136, 438, 438, 438, 438, 438, 438, 438, + 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 64, 64, 64, + 64, 612, 612, 612, 612, 612, 612, 612, 612, 613, 613, 613, 613, 64, 64, + 64, 64, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 614, 614, 614, + 614, 614, 614, 614, 614, 615, 64, 64, 64, 64, 64, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 617, 617, 617, + 617, 64, 64, 64, 64, 64, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, 64, 619, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 64, 64, 64, 64, 621, 622, 622, 622, 622, 622, 64, 64, + 623, 623, 623, 623, 623, 623, 623, 623, 624, 624, 624, 624, 624, 624, + 624, 624, 625, 625, 625, 625, 625, 625, 625, 625, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 64, 64, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 64, 64, 64, 64, 64, 64, 628, 628, 628, + 628, 628, 628, 628, 628, 629, 629, 629, 629, 629, 629, 629, 629, 629, + 629, 629, 629, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 630, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 64, 631, + 631, 631, 631, 631, 631, 64, 64, 632, 632, 632, 632, 632, 632, 64, 64, + 632, 64, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 64, 632, 632, 64, 64, 64, 632, 64, 64, + 632, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 64, 634, 635, 635, 635, 635, 635, 635, 635, 635, 636, 636, 636, 636, + 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 637, 638, + 638, 638, 638, 638, 638, 638, 639, 639, 639, 639, 639, 639, 639, 639, + 639, 639, 639, 639, 639, 639, 639, 64, 64, 64, 64, 64, 64, 64, 64, 640, + 640, 640, 640, 640, 640, 640, 640, 640, 641, 641, 641, 641, 641, 641, + 641, 641, 641, 641, 641, 641, 641, 641, 642, 642, 642, 642, 642, 642, 64, + 64, 64, 643, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 64, 64, + 64, 64, 64, 645, 646, 646, 646, 646, 646, 646, 646, 646, 647, 647, 647, + 647, 647, 647, 647, 647, 64, 64, 64, 64, 64, 64, 647, 647, 648, 649, 649, + 649, 64, 649, 649, 64, 64, 64, 64, 64, 649, 650, 649, 651, 648, 648, 648, + 648, 64, 648, 648, 648, 64, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 64, 64, 64, 64, 651, + 652, 650, 64, 64, 64, 64, 653, 654, 654, 654, 654, 654, 654, 654, 654, + 655, 655, 655, 655, 655, 655, 655, 655, 655, 64, 64, 64, 64, 64, 64, 64, + 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 657, + 657, 658, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, + 659, 660, 660, 660, 661, 661, 661, 661, 661, 661, 661, 661, 662, 661, + 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, 663, 664, 64, 64, + 64, 64, 665, 665, 665, 665, 665, 666, 666, 666, 666, 666, 666, 666, 64, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 64, + 64, 64, 668, 668, 668, 668, 668, 668, 668, 669, 669, 669, 669, 669, 669, + 669, 669, 669, 669, 669, 669, 669, 669, 64, 64, 670, 670, 670, 670, 670, + 670, 670, 670, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 64, + 64, 64, 64, 64, 672, 672, 672, 672, 672, 672, 672, 672, 673, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 64, 64, 64, 64, 64, 64, 64, 674, 674, + 674, 674, 64, 64, 64, 64, 675, 675, 675, 675, 675, 675, 675, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 64, 64, 64, 64, 64, 64, 64, 677, 677, + 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 64, 678, + 679, 678, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, + 680, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 681, 682, 682, 682, 682, 682, 682, 682, 64, 64, 64, 64, 683, 683, + 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, + 683, 683, 683, 683, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 64, + 64, 64, 64, 64, 64, 64, 681, 685, 685, 686, 687, 687, 687, 687, 687, 687, + 687, 687, 687, 687, 687, 687, 687, 686, 686, 686, 685, 685, 685, 685, + 686, 686, 688, 689, 690, 690, 691, 690, 690, 690, 690, 64, 64, 64, 64, + 64, 64, 692, 692, 692, 692, 692, 692, 692, 692, 692, 64, 64, 64, 64, 64, + 64, 64, 693, 693, 693, 693, 693, 693, 693, 693, 693, 693, 64, 64, 64, 64, + 64, 64, 694, 694, 694, 695, 695, 695, 695, 695, 695, 695, 695, 695, 695, + 695, 695, 695, 695, 695, 695, 695, 695, 695, 695, 696, 696, 696, 696, + 696, 697, 696, 696, 696, 696, 696, 696, 698, 698, 64, 699, 699, 699, 699, + 699, 699, 699, 699, 699, 699, 700, 700, 700, 700, 64, 64, 64, 64, 701, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 702, 703, 703, 701, 64, + 704, 704, 705, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, + 706, 706, 706, 706, 706, 705, 705, 705, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 705, 707, 706, 706, 706, 706, 708, 708, 708, 708, 64, 64, + 64, 64, 708, 64, 64, 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, + 706, 64, 64, 64, 64, 64, 64, 710, 710, 710, 710, 710, 710, 710, 710, 710, + 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 64, 64, 64, 711, + 711, 711, 711, 711, 711, 711, 711, 711, 711, 64, 711, 711, 711, 711, 711, + 711, 711, 711, 711, 712, 712, 712, 713, 713, 713, 712, 712, 713, 714, + 715, 713, 716, 716, 716, 716, 716, 716, 64, 64, 717, 717, 717, 717, 717, + 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 718, 719, 719, 719, + 718, 718, 718, 718, 718, 718, 720, 721, 64, 64, 64, 64, 64, 722, 722, + 722, 722, 722, 722, 722, 722, 722, 722, 64, 64, 64, 64, 64, 64, 64, 723, + 724, 724, 64, 725, 725, 725, 725, 725, 725, 725, 725, 64, 64, 725, 725, + 64, 64, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, + 725, 64, 725, 725, 725, 725, 725, 725, 725, 64, 725, 725, 64, 725, 725, + 725, 725, 725, 64, 64, 726, 725, 724, 724, 723, 724, 724, 724, 724, 64, + 64, 724, 724, 64, 64, 724, 724, 727, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 724, 64, 64, 64, 64, 64, 725, 725, 725, 725, 725, 724, 724, 64, 64, 728, + 728, 728, 728, 728, 728, 728, 64, 64, 64, 729, 729, 729, 729, 729, 729, + 729, 729, 730, 730, 730, 731, 731, 731, 731, 731, 731, 730, 731, 730, + 730, 730, 730, 731, 731, 730, 732, 733, 729, 729, 734, 729, 735, 735, + 735, 735, 735, 735, 735, 735, 735, 735, 64, 64, 64, 64, 64, 64, 736, 736, + 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 737, + 737, 737, 738, 738, 738, 738, 64, 64, 737, 737, 737, 737, 738, 738, 737, + 739, 740, 741, 741, 741, 741, 741, 741, 741, 741, 741, 64, 64, 64, 64, + 64, 64, 742, 742, 742, 742, 742, 742, 742, 742, 743, 743, 743, 744, 744, + 744, 744, 744, 744, 744, 744, 743, 743, 744, 743, 745, 744, 746, 746, + 746, 742, 64, 64, 64, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, + 64, 64, 64, 64, 64, 64, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 748, 749, 750, 749, 750, 750, 749, 749, 749, 749, 749, 749, 751, 752, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 64, 64, 64, 64, 64, 64, + 754, 754, 754, 754, 754, 754, 754, 754, 755, 755, 755, 755, 755, 755, + 755, 755, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 757, 757, + 757, 757, 757, 757, 757, 757, 757, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, 64, 64, 64, + 64, 64, 64, 64, 760, 760, 760, 760, 760, 760, 760, 760, 760, 64, 64, 64, + 64, 64, 64, 64, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 64, 762, 762, 762, 762, 762, 64, 64, 64, 763, 763, + 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 64, 512, + 64, 64, 64, 64, 64, 64, 64, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 64, 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 64, 64, 64, 64, 766, 766, 767, 767, 767, 767, 767, 767, 767, + 767, 767, 767, 767, 767, 767, 767, 64, 64, 768, 768, 768, 768, 768, 769, + 64, 64, 770, 770, 770, 770, 770, 770, 770, 770, 771, 771, 771, 771, 771, + 771, 771, 772, 772, 772, 772, 772, 773, 773, 773, 773, 774, 774, 774, + 774, 772, 773, 64, 64, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 64, 776, 776, 776, 776, 776, 776, 776, 64, 770, 770, 770, 770, 770, 64, + 64, 64, 64, 64, 770, 770, 770, 777, 777, 777, 777, 777, 777, 777, 777, + 777, 777, 777, 777, 777, 64, 64, 64, 777, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 64, 64, 64, 64, 64, 64, 64, 64, 779, 779, 779, 779, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 486, 482, 64, 64, + 64, 64, 64, 64, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, + 64, 64, 64, 64, 64, 781, 781, 781, 781, 781, 64, 64, 64, 781, 64, 64, 64, + 64, 64, 64, 64, 781, 781, 64, 64, 782, 783, 784, 785, 410, 410, 410, 410, + 64, 64, 64, 64, 277, 277, 277, 277, 277, 277, 64, 64, 277, 277, 277, 277, + 277, 277, 277, 64, 64, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 786, 786, 400, 400, 400, 277, 277, 277, 787, 786, 786, 786, + 786, 786, 410, 410, 410, 410, 410, 410, 410, 410, 136, 136, 136, 136, + 136, 136, 136, 136, 277, 277, 78, 78, 78, 78, 78, 136, 136, 277, 277, + 277, 277, 277, 277, 78, 78, 78, 78, 277, 277, 609, 609, 788, 788, 788, + 609, 64, 64, 522, 522, 64, 64, 64, 64, 64, 64, 442, 442, 442, 442, 442, + 442, 442, 442, 442, 442, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, + 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, 34, 34, 442, 64, 442, + 442, 64, 64, 442, 64, 64, 442, 442, 64, 64, 442, 442, 442, 442, 64, 442, + 442, 34, 34, 64, 34, 64, 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, + 34, 34, 34, 442, 442, 64, 442, 442, 442, 442, 64, 64, 442, 442, 442, 442, + 442, 442, 442, 442, 64, 442, 442, 442, 442, 442, 442, 442, 64, 34, 34, + 442, 442, 64, 442, 442, 442, 442, 64, 442, 442, 442, 442, 442, 64, 442, + 64, 64, 64, 442, 442, 442, 442, 442, 442, 442, 64, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 64, 64, 442, 789, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 445, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, + 442, 442, 789, 34, 34, 34, 34, 34, 34, 34, 34, 34, 445, 34, 34, 442, 442, + 442, 442, 442, 789, 34, 34, 34, 34, 34, 34, 34, 34, 34, 445, 34, 34, 34, + 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, 442, 442, 789, 34, 445, + 34, 34, 34, 34, 34, 34, 34, 34, 442, 34, 64, 64, 790, 790, 790, 790, 790, + 790, 790, 790, 790, 790, 791, 791, 791, 791, 791, 791, 791, 791, 791, + 791, 791, 791, 791, 64, 64, 792, 792, 792, 792, 792, 792, 792, 792, 792, + 793, 793, 793, 793, 793, 793, 793, 64, 126, 126, 126, 126, 64, 126, 126, + 126, 64, 126, 126, 64, 126, 64, 64, 126, 64, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 64, 126, 126, 126, 126, 64, 126, 64, 126, 64, + 64, 64, 64, 64, 64, 126, 64, 64, 64, 64, 126, 64, 126, 64, 126, 64, 126, + 126, 126, 64, 126, 64, 126, 64, 126, 64, 126, 64, 126, 126, 126, 126, 64, + 126, 64, 126, 126, 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 64, + 64, 64, 64, 64, 126, 126, 126, 64, 126, 126, 126, 113, 113, 64, 64, 64, + 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, 26, 33, 33, 33, 446, 446, 64, 64, + 64, 453, 453, 453, 453, 453, 453, 277, 64, 453, 453, 26, 26, 64, 64, 64, + 64, 453, 453, 453, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 277, 277, + 794, 489, 489, 64, 64, 64, 64, 64, 489, 489, 489, 64, 64, 64, 64, 64, + 489, 64, 64, 64, 64, 64, 64, 64, 489, 489, 64, 64, 64, 64, 64, 64, 26, + 26, 26, 26, 26, 64, 64, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, 64, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 64, 64, + 26, 26, 26, 497, 497, 497, 497, 497, 497, 496, 498, 498, 498, 498, 498, + 498, 498, 64, 64, 64, 410, 64, 64, 64, 64, 64, 64, 410, 410, 410, 410, + 410, 410, 410, 410, 568, 568, 568, 568, 568, 567, 64, 64, }; /* decomposition data */ @@ -3107,84 +3339,85 @@ static const unsigned short decomp_data[] = { 50, 49, 26085, 770, 50, 50, 26085, 770, 50, 51, 26085, 770, 50, 52, 26085, 770, 50, 53, 26085, 770, 50, 54, 26085, 770, 50, 55, 26085, 770, 50, 56, 26085, 770, 50, 57, 26085, 770, 51, 48, 26085, 770, 51, 49, - 26085, 778, 103, 97, 108, 259, 42863, 259, 294, 259, 339, 256, 35912, - 256, 26356, 256, 36554, 256, 36040, 256, 28369, 256, 20018, 256, 21477, - 256, 40860, 256, 40860, 256, 22865, 256, 37329, 256, 21895, 256, 22856, - 256, 25078, 256, 30313, 256, 32645, 256, 34367, 256, 34746, 256, 35064, - 256, 37007, 256, 27138, 256, 27931, 256, 28889, 256, 29662, 256, 33853, - 256, 37226, 256, 39409, 256, 20098, 256, 21365, 256, 27396, 256, 29211, - 256, 34349, 256, 40478, 256, 23888, 256, 28651, 256, 34253, 256, 35172, - 256, 25289, 256, 33240, 256, 34847, 256, 24266, 256, 26391, 256, 28010, - 256, 29436, 256, 37070, 256, 20358, 256, 20919, 256, 21214, 256, 25796, - 256, 27347, 256, 29200, 256, 30439, 256, 32769, 256, 34310, 256, 34396, - 256, 36335, 256, 38706, 256, 39791, 256, 40442, 256, 30860, 256, 31103, - 256, 32160, 256, 33737, 256, 37636, 256, 40575, 256, 35542, 256, 22751, - 256, 24324, 256, 31840, 256, 32894, 256, 29282, 256, 30922, 256, 36034, - 256, 38647, 256, 22744, 256, 23650, 256, 27155, 256, 28122, 256, 28431, - 256, 32047, 256, 32311, 256, 38475, 256, 21202, 256, 32907, 256, 20956, - 256, 20940, 256, 31260, 256, 32190, 256, 33777, 256, 38517, 256, 35712, - 256, 25295, 256, 27138, 256, 35582, 256, 20025, 256, 23527, 256, 24594, - 256, 29575, 256, 30064, 256, 21271, 256, 30971, 256, 20415, 256, 24489, - 256, 19981, 256, 27852, 256, 25976, 256, 32034, 256, 21443, 256, 22622, - 256, 30465, 256, 33865, 256, 35498, 256, 27578, 256, 36784, 256, 27784, - 256, 25342, 256, 33509, 256, 25504, 256, 30053, 256, 20142, 256, 20841, - 256, 20937, 256, 26753, 256, 31975, 256, 33391, 256, 35538, 256, 37327, - 256, 21237, 256, 21570, 256, 22899, 256, 24300, 256, 26053, 256, 28670, - 256, 31018, 256, 38317, 256, 39530, 256, 40599, 256, 40654, 256, 21147, - 256, 26310, 256, 27511, 256, 36706, 256, 24180, 256, 24976, 256, 25088, - 256, 25754, 256, 28451, 256, 29001, 256, 29833, 256, 31178, 256, 32244, - 256, 32879, 256, 36646, 256, 34030, 256, 36899, 256, 37706, 256, 21015, - 256, 21155, 256, 21693, 256, 28872, 256, 35010, 256, 35498, 256, 24265, - 256, 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, 20196, - 256, 22265, 256, 23527, 256, 23994, 256, 24604, 256, 29618, 256, 29801, - 256, 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, - 256, 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, - 256, 20698, 256, 23534, 256, 23615, 256, 26009, 256, 27138, 256, 29134, - 256, 30274, 256, 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, - 256, 21129, 256, 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, - 256, 30041, 256, 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, - 256, 38520, 256, 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, - 256, 24900, 256, 26647, 256, 29575, 256, 38534, 256, 21033, 256, 21519, - 256, 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, - 256, 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, - 256, 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, - 256, 38563, 256, 40023, 256, 40607, 256, 26519, 256, 28107, 256, 33256, - 256, 31435, 256, 31520, 256, 31890, 256, 29376, 256, 28825, 256, 35672, - 256, 20160, 256, 33590, 256, 21050, 256, 20999, 256, 24230, 256, 25299, - 256, 31958, 256, 23429, 256, 27934, 256, 26292, 256, 36667, 256, 34892, - 256, 38477, 256, 35211, 256, 24275, 256, 20800, 256, 21952, 256, 22618, - 256, 26228, 256, 20958, 256, 29482, 256, 30410, 256, 31036, 256, 31070, - 256, 31077, 256, 31119, 256, 38742, 256, 31934, 256, 32701, 256, 34322, - 256, 35576, 256, 36920, 256, 37117, 256, 39151, 256, 39164, 256, 39208, - 256, 40372, 256, 37086, 256, 38583, 256, 20398, 256, 20711, 256, 20813, - 256, 21193, 256, 21220, 256, 21329, 256, 21917, 256, 22022, 256, 22120, - 256, 22592, 256, 22696, 256, 23652, 256, 23662, 256, 24724, 256, 24936, - 256, 24974, 256, 25074, 256, 25935, 256, 26082, 256, 26257, 256, 26757, - 256, 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, - 256, 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, - 256, 31069, 256, 31117, 256, 31118, 256, 31296, 256, 31361, 256, 31680, - 256, 32244, 256, 32265, 256, 32321, 256, 32626, 256, 32773, 256, 33261, - 256, 33401, 256, 33401, 256, 33879, 256, 35088, 256, 35222, 256, 35585, - 256, 35641, 256, 36051, 256, 36104, 256, 36790, 256, 36920, 256, 38627, - 256, 38911, 256, 38971, 256, 24693, 256, 55376, 57070, 256, 33304, 256, - 20006, 256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, - 21191, 256, 21242, 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, - 22618, 256, 22707, 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, - 24274, 256, 24281, 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, - 24840, 256, 24974, 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, - 25628, 256, 25682, 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, - 26454, 256, 27513, 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, - 28450, 256, 28702, 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, - 29482, 256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, - 30410, 256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, - 31409, 256, 31680, 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, - 32773, 256, 33618, 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, - 35222, 256, 35519, 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, - 35565, 256, 35641, 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, - 37273, 256, 37494, 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, - 38911, 256, 38923, 256, 38971, 256, 39698, 256, 40860, 256, 55370, 56394, - 256, 55370, 56388, 256, 55372, 57301, 256, 15261, 256, 16408, 256, 16441, - 256, 55380, 56905, 256, 55383, 56528, 256, 55391, 57043, 256, 40771, 256, + 26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, 294, + 259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 256, 35912, 256, + 26356, 256, 36554, 256, 36040, 256, 28369, 256, 20018, 256, 21477, 256, + 40860, 256, 40860, 256, 22865, 256, 37329, 256, 21895, 256, 22856, 256, + 25078, 256, 30313, 256, 32645, 256, 34367, 256, 34746, 256, 35064, 256, + 37007, 256, 27138, 256, 27931, 256, 28889, 256, 29662, 256, 33853, 256, + 37226, 256, 39409, 256, 20098, 256, 21365, 256, 27396, 256, 29211, 256, + 34349, 256, 40478, 256, 23888, 256, 28651, 256, 34253, 256, 35172, 256, + 25289, 256, 33240, 256, 34847, 256, 24266, 256, 26391, 256, 28010, 256, + 29436, 256, 37070, 256, 20358, 256, 20919, 256, 21214, 256, 25796, 256, + 27347, 256, 29200, 256, 30439, 256, 32769, 256, 34310, 256, 34396, 256, + 36335, 256, 38706, 256, 39791, 256, 40442, 256, 30860, 256, 31103, 256, + 32160, 256, 33737, 256, 37636, 256, 40575, 256, 35542, 256, 22751, 256, + 24324, 256, 31840, 256, 32894, 256, 29282, 256, 30922, 256, 36034, 256, + 38647, 256, 22744, 256, 23650, 256, 27155, 256, 28122, 256, 28431, 256, + 32047, 256, 32311, 256, 38475, 256, 21202, 256, 32907, 256, 20956, 256, + 20940, 256, 31260, 256, 32190, 256, 33777, 256, 38517, 256, 35712, 256, + 25295, 256, 27138, 256, 35582, 256, 20025, 256, 23527, 256, 24594, 256, + 29575, 256, 30064, 256, 21271, 256, 30971, 256, 20415, 256, 24489, 256, + 19981, 256, 27852, 256, 25976, 256, 32034, 256, 21443, 256, 22622, 256, + 30465, 256, 33865, 256, 35498, 256, 27578, 256, 36784, 256, 27784, 256, + 25342, 256, 33509, 256, 25504, 256, 30053, 256, 20142, 256, 20841, 256, + 20937, 256, 26753, 256, 31975, 256, 33391, 256, 35538, 256, 37327, 256, + 21237, 256, 21570, 256, 22899, 256, 24300, 256, 26053, 256, 28670, 256, + 31018, 256, 38317, 256, 39530, 256, 40599, 256, 40654, 256, 21147, 256, + 26310, 256, 27511, 256, 36706, 256, 24180, 256, 24976, 256, 25088, 256, + 25754, 256, 28451, 256, 29001, 256, 29833, 256, 31178, 256, 32244, 256, + 32879, 256, 36646, 256, 34030, 256, 36899, 256, 37706, 256, 21015, 256, + 21155, 256, 21693, 256, 28872, 256, 35010, 256, 35498, 256, 24265, 256, + 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, 20196, 256, + 22265, 256, 23527, 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, + 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, + 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, + 20698, 256, 23534, 256, 23615, 256, 26009, 256, 27138, 256, 29134, 256, + 30274, 256, 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, + 21129, 256, 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, + 30041, 256, 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, + 38520, 256, 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, + 24900, 256, 26647, 256, 29575, 256, 38534, 256, 21033, 256, 21519, 256, + 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, + 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, + 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, + 38563, 256, 40023, 256, 40607, 256, 26519, 256, 28107, 256, 33256, 256, + 31435, 256, 31520, 256, 31890, 256, 29376, 256, 28825, 256, 35672, 256, + 20160, 256, 33590, 256, 21050, 256, 20999, 256, 24230, 256, 25299, 256, + 31958, 256, 23429, 256, 27934, 256, 26292, 256, 36667, 256, 34892, 256, + 38477, 256, 35211, 256, 24275, 256, 20800, 256, 21952, 256, 22618, 256, + 26228, 256, 20958, 256, 29482, 256, 30410, 256, 31036, 256, 31070, 256, + 31077, 256, 31119, 256, 38742, 256, 31934, 256, 32701, 256, 34322, 256, + 35576, 256, 36920, 256, 37117, 256, 39151, 256, 39164, 256, 39208, 256, + 40372, 256, 37086, 256, 38583, 256, 20398, 256, 20711, 256, 20813, 256, + 21193, 256, 21220, 256, 21329, 256, 21917, 256, 22022, 256, 22120, 256, + 22592, 256, 22696, 256, 23652, 256, 23662, 256, 24724, 256, 24936, 256, + 24974, 256, 25074, 256, 25935, 256, 26082, 256, 26257, 256, 26757, 256, + 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, 256, + 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, 256, + 31069, 256, 31117, 256, 31118, 256, 31296, 256, 31361, 256, 31680, 256, + 32244, 256, 32265, 256, 32321, 256, 32626, 256, 32773, 256, 33261, 256, + 33401, 256, 33401, 256, 33879, 256, 35088, 256, 35222, 256, 35585, 256, + 35641, 256, 36051, 256, 36104, 256, 36790, 256, 36920, 256, 38627, 256, + 38911, 256, 38971, 256, 24693, 256, 55376, 57070, 256, 33304, 256, 20006, + 256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191, + 256, 21242, 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618, + 256, 22707, 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, + 256, 24281, 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, + 256, 24974, 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628, + 256, 25682, 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454, + 256, 27513, 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450, + 256, 28702, 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482, + 256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410, + 256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409, + 256, 31680, 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773, + 256, 33618, 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222, + 256, 35519, 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565, + 256, 35641, 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273, + 256, 37494, 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911, + 256, 38923, 256, 38971, 256, 39698, 256, 40860, 256, 55370, 56394, 256, + 55370, 56388, 256, 55372, 57301, 256, 15261, 256, 16408, 256, 16441, 256, + 55380, 56905, 256, 55383, 56528, 256, 55391, 57043, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 102, 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 115, 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 1398, 514, 1396, 1389, 512, 1497, @@ -3409,54 +3642,64 @@ static const unsigned short decomp_data[] = { 8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, 9675, 512, 55300, 56473, 55300, 56506, 512, 55300, 56475, 55300, 56506, 512, 55300, 56485, 55300, 56506, 512, 55300, 56625, 55300, 56615, 512, 55300, 56626, 55300, - 56615, 512, 55348, 56663, 55348, 56677, 512, 55348, 56664, 55348, 56677, - 512, 55348, 56671, 55348, 56686, 512, 55348, 56671, 55348, 56687, 512, - 55348, 56671, 55348, 56688, 512, 55348, 56671, 55348, 56689, 512, 55348, - 56671, 55348, 56690, 512, 55348, 56761, 55348, 56677, 512, 55348, 56762, - 55348, 56677, 512, 55348, 56763, 55348, 56686, 512, 55348, 56764, 55348, - 56686, 512, 55348, 56763, 55348, 56687, 512, 55348, 56764, 55348, 56687, - 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, - 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, - 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, - 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, - 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, - 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, - 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, - 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, - 103, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, + 56615, 512, 55300, 57159, 55300, 57150, 512, 55300, 57159, 55300, 57175, + 512, 55301, 56505, 55301, 56506, 512, 55301, 56505, 55301, 56496, 512, + 55301, 56505, 55301, 56509, 512, 55301, 56760, 55301, 56751, 512, 55301, + 56761, 55301, 56751, 512, 55348, 56663, 55348, 56677, 512, 55348, 56664, + 55348, 56677, 512, 55348, 56671, 55348, 56686, 512, 55348, 56671, 55348, + 56687, 512, 55348, 56671, 55348, 56688, 512, 55348, 56671, 55348, 56689, + 512, 55348, 56671, 55348, 56690, 512, 55348, 56761, 55348, 56677, 512, + 55348, 56762, 55348, 56677, 512, 55348, 56763, 55348, 56686, 512, 55348, + 56764, 55348, 56686, 512, 55348, 56763, 55348, 56687, 512, 55348, 56764, + 55348, 56687, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, + 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, + 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, + 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, + 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, + 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, + 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, + 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, + 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, + 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, + 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, + 102, 262, 103, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, + 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, + 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, + 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, + 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, + 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, + 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, + 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, - 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, - 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, + 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 67, 262, 68, + 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, - 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, - 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 67, 262, 68, 262, 71, - 262, 74, 262, 75, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 102, 262, 104, 262, 105, 262, 106, 262, 107, 262, - 108, 262, 109, 262, 110, 262, 112, 262, 113, 262, 114, 262, 115, 262, + 262, 98, 262, 99, 262, 100, 262, 102, 262, 104, 262, 105, 262, 106, 262, + 107, 262, 108, 262, 109, 262, 110, 262, 112, 262, 113, 262, 114, 262, + 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, + 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, + 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, + 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, + 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, + 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, + 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, - 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, - 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, - 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, - 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, - 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, - 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, - 262, 68, 262, 69, 262, 70, 262, 71, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, - 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 73, 262, 74, - 262, 75, 262, 76, 262, 77, 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, - 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, + 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 74, 262, 75, 262, 76, + 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, + 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, + 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, + 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, + 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, + 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 73, + 262, 74, 262, 75, 262, 76, 262, 77, 262, 79, 262, 83, 262, 84, 262, 85, + 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, + 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, + 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, + 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, + 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, + 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, + 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, + 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, @@ -3494,153 +3737,146 @@ static const unsigned short decomp_data[] = { 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, - 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, - 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, - 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, - 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, - 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, - 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, 262, 914, 262, 915, - 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, - 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, - 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, - 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, - 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, - 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, - 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, - 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, - 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, - 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, - 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, - 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, - 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, - 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, - 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, - 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, - 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, - 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, - 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, - 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, - 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, - 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, - 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, - 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, - 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, - 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, - 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, - 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, - 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, - 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, - 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, - 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, - 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, - 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, - 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, - 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, - 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, - 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, - 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, - 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, - 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, - 262, 988, 262, 989, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, - 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, - 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, - 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, - 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, - 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, - 262, 54, 262, 55, 262, 56, 262, 57, 262, 1575, 262, 1576, 262, 1580, 262, - 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1603, - 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, - 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, - 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1722, 262, - 1697, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 262, 1610, + 120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, 262, 914, 262, + 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, + 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, + 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, + 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, + 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, + 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, + 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, + 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, + 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, + 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, + 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, + 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, + 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, + 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, + 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, + 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, + 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, + 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, + 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, + 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, + 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, + 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, + 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, + 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, + 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, + 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, + 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, + 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, + 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, + 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, + 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, + 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, + 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, + 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, + 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, + 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, + 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, + 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, + 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, + 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, + 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, + 982, 262, 988, 262, 989, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, + 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, + 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, + 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, + 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, + 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, + 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 1575, 262, 1576, 262, + 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, - 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 262, 1582, - 262, 1590, 262, 1594, 262, 1580, 262, 1581, 262, 1610, 262, 1604, 262, - 1606, 262, 1587, 262, 1593, 262, 1589, 262, 1602, 262, 1588, 262, 1582, - 262, 1590, 262, 1594, 262, 1722, 262, 1647, 262, 1576, 262, 1580, 262, - 1607, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1605, 262, 1606, - 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, - 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1592, 262, 1594, 262, 1646, - 262, 1697, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1607, 262, + 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, + 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, + 1722, 262, 1697, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, + 262, 1610, 262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, + 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, + 262, 1582, 262, 1590, 262, 1594, 262, 1580, 262, 1581, 262, 1610, 262, + 1604, 262, 1606, 262, 1587, 262, 1593, 262, 1589, 262, 1602, 262, 1588, + 262, 1582, 262, 1590, 262, 1594, 262, 1722, 262, 1647, 262, 1576, 262, + 1580, 262, 1607, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1605, + 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, + 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1592, 262, 1594, + 262, 1646, 262, 1697, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, + 1607, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1604, + 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, + 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, + 262, 1590, 262, 1592, 262, 1594, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, - 262, 1592, 262, 1594, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, - 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, - 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, - 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, - 262, 1594, 514, 48, 46, 514, 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, - 44, 514, 52, 44, 514, 53, 44, 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, - 57, 44, 770, 40, 65, 41, 770, 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, - 41, 770, 40, 69, 41, 770, 40, 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, - 770, 40, 73, 41, 770, 40, 74, 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, - 40, 77, 41, 770, 40, 78, 41, 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, - 81, 41, 770, 40, 82, 41, 770, 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, - 41, 770, 40, 86, 41, 770, 40, 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, - 770, 40, 90, 41, 770, 12308, 83, 12309, 263, 67, 263, 82, 519, 67, 68, - 519, 87, 90, 266, 65, 266, 66, 266, 67, 266, 68, 266, 69, 266, 70, 266, - 71, 266, 72, 266, 73, 266, 74, 266, 75, 266, 76, 266, 77, 266, 78, 266, - 79, 266, 80, 266, 81, 266, 82, 266, 83, 266, 84, 266, 85, 266, 86, 266, - 87, 266, 88, 266, 89, 266, 90, 522, 72, 86, 522, 77, 86, 522, 83, 68, - 522, 83, 83, 778, 80, 80, 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 522, - 68, 74, 522, 12411, 12363, 522, 12467, 12467, 266, 12469, 266, 25163, - 266, 23383, 266, 21452, 266, 12487, 266, 20108, 266, 22810, 266, 35299, - 266, 22825, 266, 20132, 266, 26144, 266, 28961, 266, 26009, 266, 21069, - 266, 24460, 266, 20877, 266, 26032, 266, 21021, 266, 32066, 266, 29983, - 266, 36009, 266, 22768, 266, 21561, 266, 28436, 266, 25237, 266, 25429, - 266, 19968, 266, 19977, 266, 36938, 266, 24038, 266, 20013, 266, 21491, - 266, 25351, 266, 36208, 266, 25171, 266, 31105, 266, 31354, 266, 21512, - 266, 28288, 266, 26377, 266, 26376, 266, 30003, 266, 21106, 266, 21942, - 770, 12308, 26412, 12309, 770, 12308, 19977, 12309, 770, 12308, 20108, - 12309, 770, 12308, 23433, 12309, 770, 12308, 28857, 12309, 770, 12308, - 25171, 12309, 770, 12308, 30423, 12309, 770, 12308, 21213, 12309, 770, - 12308, 25943, 12309, 263, 24471, 263, 21487, 256, 20029, 256, 20024, 256, - 20033, 256, 55360, 56610, 256, 20320, 256, 20398, 256, 20411, 256, 20482, - 256, 20602, 256, 20633, 256, 20711, 256, 20687, 256, 13470, 256, 55361, - 56890, 256, 20813, 256, 20820, 256, 20836, 256, 20855, 256, 55361, 56604, - 256, 13497, 256, 20839, 256, 20877, 256, 55361, 56651, 256, 20887, 256, - 20900, 256, 20172, 256, 20908, 256, 20917, 256, 55396, 56799, 256, 20981, - 256, 20995, 256, 13535, 256, 21051, 256, 21062, 256, 21106, 256, 21111, - 256, 13589, 256, 21191, 256, 21193, 256, 21220, 256, 21242, 256, 21253, - 256, 21254, 256, 21271, 256, 21321, 256, 21329, 256, 21338, 256, 21363, - 256, 21373, 256, 21375, 256, 21375, 256, 21375, 256, 55362, 56876, 256, - 28784, 256, 21450, 256, 21471, 256, 55362, 57187, 256, 21483, 256, 21489, - 256, 21510, 256, 21662, 256, 21560, 256, 21576, 256, 21608, 256, 21666, - 256, 21750, 256, 21776, 256, 21843, 256, 21859, 256, 21892, 256, 21892, - 256, 21913, 256, 21931, 256, 21939, 256, 21954, 256, 22294, 256, 22022, - 256, 22295, 256, 22097, 256, 22132, 256, 20999, 256, 22766, 256, 22478, - 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, 256, 22700, - 256, 55365, 56548, 256, 22770, 256, 22775, 256, 22790, 256, 22810, 256, - 22818, 256, 22882, 256, 55365, 57000, 256, 55365, 57066, 256, 23020, 256, - 23067, 256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, 256, - 23304, 256, 23358, 256, 23358, 256, 55366, 56776, 256, 23491, 256, 23512, - 256, 23527, 256, 23539, 256, 55366, 57112, 256, 23551, 256, 23558, 256, - 24403, 256, 23586, 256, 14209, 256, 23648, 256, 23662, 256, 23744, 256, - 23693, 256, 55367, 56804, 256, 23875, 256, 55367, 56806, 256, 23918, 256, - 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061, 256, - 24104, 256, 24125, 256, 24169, 256, 14434, 256, 55368, 56707, 256, 14460, - 256, 24240, 256, 24243, 256, 24246, 256, 24266, 256, 55400, 57234, 256, - 24318, 256, 55368, 57137, 256, 55368, 57137, 256, 33281, 256, 24354, 256, - 24354, 256, 14535, 256, 55372, 57016, 256, 55384, 56794, 256, 24418, 256, - 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569, 256, - 24705, 256, 14650, 256, 14620, 256, 24724, 256, 55369, 57044, 256, 24775, - 256, 24904, 256, 24908, 256, 24910, 256, 24908, 256, 24954, 256, 24974, - 256, 25010, 256, 24996, 256, 25007, 256, 25054, 256, 25074, 256, 25078, - 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, 25424, - 256, 55370, 57100, 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256, - 25572, 256, 55370, 57329, 256, 25634, 256, 25541, 256, 25513, 256, 14894, - 256, 25705, 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, 25935, - 256, 25964, 256, 55372, 56330, 256, 26083, 256, 26360, 256, 26185, 256, - 15129, 256, 26257, 256, 15112, 256, 15076, 256, 20882, 256, 20885, 256, - 26368, 256, 26268, 256, 32941, 256, 17369, 256, 26391, 256, 26395, 256, - 26401, 256, 26462, 256, 26451, 256, 55372, 57283, 256, 15177, 256, 26618, - 256, 26501, 256, 26706, 256, 26757, 256, 55373, 56429, 256, 26766, 256, - 26655, 256, 26900, 256, 15261, 256, 26946, 256, 27043, 256, 27114, 256, - 27304, 256, 55373, 56995, 256, 27355, 256, 15384, 256, 27425, 256, 55374, - 56487, 256, 27476, 256, 15438, 256, 27506, 256, 27551, 256, 27578, 256, - 27579, 256, 55374, 56973, 256, 55367, 56587, 256, 55374, 57082, 256, + 262, 1592, 262, 1594, 514, 48, 46, 514, 48, 44, 514, 49, 44, 514, 50, 44, + 514, 51, 44, 514, 52, 44, 514, 53, 44, 514, 54, 44, 514, 55, 44, 514, 56, + 44, 514, 57, 44, 770, 40, 65, 41, 770, 40, 66, 41, 770, 40, 67, 41, 770, + 40, 68, 41, 770, 40, 69, 41, 770, 40, 70, 41, 770, 40, 71, 41, 770, 40, + 72, 41, 770, 40, 73, 41, 770, 40, 74, 41, 770, 40, 75, 41, 770, 40, 76, + 41, 770, 40, 77, 41, 770, 40, 78, 41, 770, 40, 79, 41, 770, 40, 80, 41, + 770, 40, 81, 41, 770, 40, 82, 41, 770, 40, 83, 41, 770, 40, 84, 41, 770, + 40, 85, 41, 770, 40, 86, 41, 770, 40, 87, 41, 770, 40, 88, 41, 770, 40, + 89, 41, 770, 40, 90, 41, 770, 12308, 83, 12309, 263, 67, 263, 82, 519, + 67, 68, 519, 87, 90, 266, 65, 266, 66, 266, 67, 266, 68, 266, 69, 266, + 70, 266, 71, 266, 72, 266, 73, 266, 74, 266, 75, 266, 76, 266, 77, 266, + 78, 266, 79, 266, 80, 266, 81, 266, 82, 266, 83, 266, 84, 266, 85, 266, + 86, 266, 87, 266, 88, 266, 89, 266, 90, 522, 72, 86, 522, 77, 86, 522, + 83, 68, 522, 83, 83, 778, 80, 80, 86, 522, 87, 67, 515, 77, 67, 515, 77, + 68, 522, 68, 74, 522, 12411, 12363, 522, 12467, 12467, 266, 12469, 266, + 25163, 266, 23383, 266, 21452, 266, 12487, 266, 20108, 266, 22810, 266, + 35299, 266, 22825, 266, 20132, 266, 26144, 266, 28961, 266, 26009, 266, + 21069, 266, 24460, 266, 20877, 266, 26032, 266, 21021, 266, 32066, 266, + 29983, 266, 36009, 266, 22768, 266, 21561, 266, 28436, 266, 25237, 266, + 25429, 266, 19968, 266, 19977, 266, 36938, 266, 24038, 266, 20013, 266, + 21491, 266, 25351, 266, 36208, 266, 25171, 266, 31105, 266, 31354, 266, + 21512, 266, 28288, 266, 26377, 266, 26376, 266, 30003, 266, 21106, 266, + 21942, 770, 12308, 26412, 12309, 770, 12308, 19977, 12309, 770, 12308, + 20108, 12309, 770, 12308, 23433, 12309, 770, 12308, 28857, 12309, 770, + 12308, 25171, 12309, 770, 12308, 30423, 12309, 770, 12308, 21213, 12309, + 770, 12308, 25943, 12309, 263, 24471, 263, 21487, 256, 20029, 256, 20024, + 256, 20033, 256, 55360, 56610, 256, 20320, 256, 20398, 256, 20411, 256, + 20482, 256, 20602, 256, 20633, 256, 20711, 256, 20687, 256, 13470, 256, + 55361, 56890, 256, 20813, 256, 20820, 256, 20836, 256, 20855, 256, 55361, + 56604, 256, 13497, 256, 20839, 256, 20877, 256, 55361, 56651, 256, 20887, + 256, 20900, 256, 20172, 256, 20908, 256, 20917, 256, 55396, 56799, 256, + 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, 256, 21106, 256, + 21111, 256, 13589, 256, 21191, 256, 21193, 256, 21220, 256, 21242, 256, + 21253, 256, 21254, 256, 21271, 256, 21321, 256, 21329, 256, 21338, 256, + 21363, 256, 21373, 256, 21375, 256, 21375, 256, 21375, 256, 55362, 56876, + 256, 28784, 256, 21450, 256, 21471, 256, 55362, 57187, 256, 21483, 256, + 21489, 256, 21510, 256, 21662, 256, 21560, 256, 21576, 256, 21608, 256, + 21666, 256, 21750, 256, 21776, 256, 21843, 256, 21859, 256, 21892, 256, + 21892, 256, 21913, 256, 21931, 256, 21939, 256, 21954, 256, 22294, 256, + 22022, 256, 22295, 256, 22097, 256, 22132, 256, 20999, 256, 22766, 256, + 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, 256, + 22700, 256, 55365, 56548, 256, 22770, 256, 22775, 256, 22790, 256, 22810, + 256, 22818, 256, 22882, 256, 55365, 57000, 256, 55365, 57066, 256, 23020, + 256, 23067, 256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, + 256, 23304, 256, 23358, 256, 23358, 256, 55366, 56776, 256, 23491, 256, + 23512, 256, 23527, 256, 23539, 256, 55366, 57112, 256, 23551, 256, 23558, + 256, 24403, 256, 23586, 256, 14209, 256, 23648, 256, 23662, 256, 23744, + 256, 23693, 256, 55367, 56804, 256, 23875, 256, 55367, 56806, 256, 23918, + 256, 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061, + 256, 24104, 256, 24125, 256, 24169, 256, 14434, 256, 55368, 56707, 256, + 14460, 256, 24240, 256, 24243, 256, 24246, 256, 24266, 256, 55400, 57234, + 256, 24318, 256, 55368, 57137, 256, 55368, 57137, 256, 33281, 256, 24354, + 256, 24354, 256, 14535, 256, 55372, 57016, 256, 55384, 56794, 256, 24418, + 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569, + 256, 24705, 256, 14650, 256, 14620, 256, 24724, 256, 55369, 57044, 256, + 24775, 256, 24904, 256, 24908, 256, 24910, 256, 24908, 256, 24954, 256, + 24974, 256, 25010, 256, 24996, 256, 25007, 256, 25054, 256, 25074, 256, + 25078, 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, + 25424, 256, 55370, 57100, 256, 25405, 256, 25340, 256, 25448, 256, 25475, + 256, 25572, 256, 55370, 57329, 256, 25634, 256, 25541, 256, 25513, 256, + 14894, 256, 25705, 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, + 25935, 256, 25964, 256, 55372, 56330, 256, 26083, 256, 26360, 256, 26185, + 256, 15129, 256, 26257, 256, 15112, 256, 15076, 256, 20882, 256, 20885, + 256, 26368, 256, 26268, 256, 32941, 256, 17369, 256, 26391, 256, 26395, + 256, 26401, 256, 26462, 256, 26451, 256, 55372, 57283, 256, 15177, 256, + 26618, 256, 26501, 256, 26706, 256, 26757, 256, 55373, 56429, 256, 26766, + 256, 26655, 256, 26900, 256, 15261, 256, 26946, 256, 27043, 256, 27114, + 256, 27304, 256, 55373, 56995, 256, 27355, 256, 15384, 256, 27425, 256, + 55374, 56487, 256, 27476, 256, 15438, 256, 27506, 256, 27551, 256, 27578, + 256, 27579, 256, 55374, 56973, 256, 55367, 56587, 256, 55374, 57082, 256, 27726, 256, 55375, 56508, 256, 27839, 256, 27853, 256, 27751, 256, 27926, 256, 27966, 256, 28023, 256, 27969, 256, 28009, 256, 28024, 256, 28037, 256, 55375, 56606, 256, 27956, 256, 28207, 256, 28270, 256, 15667, 256, @@ -3704,14 +3940,14 @@ static const unsigned short decomp_data[] = { #define DECOMP_SHIFT2 4 static const unsigned char decomp_index0[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 13, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 14, 15, 5, 5, 5, 5, 16, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 13, 14, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 16, 5, 5, 5, 5, 17, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 18, - 5, 5, 5, 5, 5, 19, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 19, 20, + 5, 5, 5, 5, 5, 21, 22, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 23, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -3793,36 +4029,41 @@ static const unsigned short decomp_index1[] = { 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 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, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, - 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 0, 0, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 0, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 0, 305, 306, 307, 308, 309, - 310, 311, 312, 0, 0, 313, 0, 314, 0, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, - 344, 0, 0, 0, 0, 0, 0, 0, 345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, + 0, 0, 0, 0, 0, 240, 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, 0, 0, 0, 0, 0, 241, 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, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 0, 0, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 0, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 0, 307, 308, 309, 310, 311, 312, 313, 314, 0, 0, 315, + 0, 316, 0, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, 0, 0, 0, 0, 0, 0, + 347, 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, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 350, 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, 0, 0, 346, 347, 0, 0, 0, 0, 348, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 352, 0, 0, 0, 0, 353, 354, 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, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, - 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 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, 414, 415, - 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 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, 426, 427, 428, 429, 430, 0, 431, 0, 0, 432, 0, 0, 0, 0, 0, 0, - 433, 434, 435, 436, 437, 438, 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, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 0, 0, 0, + 0, 0, 0, 0, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 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, 431, 432, 433, 434, 435, 0, 436, 0, + 0, 437, 0, 0, 0, 0, 0, 0, 438, 439, 440, 441, 442, 443, 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, 444, 445, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 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 unsigned short decomp_index2[] = { @@ -4078,577 +4319,599 @@ static const unsigned short decomp_index2[] = { 6513, 6516, 6519, 6523, 6527, 6530, 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6558, 6562, 6566, 6570, 6574, 6578, 6582, 6586, 6590, 6594, 6598, 6602, 6606, 6610, 6614, 6618, 6622, 6626, 6630, 6634, 6638, 6642, - 6646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6648, 6650, 0, 0, 0, 0, 0, 0, 6652, 6654, 6656, 6658, 6660, 6662, - 6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684, 6686, - 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708, 6710, - 6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732, 6734, - 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756, 6758, - 6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780, 6782, - 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804, 6806, - 6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828, 6830, - 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852, 6854, - 6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876, 6878, - 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900, 6902, - 6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924, 6926, - 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948, 6950, - 6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972, 6974, - 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996, 6998, - 7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020, 7022, - 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044, 7046, - 7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068, 7070, - 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092, 7094, - 7096, 7098, 7100, 7102, 7104, 7106, 7108, 7110, 7112, 7114, 7116, 7118, - 7120, 7122, 7124, 7126, 7128, 7130, 7132, 7134, 7136, 7138, 7140, 7142, - 7144, 7146, 7148, 7150, 7152, 7154, 7156, 7158, 7160, 7162, 7164, 7166, - 7168, 7170, 7172, 7174, 7176, 7178, 7180, 7182, 7184, 7186, 7188, 7190, - 0, 0, 7192, 0, 7194, 0, 0, 7196, 7198, 7200, 7202, 7204, 7206, 7208, - 7210, 7212, 7214, 0, 7216, 0, 7218, 0, 0, 7220, 7222, 0, 0, 0, 7224, - 7226, 7228, 7230, 7232, 7234, 7236, 7238, 7240, 7242, 7244, 7246, 7248, - 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270, 7272, - 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, 7296, - 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312, 7314, 7316, 7318, 7320, - 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336, 7338, 7340, 7342, 7344, - 7346, 7348, 7350, 7352, 7354, 7356, 7359, 0, 0, 7361, 7363, 7365, 7367, - 7369, 7371, 7373, 7375, 7377, 7379, 7381, 7383, 7385, 7387, 7389, 7391, - 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, 7413, 7415, - 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, 7437, 7439, - 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, 7461, 7463, - 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, 7485, 7487, - 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, 7509, 7511, - 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, 7533, 7535, - 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7554, 7557, 7560, 7562, - 7564, 7566, 7569, 7572, 7575, 7577, 0, 0, 0, 0, 0, 0, 7579, 7582, 7585, - 7588, 7592, 7596, 7599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7602, 7605, - 7608, 7611, 7614, 0, 0, 0, 0, 0, 7617, 0, 7620, 7623, 7625, 7627, 7629, - 7631, 7633, 7635, 7637, 7639, 7641, 7643, 7646, 7649, 7652, 7655, 7658, - 7661, 7664, 7667, 7670, 7673, 7676, 7679, 0, 7682, 7685, 7688, 7691, - 7694, 0, 7697, 0, 7700, 7703, 0, 7706, 7709, 0, 7712, 7715, 7718, 7721, - 7724, 7727, 7730, 7733, 7736, 7739, 7742, 7744, 7746, 7748, 7750, 7752, - 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, - 7778, 7780, 7782, 7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798, 7800, - 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822, 7824, - 7826, 7828, 7830, 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, - 7850, 7852, 7854, 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, - 7874, 7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, 7892, 7894, 7896, - 7898, 7900, 7902, 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, - 7922, 7924, 7926, 7928, 7930, 7932, 7934, 7936, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7938, 7940, 7942, 7944, 7946, 7948, 7950, - 7952, 7954, 7956, 7958, 7960, 7962, 7964, 7966, 7968, 7970, 7972, 7974, - 7976, 7978, 7980, 7982, 7984, 7987, 7990, 7993, 7996, 7999, 8002, 8005, - 8008, 8011, 8014, 8017, 8020, 8023, 8026, 8029, 8032, 8035, 8038, 8040, - 8042, 8044, 8046, 8049, 8052, 8055, 8058, 8061, 8064, 8067, 8070, 8073, - 8076, 8079, 8082, 8085, 8088, 8091, 8094, 8097, 8100, 8103, 8106, 8109, - 8112, 8115, 8118, 8121, 8124, 8127, 8130, 8133, 8136, 8139, 8142, 8145, - 8148, 8151, 8154, 8157, 8160, 8163, 8166, 8169, 8172, 8175, 8178, 8181, - 8184, 8187, 8190, 8193, 8196, 8199, 8202, 8205, 8208, 8211, 8214, 8217, - 8220, 8223, 8226, 8229, 8232, 8235, 8238, 8241, 8244, 8247, 8250, 8253, - 8256, 8259, 8262, 8265, 8268, 8271, 8274, 8277, 8280, 8283, 8286, 8289, - 8292, 8295, 8298, 8301, 8304, 8307, 8310, 8313, 8316, 8319, 8322, 8325, - 8328, 8332, 8336, 8340, 8344, 8348, 8352, 8355, 8358, 8361, 8364, 8367, - 8370, 8373, 8376, 8379, 8382, 8385, 8388, 8391, 8394, 8397, 8400, 8403, - 8406, 8409, 8412, 8415, 8418, 8421, 8424, 8427, 8430, 8433, 8436, 8439, - 8442, 8445, 8448, 8451, 8454, 8457, 8460, 8463, 8466, 8469, 8472, 8475, - 8478, 8481, 8484, 8487, 8490, 8493, 8496, 8499, 8502, 8505, 8508, 8511, - 8514, 8517, 8520, 8523, 8526, 8529, 8532, 8535, 8538, 8541, 8544, 8547, - 8550, 8553, 8556, 8559, 8562, 8565, 8568, 8571, 8574, 8577, 8580, 8583, - 8586, 8589, 8592, 8595, 8598, 8601, 8604, 8607, 8610, 8613, 8616, 8619, - 8622, 8625, 8628, 8631, 8634, 8637, 8640, 8643, 8646, 8649, 8652, 8655, - 8658, 8661, 8664, 8667, 8670, 8673, 8676, 8679, 8682, 8685, 8688, 8691, - 8694, 8697, 8700, 8703, 8706, 8709, 8712, 8715, 8718, 8721, 8724, 8727, - 8730, 8733, 8736, 8739, 8742, 8745, 8748, 8751, 8754, 8757, 8760, 8763, - 8766, 8769, 8772, 8775, 8778, 8782, 8786, 8790, 8793, 8796, 8799, 8802, - 8805, 8808, 8811, 8814, 8817, 8820, 8823, 8826, 8829, 8832, 8835, 8838, - 8841, 8844, 8847, 8850, 8853, 8856, 8859, 8862, 8865, 8868, 8871, 8874, - 8877, 8880, 8883, 8886, 8889, 8892, 8895, 8898, 8901, 8904, 8907, 8910, - 8913, 8916, 8919, 8922, 8925, 8928, 8931, 8934, 8937, 8940, 8943, 8946, - 8949, 8952, 8955, 8958, 8961, 8964, 8967, 8970, 8973, 8976, 8979, 8982, - 8985, 8988, 8991, 8994, 8997, 9000, 9003, 9006, 0, 0, 9009, 9013, 9017, - 9021, 9025, 9029, 9033, 9037, 9041, 9045, 9049, 9053, 9057, 9061, 9065, - 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097, 9101, 9105, 9109, 9113, - 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145, 9149, 9153, 9157, 9161, - 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193, 9197, 9201, 9205, 9209, - 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241, 9245, 9249, 9253, 9257, - 9261, 0, 0, 9265, 9269, 9273, 9277, 9281, 9285, 9289, 9293, 9297, 9301, - 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333, 9337, 9341, 9345, 9349, - 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381, 9385, 9389, 9393, 9397, - 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, 9433, 9437, 9441, 9445, - 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, 0, 0, 0, 0, 0, 0, 0, 0, - 9481, 9485, 9489, 9494, 9499, 9504, 9509, 9514, 9519, 9524, 9528, 9547, - 9556, 0, 0, 0, 9561, 9563, 9565, 9567, 9569, 9571, 9573, 9575, 9577, - 9579, 0, 0, 0, 0, 0, 0, 9581, 9583, 9585, 9587, 9589, 9591, 9593, 9595, - 9597, 9599, 9601, 9603, 9605, 9607, 9609, 9611, 9613, 9615, 9617, 9619, - 9621, 0, 0, 9623, 9625, 9627, 9629, 9631, 9633, 9635, 9637, 9639, 9641, - 9643, 9645, 0, 9647, 9649, 9651, 9653, 9655, 9657, 9659, 9661, 9663, - 9665, 9667, 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 0, 9685, - 9687, 9689, 9691, 0, 0, 0, 0, 9693, 9696, 9699, 0, 9702, 0, 9705, 9708, - 9711, 9714, 9717, 9720, 9723, 9726, 9729, 9732, 9735, 9737, 9739, 9741, - 9743, 9745, 9747, 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, 9765, - 9767, 9769, 9771, 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, 9789, - 9791, 9793, 9795, 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, 9813, - 9815, 9817, 9819, 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, 9837, - 9839, 9841, 9843, 9845, 9847, 9849, 9851, 9853, 9855, 9857, 9859, 9861, - 9863, 9865, 9867, 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, - 9887, 9889, 9891, 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, - 9911, 9913, 9915, 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, - 9935, 9937, 9939, 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, - 9959, 9961, 9963, 9965, 9967, 9969, 9972, 9975, 9978, 9981, 9984, 9987, - 9990, 0, 0, 0, 0, 9993, 9995, 9997, 9999, 10001, 10003, 10005, 10007, - 10009, 10011, 10013, 10015, 10017, 10019, 10021, 10023, 10025, 10027, - 10029, 10031, 10033, 10035, 10037, 10039, 10041, 10043, 10045, 10047, - 10049, 10051, 10053, 10055, 10057, 10059, 10061, 10063, 10065, 10067, - 10069, 10071, 10073, 10075, 10077, 10079, 10081, 10083, 10085, 10087, - 10089, 10091, 10093, 10095, 10097, 10099, 10101, 10103, 10105, 10107, - 10109, 10111, 10113, 10115, 10117, 10119, 10121, 10123, 10125, 10127, - 10129, 10131, 10133, 10135, 10137, 10139, 10141, 10143, 10145, 10147, - 10149, 10151, 10153, 10155, 10157, 10159, 10161, 10163, 10165, 10167, - 10169, 10171, 10173, 10175, 10177, 10179, 10181, 10183, 10185, 10187, - 10189, 10191, 10193, 10195, 10197, 10199, 10201, 10203, 10205, 10207, - 10209, 10211, 10213, 10215, 10217, 10219, 10221, 10223, 10225, 10227, - 10229, 10231, 10233, 10235, 10237, 10239, 10241, 10243, 10245, 10247, - 10249, 10251, 10253, 10255, 10257, 10259, 10261, 10263, 10265, 10267, - 10269, 10271, 10273, 10275, 10277, 10279, 10281, 10283, 10285, 10287, - 10289, 10291, 10293, 10295, 10297, 10299, 10301, 10303, 10305, 10307, - 10309, 10311, 10313, 10315, 10317, 10319, 10321, 10323, 10325, 10327, - 10329, 10331, 10333, 10335, 10337, 10339, 10341, 10343, 10345, 10347, - 10349, 10351, 10353, 10355, 10357, 10359, 10361, 10363, 10365, 10367, - 10369, 10371, 0, 0, 0, 10373, 10375, 10377, 10379, 10381, 10383, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6646, 6648, 0, 0, 6650, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6652, 6654, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6656, 6658, 6660, + 6662, 6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684, + 6686, 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708, + 6710, 6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732, + 6734, 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756, + 6758, 6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780, + 6782, 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804, + 6806, 6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828, + 6830, 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852, + 6854, 6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876, + 6878, 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900, + 6902, 6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924, + 6926, 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948, + 6950, 6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972, + 6974, 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996, + 6998, 7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020, + 7022, 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044, + 7046, 7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068, + 7070, 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092, + 7094, 7096, 7098, 7100, 7102, 7104, 7106, 7108, 7110, 7112, 7114, 7116, + 7118, 7120, 7122, 7124, 7126, 7128, 7130, 7132, 7134, 7136, 7138, 7140, + 7142, 7144, 7146, 7148, 7150, 7152, 7154, 7156, 7158, 7160, 7162, 7164, + 7166, 7168, 7170, 7172, 7174, 7176, 7178, 7180, 7182, 7184, 7186, 7188, + 7190, 7192, 7194, 7196, 7198, 7200, 7202, 0, 0, 7204, 0, 7206, 0, 0, + 7208, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 0, 7228, 0, + 7230, 0, 0, 7232, 7234, 0, 0, 0, 7236, 7238, 7240, 7242, 7244, 7246, + 7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270, + 7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, + 7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312, 7314, 7316, 7318, + 7320, 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336, 7338, 7340, 7342, + 7344, 7346, 7348, 7350, 7352, 7354, 7356, 7358, 7360, 7362, 7364, 7366, + 7368, 7371, 0, 0, 7373, 7375, 7377, 7379, 7381, 7383, 7385, 7387, 7389, + 7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, 7413, + 7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, 7437, + 7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, 7461, + 7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, 7485, + 7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, 7509, + 7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, 7533, + 7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, 7557, + 7559, 7561, 7563, 7566, 7569, 7572, 7574, 7576, 7578, 7581, 7584, 7587, + 7589, 0, 0, 0, 0, 0, 0, 7591, 7594, 7597, 7600, 7604, 7608, 7611, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7614, 7617, 7620, 7623, 7626, 0, 0, 0, 0, + 0, 7629, 0, 7632, 7635, 7637, 7639, 7641, 7643, 7645, 7647, 7649, 7651, + 7653, 7655, 7658, 7661, 7664, 7667, 7670, 7673, 7676, 7679, 7682, 7685, + 7688, 7691, 0, 7694, 7697, 7700, 7703, 7706, 0, 7709, 0, 7712, 7715, 0, + 7718, 7721, 0, 7724, 7727, 7730, 7733, 7736, 7739, 7742, 7745, 7748, + 7751, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774, + 7776, 7778, 7780, 7782, 7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798, + 7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822, + 7824, 7826, 7828, 7830, 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, + 7848, 7850, 7852, 7854, 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, + 7872, 7874, 7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, 7892, 7894, + 7896, 7898, 7900, 7902, 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918, + 7920, 7922, 7924, 7926, 7928, 7930, 7932, 7934, 7936, 7938, 7940, 7942, + 7944, 7946, 7948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7950, 7952, 7954, 7956, 7958, 7960, 7962, 7964, 7966, 7968, 7970, 7972, + 7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, 7990, 7992, 7994, 7996, + 7999, 8002, 8005, 8008, 8011, 8014, 8017, 8020, 8023, 8026, 8029, 8032, + 8035, 8038, 8041, 8044, 8047, 8050, 8052, 8054, 8056, 8058, 8061, 8064, + 8067, 8070, 8073, 8076, 8079, 8082, 8085, 8088, 8091, 8094, 8097, 8100, + 8103, 8106, 8109, 8112, 8115, 8118, 8121, 8124, 8127, 8130, 8133, 8136, + 8139, 8142, 8145, 8148, 8151, 8154, 8157, 8160, 8163, 8166, 8169, 8172, + 8175, 8178, 8181, 8184, 8187, 8190, 8193, 8196, 8199, 8202, 8205, 8208, + 8211, 8214, 8217, 8220, 8223, 8226, 8229, 8232, 8235, 8238, 8241, 8244, + 8247, 8250, 8253, 8256, 8259, 8262, 8265, 8268, 8271, 8274, 8277, 8280, + 8283, 8286, 8289, 8292, 8295, 8298, 8301, 8304, 8307, 8310, 8313, 8316, + 8319, 8322, 8325, 8328, 8331, 8334, 8337, 8340, 8344, 8348, 8352, 8356, + 8360, 8364, 8367, 8370, 8373, 8376, 8379, 8382, 8385, 8388, 8391, 8394, + 8397, 8400, 8403, 8406, 8409, 8412, 8415, 8418, 8421, 8424, 8427, 8430, + 8433, 8436, 8439, 8442, 8445, 8448, 8451, 8454, 8457, 8460, 8463, 8466, + 8469, 8472, 8475, 8478, 8481, 8484, 8487, 8490, 8493, 8496, 8499, 8502, + 8505, 8508, 8511, 8514, 8517, 8520, 8523, 8526, 8529, 8532, 8535, 8538, + 8541, 8544, 8547, 8550, 8553, 8556, 8559, 8562, 8565, 8568, 8571, 8574, + 8577, 8580, 8583, 8586, 8589, 8592, 8595, 8598, 8601, 8604, 8607, 8610, + 8613, 8616, 8619, 8622, 8625, 8628, 8631, 8634, 8637, 8640, 8643, 8646, + 8649, 8652, 8655, 8658, 8661, 8664, 8667, 8670, 8673, 8676, 8679, 8682, + 8685, 8688, 8691, 8694, 8697, 8700, 8703, 8706, 8709, 8712, 8715, 8718, + 8721, 8724, 8727, 8730, 8733, 8736, 8739, 8742, 8745, 8748, 8751, 8754, + 8757, 8760, 8763, 8766, 8769, 8772, 8775, 8778, 8781, 8784, 8787, 8790, + 8794, 8798, 8802, 8805, 8808, 8811, 8814, 8817, 8820, 8823, 8826, 8829, + 8832, 8835, 8838, 8841, 8844, 8847, 8850, 8853, 8856, 8859, 8862, 8865, + 8868, 8871, 8874, 8877, 8880, 8883, 8886, 8889, 8892, 8895, 8898, 8901, + 8904, 8907, 8910, 8913, 8916, 8919, 8922, 8925, 8928, 8931, 8934, 8937, + 8940, 8943, 8946, 8949, 8952, 8955, 8958, 8961, 8964, 8967, 8970, 8973, + 8976, 8979, 8982, 8985, 8988, 8991, 8994, 8997, 9000, 9003, 9006, 9009, + 9012, 9015, 9018, 0, 0, 9021, 9025, 9029, 9033, 9037, 9041, 9045, 9049, + 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097, + 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145, + 9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193, + 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241, + 9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, 0, 0, 9277, 9281, 9285, + 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333, + 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381, + 9385, 9389, 9393, 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, + 9433, 9437, 9441, 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, + 9481, 9485, 9489, 0, 0, 0, 0, 0, 0, 0, 0, 9493, 9497, 9501, 9506, 9511, + 9516, 9521, 9526, 9531, 9536, 9540, 9559, 9568, 0, 0, 0, 9573, 9575, + 9577, 9579, 9581, 9583, 9585, 9587, 9589, 9591, 0, 0, 0, 0, 0, 0, 9593, + 9595, 9597, 9599, 9601, 9603, 9605, 9607, 9609, 9611, 9613, 9615, 9617, + 9619, 9621, 9623, 9625, 9627, 9629, 9631, 9633, 0, 0, 9635, 9637, 9639, + 9641, 9643, 9645, 9647, 9649, 9651, 9653, 9655, 9657, 0, 9659, 9661, + 9663, 9665, 9667, 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, + 9687, 9689, 9691, 9693, 9695, 0, 9697, 9699, 9701, 9703, 0, 0, 0, 0, + 9705, 9708, 9711, 0, 9714, 0, 9717, 9720, 9723, 9726, 9729, 9732, 9735, + 9738, 9741, 9744, 9747, 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, + 9765, 9767, 9769, 9771, 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, + 9789, 9791, 9793, 9795, 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, + 9813, 9815, 9817, 9819, 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, + 9837, 9839, 9841, 9843, 9845, 9847, 9849, 9851, 9853, 9855, 9857, 9859, + 9861, 9863, 9865, 9867, 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, + 9885, 9887, 9889, 9891, 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, + 9909, 9911, 9913, 9915, 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, + 9933, 9935, 9937, 9939, 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, + 9957, 9959, 9961, 9963, 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979, + 9981, 9984, 9987, 9990, 9993, 9996, 9999, 10002, 0, 0, 0, 0, 10005, + 10007, 10009, 10011, 10013, 10015, 10017, 10019, 10021, 10023, 10025, + 10027, 10029, 10031, 10033, 10035, 10037, 10039, 10041, 10043, 10045, + 10047, 10049, 10051, 10053, 10055, 10057, 10059, 10061, 10063, 10065, + 10067, 10069, 10071, 10073, 10075, 10077, 10079, 10081, 10083, 10085, + 10087, 10089, 10091, 10093, 10095, 10097, 10099, 10101, 10103, 10105, + 10107, 10109, 10111, 10113, 10115, 10117, 10119, 10121, 10123, 10125, + 10127, 10129, 10131, 10133, 10135, 10137, 10139, 10141, 10143, 10145, + 10147, 10149, 10151, 10153, 10155, 10157, 10159, 10161, 10163, 10165, + 10167, 10169, 10171, 10173, 10175, 10177, 10179, 10181, 10183, 10185, + 10187, 10189, 10191, 10193, 10195, 10197, 10199, 10201, 10203, 10205, + 10207, 10209, 10211, 10213, 10215, 10217, 10219, 10221, 10223, 10225, + 10227, 10229, 10231, 10233, 10235, 10237, 10239, 10241, 10243, 10245, + 10247, 10249, 10251, 10253, 10255, 10257, 10259, 10261, 10263, 10265, + 10267, 10269, 10271, 10273, 10275, 10277, 10279, 10281, 10283, 10285, + 10287, 10289, 10291, 10293, 10295, 10297, 10299, 10301, 10303, 10305, + 10307, 10309, 10311, 10313, 10315, 10317, 10319, 10321, 10323, 10325, + 10327, 10329, 10331, 10333, 10335, 10337, 10339, 10341, 10343, 10345, + 10347, 10349, 10351, 10353, 10355, 10357, 10359, 10361, 10363, 10365, + 10367, 10369, 10371, 10373, 10375, 10377, 10379, 10381, 10383, 0, 0, 0, 10385, 10387, 10389, 10391, 10393, 10395, 0, 0, 10397, 10399, 10401, - 10403, 10405, 10407, 0, 0, 10409, 10411, 10413, 0, 0, 0, 10415, 10417, - 10419, 10421, 10423, 10425, 10427, 0, 10429, 10431, 10433, 10435, 10437, - 10439, 10441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10443, 0, 10448, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 10458, 10463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 10468, 10473, 10478, 10483, 10488, 10493, 10498, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10503, 10508, 10513, 10518, - 10523, 10528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10533, 10535, - 10537, 10539, 10541, 10543, 10545, 10547, 10549, 10551, 10553, 10555, - 10557, 10559, 10561, 10563, 10565, 10567, 10569, 10571, 10573, 10575, - 10577, 10579, 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, - 10597, 10599, 10601, 10603, 10605, 10607, 10609, 10611, 10613, 10615, - 10617, 10619, 10621, 10623, 10625, 10627, 10629, 10631, 10633, 10635, - 10637, 10639, 10641, 10643, 10645, 10647, 10649, 10651, 10653, 10655, - 10657, 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, 10675, - 10677, 10679, 10681, 10683, 10685, 10687, 10689, 10691, 10693, 10695, - 10697, 10699, 10701, 0, 10703, 10705, 10707, 10709, 10711, 10713, 10715, - 10717, 10719, 10721, 10723, 10725, 10727, 10729, 10731, 10733, 10735, - 10737, 10739, 10741, 10743, 10745, 10747, 10749, 10751, 10753, 10755, - 10757, 10759, 10761, 10763, 10765, 10767, 10769, 10771, 10773, 10775, - 10777, 10779, 10781, 10783, 10785, 10787, 10789, 10791, 10793, 10795, - 10797, 10799, 10801, 10803, 10805, 10807, 10809, 10811, 10813, 10815, - 10817, 10819, 10821, 10823, 10825, 10827, 10829, 10831, 10833, 10835, - 10837, 10839, 10841, 10843, 0, 10845, 10847, 0, 0, 10849, 0, 0, 10851, - 10853, 0, 0, 10855, 10857, 10859, 10861, 0, 10863, 10865, 10867, 10869, - 10871, 10873, 10875, 10877, 10879, 10881, 10883, 10885, 0, 10887, 0, - 10889, 10891, 10893, 10895, 10897, 10899, 10901, 0, 10903, 10905, 10907, - 10909, 10911, 10913, 10915, 10917, 10919, 10921, 10923, 10925, 10927, - 10929, 10931, 10933, 10935, 10937, 10939, 10941, 10943, 10945, 10947, - 10949, 10951, 10953, 10955, 10957, 10959, 10961, 10963, 10965, 10967, - 10969, 10971, 10973, 10975, 10977, 10979, 10981, 10983, 10985, 10987, - 10989, 10991, 10993, 10995, 10997, 10999, 11001, 11003, 11005, 11007, - 11009, 11011, 11013, 11015, 11017, 11019, 11021, 11023, 11025, 11027, - 11029, 11031, 0, 11033, 11035, 11037, 11039, 0, 0, 11041, 11043, 11045, - 11047, 11049, 11051, 11053, 11055, 0, 11057, 11059, 11061, 11063, 11065, - 11067, 11069, 0, 11071, 11073, 11075, 11077, 11079, 11081, 11083, 11085, - 11087, 11089, 11091, 11093, 11095, 11097, 11099, 11101, 11103, 11105, - 11107, 11109, 11111, 11113, 11115, 11117, 11119, 11121, 11123, 11125, 0, - 11127, 11129, 11131, 11133, 0, 11135, 11137, 11139, 11141, 11143, 0, - 11145, 0, 0, 0, 11147, 11149, 11151, 11153, 11155, 11157, 11159, 0, - 11161, 11163, 11165, 11167, 11169, 11171, 11173, 11175, 11177, 11179, - 11181, 11183, 11185, 11187, 11189, 11191, 11193, 11195, 11197, 11199, - 11201, 11203, 11205, 11207, 11209, 11211, 11213, 11215, 11217, 11219, - 11221, 11223, 11225, 11227, 11229, 11231, 11233, 11235, 11237, 11239, - 11241, 11243, 11245, 11247, 11249, 11251, 11253, 11255, 11257, 11259, - 11261, 11263, 11265, 11267, 11269, 11271, 11273, 11275, 11277, 11279, - 11281, 11283, 11285, 11287, 11289, 11291, 11293, 11295, 11297, 11299, - 11301, 11303, 11305, 11307, 11309, 11311, 11313, 11315, 11317, 11319, - 11321, 11323, 11325, 11327, 11329, 11331, 11333, 11335, 11337, 11339, - 11341, 11343, 11345, 11347, 11349, 11351, 11353, 11355, 11357, 11359, - 11361, 11363, 11365, 11367, 11369, 11371, 11373, 11375, 11377, 11379, - 11381, 11383, 11385, 11387, 11389, 11391, 11393, 11395, 11397, 11399, - 11401, 11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, - 11421, 11423, 11425, 11427, 11429, 11431, 11433, 11435, 11437, 11439, - 11441, 11443, 11445, 11447, 11449, 11451, 11453, 11455, 11457, 11459, - 11461, 11463, 11465, 11467, 11469, 11471, 11473, 11475, 11477, 11479, - 11481, 11483, 11485, 11487, 11489, 11491, 11493, 11495, 11497, 11499, - 11501, 11503, 11505, 11507, 11509, 11511, 11513, 11515, 11517, 11519, - 11521, 11523, 11525, 11527, 11529, 11531, 11533, 11535, 11537, 11539, - 11541, 11543, 11545, 11547, 11549, 11551, 11553, 11555, 11557, 11559, - 11561, 11563, 11565, 11567, 11569, 11571, 11573, 11575, 11577, 11579, - 11581, 11583, 11585, 11587, 11589, 11591, 11593, 11595, 11597, 11599, - 11601, 11603, 11605, 11607, 11609, 11611, 11613, 11615, 11617, 11619, - 11621, 11623, 11625, 11627, 11629, 11631, 11633, 11635, 11637, 11639, - 11641, 11643, 11645, 11647, 11649, 11651, 11653, 11655, 11657, 11659, - 11661, 11663, 11665, 11667, 11669, 11671, 11673, 11675, 11677, 11679, - 11681, 11683, 11685, 11687, 11689, 11691, 11693, 11695, 11697, 11699, - 11701, 11703, 11705, 11707, 11709, 11711, 11713, 11715, 11717, 11719, - 11721, 11723, 11725, 11727, 11729, 11731, 11733, 11735, 11737, 11739, - 11741, 11743, 11745, 11747, 11749, 11751, 11753, 11755, 11757, 11759, - 11761, 11763, 11765, 11767, 11769, 11771, 11773, 11775, 11777, 11779, - 11781, 11783, 11785, 11787, 11789, 11791, 11793, 11795, 11797, 11799, - 11801, 11803, 11805, 11807, 11809, 11811, 11813, 11815, 11817, 11819, - 11821, 11823, 11825, 11827, 11829, 11831, 11833, 11835, 11837, 11839, 0, - 0, 11841, 11843, 11845, 11847, 11849, 11851, 11853, 11855, 11857, 11859, - 11861, 11863, 11865, 11867, 11869, 11871, 11873, 11875, 11877, 11879, - 11881, 11883, 11885, 11887, 11889, 11891, 11893, 11895, 11897, 11899, - 11901, 11903, 11905, 11907, 11909, 11911, 11913, 11915, 11917, 11919, - 11921, 11923, 11925, 11927, 11929, 11931, 11933, 11935, 11937, 11939, - 11941, 11943, 11945, 11947, 11949, 11951, 11953, 11955, 11957, 11959, - 11961, 11963, 11965, 11967, 11969, 11971, 11973, 11975, 11977, 11979, - 11981, 11983, 11985, 11987, 11989, 11991, 11993, 11995, 11997, 11999, - 12001, 12003, 12005, 12007, 12009, 12011, 12013, 12015, 12017, 12019, - 12021, 12023, 12025, 12027, 12029, 12031, 12033, 12035, 12037, 12039, - 12041, 12043, 12045, 12047, 12049, 12051, 12053, 12055, 12057, 12059, - 12061, 12063, 12065, 12067, 12069, 12071, 12073, 12075, 12077, 12079, - 12081, 12083, 12085, 12087, 12089, 12091, 12093, 12095, 12097, 12099, - 12101, 12103, 12105, 12107, 12109, 12111, 12113, 12115, 12117, 12119, - 12121, 12123, 12125, 12127, 12129, 12131, 12133, 12135, 12137, 12139, - 12141, 12143, 12145, 12147, 12149, 12151, 12153, 12155, 12157, 12159, - 12161, 12163, 12165, 12167, 12169, 12171, 12173, 12175, 12177, 12179, - 12181, 12183, 12185, 12187, 12189, 12191, 12193, 12195, 12197, 12199, - 12201, 12203, 12205, 12207, 12209, 12211, 12213, 12215, 12217, 12219, - 12221, 12223, 12225, 12227, 12229, 12231, 12233, 12235, 12237, 12239, - 12241, 12243, 12245, 12247, 12249, 12251, 12253, 12255, 12257, 12259, - 12261, 12263, 12265, 12267, 12269, 12271, 12273, 12275, 12277, 12279, - 12281, 12283, 12285, 12287, 12289, 12291, 12293, 12295, 12297, 12299, - 12301, 12303, 12305, 12307, 12309, 12311, 12313, 12315, 12317, 12319, - 12321, 12323, 12325, 12327, 12329, 12331, 12333, 12335, 12337, 12339, - 12341, 12343, 12345, 12347, 12349, 12351, 12353, 12355, 12357, 12359, - 12361, 12363, 12365, 12367, 12369, 12371, 12373, 12375, 12377, 12379, - 12381, 12383, 12385, 12387, 12389, 12391, 12393, 12395, 12397, 12399, - 12401, 12403, 12405, 12407, 12409, 12411, 12413, 12415, 12417, 12419, - 12421, 12423, 0, 0, 12425, 12427, 12429, 12431, 12433, 12435, 12437, - 12439, 12441, 12443, 12445, 12447, 12449, 12451, 12453, 12455, 12457, - 12459, 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, 12477, - 12479, 12481, 12483, 12485, 12487, 12489, 12491, 12493, 12495, 12497, - 12499, 12501, 12503, 12505, 12507, 12509, 12511, 12513, 12515, 12517, - 12519, 12521, 12523, 12525, 12527, 12529, 12531, 0, 12533, 12535, 12537, - 12539, 12541, 12543, 12545, 12547, 12549, 12551, 12553, 12555, 12557, - 12559, 12561, 12563, 12565, 12567, 12569, 12571, 12573, 12575, 12577, - 12579, 12581, 12583, 12585, 0, 12587, 12589, 0, 12591, 0, 0, 12593, 0, - 12595, 12597, 12599, 12601, 12603, 12605, 12607, 12609, 12611, 12613, 0, - 12615, 12617, 12619, 12621, 0, 12623, 0, 12625, 0, 0, 0, 0, 0, 0, 12627, - 0, 0, 0, 0, 12629, 0, 12631, 0, 12633, 0, 12635, 12637, 12639, 0, 12641, - 12643, 0, 12645, 0, 0, 12647, 0, 12649, 0, 12651, 0, 12653, 0, 12655, 0, - 12657, 12659, 0, 12661, 0, 0, 12663, 12665, 12667, 12669, 0, 12671, - 12673, 12675, 12677, 12679, 12681, 12683, 0, 12685, 12687, 12689, 12691, - 0, 12693, 12695, 12697, 12699, 0, 12701, 0, 12703, 12705, 12707, 12709, - 12711, 12713, 12715, 12717, 12719, 12721, 0, 12723, 12725, 12727, 12729, - 12731, 12733, 12735, 12737, 12739, 12741, 12743, 12745, 12747, 12749, - 12751, 12753, 12755, 0, 0, 0, 0, 0, 12757, 12759, 12761, 0, 12763, 12765, - 12767, 12769, 12771, 0, 12773, 12775, 12777, 12779, 12781, 12783, 12785, - 12787, 12789, 12791, 12793, 12795, 12797, 12799, 12801, 12803, 12805, 0, - 0, 0, 0, 12807, 12810, 12813, 12816, 12819, 12822, 12825, 12828, 12831, - 12834, 12837, 0, 0, 0, 0, 0, 12840, 12844, 12848, 12852, 12856, 12860, - 12864, 12868, 12872, 12876, 12880, 12884, 12888, 12892, 12896, 12900, - 12904, 12908, 12912, 12916, 12920, 12924, 12928, 12932, 12936, 12940, - 12944, 12948, 12950, 12952, 12955, 0, 12958, 12960, 12962, 12964, 12966, - 12968, 12970, 12972, 12974, 12976, 12978, 12980, 12982, 12984, 12986, - 12988, 12990, 12992, 12994, 12996, 12998, 13000, 13002, 13004, 13006, - 13008, 13010, 13013, 13016, 13019, 13022, 13026, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 13029, 13032, 0, 0, 0, 0, 13035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 13038, 13041, 13044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 13046, 13048, 13050, 13052, 13054, 13056, 13058, 13060, 13062, 13064, - 13066, 13068, 13070, 13072, 13074, 13076, 13078, 13080, 13082, 13084, - 13086, 13088, 13090, 13092, 13094, 13096, 13098, 13100, 13102, 13104, - 13106, 13108, 13110, 13112, 13114, 13116, 13118, 13120, 13122, 13124, - 13126, 13128, 13130, 0, 0, 0, 0, 0, 13132, 13136, 13140, 13144, 13148, - 13152, 13156, 13160, 13164, 0, 0, 0, 0, 0, 0, 0, 13168, 13170, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13172, 13174, 13176, 13178, 13181, - 13183, 13185, 13187, 13189, 13191, 13193, 13195, 13197, 13199, 13202, - 13204, 13206, 13208, 13210, 13213, 13215, 13217, 13219, 13222, 13224, - 13226, 13228, 13230, 13232, 13235, 13237, 13239, 13241, 13243, 13245, - 13247, 13249, 13251, 13253, 13255, 13257, 13259, 13261, 13263, 13265, - 13267, 13269, 13271, 13273, 13275, 13277, 13279, 13281, 13284, 13286, - 13288, 13290, 13293, 13295, 13297, 13299, 13301, 13303, 13305, 13307, - 13309, 13311, 13313, 13315, 13317, 13319, 13321, 13323, 13325, 13327, - 13329, 13331, 13333, 13335, 13337, 13339, 13341, 13343, 13345, 13347, - 13349, 13351, 13353, 13355, 13357, 13360, 13362, 13364, 13366, 13368, - 13370, 13372, 13375, 13378, 13380, 13382, 13384, 13386, 13388, 13390, - 13392, 13394, 13396, 13398, 13401, 13403, 13405, 13407, 13409, 13412, - 13414, 13416, 13418, 13420, 13422, 13424, 13426, 13428, 13430, 13433, - 13435, 13438, 13440, 13442, 13444, 13446, 13448, 13450, 13452, 13454, - 13456, 13458, 13460, 13463, 13465, 13467, 13469, 13471, 13473, 13476, - 13478, 13481, 13484, 13486, 13488, 13490, 13492, 13495, 13498, 13500, - 13502, 13504, 13506, 13508, 13510, 13512, 13514, 13516, 13518, 13520, - 13523, 13525, 13527, 13529, 13531, 13533, 13535, 13537, 13539, 13541, - 13543, 13545, 13547, 13549, 13551, 13553, 13555, 13557, 13559, 13561, - 13564, 13566, 13568, 13570, 13572, 13574, 13577, 13579, 13581, 13583, - 13585, 13587, 13589, 13591, 13593, 13595, 13597, 13599, 13602, 13604, - 13606, 13608, 13610, 13612, 13614, 13616, 13618, 13620, 13622, 13624, - 13626, 13628, 13630, 13632, 13634, 13636, 13638, 13641, 13643, 13645, - 13647, 13649, 13651, 13654, 13656, 13658, 13660, 13662, 13664, 13666, - 13668, 13670, 13673, 13675, 13677, 13679, 13682, 13684, 13686, 13688, - 13690, 13692, 13694, 13697, 13700, 13703, 13705, 13708, 13710, 13712, - 13714, 13716, 13718, 13720, 13722, 13724, 13726, 13728, 13731, 13733, - 13735, 13737, 13739, 13741, 13743, 13746, 13748, 13750, 13753, 13756, - 13758, 13760, 13762, 13764, 13766, 13768, 13770, 13772, 13774, 13777, - 13779, 13782, 13784, 13787, 13789, 13791, 13793, 13796, 13798, 13800, - 13803, 13806, 13808, 13810, 13812, 13814, 13816, 13818, 13820, 13822, - 13824, 13826, 13828, 13830, 13832, 13835, 13837, 13840, 13842, 13845, - 13847, 13850, 13853, 13856, 13858, 13860, 13862, 13865, 13868, 13871, - 13874, 13876, 13878, 13880, 13882, 13884, 13886, 13888, 13890, 13893, - 13895, 13897, 13899, 13901, 13904, 13906, 13909, 13912, 13914, 13916, - 13918, 13920, 13922, 13924, 13927, 13930, 13933, 13935, 13937, 13940, - 13942, 13944, 13946, 13949, 13951, 13953, 13955, 13957, 13959, 13962, - 13964, 13966, 13968, 13970, 13972, 13974, 13977, 13980, 13982, 13985, - 13987, 13990, 13992, 13994, 13996, 13999, 14002, 14004, 14007, 14009, - 14012, 14014, 14016, 14018, 14020, 14022, 14024, 14027, 14030, 14033, - 14036, 14038, 14040, 14042, 14044, 14046, 14048, 14050, 14052, 14054, - 14056, 14058, 14060, 14063, 14065, 14067, 14069, 14071, 14073, 14075, - 14077, 14079, 14081, 14083, 14085, 14087, 14090, 14093, 14096, 14098, - 14100, 14102, 14104, 14107, 14109, 14112, 14114, 14116, 14119, 14122, - 14124, 14126, 14128, 14130, 14132, 14134, 14136, 14138, 14140, 14142, - 14144, 14146, 14148, 14150, 14152, 14154, 14156, 14158, 14160, 14163, - 14165, 14167, 14169, 14171, 14173, 14176, 14179, 14181, 14183, 14185, - 14187, 14189, 14191, 14194, 14196, 14198, 14200, 14202, 14205, 14208, - 14210, 14212, 14214, 14217, 14219, 14221, 14224, 14227, 14229, 14231, - 14233, 14236, 14238, 14240, 14242, 14244, 14246, 14248, 14250, 14253, - 14255, 14257, 14259, 14262, 14264, 14266, 14268, 14270, 14273, 14276, - 14278, 14280, 14282, 14285, 14287, 14290, 14292, 14294, 14296, 14299, - 14301, 14303, 14305, 14307, 14309, 14311, 14313, 14316, 14318, 14320, - 14322, 14324, 14326, 14328, 14331, 14333, 14336, 14339, 14342, 14344, - 14346, 14348, 14350, 14352, 14354, 14356, 14358, 0, 0, + 10403, 10405, 10407, 0, 0, 10409, 10411, 10413, 10415, 10417, 10419, 0, + 0, 10421, 10423, 10425, 0, 0, 0, 10427, 10429, 10431, 10433, 10435, + 10437, 10439, 0, 10441, 10443, 10445, 10447, 10449, 10451, 10453, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10455, 0, 10460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10470, 10475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10480, 10485, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10490, 10495, 0, 10500, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10505, 10510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10515, 10520, 10525, 10530, 10535, 10540, 10545, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10550, 10555, 10560, + 10565, 10570, 10575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10580, + 10582, 10584, 10586, 10588, 10590, 10592, 10594, 10596, 10598, 10600, + 10602, 10604, 10606, 10608, 10610, 10612, 10614, 10616, 10618, 10620, + 10622, 10624, 10626, 10628, 10630, 10632, 10634, 10636, 10638, 10640, + 10642, 10644, 10646, 10648, 10650, 10652, 10654, 10656, 10658, 10660, + 10662, 10664, 10666, 10668, 10670, 10672, 10674, 10676, 10678, 10680, + 10682, 10684, 10686, 10688, 10690, 10692, 10694, 10696, 10698, 10700, + 10702, 10704, 10706, 10708, 10710, 10712, 10714, 10716, 10718, 10720, + 10722, 10724, 10726, 10728, 10730, 10732, 10734, 10736, 10738, 10740, + 10742, 10744, 10746, 10748, 0, 10750, 10752, 10754, 10756, 10758, 10760, + 10762, 10764, 10766, 10768, 10770, 10772, 10774, 10776, 10778, 10780, + 10782, 10784, 10786, 10788, 10790, 10792, 10794, 10796, 10798, 10800, + 10802, 10804, 10806, 10808, 10810, 10812, 10814, 10816, 10818, 10820, + 10822, 10824, 10826, 10828, 10830, 10832, 10834, 10836, 10838, 10840, + 10842, 10844, 10846, 10848, 10850, 10852, 10854, 10856, 10858, 10860, + 10862, 10864, 10866, 10868, 10870, 10872, 10874, 10876, 10878, 10880, + 10882, 10884, 10886, 10888, 10890, 0, 10892, 10894, 0, 0, 10896, 0, 0, + 10898, 10900, 0, 0, 10902, 10904, 10906, 10908, 0, 10910, 10912, 10914, + 10916, 10918, 10920, 10922, 10924, 10926, 10928, 10930, 10932, 0, 10934, + 0, 10936, 10938, 10940, 10942, 10944, 10946, 10948, 0, 10950, 10952, + 10954, 10956, 10958, 10960, 10962, 10964, 10966, 10968, 10970, 10972, + 10974, 10976, 10978, 10980, 10982, 10984, 10986, 10988, 10990, 10992, + 10994, 10996, 10998, 11000, 11002, 11004, 11006, 11008, 11010, 11012, + 11014, 11016, 11018, 11020, 11022, 11024, 11026, 11028, 11030, 11032, + 11034, 11036, 11038, 11040, 11042, 11044, 11046, 11048, 11050, 11052, + 11054, 11056, 11058, 11060, 11062, 11064, 11066, 11068, 11070, 11072, + 11074, 11076, 11078, 0, 11080, 11082, 11084, 11086, 0, 0, 11088, 11090, + 11092, 11094, 11096, 11098, 11100, 11102, 0, 11104, 11106, 11108, 11110, + 11112, 11114, 11116, 0, 11118, 11120, 11122, 11124, 11126, 11128, 11130, + 11132, 11134, 11136, 11138, 11140, 11142, 11144, 11146, 11148, 11150, + 11152, 11154, 11156, 11158, 11160, 11162, 11164, 11166, 11168, 11170, + 11172, 0, 11174, 11176, 11178, 11180, 0, 11182, 11184, 11186, 11188, + 11190, 0, 11192, 0, 0, 0, 11194, 11196, 11198, 11200, 11202, 11204, + 11206, 0, 11208, 11210, 11212, 11214, 11216, 11218, 11220, 11222, 11224, + 11226, 11228, 11230, 11232, 11234, 11236, 11238, 11240, 11242, 11244, + 11246, 11248, 11250, 11252, 11254, 11256, 11258, 11260, 11262, 11264, + 11266, 11268, 11270, 11272, 11274, 11276, 11278, 11280, 11282, 11284, + 11286, 11288, 11290, 11292, 11294, 11296, 11298, 11300, 11302, 11304, + 11306, 11308, 11310, 11312, 11314, 11316, 11318, 11320, 11322, 11324, + 11326, 11328, 11330, 11332, 11334, 11336, 11338, 11340, 11342, 11344, + 11346, 11348, 11350, 11352, 11354, 11356, 11358, 11360, 11362, 11364, + 11366, 11368, 11370, 11372, 11374, 11376, 11378, 11380, 11382, 11384, + 11386, 11388, 11390, 11392, 11394, 11396, 11398, 11400, 11402, 11404, + 11406, 11408, 11410, 11412, 11414, 11416, 11418, 11420, 11422, 11424, + 11426, 11428, 11430, 11432, 11434, 11436, 11438, 11440, 11442, 11444, + 11446, 11448, 11450, 11452, 11454, 11456, 11458, 11460, 11462, 11464, + 11466, 11468, 11470, 11472, 11474, 11476, 11478, 11480, 11482, 11484, + 11486, 11488, 11490, 11492, 11494, 11496, 11498, 11500, 11502, 11504, + 11506, 11508, 11510, 11512, 11514, 11516, 11518, 11520, 11522, 11524, + 11526, 11528, 11530, 11532, 11534, 11536, 11538, 11540, 11542, 11544, + 11546, 11548, 11550, 11552, 11554, 11556, 11558, 11560, 11562, 11564, + 11566, 11568, 11570, 11572, 11574, 11576, 11578, 11580, 11582, 11584, + 11586, 11588, 11590, 11592, 11594, 11596, 11598, 11600, 11602, 11604, + 11606, 11608, 11610, 11612, 11614, 11616, 11618, 11620, 11622, 11624, + 11626, 11628, 11630, 11632, 11634, 11636, 11638, 11640, 11642, 11644, + 11646, 11648, 11650, 11652, 11654, 11656, 11658, 11660, 11662, 11664, + 11666, 11668, 11670, 11672, 11674, 11676, 11678, 11680, 11682, 11684, + 11686, 11688, 11690, 11692, 11694, 11696, 11698, 11700, 11702, 11704, + 11706, 11708, 11710, 11712, 11714, 11716, 11718, 11720, 11722, 11724, + 11726, 11728, 11730, 11732, 11734, 11736, 11738, 11740, 11742, 11744, + 11746, 11748, 11750, 11752, 11754, 11756, 11758, 11760, 11762, 11764, + 11766, 11768, 11770, 11772, 11774, 11776, 11778, 11780, 11782, 11784, + 11786, 11788, 11790, 11792, 11794, 11796, 11798, 11800, 11802, 11804, + 11806, 11808, 11810, 11812, 11814, 11816, 11818, 11820, 11822, 11824, + 11826, 11828, 11830, 11832, 11834, 11836, 11838, 11840, 11842, 11844, + 11846, 11848, 11850, 11852, 11854, 11856, 11858, 11860, 11862, 11864, + 11866, 11868, 11870, 11872, 11874, 11876, 11878, 11880, 11882, 11884, + 11886, 0, 0, 11888, 11890, 11892, 11894, 11896, 11898, 11900, 11902, + 11904, 11906, 11908, 11910, 11912, 11914, 11916, 11918, 11920, 11922, + 11924, 11926, 11928, 11930, 11932, 11934, 11936, 11938, 11940, 11942, + 11944, 11946, 11948, 11950, 11952, 11954, 11956, 11958, 11960, 11962, + 11964, 11966, 11968, 11970, 11972, 11974, 11976, 11978, 11980, 11982, + 11984, 11986, 11988, 11990, 11992, 11994, 11996, 11998, 12000, 12002, + 12004, 12006, 12008, 12010, 12012, 12014, 12016, 12018, 12020, 12022, + 12024, 12026, 12028, 12030, 12032, 12034, 12036, 12038, 12040, 12042, + 12044, 12046, 12048, 12050, 12052, 12054, 12056, 12058, 12060, 12062, + 12064, 12066, 12068, 12070, 12072, 12074, 12076, 12078, 12080, 12082, + 12084, 12086, 12088, 12090, 12092, 12094, 12096, 12098, 12100, 12102, + 12104, 12106, 12108, 12110, 12112, 12114, 12116, 12118, 12120, 12122, + 12124, 12126, 12128, 12130, 12132, 12134, 12136, 12138, 12140, 12142, + 12144, 12146, 12148, 12150, 12152, 12154, 12156, 12158, 12160, 12162, + 12164, 12166, 12168, 12170, 12172, 12174, 12176, 12178, 12180, 12182, + 12184, 12186, 12188, 12190, 12192, 12194, 12196, 12198, 12200, 12202, + 12204, 12206, 12208, 12210, 12212, 12214, 12216, 12218, 12220, 12222, + 12224, 12226, 12228, 12230, 12232, 12234, 12236, 12238, 12240, 12242, + 12244, 12246, 12248, 12250, 12252, 12254, 12256, 12258, 12260, 12262, + 12264, 12266, 12268, 12270, 12272, 12274, 12276, 12278, 12280, 12282, + 12284, 12286, 12288, 12290, 12292, 12294, 12296, 12298, 12300, 12302, + 12304, 12306, 12308, 12310, 12312, 12314, 12316, 12318, 12320, 12322, + 12324, 12326, 12328, 12330, 12332, 12334, 12336, 12338, 12340, 12342, + 12344, 12346, 12348, 12350, 12352, 12354, 12356, 12358, 12360, 12362, + 12364, 12366, 12368, 12370, 12372, 12374, 12376, 12378, 12380, 12382, + 12384, 12386, 12388, 12390, 12392, 12394, 12396, 12398, 12400, 12402, + 12404, 12406, 12408, 12410, 12412, 12414, 12416, 12418, 12420, 12422, + 12424, 12426, 12428, 12430, 12432, 12434, 12436, 12438, 12440, 12442, + 12444, 12446, 12448, 12450, 12452, 12454, 12456, 12458, 12460, 12462, + 12464, 12466, 12468, 12470, 0, 0, 12472, 12474, 12476, 12478, 12480, + 12482, 12484, 12486, 12488, 12490, 12492, 12494, 12496, 12498, 12500, + 12502, 12504, 12506, 12508, 12510, 12512, 12514, 12516, 12518, 12520, + 12522, 12524, 12526, 12528, 12530, 12532, 12534, 12536, 12538, 12540, + 12542, 12544, 12546, 12548, 12550, 12552, 12554, 12556, 12558, 12560, + 12562, 12564, 12566, 12568, 12570, 12572, 12574, 12576, 12578, 0, 12580, + 12582, 12584, 12586, 12588, 12590, 12592, 12594, 12596, 12598, 12600, + 12602, 12604, 12606, 12608, 12610, 12612, 12614, 12616, 12618, 12620, + 12622, 12624, 12626, 12628, 12630, 12632, 0, 12634, 12636, 0, 12638, 0, + 0, 12640, 0, 12642, 12644, 12646, 12648, 12650, 12652, 12654, 12656, + 12658, 12660, 0, 12662, 12664, 12666, 12668, 0, 12670, 0, 12672, 0, 0, 0, + 0, 0, 0, 12674, 0, 0, 0, 0, 12676, 0, 12678, 0, 12680, 0, 12682, 12684, + 12686, 0, 12688, 12690, 0, 12692, 0, 0, 12694, 0, 12696, 0, 12698, 0, + 12700, 0, 12702, 0, 12704, 12706, 0, 12708, 0, 0, 12710, 12712, 12714, + 12716, 0, 12718, 12720, 12722, 12724, 12726, 12728, 12730, 0, 12732, + 12734, 12736, 12738, 0, 12740, 12742, 12744, 12746, 0, 12748, 0, 12750, + 12752, 12754, 12756, 12758, 12760, 12762, 12764, 12766, 12768, 0, 12770, + 12772, 12774, 12776, 12778, 12780, 12782, 12784, 12786, 12788, 12790, + 12792, 12794, 12796, 12798, 12800, 12802, 0, 0, 0, 0, 0, 12804, 12806, + 12808, 0, 12810, 12812, 12814, 12816, 12818, 0, 12820, 12822, 12824, + 12826, 12828, 12830, 12832, 12834, 12836, 12838, 12840, 12842, 12844, + 12846, 12848, 12850, 12852, 0, 0, 0, 0, 12854, 12857, 12860, 12863, + 12866, 12869, 12872, 12875, 12878, 12881, 12884, 0, 0, 0, 0, 0, 12887, + 12891, 12895, 12899, 12903, 12907, 12911, 12915, 12919, 12923, 12927, + 12931, 12935, 12939, 12943, 12947, 12951, 12955, 12959, 12963, 12967, + 12971, 12975, 12979, 12983, 12987, 12991, 12995, 12997, 12999, 13002, 0, + 13005, 13007, 13009, 13011, 13013, 13015, 13017, 13019, 13021, 13023, + 13025, 13027, 13029, 13031, 13033, 13035, 13037, 13039, 13041, 13043, + 13045, 13047, 13049, 13051, 13053, 13055, 13057, 13060, 13063, 13066, + 13069, 13073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13076, 13079, 0, 0, 0, 0, + 13082, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13085, 13088, 13091, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13093, 13095, 13097, 13099, 13101, + 13103, 13105, 13107, 13109, 13111, 13113, 13115, 13117, 13119, 13121, + 13123, 13125, 13127, 13129, 13131, 13133, 13135, 13137, 13139, 13141, + 13143, 13145, 13147, 13149, 13151, 13153, 13155, 13157, 13159, 13161, + 13163, 13165, 13167, 13169, 13171, 13173, 13175, 13177, 0, 0, 0, 0, 0, + 13179, 13183, 13187, 13191, 13195, 13199, 13203, 13207, 13211, 0, 0, 0, + 0, 0, 0, 0, 13215, 13217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13219, 13221, 13223, 13225, 13228, 13230, 13232, 13234, 13236, 13238, + 13240, 13242, 13244, 13246, 13249, 13251, 13253, 13255, 13257, 13260, + 13262, 13264, 13266, 13269, 13271, 13273, 13275, 13277, 13279, 13282, + 13284, 13286, 13288, 13290, 13292, 13294, 13296, 13298, 13300, 13302, + 13304, 13306, 13308, 13310, 13312, 13314, 13316, 13318, 13320, 13322, + 13324, 13326, 13328, 13331, 13333, 13335, 13337, 13340, 13342, 13344, + 13346, 13348, 13350, 13352, 13354, 13356, 13358, 13360, 13362, 13364, + 13366, 13368, 13370, 13372, 13374, 13376, 13378, 13380, 13382, 13384, + 13386, 13388, 13390, 13392, 13394, 13396, 13398, 13400, 13402, 13404, + 13407, 13409, 13411, 13413, 13415, 13417, 13419, 13422, 13425, 13427, + 13429, 13431, 13433, 13435, 13437, 13439, 13441, 13443, 13445, 13448, + 13450, 13452, 13454, 13456, 13459, 13461, 13463, 13465, 13467, 13469, + 13471, 13473, 13475, 13477, 13480, 13482, 13485, 13487, 13489, 13491, + 13493, 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13510, 13512, + 13514, 13516, 13518, 13520, 13523, 13525, 13528, 13531, 13533, 13535, + 13537, 13539, 13542, 13545, 13547, 13549, 13551, 13553, 13555, 13557, + 13559, 13561, 13563, 13565, 13567, 13570, 13572, 13574, 13576, 13578, + 13580, 13582, 13584, 13586, 13588, 13590, 13592, 13594, 13596, 13598, + 13600, 13602, 13604, 13606, 13608, 13611, 13613, 13615, 13617, 13619, + 13621, 13624, 13626, 13628, 13630, 13632, 13634, 13636, 13638, 13640, + 13642, 13644, 13646, 13649, 13651, 13653, 13655, 13657, 13659, 13661, + 13663, 13665, 13667, 13669, 13671, 13673, 13675, 13677, 13679, 13681, + 13683, 13685, 13688, 13690, 13692, 13694, 13696, 13698, 13701, 13703, + 13705, 13707, 13709, 13711, 13713, 13715, 13717, 13720, 13722, 13724, + 13726, 13729, 13731, 13733, 13735, 13737, 13739, 13741, 13744, 13747, + 13750, 13752, 13755, 13757, 13759, 13761, 13763, 13765, 13767, 13769, + 13771, 13773, 13775, 13778, 13780, 13782, 13784, 13786, 13788, 13790, + 13793, 13795, 13797, 13800, 13803, 13805, 13807, 13809, 13811, 13813, + 13815, 13817, 13819, 13821, 13824, 13826, 13829, 13831, 13834, 13836, + 13838, 13840, 13843, 13845, 13847, 13850, 13853, 13855, 13857, 13859, + 13861, 13863, 13865, 13867, 13869, 13871, 13873, 13875, 13877, 13879, + 13882, 13884, 13887, 13889, 13892, 13894, 13897, 13900, 13903, 13905, + 13907, 13909, 13912, 13915, 13918, 13921, 13923, 13925, 13927, 13929, + 13931, 13933, 13935, 13937, 13940, 13942, 13944, 13946, 13948, 13951, + 13953, 13956, 13959, 13961, 13963, 13965, 13967, 13969, 13971, 13974, + 13977, 13980, 13982, 13984, 13987, 13989, 13991, 13993, 13996, 13998, + 14000, 14002, 14004, 14006, 14009, 14011, 14013, 14015, 14017, 14019, + 14021, 14024, 14027, 14029, 14032, 14034, 14037, 14039, 14041, 14043, + 14046, 14049, 14051, 14054, 14056, 14059, 14061, 14063, 14065, 14067, + 14069, 14071, 14074, 14077, 14080, 14083, 14085, 14087, 14089, 14091, + 14093, 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14110, 14112, + 14114, 14116, 14118, 14120, 14122, 14124, 14126, 14128, 14130, 14132, + 14134, 14137, 14140, 14143, 14145, 14147, 14149, 14151, 14154, 14156, + 14159, 14161, 14163, 14166, 14169, 14171, 14173, 14175, 14177, 14179, + 14181, 14183, 14185, 14187, 14189, 14191, 14193, 14195, 14197, 14199, + 14201, 14203, 14205, 14207, 14210, 14212, 14214, 14216, 14218, 14220, + 14223, 14226, 14228, 14230, 14232, 14234, 14236, 14238, 14241, 14243, + 14245, 14247, 14249, 14252, 14255, 14257, 14259, 14261, 14264, 14266, + 14268, 14271, 14274, 14276, 14278, 14280, 14283, 14285, 14287, 14289, + 14291, 14293, 14295, 14297, 14300, 14302, 14304, 14306, 14309, 14311, + 14313, 14315, 14317, 14320, 14323, 14325, 14327, 14329, 14332, 14334, + 14337, 14339, 14341, 14343, 14346, 14348, 14350, 14352, 14354, 14356, + 14358, 14360, 14363, 14365, 14367, 14369, 14371, 14373, 14375, 14378, + 14380, 14383, 14386, 14389, 14391, 14393, 14395, 14397, 14399, 14401, + 14403, 14405, 0, 0, }; /* NFC pairs */ #define COMP_SHIFT1 2 #define COMP_SHIFT2 1 static const unsigned short comp_index0[] = { - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, - 0, 0, 0, 0, 7, 0, 8, 9, 0, 0, 0, 10, 11, 12, 0, 0, 0, 0, 13, 14, 15, 16, - 0, 0, 0, 17, 18, 19, 20, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 22, 23, 24, 0, 0, - 0, 0, 25, 26, 27, 28, 0, 0, 0, 29, 30, 31, 32, 0, 0, 0, 33, 0, 0, 0, 0, - 0, 0, 34, 35, 36, 37, 0, 0, 0, 38, 39, 40, 41, 0, 0, 0, 42, 0, 43, 0, 0, - 0, 0, 44, 45, 46, 47, 0, 0, 0, 48, 49, 50, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, - 0, 52, 53, 54, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 59, 60, 61, 62, 0, 0, - 0, 63, 64, 65, 66, 0, 0, 0, 67, 0, 68, 0, 0, 0, 0, 69, 0, 70, 0, 0, 0, 0, - 71, 0, 0, 0, 0, 0, 0, 72, 73, 74, 0, 0, 0, 0, 75, 76, 77, 78, 0, 0, 0, - 79, 80, 81, 0, 0, 0, 0, 82, 0, 83, 84, 0, 0, 0, 85, 86, 87, 0, 0, 0, 0, - 88, 89, 90, 91, 0, 0, 0, 92, 93, 94, 95, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, - 97, 98, 99, 0, 0, 0, 0, 100, 101, 102, 103, 0, 0, 0, 104, 105, 106, 107, - 0, 0, 0, 108, 109, 0, 0, 0, 0, 0, 110, 111, 112, 113, 0, 0, 0, 114, 115, - 116, 117, 0, 0, 0, 118, 0, 119, 0, 0, 0, 0, 120, 121, 122, 123, 0, 0, 0, - 124, 125, 126, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 128, 129, 130, 131, 0, - 0, 0, 132, 133, 134, 0, 0, 0, 0, 135, 136, 137, 138, 0, 0, 0, 139, 140, - 141, 142, 0, 0, 0, 143, 0, 144, 0, 0, 0, 0, 145, 146, 147, 0, 0, 0, 0, - 148, 0, 0, 0, 0, 0, 0, 149, 150, 151, 0, 0, 0, 0, 152, 153, 154, 155, 0, - 0, 0, 156, 0, 0, 157, 0, 0, 0, 158, 159, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, - 0, 0, 161, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, - 0, 164, 165, 0, 0, 0, 0, 0, 166, 0, 0, 0, 0, 0, 0, 167, 168, 0, 0, 0, 0, - 0, 169, 0, 0, 0, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, - 172, 173, 0, 0, 0, 0, 0, 174, 175, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, - 177, 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 180, - 181, 0, 0, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 183, 184, 0, 0, 0, 0, 0, 185, - 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 188, 189, - 0, 0, 0, 0, 0, 190, 191, 0, 0, 0, 0, 0, 192, 193, 0, 0, 0, 0, 0, 194, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 197, 0, 0, - 0, 0, 0, 0, 198, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, - 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, - 0, 0, 204, 0, 0, 0, 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 0, - 0, 207, 208, 209, 0, 0, 0, 0, 210, 211, 212, 0, 0, 0, 0, 213, 214, 215, - 0, 0, 0, 0, 216, 217, 218, 0, 0, 0, 0, 0, 219, 0, 0, 0, 0, 0, 220, 0, 0, - 0, 0, 0, 0, 221, 0, 0, 0, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, - 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, - 0, 0, 227, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 229, 230, 0, 231, 0, - 0, 0, 232, 233, 0, 0, 0, 0, 0, 234, 235, 0, 236, 0, 0, 0, 237, 238, 0, 0, - 0, 0, 0, 239, 240, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 242, 243, 0, 0, - 0, 0, 0, 244, 245, 0, 246, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 248, - 0, 0, 0, 249, 250, 0, 251, 0, 0, 0, 252, 253, 0, 0, 0, 0, 0, 254, 255, 0, - 256, 0, 0, 0, 257, 258, 0, 259, 0, 0, 0, 260, 261, 0, 0, 0, 0, 0, 0, 262, - 0, 0, 0, 0, 0, 263, 264, 0, 265, 0, 0, 0, 266, 267, 0, 268, 0, 0, 0, 269, - 0, 0, 270, 0, 0, 0, 271, 0, 0, 272, 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, 0, 277, 0, - 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 0, 0, 280, 0, 0, - 0, 0, 0, 0, 281, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 283, 0, 0, 0, - 0, 0, 0, 284, 285, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, - 0, 0, 288, 0, 0, 0, 0, 0, 0, 289, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, - 0, 291, 0, 0, 0, 0, 0, 0, 292, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, - 294, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 297, - 298, 0, 0, 0, 0, 0, 299, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 301, 0, - 0, 0, 0, 0, 0, 302, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 304, 0, - 0, 0, 0, 0, 305, 0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, - 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 310, 0, 0, 0, 0, 0, 311, 0, - 0, 0, 0, 0, 0, 312, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 314, 0, 0, - 0, 0, 0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 317, 0, 0, - 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 320, 0, 0, 0, - 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 322, 323, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, - 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, - 0, 0, 328, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, - 0, 331, 332, 0, 0, 0, 0, 0, 333, 0, 0, 0, 0, 0, 0, 0, 334, 0, 0, 0, 0, 0, - 0, 335, 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, 0, 0, 0, 337, 0, 0, 0, 0, 0, 0, - 338, 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, 341, - 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 344, 0, - 0, 0, 0, 0, 0, 345, 346, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 348, 0, - 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 351, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, - 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, - 0, 0, 358, 0, 0, 359, 0, 0, 0, 360, 0, 0, 361, 0, 0, 0, 0, 0, 0, 362, 0, - 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, 0, 365, 0, 0, - 0, 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 368, 0, 0, 369, 0, 0, 0, - 370, 0, 0, 371, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, - 0, 0, 374, 0, 0, 0, 0, 0, 0, 375, 0, 0, 0, 0, 0, 0, 376, 0, 0, 0, 0, 0, - 0, 377, 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 380, 0, 0, - 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 382, 0, 0, 383, 0, 0, 0, 384, 0, 0, - 385, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 388, - 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 391, 0, - 0, 0, 392, 0, 0, 393, 0, 0, 0, 394, 0, 0, 395, 0, 0, 0, 0, 0, 0, 396, 0, - 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 0, 399, 0, 0, - 0, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 401, 0, 0, 0, 402, 0, 0, 403, 0, 0, 0, - 404, 0, 0, 405, 0, 0, 0, 406, 0, 0, 407, 0, 0, 0, 408, 0, 0, 409, 0, 0, - 0, 410, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 412, 0, 0, 0, 0, 0, 0, - 413, 0, 0, 0, 0, 0, 0, 414, 0, 0, 415, 0, 0, 0, 416, 0, 0, 417, 0, 0, 0, - 418, 0, 0, 419, 0, 0, 0, 420, 0, 0, 421, 0, 0, 0, 422, 0, 0, 423, 0, 0, - 0, 0, 0, 0, 424, 0, 0, 0, 0, 0, 0, 425, 0, 0, 0, 0, 0, 0, 426, 0, 0, 0, - 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 429, 0, 0, 0, 430, - 0, 0, 431, 0, 0, 0, 432, 0, 0, 433, 0, 0, 0, 0, 0, 0, 434, 0, 0, 0, 0, 0, - 0, 435, 0, 0, 0, 0, 0, 0, 436, 0, 0, 0, 0, 0, 0, 437, 0, 0, 0, 0, 0, 0, - 438, 0, 0, 0, 0, 0, 0, 439, 0, 0, 0, 0, 0, 0, 440, 0, 0, 0, 0, 0, 0, 441, - 0, 0, 0, 0, 0, 0, 442, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 444, 0, 0, 445, 0, - 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 447, 0, 0, 0, 448, 0, 0, 449, 0, 0, - 0, 0, 0, 0, 450, 0, 0, 0, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, 452, 0, 0, 0, - 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 454, 0, 0, 0, 0, 0, 0, 455, 0, 0, 0, 0, - 0, 0, 456, 0, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, - 0, 459, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, 0, 0, 0, 461, 0, 0, 0, 0, 0, 0, - 462, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, 0, 465, - 0, 0, 0, 0, 0, 0, 466, 0, 0, 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 468, 0, - 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 0, 471, 0, 0, - 0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, 0, 474, 0, 0, 0, - 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 476, 0, 0, 0, 0, 0, 0, 477, 0, 0, 0, 0, - 0, 0, 478, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, - 0, 481, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 483, 0, 0, 0, 0, 0, 0, - 484, 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0, 0, 0, 0, 0, 487, - 0, 0, 0, 0, 0, 0, 488, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, 0, 0, 0, 490, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 0, - 493, 0, 0, 0, 0, 0, 0, 494, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 496, - 0, 0, 0, 0, 0, 0, 497, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 499, 0, - 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 502, 0, 0, - 0, 0, 0, 0, 503, 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0, - 0, 0, 0, 506, 0, 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, - 0, 0, 509, 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, - 0, 512, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 518, - 0, 0, 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 521, 0, - 0, 0, 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 524, 0, 0, - 0, 0, 0, 0, 525, 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, - 0, 0, 0, 528, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 530, 0, 0, 0, 0, - 0, 0, 531, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, - 0, 534, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, 0, 0, 0, - 537, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 539, 0, 0, 0, 0, 0, 0, 540, - 0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, 543, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, + 5, 6, 7, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 11, 12, 13, 14, 0, 0, 0, 0, 0, + 15, 16, 17, 0, 0, 0, 0, 18, 19, 20, 21, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, + 23, 24, 25, 26, 0, 0, 0, 0, 27, 28, 29, 30, 0, 0, 0, 0, 31, 32, 33, 34, + 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 36, 0, 37, 38, 39, 0, 0, 0, 40, 41, 42, + 43, 0, 0, 0, 0, 44, 45, 46, 0, 0, 0, 0, 0, 47, 48, 49, 50, 0, 0, 0, 51, + 52, 53, 54, 0, 0, 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, 57, 58, 59, 60, 0, 0, + 0, 0, 61, 62, 63, 0, 0, 0, 0, 0, 64, 65, 66, 67, 0, 0, 0, 68, 69, 70, 71, + 0, 0, 0, 0, 72, 0, 73, 0, 0, 0, 0, 0, 74, 0, 75, 0, 0, 0, 0, 0, 76, 0, 0, + 0, 0, 0, 0, 77, 78, 79, 0, 0, 0, 0, 0, 80, 81, 82, 83, 0, 0, 0, 0, 84, + 85, 86, 0, 0, 0, 0, 0, 87, 88, 0, 89, 0, 0, 0, 90, 91, 0, 92, 0, 0, 0, 0, + 0, 93, 94, 95, 0, 0, 0, 0, 96, 97, 98, 99, 0, 0, 0, 0, 100, 0, 0, 0, 0, + 0, 0, 101, 102, 0, 103, 0, 0, 0, 0, 104, 105, 106, 107, 0, 0, 0, 0, 108, + 109, 110, 111, 0, 0, 0, 0, 112, 113, 0, 0, 0, 0, 0, 114, 115, 116, 117, + 0, 0, 0, 0, 118, 119, 120, 121, 0, 0, 0, 0, 122, 0, 123, 0, 0, 0, 0, 124, + 125, 126, 127, 128, 0, 0, 0, 129, 130, 131, 132, 0, 0, 0, 0, 133, 134, 0, + 0, 0, 0, 0, 0, 135, 136, 137, 138, 0, 0, 0, 139, 140, 141, 142, 0, 0, 0, + 0, 0, 143, 144, 145, 0, 0, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0, 150, 0, + 151, 0, 0, 0, 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, 155, 0, 0, 0, 0, 0, 0, + 156, 157, 158, 0, 0, 0, 0, 0, 159, 160, 161, 162, 0, 0, 0, 163, 0, 0, 0, + 164, 0, 0, 0, 165, 166, 0, 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 0, 0, 168, + 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, + 172, 173, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 175, 176, 0, 0, 0, 0, + 0, 0, 177, 178, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, + 0, 0, 0, 181, 182, 183, 0, 0, 0, 0, 0, 184, 185, 0, 0, 0, 0, 0, 0, 186, + 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 188, 189, 0, 0, 0, 0, 0, 0, + 190, 0, 0, 0, 0, 0, 0, 0, 191, 192, 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, 0, 0, + 0, 194, 195, 0, 0, 0, 0, 0, 0, 196, 197, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, + 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 200, 201, 202, 0, 0, 0, 0, 0, 203, + 204, 0, 0, 0, 0, 0, 0, 205, 206, 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, 0, 0, 0, + 208, 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, + 0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, + 0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, + 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 219, 0, + 0, 0, 0, 0, 0, 220, 221, 222, 0, 0, 0, 0, 0, 223, 224, 225, 0, 0, 0, 0, + 0, 226, 227, 228, 0, 0, 0, 0, 0, 229, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, + 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 235, 0, + 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 238, + 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, + 241, 0, 0, 0, 0, 0, 0, 242, 0, 243, 244, 0, 0, 0, 0, 245, 246, 0, 0, 0, + 0, 0, 247, 0, 248, 0, 249, 0, 0, 0, 250, 251, 252, 0, 0, 0, 0, 0, 253, 0, + 254, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 256, 257, 258, 0, 0, 0, 0, 0, + 259, 0, 260, 0, 261, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 263, 0, + 0, 0, 264, 265, 266, 0, 267, 0, 0, 0, 268, 0, 269, 0, 0, 0, 0, 0, 270, 0, + 271, 272, 0, 0, 0, 0, 273, 274, 0, 275, 0, 0, 0, 276, 0, 277, 0, 0, 0, 0, + 0, 0, 0, 278, 0, 0, 0, 0, 0, 279, 280, 281, 282, 0, 0, 0, 0, 283, 284, 0, + 285, 0, 0, 0, 286, 0, 0, 0, 287, 0, 0, 0, 288, 0, 0, 0, 289, 0, 0, 0, 0, + 0, 0, 290, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 292, 0, 0, 0, 0, 0, 0, + 0, 293, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 298, 299, 0, 0, 0, + 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 302, 0, 0, + 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 305, 0, + 0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 308, + 0, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 0, + 311, 312, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, + 0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 317, 0, 0, 0, 0, + 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0, + 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 323, 0, + 0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 326, 0, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0, + 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, + 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 333, 0, 0, 0, 0, 0, 0, 334, 0, 0, + 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 336, 337, 0, 0, 0, 0, 0, 0, 0, + 338, 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, + 0, 341, 0, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, + 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, + 0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 350, 0, + 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 353, + 0, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0, + 356, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 358, 0, 0, 0, 0, 0, 0, + 0, 359, 0, 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 361, 0, 362, 0, 0, 0, + 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, 0, 0, 365, 0, + 0, 0, 0, 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 368, + 0, 0, 0, 0, 0, 0, 369, 370, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0, + 372, 0, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 374, 0, 0, 0, 0, 0, 0, + 0, 375, 0, 0, 376, 0, 0, 0, 0, 377, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 379, + 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0, + 382, 0, 0, 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 385, 0, + 0, 386, 0, 0, 0, 0, 387, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, + 0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 391, 0, 0, 0, 0, 0, 0, 0, 392, 0, 0, 0, + 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 395, 0, 0, 0, 0, 0, + 0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, + 0, 0, 0, 399, 0, 0, 400, 0, 0, 0, 0, 401, 0, 0, 402, 0, 0, 0, 0, 0, 0, 0, + 403, 0, 0, 0, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 405, 0, 0, 0, 0, 0, 0, + 0, 406, 0, 0, 0, 0, 0, 0, 0, 407, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 409, + 0, 0, 410, 0, 0, 0, 0, 411, 0, 0, 412, 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, + 0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, + 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, 0, 418, 0, 0, 0, 419, 0, 0, 420, 0, + 0, 0, 0, 421, 0, 0, 422, 0, 0, 0, 423, 0, 0, 0, 424, 0, 0, 0, 425, 0, 0, + 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 429, 0, + 0, 0, 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, 0, 0, 431, 0, 0, 432, 0, 0, 0, 0, + 433, 0, 0, 434, 0, 0, 0, 435, 0, 0, 0, 436, 0, 0, 0, 437, 0, 0, 0, 438, + 0, 0, 0, 439, 0, 0, 440, 0, 0, 0, 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, + 442, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0, + 0, 445, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 447, 0, 0, 0, 448, 0, 0, 0, + 449, 0, 0, 450, 0, 0, 0, 0, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, 0, 452, 0, 0, + 0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 454, 0, 0, 0, 0, 0, 0, 0, 455, 0, + 0, 0, 0, 0, 0, 0, 456, 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 458, + 0, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, 461, 0, 0, + 0, 462, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 465, 0, + 0, 0, 466, 0, 0, 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 0, 468, 0, 0, 0, 0, + 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0, + 0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, 0, 0, 474, 0, + 0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, 0, 0, 0, 0, 0, 477, + 0, 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 0, + 480, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, + 0, 483, 0, 0, 0, 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, + 0, 0, 0, 486, 0, 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 0, + 0, 0, 0, 0, 489, 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 491, 0, 0, + 0, 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, 0, 0, 494, + 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, + 497, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0, + 0, 500, 0, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, + 0, 0, 503, 0, 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0, + 0, 0, 0, 0, 506, 0, 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 508, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, + 0, 0, 511, 0, 0, 0, 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, + 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 515, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, + 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 0, 518, 0, 0, 0, 0, 0, 0, 0, 519, 0, + 0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, 0, 0, 522, + 0, 0, 0, 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, + 525, 0, 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, 0, 0, + 0, 528, 0, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 530, 0, 0, 0, 0, + 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, + 0, 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0, + 0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 0, 539, + 0, 0, 0, 0, 0, 0, 540, 0, 0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0, + 542, 0, 0, 0, 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0, + 0, 545, 0, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 0, 0, 0, 0, 547, 0, 0, 0, 0, + 0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0, + 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0, + 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 556, + 0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, 0, 0, + 559, 0, 0, 0, 0, 0, 0, 0, 560, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, + 0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 564, }; static const unsigned short comp_index1[] = { - 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 4, 5, 6, 7, 8, 9, 10, 0, - 11, 12, 0, 13, 0, 0, 0, 14, 15, 0, 0, 0, 0, 16, 0, 0, 17, 18, 0, 19, 0, - 20, 0, 0, 0, 0, 21, 0, 0, 0, 0, 22, 0, 23, 0, 0, 24, 0, 25, 26, 0, 27, 0, - 0, 28, 29, 30, 31, 32, 33, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 0, 0, - 39, 40, 41, 42, 43, 0, 44, 0, 0, 0, 0, 45, 0, 0, 46, 0, 47, 0, 48, 0, 0, - 49, 0, 50, 0, 51, 0, 0, 0, 52, 53, 54, 55, 56, 57, 58, 0, 59, 0, 0, 60, - 61, 0, 0, 0, 0, 62, 0, 0, 63, 0, 0, 0, 0, 64, 0, 0, 65, 0, 66, 0, 0, 67, - 0, 0, 68, 0, 0, 0, 0, 69, 0, 0, 70, 0, 71, 72, 0, 73, 0, 0, 74, 0, 0, 75, - 76, 0, 0, 0, 77, 78, 0, 79, 0, 80, 0, 0, 81, 0, 82, 83, 0, 84, 0, 0, 85, - 86, 87, 88, 89, 90, 91, 0, 92, 0, 0, 93, 94, 0, 0, 95, 96, 0, 0, 97, 0, - 98, 99, 0, 100, 0, 101, 0, 0, 102, 0, 0, 103, 104, 0, 105, 0, 106, 0, 0, - 107, 0, 108, 0, 0, 0, 0, 109, 0, 110, 0, 0, 111, 0, 112, 113, 0, 114, 0, - 0, 115, 116, 117, 118, 119, 120, 121, 0, 122, 123, 0, 124, 125, 0, 0, 0, - 0, 126, 0, 0, 127, 0, 0, 0, 128, 129, 0, 130, 131, 0, 0, 0, 0, 0, 0, 132, - 133, 134, 135, 136, 137, 0, 0, 0, 138, 0, 0, 0, 139, 140, 0, 141, 0, 142, - 0, 0, 143, 0, 0, 0, 0, 144, 0, 0, 145, 146, 147, 148, 149, 150, 151, 0, - 152, 153, 0, 154, 0, 0, 0, 155, 156, 0, 0, 0, 0, 157, 0, 0, 158, 159, 0, - 160, 0, 161, 0, 0, 0, 0, 162, 0, 0, 0, 0, 163, 0, 164, 0, 0, 165, 0, 166, - 167, 0, 168, 0, 0, 169, 170, 171, 172, 173, 174, 175, 0, 176, 0, 177, - 178, 179, 0, 0, 0, 0, 0, 0, 180, 181, 182, 183, 184, 0, 185, 0, 0, 0, 0, - 186, 0, 0, 187, 0, 188, 0, 189, 0, 0, 190, 0, 191, 0, 192, 193, 0, 0, - 194, 195, 196, 197, 198, 199, 200, 0, 201, 0, 0, 202, 203, 0, 0, 0, 0, - 204, 0, 0, 0, 205, 0, 0, 206, 0, 0, 0, 0, 207, 0, 0, 208, 0, 209, 0, 0, - 210, 0, 0, 211, 0, 0, 0, 0, 212, 0, 0, 213, 0, 214, 215, 0, 216, 0, 0, - 217, 0, 0, 218, 219, 0, 0, 0, 220, 221, 0, 222, 0, 223, 0, 0, 224, 0, - 225, 226, 0, 227, 0, 0, 228, 229, 230, 231, 232, 233, 234, 0, 235, 0, 0, - 236, 237, 0, 0, 238, 239, 0, 0, 240, 0, 241, 242, 0, 243, 0, 244, 0, 0, - 245, 0, 0, 246, 247, 0, 248, 0, 249, 0, 0, 250, 0, 251, 0, 0, 0, 0, 252, - 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 0, 0, 258, 259, 260, 261, 262, - 263, 264, 0, 265, 266, 0, 267, 268, 0, 0, 0, 0, 269, 0, 0, 270, 0, 0, 0, - 271, 272, 0, 273, 274, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 276, 277, 278, - 279, 280, 281, 0, 0, 0, 282, 0, 0, 0, 283, 284, 0, 285, 0, 286, 0, 0, - 287, 0, 0, 0, 0, 288, 0, 0, 289, 0, 0, 0, 0, 0, 290, 0, 291, 292, 0, 0, - 293, 0, 0, 0, 0, 0, 294, 0, 295, 0, 0, 0, 296, 0, 297, 0, 298, 0, 0, 0, - 299, 300, 0, 0, 301, 0, 0, 0, 302, 0, 0, 0, 303, 304, 0, 0, 305, 0, 0, 0, - 306, 0, 307, 308, 0, 0, 309, 0, 310, 0, 0, 0, 311, 0, 312, 0, 0, 313, 0, - 0, 314, 315, 0, 0, 316, 0, 0, 0, 0, 0, 317, 0, 318, 0, 0, 0, 319, 0, 320, - 0, 321, 0, 0, 0, 322, 323, 0, 0, 324, 0, 0, 0, 325, 0, 0, 0, 326, 327, 0, - 0, 328, 0, 0, 0, 329, 0, 330, 331, 0, 0, 332, 0, 333, 0, 0, 0, 334, 0, - 335, 0, 0, 336, 0, 0, 337, 338, 0, 0, 339, 0, 0, 0, 340, 341, 0, 0, 342, - 0, 0, 0, 343, 0, 0, 0, 344, 0, 0, 0, 345, 0, 0, 0, 346, 0, 0, 0, 0, 0, 0, - 347, 0, 0, 0, 348, 0, 0, 0, 349, 0, 0, 0, 350, 351, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 353, 0, 0, 0, 354, 0, 0, 0, 355, 356, 357, 0, 0, 358, 0, 0, - 0, 359, 0, 0, 0, 360, 361, 0, 0, 362, 0, 0, 0, 363, 0, 0, 0, 364, 365, 0, - 0, 366, 0, 0, 0, 367, 0, 0, 0, 368, 369, 0, 0, 370, 0, 0, 0, 371, 0, 0, - 0, 0, 372, 0, 0, 0, 0, 373, 0, 0, 0, 374, 0, 0, 0, 375, 0, 0, 0, 376, 0, - 0, 0, 377, 0, 0, 0, 378, 0, 0, 0, 379, 0, 0, 0, 380, 0, 0, 381, 0, 0, - 382, 0, 383, 0, 0, 0, 0, 384, 0, 0, 385, 0, 386, 0, 0, 0, 0, 0, 0, 387, - 388, 0, 0, 0, 0, 0, 0, 389, 0, 0, 390, 0, 391, 0, 392, 393, 0, 0, 0, 394, - 395, 0, 0, 0, 0, 0, 0, 396, 0, 0, 0, 397, 398, 0, 399, 400, 0, 0, 0, 401, - 402, 0, 0, 0, 0, 0, 0, 403, 0, 0, 404, 0, 0, 0, 405, 0, 0, 0, 406, 0, - 407, 0, 408, 0, 0, 0, 0, 409, 0, 0, 410, 0, 411, 0, 0, 0, 0, 0, 0, 412, - 413, 0, 0, 0, 0, 0, 0, 414, 0, 0, 415, 0, 416, 0, 417, 418, 0, 0, 0, 419, - 0, 0, 420, 0, 421, 0, 0, 0, 0, 0, 0, 422, 0, 0, 0, 423, 424, 0, 425, 426, - 0, 0, 0, 427, 0, 0, 428, 0, 429, 0, 0, 0, 0, 0, 0, 430, 0, 0, 431, 0, - 432, 0, 0, 0, 0, 0, 433, 0, 434, 0, 0, 0, 0, 0, 435, 0, 0, 0, 436, 0, - 437, 0, 0, 438, 0, 0, 0, 439, 0, 0, 440, 441, 442, 0, 0, 0, 443, 0, 444, - 445, 0, 0, 446, 447, 0, 0, 0, 448, 449, 0, 450, 451, 452, 0, 0, 0, 0, 0, - 0, 453, 0, 0, 454, 455, 0, 456, 0, 0, 0, 0, 0, 457, 0, 0, 0, 458, 0, 0, - 0, 459, 0, 0, 460, 461, 462, 0, 0, 0, 463, 0, 464, 465, 0, 0, 466, 467, - 0, 0, 0, 468, 469, 0, 470, 471, 472, 0, 0, 0, 0, 0, 0, 473, 0, 0, 474, - 475, 0, 476, 0, 0, 0, 0, 0, 477, 0, 0, 0, 478, 0, 0, 0, 479, 0, 0, 0, - 480, 0, 0, 481, 0, 0, 0, 482, 0, 0, 0, 0, 483, 0, 0, 0, 484, 0, 0, 0, - 485, 0, 0, 0, 486, 0, 0, 0, 487, 488, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, - 490, 0, 0, 0, 491, 0, 0, 0, 492, 0, 0, 0, 493, 494, 0, 0, 0, 495, 0, 0, - 0, 496, 0, 0, 0, 0, 497, 0, 0, 0, 0, 498, 499, 500, 0, 0, 0, 0, 0, 0, - 501, 502, 0, 0, 0, 0, 0, 0, 503, 504, 0, 0, 0, 0, 505, 0, 0, 0, 506, 507, - 0, 0, 508, 0, 0, 0, 0, 509, 510, 0, 0, 511, 0, 0, 0, 0, 512, 513, 0, 0, - 0, 0, 0, 0, 514, 0, 515, 0, 0, 0, 516, 0, 0, 0, 517, 0, 0, 0, 518, 0, 0, - 0, 519, 0, 0, 0, 520, 0, 0, 0, 521, 0, 0, 0, 522, 0, 0, 0, 523, 0, 0, 0, - 524, 0, 0, 0, 525, 0, 0, 0, 526, 0, 0, 0, 0, 527, 0, 0, 0, 528, 0, 0, 0, - 529, 0, 0, 0, 530, 0, 0, 0, 0, 531, 0, 0, 0, 532, 0, 533, 534, 0, 0, 535, - 536, 0, 0, 537, 0, 0, 0, 538, 0, 0, 0, 539, 0, 0, 0, 540, 0, 0, 541, 0, - 0, 0, 0, 0, 542, 0, 543, 0, 0, 0, 0, 0, 544, 0, 0, 0, 545, 0, 0, 0, 546, - 0, 0, 0, 547, 0, 0, 0, 548, 0, 0, 0, 549, 0, 0, 0, 550, 0, 551, 0, 0, 0, - 0, 0, 552, 0, 553, 0, 0, 0, 0, 0, 554, 0, 0, 0, 555, 0, 0, 0, 556, 0, 0, - 0, 557, 0, 0, 0, 558, 0, 0, 0, 559, 0, 0, 0, 560, 0, 561, 0, 0, 0, 562, - 0, 0, 0, 563, 0, 0, 0, 564, 0, 0, 0, 565, 0, 0, 0, 0, 0, 566, 0, 567, 0, - 0, 0, 0, 0, 568, 0, 0, 0, 569, 0, 0, 0, 570, 0, 0, 0, 571, 0, 0, 0, 572, - 0, 0, 0, 573, 0, 0, 0, 574, 0, 575, 0, 0, 0, 0, 0, 576, 0, 577, 0, 0, 0, - 0, 0, 578, 0, 0, 0, 579, 0, 0, 0, 580, 0, 0, 0, 581, 0, 0, 0, 582, 0, 0, - 0, 583, 0, 0, 0, 584, 0, 585, 0, 0, 0, 0, 0, 586, 0, 587, 0, 0, 0, 0, 0, - 588, 0, 589, 0, 0, 0, 0, 0, 590, 0, 591, 0, 0, 0, 0, 0, 592, 0, 593, 0, - 0, 0, 594, 0, 0, 0, 595, 0, 0, 0, 596, 0, 0, 0, 597, 0, 0, 0, 0, 0, 598, - 0, 599, 0, 0, 0, 0, 0, 600, 0, 601, 0, 0, 0, 0, 0, 602, 0, 603, 0, 0, 0, - 0, 0, 604, 0, 605, 0, 0, 0, 0, 0, 606, 0, 0, 0, 607, 0, 0, 0, 608, 0, 0, - 0, 609, 0, 0, 0, 610, 0, 0, 0, 611, 0, 0, 0, 612, 0, 613, 0, 0, 0, 0, 0, - 614, 0, 615, 0, 0, 0, 0, 0, 616, 0, 0, 0, 617, 0, 0, 0, 618, 0, 0, 0, - 619, 0, 0, 0, 620, 0, 0, 0, 621, 0, 0, 0, 622, 0, 0, 0, 623, 0, 0, 0, - 624, 0, 0, 0, 625, 0, 0, 0, 626, 0, 627, 0, 0, 0, 0, 0, 628, 0, 0, 0, - 629, 0, 0, 0, 630, 0, 631, 0, 0, 0, 0, 0, 632, 0, 0, 633, 0, 0, 0, 634, - 0, 0, 0, 635, 0, 0, 0, 636, 0, 0, 0, 637, 0, 0, 0, 638, 0, 0, 0, 639, 0, - 0, 0, 640, 0, 0, 0, 641, 0, 0, 0, 642, 0, 0, 0, 643, 0, 0, 0, 644, 0, 0, - 0, 645, 0, 0, 0, 646, 0, 0, 0, 647, 0, 0, 0, 648, 0, 0, 0, 649, 0, 0, 0, - 650, 0, 0, 0, 651, 0, 0, 0, 652, 0, 0, 0, 653, 0, 0, 0, 654, 0, 0, 0, - 655, 0, 0, 0, 656, 0, 0, 0, 657, 0, 0, 0, 658, 0, 0, 0, 659, 0, 0, 0, - 660, 0, 0, 0, 661, 0, 0, 0, 662, 0, 0, 0, 663, 0, 0, 0, 664, 0, 0, 0, - 665, 0, 0, 0, 666, 0, 0, 0, 667, 0, 0, 0, 668, 0, 0, 0, 669, 0, 0, 0, - 670, 0, 0, 0, 671, 0, 0, 0, 672, 0, 0, 0, 673, 0, 0, 0, 0, 674, 0, 0, 0, - 675, 0, 0, 0, 676, 0, 0, 0, 677, 0, 0, 0, 678, 0, 0, 0, 679, 0, 0, 0, - 680, 0, 0, 0, 681, 0, 0, 0, 682, 0, 0, 0, 683, 0, 0, 0, 684, 0, 0, 0, - 685, 0, 0, 0, 686, 0, 0, 0, 687, 0, 0, 0, 688, 0, 0, 0, 689, 0, 0, 0, - 690, 0, 0, 0, 691, 0, 0, 0, 692, 0, 0, 0, 693, 0, 0, 0, 694, 0, 0, 0, - 695, 0, 0, 0, 696, 0, 0, 0, 697, 0, 0, 0, 698, 0, 0, 0, 699, 0, 0, 0, - 700, 0, 0, 0, 701, 0, 0, 0, 702, 0, 0, 0, 703, 0, 0, 0, 704, 0, 0, 0, - 705, 0, 0, 0, 706, 0, 0, 0, 707, 0, 0, 0, 708, 0, 0, 0, 709, 0, 0, 0, - 710, 0, 0, 0, 711, 0, 0, 0, 712, 0, 0, 0, 713, 0, 0, 0, 714, 0, 0, 0, - 715, 0, 0, 0, 716, 0, 0, 0, 717, 0, 0, 0, 718, 0, 0, 0, 719, 0, 0, 0, - 720, 0, 0, 0, 721, 0, 0, 0, 0, 722, 0, 0, 0, 723, 0, 0, 0, 724, 0, 0, 0, - 725, 0, 0, 0, 726, + 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, + 0, 11, 12, 0, 13, 0, 0, 0, 0, 0, 0, 14, 15, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 17, 18, 0, 19, 0, 20, 0, 0, 0, 0, 21, 0, 0, 0, 22, 0, 23, 0, 0, 24, 0, + 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 33, 34, 0, 35, 0, 36, 37, 38, 0, 0, + 0, 0, 0, 39, 0, 0, 0, 40, 41, 42, 43, 0, 44, 0, 0, 0, 0, 45, 0, 0, 0, 0, + 0, 46, 0, 47, 0, 48, 0, 0, 49, 0, 50, 0, 51, 0, 0, 52, 53, 54, 55, 56, + 57, 58, 0, 59, 0, 0, 60, 61, 0, 0, 0, 62, 0, 0, 0, 0, 0, 63, 64, 0, 0, + 65, 0, 66, 0, 0, 67, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 69, 0, 0, 70, 0, 71, + 72, 0, 73, 0, 74, 0, 0, 75, 0, 0, 0, 0, 76, 0, 0, 77, 78, 0, 79, 0, 80, + 0, 0, 81, 0, 82, 83, 0, 84, 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, 90, 91, 0, + 92, 0, 0, 93, 0, 0, 0, 94, 0, 0, 95, 0, 0, 0, 96, 0, 0, 97, 0, 98, 99, 0, + 100, 0, 101, 0, 0, 102, 0, 103, 104, 0, 105, 0, 106, 0, 0, 107, 0, 108, + 0, 0, 0, 109, 0, 110, 0, 0, 111, 0, 112, 113, 0, 114, 0, 0, 0, 0, 0, 115, + 116, 117, 118, 119, 120, 121, 0, 122, 123, 0, 124, 125, 0, 0, 0, 126, 0, + 0, 127, 0, 0, 128, 129, 0, 130, 131, 0, 0, 0, 0, 0, 132, 0, 0, 0, 133, + 134, 135, 136, 137, 0, 0, 0, 138, 0, 0, 139, 140, 0, 141, 0, 142, 0, 0, + 143, 0, 0, 0, 0, 144, 0, 145, 146, 147, 148, 149, 150, 151, 0, 152, 153, + 0, 154, 0, 0, 155, 0, 0, 0, 0, 156, 157, 0, 0, 0, 0, 0, 158, 159, 0, 160, + 0, 161, 162, 0, 0, 0, 163, 0, 164, 0, 0, 165, 0, 166, 167, 0, 168, 0, + 169, 170, 171, 172, 173, 174, 175, 0, 176, 0, 177, 178, 179, 0, 0, 0, 0, + 0, 180, 0, 0, 0, 181, 182, 183, 184, 0, 185, 186, 0, 0, 0, 0, 0, 187, 0, + 188, 0, 189, 0, 0, 190, 0, 191, 0, 192, 193, 0, 194, 195, 196, 197, 198, + 199, 200, 0, 201, 0, 0, 202, 203, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 0, + 0, 206, 0, 0, 0, 0, 207, 0, 0, 208, 0, 209, 0, 0, 210, 0, 211, 0, 0, 0, + 0, 212, 0, 0, 213, 0, 214, 215, 0, 216, 0, 217, 0, 0, 218, 219, 0, 0, 0, + 0, 0, 0, 220, 221, 0, 222, 0, 223, 0, 0, 224, 0, 225, 226, 0, 227, 0, 0, + 0, 0, 0, 228, 229, 230, 231, 232, 233, 234, 0, 235, 0, 0, 236, 0, 0, 0, + 237, 0, 0, 238, 0, 0, 0, 239, 0, 0, 240, 0, 241, 242, 0, 243, 0, 244, 0, + 0, 245, 0, 0, 0, 0, 0, 246, 247, 0, 248, 0, 249, 0, 0, 250, 0, 251, 0, 0, + 0, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 0, 258, 259, 260, 261, + 262, 263, 264, 0, 265, 266, 0, 267, 268, 0, 0, 0, 269, 0, 0, 270, 0, 0, + 0, 0, 0, 0, 271, 272, 0, 273, 274, 0, 0, 0, 275, 0, 276, 0, 0, 0, 277, + 278, 279, 280, 281, 0, 0, 0, 282, 0, 0, 283, 284, 0, 285, 0, 286, 0, 0, + 287, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 289, 0, 290, 0, 0, 0, 0, 291, 292, + 0, 0, 293, 0, 0, 0, 0, 294, 295, 0, 0, 0, 0, 0, 0, 296, 0, 297, 0, 0, 0, + 0, 298, 0, 0, 299, 300, 0, 0, 301, 0, 0, 302, 0, 0, 0, 0, 0, 0, 303, 304, + 0, 0, 305, 0, 0, 306, 0, 307, 308, 0, 0, 0, 0, 0, 309, 310, 0, 0, 0, 0, + 0, 0, 311, 0, 312, 0, 0, 313, 0, 0, 0, 0, 0, 314, 315, 0, 0, 316, 0, 0, + 0, 0, 317, 318, 0, 0, 0, 0, 0, 0, 319, 0, 320, 0, 0, 0, 0, 321, 0, 0, + 322, 323, 0, 0, 324, 0, 0, 325, 0, 0, 0, 0, 0, 0, 326, 327, 0, 0, 328, 0, + 0, 329, 0, 330, 331, 0, 0, 0, 0, 0, 332, 333, 0, 0, 0, 0, 0, 0, 334, 0, + 335, 0, 0, 336, 0, 0, 0, 0, 0, 337, 338, 0, 0, 339, 0, 0, 340, 341, 0, 0, + 342, 0, 0, 343, 0, 0, 0, 0, 0, 0, 344, 0, 0, 345, 0, 0, 346, 0, 0, 0, 0, + 0, 347, 0, 0, 348, 0, 0, 349, 0, 0, 350, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, + 352, 0, 353, 0, 0, 354, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 356, 357, 0, 0, + 358, 0, 0, 0, 359, 0, 0, 360, 361, 0, 0, 362, 0, 0, 0, 363, 0, 0, 364, + 365, 0, 0, 366, 0, 0, 0, 367, 0, 0, 368, 369, 0, 0, 370, 0, 0, 0, 371, 0, + 0, 0, 372, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 374, 0, 0, 375, 0, 0, 376, 0, + 0, 377, 0, 0, 0, 0, 0, 0, 378, 0, 0, 379, 0, 0, 380, 0, 0, 0, 0, 0, 381, + 0, 382, 0, 383, 384, 0, 0, 0, 0, 0, 0, 385, 386, 0, 0, 0, 0, 0, 0, 387, + 0, 0, 0, 388, 0, 0, 389, 0, 0, 390, 0, 0, 0, 0, 391, 0, 392, 393, 0, 0, + 0, 394, 0, 0, 0, 395, 0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 398, 0, + 399, 400, 0, 0, 0, 401, 0, 0, 0, 402, 0, 0, 403, 0, 0, 404, 0, 0, 0, 0, + 0, 0, 405, 0, 0, 406, 0, 0, 0, 0, 407, 0, 408, 0, 0, 0, 0, 409, 0, 0, + 410, 0, 0, 0, 0, 411, 0, 0, 412, 0, 0, 0, 413, 0, 0, 414, 0, 0, 0, 0, 0, + 0, 415, 416, 0, 417, 418, 0, 0, 0, 419, 0, 0, 420, 0, 0, 0, 0, 421, 0, 0, + 422, 0, 0, 423, 0, 0, 0, 424, 0, 425, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, + 0, 428, 429, 0, 0, 0, 0, 0, 0, 430, 0, 0, 431, 0, 0, 0, 0, 432, 0, 433, + 0, 0, 0, 0, 434, 0, 435, 0, 0, 0, 0, 0, 0, 436, 437, 0, 0, 438, 0, 0, + 439, 0, 440, 441, 0, 0, 0, 442, 0, 0, 443, 0, 444, 445, 0, 446, 447, 0, + 0, 448, 0, 0, 0, 449, 0, 450, 451, 0, 0, 0, 452, 0, 0, 0, 0, 0, 453, 0, + 454, 455, 0, 456, 457, 0, 0, 0, 0, 0, 0, 458, 0, 0, 459, 0, 460, 461, 0, + 0, 0, 462, 0, 0, 463, 0, 464, 465, 0, 466, 467, 0, 0, 468, 0, 0, 0, 469, + 0, 470, 471, 0, 0, 0, 472, 0, 0, 0, 0, 0, 473, 0, 474, 475, 0, 476, 477, + 0, 0, 0, 0, 0, 0, 478, 0, 0, 479, 0, 0, 480, 0, 0, 0, 0, 0, 481, 0, 0, + 482, 0, 0, 0, 483, 0, 0, 484, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0, + 487, 488, 0, 489, 0, 0, 490, 0, 0, 0, 0, 0, 0, 491, 0, 0, 492, 0, 0, 493, + 0, 0, 0, 494, 0, 0, 495, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 497, 0, 0, 0, + 498, 499, 0, 0, 0, 500, 0, 0, 0, 0, 0, 501, 502, 0, 503, 0, 0, 0, 504, 0, + 0, 0, 505, 0, 0, 506, 507, 0, 0, 0, 0, 0, 508, 0, 0, 0, 509, 510, 0, 0, + 0, 0, 0, 511, 0, 0, 0, 512, 513, 0, 514, 0, 0, 0, 0, 515, 0, 0, 516, 0, + 0, 517, 0, 0, 0, 0, 0, 0, 518, 0, 0, 519, 0, 0, 520, 0, 0, 521, 0, 0, 0, + 0, 0, 0, 522, 0, 0, 523, 0, 0, 524, 0, 0, 525, 0, 0, 0, 0, 0, 0, 526, 0, + 0, 0, 527, 0, 0, 528, 0, 0, 529, 0, 0, 530, 0, 0, 0, 531, 0, 0, 0, 0, 0, + 0, 532, 533, 534, 0, 0, 0, 0, 0, 535, 536, 0, 0, 0, 0, 0, 537, 0, 0, 538, + 0, 0, 539, 0, 0, 0, 0, 0, 0, 540, 0, 541, 0, 0, 0, 0, 0, 542, 543, 0, 0, + 0, 0, 0, 544, 0, 0, 545, 0, 0, 546, 0, 0, 0, 0, 0, 0, 547, 0, 0, 548, 0, + 0, 549, 0, 0, 550, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 552, 553, 0, 0, 0, 0, + 0, 554, 0, 0, 555, 0, 0, 556, 0, 0, 0, 0, 0, 0, 557, 0, 0, 558, 0, 0, + 559, 0, 0, 560, 0, 0, 0, 0, 561, 0, 0, 562, 0, 0, 0, 0, 0, 0, 563, 0, 0, + 564, 0, 0, 565, 0, 0, 0, 0, 0, 566, 567, 0, 0, 0, 0, 0, 568, 0, 0, 569, + 0, 0, 570, 0, 0, 0, 0, 0, 0, 571, 0, 0, 572, 0, 0, 573, 0, 0, 574, 0, 0, + 0, 0, 575, 0, 0, 0, 0, 0, 576, 577, 0, 0, 0, 0, 0, 578, 0, 0, 579, 0, 0, + 580, 0, 0, 0, 0, 0, 0, 581, 0, 0, 582, 0, 0, 583, 0, 0, 584, 0, 0, 0, 0, + 585, 0, 0, 0, 0, 0, 586, 587, 0, 0, 0, 0, 0, 588, 0, 0, 0, 0, 589, 0, + 590, 0, 0, 0, 0, 591, 0, 592, 0, 0, 0, 0, 593, 0, 0, 594, 0, 0, 0, 0, 0, + 0, 595, 0, 0, 596, 0, 0, 597, 0, 0, 0, 0, 0, 598, 599, 0, 0, 0, 0, 0, + 600, 0, 0, 0, 0, 601, 0, 602, 0, 0, 0, 0, 603, 0, 604, 0, 0, 0, 0, 605, + 0, 0, 0, 0, 0, 606, 0, 0, 607, 0, 0, 608, 0, 0, 609, 0, 0, 0, 0, 0, 0, + 610, 0, 0, 611, 0, 0, 612, 0, 0, 0, 0, 613, 0, 614, 0, 0, 0, 0, 615, 0, + 0, 0, 0, 0, 616, 0, 0, 617, 0, 0, 618, 0, 0, 619, 0, 0, 0, 0, 0, 0, 620, + 0, 0, 621, 0, 0, 622, 0, 0, 623, 0, 0, 0, 0, 0, 0, 624, 0, 0, 625, 0, 0, + 626, 0, 0, 0, 0, 627, 0, 628, 0, 0, 0, 0, 0, 0, 629, 0, 0, 630, 0, 0, 0, + 0, 631, 0, 632, 0, 0, 0, 0, 0, 633, 0, 0, 634, 0, 0, 635, 0, 0, 636, 0, + 0, 0, 0, 0, 0, 637, 0, 0, 638, 0, 0, 639, 0, 0, 640, 0, 0, 0, 0, 0, 0, + 641, 0, 0, 642, 0, 0, 643, 0, 0, 644, 0, 0, 0, 0, 0, 0, 645, 0, 0, 646, + 0, 0, 647, 0, 0, 648, 0, 0, 0, 0, 0, 0, 649, 0, 0, 650, 0, 0, 651, 0, 0, + 652, 0, 0, 0, 0, 0, 0, 653, 0, 0, 654, 0, 0, 655, 0, 0, 656, 0, 0, 0, 0, + 0, 0, 657, 0, 0, 658, 0, 0, 659, 0, 0, 660, 0, 0, 0, 0, 0, 0, 661, 0, 0, + 662, 0, 0, 663, 0, 0, 664, 0, 0, 0, 0, 0, 0, 665, 0, 0, 666, 0, 0, 667, + 0, 0, 668, 0, 0, 0, 0, 0, 0, 669, 0, 0, 670, 0, 0, 671, 0, 0, 672, 0, 0, + 0, 0, 0, 0, 673, 0, 0, 0, 674, 0, 0, 675, 0, 0, 676, 0, 0, 677, 0, 0, 0, + 0, 0, 0, 678, 0, 0, 679, 0, 0, 680, 0, 0, 681, 0, 0, 0, 0, 0, 0, 682, 0, + 0, 683, 0, 0, 684, 0, 0, 685, 0, 0, 0, 0, 0, 0, 686, 0, 0, 687, 0, 0, + 688, 0, 0, 689, 0, 0, 0, 0, 0, 0, 690, 0, 0, 691, 0, 0, 692, 0, 0, 693, + 0, 0, 0, 0, 0, 0, 694, 0, 0, 695, 0, 0, 696, 0, 0, 697, 0, 0, 0, 0, 0, 0, + 698, 0, 0, 699, 0, 0, 700, 0, 0, 701, 0, 0, 0, 0, 0, 0, 702, 0, 0, 703, + 0, 0, 704, 0, 0, 705, 0, 0, 0, 0, 0, 0, 706, 0, 0, 707, 0, 0, 708, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 710, 0, 0, 711, 0, 0, 712, 0, 0, 713, 0, 0, 0, 0, + 0, 0, 714, 0, 0, 715, 0, 0, 716, 0, 0, 717, 0, 0, 0, 0, 0, 0, 718, 0, 0, + 719, 0, 0, 720, 0, 0, 721, 0, 0, 0, 722, 0, 0, 0, 0, 0, 0, 723, 0, 0, + 724, 0, 0, 725, 0, 0, 726, 0, 0, 0, 727, 0, 0, 0, 728, 729, 0, 0, 730, 0, + 0, 0, 0, 0, 0, 731, }; static const unsigned int comp_data[] = { @@ -4749,6 +5012,6 @@ static const unsigned int comp_data[] = { 12480, 0, 12482, 0, 12485, 0, 12487, 0, 12489, 0, 12496, 12497, 12499, 12500, 12502, 12503, 12505, 12506, 12508, 12509, 12535, 0, 12536, 0, 12537, 0, 12538, 0, 12542, 0, 69786, 0, 69788, 0, 69803, 0, 0, 69934, 0, - 69935, + 69935, 70475, 70476, 70844, 70843, 70846, 0, 0, 71098, 0, 71099, }; diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh index 7be4b04..a2c59da 100644 --- a/src/hb-unicode-private.hh +++ b/src/hb-unicode-private.hh @@ -32,8 +32,6 @@ #define HB_UNICODE_PRIVATE_HH #include "hb-private.hh" - -#include "hb-unicode.h" #include "hb-object-private.hh" @@ -104,57 +102,70 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE } - unsigned int + inline unsigned int modified_combining_class (hb_codepoint_t unicode) { + /* XXX This hack belongs to the Myanmar shaper. */ + if (unlikely (unicode == 0x1037u)) unicode = 0x103Au; + + /* XXX This hack belongs to the SEA shaper (for Tai Tham): + * Reorder SAKOT to ensure it comes after any tone marks. */ + if (unlikely (unicode == 0x1A60u)) return 254; + + /* XXX This hack belongs to the Tibetan shaper: + * Reorder PADMA to ensure it comes after any vowel marks. */ + if (unlikely (unicode == 0x0FC6u)) return 254; + return _hb_modified_combining_class[combining_class (unicode)]; } - inline hb_bool_t + static inline hb_bool_t is_variation_selector (hb_codepoint_t unicode) { - return unlikely (hb_in_ranges<hb_codepoint_t> (unicode, - 0x180B, 0x180D, /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */ - 0xFE00, 0xFE0F, /* VARIATION SELECTOR-1..16 */ - 0xE0100, 0xE01EF)); /* VARIATION SELECTOR-17..256 */ + /* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the + * Arabic shaper. No need to match them here. */ + return unlikely (hb_in_ranges (unicode, + 0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */ + 0xE0100u, 0xE01EFu)); /* VARIATION SELECTOR-17..256 */ } /* Default_Ignorable codepoints: * - * Note that as of Oct 2012 (Unicode 6.2), U+180E MONGOLIAN VOWEL SEPARATOR - * is NOT Default_Ignorable, but it really behaves in a way that it should - * be. That has been reported to the Unicode Technical Committee for - * consideration. As such, we include it here, since Uniscribe removes it. - * - * Gathered from: - * http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on - * - * Last updated to the page with the following versions: - * Version 3.6; ICU version: 50.0.1.0; Unicode version: 6.1.0.0 - * - * 4,167 Code Points - * - * [\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001D173-\U0001D17A\U000E0000-\U000E0FFF] + * Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable, + * we do NOT want to hide them, as the way Uniscribe has implemented them + * is with regular spacing glyphs, and that's the way fonts are made to work. + * As such, we make exceptions for those four. * - * 00AD ;SOFT HYPHEN - * 034F ;COMBINING GRAPHEME JOINER - * 115F ;HANGUL CHOSEONG FILLER - * 1160 ;HANGUL JUNGSEONG FILLER - * 17B4 ;KHMER VOWEL INHERENT AQ - * 17B5 ;KHMER VOWEL INHERENT AA - * 180B..180D ;MONGOLIAN FREE VARIATION SELECTOR THREE - * 200B..200F ;RIGHT-TO-LEFT MARK - * 202A..202E ;RIGHT-TO-LEFT OVERRIDE - * 2060..206F ;NOMINAL DIGIT SHAPES - * 3164 ;HANGUL FILLER - * FE00..FE0F ;VARIATION SELECTOR-16 - * FEFF ;ZERO WIDTH NO-BREAK SPACE - * FFA0 ;HALFWIDTH HANGUL FILLER - * FFF0..FFF8 ;<unassigned-FFF8> - * 1D173..1D17A ;MUSICAL SYMBOL END PHRASE - * E0000..E0FFF ;<unassigned-E0FFF> + * Unicode 7.0: + * $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/' + * 00AD # Cf SOFT HYPHEN + * 034F # Mn COMBINING GRAPHEME JOINER + * 061C # Cf ARABIC LETTER MARK + * 115F..1160 # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER + * 17B4..17B5 # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + * 180B..180D # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + * 180E # Cf MONGOLIAN VOWEL SEPARATOR + * 200B..200F # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK + * 202A..202E # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + * 2060..2064 # Cf [5] WORD JOINER..INVISIBLE PLUS + * 2065 # Cn <reserved-2065> + * 2066..206F # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + * 3164 # Lo HANGUL FILLER + * FE00..FE0F # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + * FEFF # Cf ZERO WIDTH NO-BREAK SPACE + * FFA0 # Lo HALFWIDTH HANGUL FILLER + * FFF0..FFF8 # Cn [9] <reserved-FFF0>..<reserved-FFF8> + * 1BCA0..1BCA3 # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + * 1D173..1D17A # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + * E0000 # Cn <reserved-E0000> + * E0001 # Cf LANGUAGE TAG + * E0002..E001F # Cn [30] <reserved-E0002>..<reserved-E001F> + * E0020..E007F # Cf [96] TAG SPACE..CANCEL TAG + * E0080..E00FF # Cn [128] <reserved-E0080>..<reserved-E00FF> + * E0100..E01EF # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + * E01F0..E0FFF # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> */ - inline hb_bool_t + static inline hb_bool_t is_default_ignorable (hb_codepoint_t ch) { hb_codepoint_t plane = ch >> 16; @@ -163,17 +174,16 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE /* BMP */ hb_codepoint_t page = ch >> 8; switch (page) { - case 0x00: return unlikely (ch == 0x00AD); - case 0x03: return unlikely (ch == 0x034F); - case 0x11: return hb_in_range<hb_codepoint_t> (ch, 0x115F, 0x1160); - case 0x17: return hb_in_range<hb_codepoint_t> (ch, 0x17B4, 0x17B5); - case 0x18: return hb_in_range<hb_codepoint_t> (ch, 0x180B, 0x180E); - case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200B, 0x200F, - 0x202A, 0x202E, - 0x2060, 0x206F); - case 0x31: return unlikely (ch == 0x3164); - case 0xFE: return hb_in_range<hb_codepoint_t> (ch, 0xFE00, 0xFE0F) || ch == 0xFEFF; - case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8) || ch == 0xFFA0; + case 0x00: return unlikely (ch == 0x00ADu); + case 0x03: return unlikely (ch == 0x034Fu); + case 0x06: return unlikely (ch == 0x061Cu); + case 0x17: return hb_in_range (ch, 0x17B4u, 0x17B5u); + case 0x18: return hb_in_range (ch, 0x180Bu, 0x180Eu); + case 0x20: return hb_in_ranges (ch, 0x200Bu, 0x200Fu, + 0x202Au, 0x202Eu, + 0x2060u, 0x206Fu); + case 0xFE: return hb_in_range (ch, 0xFE00u, 0xFE0Fu) || ch == 0xFEFFu; + case 0xFF: return hb_in_range (ch, 0xFFF0u, 0xFFF8u); default: return false; } } @@ -181,8 +191,9 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE { /* Other planes */ switch (plane) { - case 0x01: return hb_in_range<hb_codepoint_t> (ch, 0x0001D173, 0x0001D17A); - case 0x0E: return hb_in_range<hb_codepoint_t> (ch, 0x000E0000, 0x000E0FFF); + case 0x01: return hb_in_ranges (ch, 0x1BCA0u, 0x1BCA3u, + 0x1D173u, 0x1D17Au); + case 0x0E: return hb_in_range (ch, 0xE0000u, 0xE0FFFu); default: return false; } } diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index 0a3907e..d59dfb2 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -133,7 +133,7 @@ hb_unicode_funcs_get_default (void) #ifdef HAVE_GLIB HB_UNICODE_FUNCS_IMPLEMENT(glib) -#elif defined(HAVE_ICU) +#elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN) HB_UNICODE_FUNCS_IMPLEMENT(icu) #elif defined(HAVE_UCDN) HB_UNICODE_FUNCS_IMPLEMENT(ucdn) @@ -146,10 +146,25 @@ hb_unicode_funcs_get_default (void) } #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL) -#pragma message("Could not find any Unicode functions implementation, you have to provide your own.") -#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.") +#ifdef _MSC_VER +#pragma message("Could not find any Unicode functions implementation, you have to provide your own") +#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS") +#else +#warning "Could not find any Unicode functions implementation, you have to provide your own" +#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS" +#endif #endif +/** + * hb_unicode_funcs_create: (Xconstructor) + * @parent: (allow-none): + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_unicode_funcs_t * hb_unicode_funcs_create (hb_unicode_funcs_t *parent) { @@ -187,18 +202,45 @@ const hb_unicode_funcs_t _hb_unicode_funcs_nil = { } }; +/** + * hb_unicode_funcs_get_empty: + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_unicode_funcs_t * hb_unicode_funcs_get_empty (void) { return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil); } +/** + * hb_unicode_funcs_reference: (skip) + * @ufuncs: Unicode functions. + * + * + * + * Return value: (transfer full): + * + * Since: 1.0 + **/ hb_unicode_funcs_t * hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs) { return hb_object_reference (ufuncs); } +/** + * hb_unicode_funcs_destroy: (skip) + * @ufuncs: Unicode functions. + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) { @@ -214,6 +256,20 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) free (ufuncs); } +/** + * hb_unicode_funcs_set_user_data: (skip) + * @ufuncs: Unicode functions. + * @key: + * @data: + * @destroy: + * @replace: + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, hb_user_data_key_t *key, @@ -224,6 +280,17 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, return hb_object_set_user_data (ufuncs, key, data, destroy, replace); } +/** + * hb_unicode_funcs_get_user_data: (skip) + * @ufuncs: Unicode functions. + * @key: + * + * + * + * Return value: (transfer none): + * + * Since: 1.0 + **/ void * hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, hb_user_data_key_t *key) @@ -232,21 +299,49 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, } +/** + * hb_unicode_funcs_make_immutable: + * @ufuncs: Unicode functions. + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) { - if (hb_object_is_inert (ufuncs)) + if (unlikely (hb_object_is_inert (ufuncs))) return; ufuncs->immutable = true; } +/** + * hb_unicode_funcs_is_immutable: + * @ufuncs: Unicode functions. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs) { return ufuncs->immutable; } +/** + * hb_unicode_funcs_get_parent: + * @ufuncs: Unicode functions. + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_unicode_funcs_t * hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs) { @@ -294,6 +389,19 @@ hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE #undef HB_UNICODE_FUNC_IMPLEMENT +/** + * hb_unicode_compose: + * @ufuncs: Unicode functions. + * @a: + * @b: + * @ab: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_unicode_compose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t a, @@ -303,6 +411,19 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs, return ufuncs->compose (a, b, ab); } +/** + * hb_unicode_decompose: + * @ufuncs: Unicode functions. + * @ab: + * @a: (out): + * @b: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ hb_bool_t hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t ab, @@ -312,6 +433,18 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, return ufuncs->decompose (ab, a, b); } +/** + * hb_unicode_decompose_compatibility: + * @ufuncs: Unicode functions. + * @u: + * @decomposed: (out): + * + * + * + * Return value: + * + * Since: 1.0 + **/ unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_codepoint_t u, diff --git a/src/hb-unicode.h b/src/hb-unicode.h index 2e10d98..1c4e097 100644 --- a/src/hb-unicode.h +++ b/src/hb-unicode.h @@ -248,7 +248,7 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_decompose_compatibility_func_t: - * @ufuncs: Unicode function structure + * @ufuncs: a Unicode function structure * @u: codepoint to decompose * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func() @@ -274,44 +274,132 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_ /* setters */ +/** + * hb_unicode_funcs_set_combining_class_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_combining_class_func_t combining_class_func, + hb_unicode_combining_class_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_unicode_funcs_set_eastasian_width_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_eastasian_width_func_t eastasian_width_func, + hb_unicode_eastasian_width_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_unicode_funcs_set_general_category_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_general_category_func_t general_category_func, + hb_unicode_general_category_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_unicode_funcs_set_mirroring_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_mirroring_func_t mirroring_func, + hb_unicode_mirroring_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_unicode_funcs_set_script_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_script_func_t script_func, + hb_unicode_script_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_unicode_funcs_set_compose_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_compose_func_t compose_func, + hb_unicode_compose_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_unicode_funcs_set_decompose_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_decompose_func_t decompose_func, + hb_unicode_decompose_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_unicode_funcs_set_decompose_compatibility_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.0 + **/ void hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_decompose_compatibility_func_t decompose_compatibility_func, + hb_unicode_decompose_compatibility_func_t func, void *user_data, hb_destroy_func_t destroy); /* accessors */ diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index 2f01c28..74ae3a3 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2011,2012 Google, Inc. + * Copyright © 2011,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -24,17 +24,16 @@ * Google Author(s): Behdad Esfahbod */ -#define _WIN32_WINNT 0x0600 -#define WIN32_LEAN_AND_MEAN - #define HB_SHAPER uniscribe #include "hb-shaper-impl-private.hh" #include <windows.h> #include <usp10.h> +#include <rpc.h> #include "hb-uniscribe.h" +#include "hb-open-file-private.hh" #include "hb-ot-name-table.hh" #include "hb-ot-tag.h" @@ -44,17 +43,250 @@ #endif -/* -DWORD GetFontData( - __in HDC hdc, - __in DWORD dwTable, - __in DWORD dwOffset, - __out LPVOID lpvBuffer, - __in DWORD cbData +typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/( + const WCHAR *pwcInChars, + int cInChars, + int cMaxItems, + const SCRIPT_CONTROL *psControl, + const SCRIPT_STATE *psState, + SCRIPT_ITEM *pItems, + OPENTYPE_TAG *pScriptTags, + int *pcItems +); + +typedef HRESULT (WINAPI *SSOT) /*ScriptShapeOpenType*/( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + int cChars, + int cMaxGlyphs, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + WORD *pwOutGlyphs, + SCRIPT_GLYPHPROP *pOutGlyphProps, + int *pcGlyphs +); + +typedef HRESULT (WINAPI *SPOT) /*ScriptPlaceOpenType*/( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + int cChars, + const WORD *pwGlyphs, + const SCRIPT_GLYPHPROP *pGlyphProps, + int cGlyphs, + int *piAdvance, + GOFFSET *pGoffset, + ABC *pABC ); -*/ +/* Fallback implementations. */ + +static HRESULT WINAPI +hb_ScriptItemizeOpenType( + const WCHAR *pwcInChars, + int cInChars, + int cMaxItems, + const SCRIPT_CONTROL *psControl, + const SCRIPT_STATE *psState, + SCRIPT_ITEM *pItems, + OPENTYPE_TAG *pScriptTags, + int *pcItems +) +{ +{ + return ScriptItemize (pwcInChars, + cInChars, + cMaxItems, + psControl, + psState, + pItems, + pcItems); +} +} + +static HRESULT WINAPI +hb_ScriptShapeOpenType( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + int cChars, + int cMaxGlyphs, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + WORD *pwOutGlyphs, + SCRIPT_GLYPHPROP *pOutGlyphProps, + int *pcGlyphs +) +{ + SCRIPT_VISATTR *psva = (SCRIPT_VISATTR *) pOutGlyphProps; + return ScriptShape (hdc, + psc, + pwcChars, + cChars, + cMaxGlyphs, + psa, + pwOutGlyphs, + pwLogClust, + psva, + pcGlyphs); +} + +static HRESULT WINAPI +hb_ScriptPlaceOpenType( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + int cChars, + const WORD *pwGlyphs, + const SCRIPT_GLYPHPROP *pGlyphProps, + int cGlyphs, + int *piAdvance, + GOFFSET *pGoffset, + ABC *pABC +) +{ + SCRIPT_VISATTR *psva = (SCRIPT_VISATTR *) pGlyphProps; + return ScriptPlace (hdc, + psc, + pwGlyphs, + cGlyphs, + psva, + psa, + piAdvance, + pGoffset, + pABC); +} + + +struct hb_uniscribe_shaper_funcs_t { + SIOT ScriptItemizeOpenType; + SSOT ScriptShapeOpenType; + SPOT ScriptPlaceOpenType; + + inline void init (void) + { + HMODULE hinstLib; + this->ScriptItemizeOpenType = NULL; + this->ScriptShapeOpenType = NULL; + this->ScriptPlaceOpenType = NULL; + + hinstLib = GetModuleHandle (TEXT ("usp10.dll")); + if (hinstLib) + { + this->ScriptItemizeOpenType = (SIOT) GetProcAddress (hinstLib, "ScriptItemizeOpenType"); + this->ScriptShapeOpenType = (SSOT) GetProcAddress (hinstLib, "ScriptShapeOpenType"); + this->ScriptPlaceOpenType = (SPOT) GetProcAddress (hinstLib, "ScriptPlaceOpenType"); + } + if (!this->ScriptItemizeOpenType || + !this->ScriptShapeOpenType || + !this->ScriptPlaceOpenType) + { + DEBUG_MSG (UNISCRIBE, NULL, "OpenType versions of functions not found; falling back."); + this->ScriptItemizeOpenType = hb_ScriptItemizeOpenType; + this->ScriptShapeOpenType = hb_ScriptShapeOpenType; + this->ScriptPlaceOpenType = hb_ScriptPlaceOpenType; + } + } +}; +static hb_uniscribe_shaper_funcs_t *uniscribe_funcs; + +static inline void +free_uniscribe_funcs (void) +{ + free (uniscribe_funcs); +} + +static hb_uniscribe_shaper_funcs_t * +hb_uniscribe_shaper_get_funcs (void) +{ +retry: + hb_uniscribe_shaper_funcs_t *funcs = (hb_uniscribe_shaper_funcs_t *) hb_atomic_ptr_get (&uniscribe_funcs); + + if (unlikely (!funcs)) + { + funcs = (hb_uniscribe_shaper_funcs_t *) calloc (1, sizeof (hb_uniscribe_shaper_funcs_t)); + if (unlikely (!funcs)) + return NULL; + + funcs->init (); + + if (!hb_atomic_ptr_cmpexch (&uniscribe_funcs, NULL, funcs)) { + free (funcs); + goto retry; + } + +#ifdef HB_USE_ATEXIT + atexit (free_uniscribe_funcs); /* First person registers atexit() callback. */ +#endif + } + + return funcs; +} + + +struct active_feature_t { + OPENTYPE_FEATURE_RECORD rec; + unsigned int order; + + static int cmp (const active_feature_t *a, const active_feature_t *b) { + return a->rec.tagFeature < b->rec.tagFeature ? -1 : a->rec.tagFeature > b->rec.tagFeature ? 1 : + a->order < b->order ? -1 : a->order > b->order ? 1 : + a->rec.lParameter < b->rec.lParameter ? -1 : a->rec.lParameter > b->rec.lParameter ? 1 : + 0; + } + bool operator== (const active_feature_t *f) { + return cmp (this, f) == 0; + } +}; + +struct feature_event_t { + unsigned int index; + bool start; + active_feature_t feature; + + static int cmp (const feature_event_t *a, const feature_event_t *b) { + return a->index < b->index ? -1 : a->index > b->index ? 1 : + a->start < b->start ? -1 : a->start > b->start ? 1 : + active_feature_t::cmp (&a->feature, &b->feature); + } +}; + +struct range_record_t { + TEXTRANGE_PROPERTIES props; + unsigned int index_first; /* == start */ + unsigned int index_last; /* == end - 1 */ +}; + HB_SHAPER_DATA_ENSURE_DECLARE(uniscribe, face) HB_SHAPER_DATA_ENSURE_DECLARE(uniscribe, font) @@ -65,8 +297,133 @@ HB_SHAPER_DATA_ENSURE_DECLARE(uniscribe, font) struct hb_uniscribe_shaper_face_data_t { HANDLE fh; + hb_uniscribe_shaper_funcs_t *funcs; + wchar_t face_name[LF_FACESIZE]; }; +/* face_name should point to a wchar_t[LF_FACESIZE] object. */ +static void +_hb_generate_unique_face_name (wchar_t *face_name, unsigned int *plen) +{ + /* We'll create a private name for the font from a UUID using a simple, + * somewhat base64-like encoding scheme */ + const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; + UUID id; + UuidCreate ((UUID*) &id); + ASSERT_STATIC (2 + 3 * (16/2) < LF_FACESIZE); + unsigned int name_str_len = 0; + face_name[name_str_len++] = 'F'; + face_name[name_str_len++] = '_'; + unsigned char *p = (unsigned char *) &id; + for (unsigned int i = 0; i < 16; i += 2) + { + /* Spread the 16 bits from two bytes of the UUID across three chars of face_name, + * using the bits in groups of 5,5,6 to select chars from enc. + * This will generate 24 characters; with the 'F_' prefix we already provided, + * the name will be 26 chars (plus the NUL terminator), so will always fit within + * face_name (LF_FACESIZE = 32). */ + face_name[name_str_len++] = enc[p[i] >> 3]; + face_name[name_str_len++] = enc[((p[i] << 2) | (p[i + 1] >> 6)) & 0x1f]; + face_name[name_str_len++] = enc[p[i + 1] & 0x3f]; + } + face_name[name_str_len] = 0; + if (plen) + *plen = name_str_len; +} + +/* Destroys blob. */ +static hb_blob_t * +_hb_rename_font (hb_blob_t *blob, wchar_t *new_name) +{ + /* Create a copy of the font data, with the 'name' table replaced by a + * table that names the font with our private F_* name created above. + * For simplicity, we just append a new 'name' table and update the + * sfnt directory; the original table is left in place, but unused. + * + * The new table will contain just 5 name IDs: family, style, unique, + * full, PS. All of them point to the same name data with our unique name. + */ + + blob = OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (blob); + + unsigned int length, new_length, name_str_len; + const char *orig_sfnt_data = hb_blob_get_data (blob, &length); + + _hb_generate_unique_face_name (new_name, &name_str_len); + + static const uint16_t name_IDs[] = { 1, 2, 3, 4, 6 }; + + unsigned int name_table_length = OT::name::min_size + + ARRAY_LENGTH (name_IDs) * OT::NameRecord::static_size + + name_str_len * 2; /* for name data in UTF16BE form */ + unsigned int name_table_offset = (length + 3) & ~3; + + new_length = name_table_offset + ((name_table_length + 3) & ~3); + void *new_sfnt_data = calloc (1, new_length); + if (!new_sfnt_data) + { + hb_blob_destroy (blob); + return NULL; + } + + memcpy(new_sfnt_data, orig_sfnt_data, length); + + OT::name &name = OT::StructAtOffset<OT::name> (new_sfnt_data, name_table_offset); + name.format.set (0); + name.count.set (ARRAY_LENGTH (name_IDs)); + name.stringOffset.set (name.get_size ()); + for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++) + { + OT::NameRecord &record = name.nameRecord[i]; + record.platformID.set (3); + record.encodingID.set (1); + record.languageID.set (0x0409u); /* English */ + record.nameID.set (name_IDs[i]); + record.length.set (name_str_len * 2); + record.offset.set (0); + } + + /* Copy string data from new_name, converting wchar_t to UTF16BE. */ + unsigned char *p = &OT::StructAfter<unsigned char> (name); + for (unsigned int i = 0; i < name_str_len; i++) + { + *p++ = new_name[i] >> 8; + *p++ = new_name[i] & 0xff; + } + + /* Adjust name table entry to point to new name table */ + const OT::OpenTypeFontFile &file = * (OT::OpenTypeFontFile *) (new_sfnt_data); + unsigned int face_count = file.get_face_count (); + for (unsigned int face_index = 0; face_index < face_count; face_index++) + { + /* Note: doing multiple edits (ie. TTC) can be unsafe. There may be + * toe-stepping. But we don't really care. */ + const OT::OpenTypeFontFace &face = file.get_face (face_index); + unsigned int index; + if (face.find_table_index (HB_OT_TAG_name, &index)) + { + OT::TableRecord &record = const_cast<OT::TableRecord &> (face.get_table (index)); + record.checkSum.set_for_data (&name, name_table_length); + record.offset.set (name_table_offset); + record.length.set (name_table_length); + } + else if (face_index == 0) /* Fail if first face doesn't have 'name' table. */ + { + free (new_sfnt_data); + hb_blob_destroy (blob); + return NULL; + } + } + + /* The checkSumAdjustment field in the 'head' table is now wrong, + * but that doesn't actually seem to cause any problems so we don't + * bother. */ + + hb_blob_destroy (blob); + return hb_blob_create ((const char *) new_sfnt_data, new_length, + HB_MEMORY_MODE_WRITABLE, NULL, free); +} + hb_uniscribe_shaper_face_data_t * _hb_uniscribe_shaper_face_data_create (hb_face_t *face) { @@ -74,16 +431,30 @@ _hb_uniscribe_shaper_face_data_create (hb_face_t *face) if (unlikely (!data)) return NULL; + data->funcs = hb_uniscribe_shaper_get_funcs (); + if (unlikely (!data->funcs)) + { + free (data); + return NULL; + } + hb_blob_t *blob = hb_face_reference_blob (face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) + if (unlikely (!hb_blob_get_length (blob))) DEBUG_MSG (UNISCRIBE, face, "Face has empty blob"); + blob = _hb_rename_font (blob, data->face_name); + if (unlikely (!blob)) + { + free (data); + return NULL; + } + DWORD num_fonts_installed; - data->fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); - hb_blob_destroy (blob); - if (unlikely (!data->fh)) { + data->fh = AddFontMemResourceEx ((void *) hb_blob_get_data (blob, NULL), + hb_blob_get_length (blob), + 0, &num_fonts_installed); + if (unlikely (!data->fh)) + { DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed"); free (data); return NULL; @@ -119,26 +490,10 @@ populate_log_font (LOGFONTW *lf, lf->lfHeight = -font->y_scale; lf->lfCharSet = DEFAULT_CHARSET; - hb_blob_t *blob = OT::Sanitizer<OT::name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e'))); - const OT::name *name_table = OT::Sanitizer<OT::name>::lock_instance (blob); - unsigned int len = name_table->get_name (3, 1, 0x409, 4, - lf->lfFaceName, - sizeof (lf->lfFaceName[0]) * LF_FACESIZE) - / sizeof (lf->lfFaceName[0]); - hb_blob_destroy (blob); - - if (unlikely (!len)) { - DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry"); - return false; - } - if (unlikely (len >= LF_FACESIZE)) { - DEBUG_MSG (UNISCRIBE, NULL, "Font name too long"); - return false; - } + hb_face_t *face = font->face; + hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - for (unsigned int i = 0; i < len; i++) - lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]); - lf->lfFaceName[len] = 0; + memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName)); return true; } @@ -240,6 +595,126 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, hb_face_t *face = font->face; hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs; + + /* + * Set up features. + */ + hb_auto_array_t<OPENTYPE_FEATURE_RECORD> feature_records; + hb_auto_array_t<range_record_t> range_records; + if (num_features) + { + /* Sort features by start/end events. */ + hb_auto_array_t<feature_event_t> feature_events; + for (unsigned int i = 0; i < num_features; i++) + { + active_feature_t feature; + feature.rec.tagFeature = hb_uint32_swap (features[i].tag); + feature.rec.lParameter = features[i].value; + feature.order = i; + + feature_event_t *event; + + event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = features[i].start; + event->start = true; + event->feature = feature; + + event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = features[i].end; + event->start = false; + event->feature = feature; + } + feature_events.qsort (); + /* Add a strategic final event. */ + { + active_feature_t feature; + feature.rec.tagFeature = 0; + feature.rec.lParameter = 0; + feature.order = num_features + 1; + + feature_event_t *event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = 0; /* This value does magic. */ + event->start = false; + event->feature = feature; + } + + /* Scan events and save features for each range. */ + hb_auto_array_t<active_feature_t> active_features; + unsigned int last_index = 0; + for (unsigned int i = 0; i < feature_events.len; i++) + { + feature_event_t *event = &feature_events[i]; + + if (event->index != last_index) + { + /* Save a snapshot of active features and the range. */ + range_record_t *range = range_records.push (); + if (unlikely (!range)) + goto fail_features; + + unsigned int offset = feature_records.len; + + active_features.qsort (); + for (unsigned int j = 0; j < active_features.len; j++) + { + if (!j || active_features[j].rec.tagFeature != feature_records[feature_records.len - 1].tagFeature) + { + OPENTYPE_FEATURE_RECORD *feature = feature_records.push (); + if (unlikely (!feature)) + goto fail_features; + *feature = active_features[j].rec; + } + else + { + /* Overrides value for existing feature. */ + feature_records[feature_records.len - 1].lParameter = active_features[j].rec.lParameter; + } + } + + /* Will convert to pointer after all is ready, since feature_records.array + * may move as we grow it. */ + range->props.potfRecords = reinterpret_cast<OPENTYPE_FEATURE_RECORD *> (offset); + range->props.cotfRecords = feature_records.len - offset; + range->index_first = last_index; + range->index_last = event->index - 1; + + last_index = event->index; + } + + if (event->start) { + active_feature_t *feature = active_features.push (); + if (unlikely (!feature)) + goto fail_features; + *feature = event->feature; + } else { + active_feature_t *feature = active_features.find (&event->feature); + if (feature) + active_features.remove (feature - active_features.array); + } + } + + if (!range_records.len) /* No active feature found. */ + goto fail_features; + + /* Fixup the pointers. */ + for (unsigned int i = 0; i < range_records.len; i++) + { + range_record_t *range = &range_records[i]; + range->props.potfRecords = feature_records.array + reinterpret_cast<uintptr_t> (range->props.potfRecords); + } + } + else + { + fail_features: + num_features = 0; + } #define FAIL(...) \ HB_STMT_START { \ @@ -252,42 +727,61 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, retry: unsigned int scratch_size; - char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); - - /* Allocate char buffers; they all fit */ + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); #define ALLOCATE_ARRAY(Type, name, len) \ Type *name = (Type *) scratch; \ - scratch += (len) * sizeof ((name)[0]); \ - scratch_size -= (len) * sizeof ((name)[0]); + { \ + unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ + assert (_consumed <= scratch_size); \ + scratch += _consumed; \ + scratch_size -= _consumed; \ + } #define utf16_index() var1.u32 - WCHAR *pchars = (WCHAR *) scratch; + ALLOCATE_ARRAY (WCHAR, pchars, buffer->len * 2); + unsigned int chars_len = 0; - for (unsigned int i = 0; i < buffer->len; i++) { + 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 < 0x10000)) + if (likely (c <= 0xFFFFu)) pchars[chars_len++] = c; - else if (unlikely (c >= 0x110000)) - pchars[chars_len++] = 0xFFFD; + else if (unlikely (c > 0x10FFFFu)) + pchars[chars_len++] = 0xFFFDu; else { - pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); - pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); + pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1)); } } - ALLOCATE_ARRAY (WCHAR, wchars, chars_len); ALLOCATE_ARRAY (WORD, log_clusters, chars_len); ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len); - /* On Windows, we don't care about alignment...*/ - unsigned int glyphs_size = scratch_size / (sizeof (WORD) + - sizeof (SCRIPT_GLYPHPROP) + - sizeof (int) + - sizeof (GOFFSET) + - sizeof (uint32_t)); + 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. */ + } + } + + /* 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 (SCRIPT_GLYPHPROP) + + sizeof (int) + + sizeof (GOFFSET) + + sizeof (uint32_t)); ALLOCATE_ARRAY (WORD, glyphs, glyphs_size); ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size); @@ -295,6 +789,14 @@ retry: ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size); ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); + /* Note: + * We can't touch the contents of glyph_props. Our fallback + * implementations of Shape and Place functions use that buffer + * by casting it to a different type. It works because they + * both agree about it, but if we want to access it here we + * need address that issue first. + */ + #undef ALLOCATE_ARRAY #define MAX_ITEMS 256 @@ -312,62 +814,96 @@ retry: bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; bidi_state.fOverrideDirection = 1; - hr = ScriptItemizeOpenType (wchars, - chars_len, - MAX_ITEMS, - &bidi_control, - &bidi_state, - items, - script_tags, - &item_count); + hr = funcs->ScriptItemizeOpenType (pchars, + chars_len, + MAX_ITEMS, + &bidi_control, + &bidi_state, + items, + script_tags, + &item_count); if (unlikely (FAILED (hr))) FAIL ("ScriptItemizeOpenType() failed: 0x%08xL", hr); #undef MAX_ITEMS - int *range_char_counts = NULL; - TEXTRANGE_PROPERTIES **range_properties = NULL; - int range_count = 0; - if (num_features) { - /* TODO setup ranges */ - } - OPENTYPE_TAG language_tag = hb_uint32_swap (hb_ot_tag_from_language (buffer->props.language)); + hb_auto_array_t<TEXTRANGE_PROPERTIES*> range_properties; + hb_auto_array_t<int> range_char_counts; unsigned int glyphs_offset = 0; unsigned int glyphs_len; bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - for (unsigned int j = 0; j < item_count; j++) + for (unsigned int i = 0; i < item_count; i++) { - unsigned int i = backward ? item_count - 1 - j : j; unsigned int chars_offset = items[i].iCharPos; unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; + if (num_features) + { + range_properties.shrink (0); + range_char_counts.shrink (0); + + range_record_t *last_range = &range_records[0]; + + for (unsigned int k = chars_offset; k < chars_offset + item_chars_len; k++) + { + range_record_t *range = last_range; + while (log_clusters[k] < range->index_first) + range--; + while (log_clusters[k] > range->index_last) + range++; + if (!range_properties.len || + &range->props != range_properties[range_properties.len - 1]) + { + TEXTRANGE_PROPERTIES **props = range_properties.push (); + int *c = range_char_counts.push (); + if (unlikely (!props || !c)) + { + range_properties.shrink (0); + range_char_counts.shrink (0); + break; + } + *props = &range->props; + *c = 1; + } + else + { + range_char_counts[range_char_counts.len - 1]++; + } + + last_range = range; + } + } + + /* Asking for glyphs in logical order circumvents at least + * one bug in Uniscribe. */ + items[i].a.fLogicalOrder = true; + retry_shape: - hr = ScriptShapeOpenType (font_data->hdc, - &font_data->script_cache, - &items[i].a, - script_tags[i], - language_tag, - range_char_counts, - range_properties, - range_count, - wchars + chars_offset, - item_chars_len, - glyphs_size - glyphs_offset, - /* out */ - log_clusters + chars_offset, - char_props + chars_offset, - glyphs + glyphs_offset, - glyph_props + glyphs_offset, - (int *) &glyphs_len); + hr = funcs->ScriptShapeOpenType (font_data->hdc, + &font_data->script_cache, + &items[i].a, + script_tags[i], + language_tag, + range_char_counts.array, + range_properties.array, + range_properties.len, + pchars + chars_offset, + item_chars_len, + glyphs_size - glyphs_offset, + /* out */ + log_clusters + chars_offset, + char_props + chars_offset, + glyphs + glyphs_offset, + glyph_props + glyphs_offset, + (int *) &glyphs_len); if (unlikely (items[i].a.fNoGlyphIndex)) FAIL ("ScriptShapeOpenType() set fNoGlyphIndex"); if (unlikely (hr == E_OUTOFMEMORY)) { - buffer->ensure (buffer->allocated * 2); - if (buffer->in_error) + if (unlikely (!buffer->ensure (buffer->allocated * 2))) FAIL ("Buffer resize failed"); goto retry; } @@ -386,28 +922,36 @@ retry: for (unsigned int j = chars_offset; j < chars_offset + item_chars_len; j++) log_clusters[j] += glyphs_offset; - hr = ScriptPlaceOpenType (font_data->hdc, - &font_data->script_cache, - &items[i].a, - script_tags[i], - language_tag, - range_char_counts, - range_properties, - range_count, - wchars + chars_offset, - log_clusters + chars_offset, - char_props + chars_offset, - item_chars_len, - glyphs + glyphs_offset, - glyph_props + glyphs_offset, - glyphs_len, - /* out */ - advances + glyphs_offset, - offsets + glyphs_offset, - NULL); + hr = funcs->ScriptPlaceOpenType (font_data->hdc, + &font_data->script_cache, + &items[i].a, + script_tags[i], + language_tag, + range_char_counts.array, + range_properties.array, + range_properties.len, + pchars + chars_offset, + log_clusters + chars_offset, + char_props + chars_offset, + item_chars_len, + glyphs + glyphs_offset, + glyph_props + glyphs_offset, + glyphs_len, + /* out */ + advances + glyphs_offset, + offsets + glyphs_offset, + NULL); if (unlikely (FAILED (hr))) FAIL ("ScriptPlaceOpenType() failed: 0x%08xL", hr); + if (DEBUG_ENABLED (UNISCRIBE)) + fprintf (stderr, "Item %d RTL %d LayoutRTL %d LogicalOrder %d ScriptTag %c%c%c%c\n", + i, + items[i].a.fRTL, + items[i].a.fLayoutRTL, + items[i].a.fLogicalOrder, + HB_UNTAG (hb_uint32_swap (script_tags[i]))); + glyphs_offset += glyphs_len; } glyphs_len = glyphs_offset; @@ -422,20 +966,13 @@ retry: uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; *p = MIN (*p, buffer->info[i].cluster); } - if (!backward) { - for (unsigned int i = 1; i < glyphs_len; i++) - if (vis_clusters[i] == -1) - vis_clusters[i] = vis_clusters[i - 1]; - } else { - for (int i = glyphs_len - 2; i >= 0; i--) - if (vis_clusters[i] == -1) - vis_clusters[i] = vis_clusters[i + 1]; - } + for (unsigned int i = 1; i < glyphs_len; i++) + if (vis_clusters[i] == -1) + vis_clusters[i] = vis_clusters[i - 1]; #undef utf16_index - buffer->ensure (glyphs_len); - if (buffer->in_error) + if (unlikely (!buffer->ensure (glyphs_len))) FAIL ("Buffer in error"); #undef FAIL @@ -464,10 +1001,13 @@ retry: /* TODO vertical */ pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; + pos->x_offset = backward ? -info->var1.u32 : info->var1.u32; pos->y_offset = info->var2.u32; } + if (backward) + hb_buffer_reverse (buffer); + /* Wow, done! */ return true; } diff --git a/src/hb-uniscribe.h b/src/hb-uniscribe.h index 51887c8..001ab38 100644 --- a/src/hb-uniscribe.h +++ b/src/hb-uniscribe.h @@ -29,9 +29,6 @@ #include "hb.h" -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 -#endif #include <windows.h> HB_BEGIN_DECLS diff --git a/src/hb-utf-private.hh b/src/hb-utf-private.hh index b9a6519..0b798a0 100644 --- a/src/hb-utf-private.hh +++ b/src/hb-utf-private.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2011,2012 Google, Inc. + * Copyright © 2011,2012,2014 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -29,176 +29,221 @@ #include "hb-private.hh" +template <typename T, bool validate=true> struct hb_utf_t; + /* UTF-8 */ -#define HB_UTF8_COMPUTE(Char, Mask, Len) \ - if (Char < 128) { Len = 1; Mask = 0x7f; } \ - else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \ - else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \ - else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \ - else Len = 0; - -static inline const uint8_t * -hb_utf_next (const uint8_t *text, - const uint8_t *end, - hb_codepoint_t *unicode) +template <> +struct hb_utf_t<uint8_t, true> { - hb_codepoint_t c = *text, mask; - unsigned int len; - - /* TODO check for overlong sequences? */ - - HB_UTF8_COMPUTE (c, mask, len); - if (unlikely (!len || (unsigned int) (end - text) < len)) { - *unicode = -1; - return text + 1; - } else { - hb_codepoint_t result; - unsigned int i; - result = c & mask; - for (i = 1; i < len; i++) + static inline const uint8_t * + next (const uint8_t *text, + const uint8_t *end, + hb_codepoint_t *unicode, + hb_codepoint_t replacement) + { + /* Written to only accept well-formed sequences. + * Based on ideas from ICU's U8_NEXT. + * Generates one "replacement" for each ill-formed byte. */ + + hb_codepoint_t c = *text++; + + if (c > 0x7Fu) + { + if (hb_in_range (c, 0xC2u, 0xDFu)) /* Two-byte */ { - if (unlikely ((text[i] & 0xc0) != 0x80)) - { - *unicode = -1; - return text + 1; - } - result <<= 6; - result |= (text[i] & 0x3f); + unsigned int t1; + if (likely (text < end && + (t1 = text[0] - 0x80u) <= 0x3Fu)) + { + c = ((c&0x1Fu)<<6) | t1; + text++; + } + else + goto error; } - *unicode = result; - return text + len; - } -} + else if (hb_in_range (c, 0xE0u, 0xEFu)) /* Three-byte */ + { + unsigned int t1, t2; + if (likely (1 < end - text && + (t1 = text[0] - 0x80u) <= 0x3Fu && + (t2 = text[1] - 0x80u) <= 0x3Fu)) + { + c = ((c&0xFu)<<12) | (t1<<6) | t2; + if (unlikely (c < 0x0800u || hb_in_range (c, 0xD800u, 0xDFFFu))) + goto error; + text += 2; + } + else + goto error; + } + else if (hb_in_range (c, 0xF0u, 0xF4u)) /* Four-byte */ + { + unsigned int t1, t2, t3; + if (likely (2 < end - text && + (t1 = text[0] - 0x80u) <= 0x3Fu && + (t2 = text[1] - 0x80u) <= 0x3Fu && + (t3 = text[2] - 0x80u) <= 0x3Fu)) + { + c = ((c&0x7u)<<18) | (t1<<12) | (t2<<6) | t3; + if (unlikely (!hb_in_range (c, 0x10000u, 0x10FFFFu))) + goto error; + text += 3; + } + else + goto error; + } + else + goto error; + } -static inline const uint8_t * -hb_utf_prev (const uint8_t *text, - const uint8_t *start, - hb_codepoint_t *unicode) -{ - const uint8_t *end = text--; - while (start < text && (*text & 0xc0) == 0x80 && end - text < 4) - text--; + *unicode = c; + return text; + + error: + *unicode = replacement; + return text; + } - hb_codepoint_t c = *text, mask; - unsigned int len; + static inline const uint8_t * + prev (const uint8_t *text, + const uint8_t *start, + hb_codepoint_t *unicode, + hb_codepoint_t replacement) + { + const uint8_t *end = text--; + while (start < text && (*text & 0xc0) == 0x80 && end - text < 4) + text--; - /* TODO check for overlong sequences? */ + if (likely (next (text, end, unicode, replacement) == end)) + return text; - HB_UTF8_COMPUTE (c, mask, len); - if (unlikely (!len || (unsigned int) (end - text) != len)) { - *unicode = -1; + *unicode = replacement; return end - 1; - } else { - hb_codepoint_t result; - unsigned int i; - result = c & mask; - for (i = 1; i < len; i++) - { - result <<= 6; - result |= (text[i] & 0x3f); - } - *unicode = result; - return text; } -} - -static inline unsigned int -hb_utf_strlen (const uint8_t *text) -{ - return strlen ((const char *) text); -} + static inline unsigned int + strlen (const uint8_t *text) + { + return ::strlen ((const char *) text); + } +}; /* UTF-16 */ -static inline const uint16_t * -hb_utf_next (const uint16_t *text, - const uint16_t *end, - hb_codepoint_t *unicode) +template <> +struct hb_utf_t<uint16_t, true> { - hb_codepoint_t c = *text++; - - if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xd800, 0xdbff))) + static inline const uint16_t * + next (const uint16_t *text, + const uint16_t *end, + hb_codepoint_t *unicode, + hb_codepoint_t replacement) { - /* high surrogate */ - hb_codepoint_t l; - if (text < end && ((l = *text), likely (hb_in_range<hb_codepoint_t> (l, 0xdc00, 0xdfff)))) + hb_codepoint_t c = *text++; + + if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu))) { - /* low surrogate */ - *unicode = (c << 10) + l - ((0xd800 << 10) - 0x10000 + 0xdc00); - text++; - } else - *unicode = -1; - } else - *unicode = c; + *unicode = c; + return text; + } - return text; -} + if (likely (hb_in_range (c, 0xD800u, 0xDBFFu))) + { + /* High-surrogate in c */ + hb_codepoint_t l; + if (text < end && ((l = *text), likely (hb_in_range (l, 0xDC00u, 0xDFFFu)))) + { + /* Low-surrogate in l */ + *unicode = (c << 10) + l - ((0xD800u << 10) - 0x10000u + 0xDC00u); + text++; + return text; + } + } -static inline const uint16_t * -hb_utf_prev (const uint16_t *text, - const uint16_t *start, - hb_codepoint_t *unicode) -{ - hb_codepoint_t c = *--text; + /* Lonely / out-of-order surrogate. */ + *unicode = replacement; + return text; + } - if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xdc00, 0xdfff))) + static inline const uint16_t * + prev (const uint16_t *text, + const uint16_t *start, + hb_codepoint_t *unicode, + hb_codepoint_t replacement) { - /* low surrogate */ - hb_codepoint_t h; - if (start < text && ((h = *(text - 1)), likely (hb_in_range<hb_codepoint_t> (h, 0xd800, 0xdbff)))) + const uint16_t *end = text--; + hb_codepoint_t c = *text; + + if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu))) { - /* high surrogate */ - *unicode = (h << 10) + c - ((0xd800 << 10) - 0x10000 + 0xdc00); - text--; - } else - *unicode = -1; - } else - *unicode = c; + *unicode = c; + return text; + } - return text; -} + if (likely (start < text && hb_in_range (c, 0xDC00u, 0xDFFFu))) + text--; + if (likely (next (text, end, unicode, replacement) == end)) + return text; -static inline unsigned int -hb_utf_strlen (const uint16_t *text) -{ - unsigned int l = 0; - while (*text++) l++; - return l; -} + *unicode = replacement; + return end - 1; + } + + + static inline unsigned int + strlen (const uint16_t *text) + { + unsigned int l = 0; + while (*text++) l++; + return l; + } +}; /* UTF-32 */ -static inline const uint32_t * -hb_utf_next (const uint32_t *text, - const uint32_t *end HB_UNUSED, - hb_codepoint_t *unicode) +template <bool validate> +struct hb_utf_t<uint32_t, validate> { - *unicode = *text++; - return text; -} - -static inline const uint32_t * -hb_utf_prev (const uint32_t *text, - const uint32_t *start HB_UNUSED, - hb_codepoint_t *unicode) -{ - *unicode = *--text; - return text; -} + static inline const uint32_t * + next (const uint32_t *text, + const uint32_t *end HB_UNUSED, + hb_codepoint_t *unicode, + hb_codepoint_t replacement) + { + hb_codepoint_t c = *text++; + if (validate && unlikely (c > 0x10FFFFu || hb_in_range (c, 0xD800u, 0xDFFFu))) + goto error; + *unicode = c; + return text; -static inline unsigned int -hb_utf_strlen (const uint32_t *text) -{ - unsigned int l = 0; - while (*text++) l++; - return l; -} + error: + *unicode = replacement; + return text; + } + + static inline const uint32_t * + prev (const uint32_t *text, + const uint32_t *start HB_UNUSED, + hb_codepoint_t *unicode, + hb_codepoint_t replacement) + { + next (text - 1, text, unicode, replacement); + return text - 1; + } + + static inline unsigned int + strlen (const uint32_t *text) + { + unsigned int l = 0; + while (*text++) l++; + return l; + } +}; #endif /* HB_UTF_PRIVATE_HH */ diff --git a/src/hb-version.h b/src/hb-version.h index ebe0401..e1a5f61 100644 --- a/src/hb-version.h +++ b/src/hb-version.h @@ -38,12 +38,12 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 0 #define HB_VERSION_MINOR 9 -#define HB_VERSION_MICRO 12 +#define HB_VERSION_MICRO 35 -#define HB_VERSION_STRING "0.9.12" +#define HB_VERSION_STRING "0.9.35" -#define HB_VERSION_CHECK(major,minor,micro) \ - ((major)*10000+(minor)*100+(micro) >= \ +#define HB_VERSION_ATLEAST(major,minor,micro) \ + ((major)*10000+(minor)*100+(micro) <= \ HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) @@ -56,9 +56,9 @@ const char * hb_version_string (void); hb_bool_t -hb_version_check (unsigned int major, - unsigned int minor, - unsigned int micro); +hb_version_atleast (unsigned int major, + unsigned int minor, + unsigned int micro); HB_END_DECLS diff --git a/src/hb-version.h.in b/src/hb-version.h.in index 43634f9..2517160 100644 --- a/src/hb-version.h.in +++ b/src/hb-version.h.in @@ -42,8 +42,8 @@ HB_BEGIN_DECLS #define HB_VERSION_STRING "@HB_VERSION@" -#define HB_VERSION_CHECK(major,minor,micro) \ - ((major)*10000+(minor)*100+(micro) >= \ +#define HB_VERSION_ATLEAST(major,minor,micro) \ + ((major)*10000+(minor)*100+(micro) <= \ HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) @@ -56,9 +56,9 @@ const char * hb_version_string (void); hb_bool_t -hb_version_check (unsigned int major, - unsigned int minor, - unsigned int micro); +hb_version_atleast (unsigned int major, + unsigned int minor, + unsigned int micro); HB_END_DECLS diff --git a/src/hb-warning.cc b/src/hb-warning.cc index 4f1f65f..e0f88e2 100644 --- a/src/hb-warning.cc +++ b/src/hb-warning.cc @@ -53,14 +53,3 @@ #endif -#include "hb-unicode-private.hh" - -#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL) -#ifdef _MSC_VER -#pragma message("Could not find any Unicode functions implementation, you have to provide your own") -#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS") -#else -#warning "Could not find any Unicode functions implementation, you have to provide your own" -#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS" -#endif -#endif @@ -31,6 +31,8 @@ #include "hb-blob.h" #include "hb-buffer.h" #include "hb-common.h" +#include "hb-deprecated.h" +#include "hb-face.h" #include "hb-font.h" #include "hb-set.h" #include "hb-shape.h" diff --git a/src/main.cc b/src/main.cc index b362744..f9708cc 100644 --- a/src/main.cc +++ b/src/main.cc @@ -131,8 +131,11 @@ main (int argc, char **argv) else printf (" Language System %2d of %2d: %.4s\n", n_langsys, num_langsys, (const char *)script.get_lang_sys_tag (n_langsys)); - if (langsys.get_required_feature_index () == Index::NOT_FOUND_INDEX) + if (!langsys.has_required_feature ()) printf (" No required feature\n"); + else + printf (" Required feature index: %d\n", + langsys.get_required_feature_index ()); int num_features = langsys.get_feature_count (); printf (" %d feature(s) found in language system\n", num_features); @@ -147,11 +150,10 @@ main (int argc, char **argv) printf (" %d feature(s) found in table\n", num_features); for (int n_feature = 0; n_feature < num_features; n_feature++) { const Feature &feature = g.get_feature (n_feature); - printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature, num_features, - (const char *)g.get_feature_tag(n_feature), - feature.get_lookup_count()); - int num_lookups = feature.get_lookup_count (); + printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features, + HB_UNTAG(g.get_feature_tag(n_feature))); + printf (" %d lookup(s) found in feature\n", num_lookups); for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups, @@ -170,7 +172,7 @@ main (int argc, char **argv) } break; - case GDEF::Tag: + case GDEF::tableTag: { const GDEF &gdef = *CastP<GDEF> (font_data + table.offset); diff --git a/src/test-buffer-serialize.cc b/src/test-buffer-serialize.cc new file mode 100644 index 0000000..18c46e9 --- /dev/null +++ b/src/test-buffer-serialize.cc @@ -0,0 +1,129 @@ +/* + * 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "hb.h" +#ifdef HAVE_FREETYPE +#include "hb-ft.h" +#endif + +#ifdef HAVE_GLIB +# include <glib.h> +# if !GLIB_CHECK_VERSION (2, 22, 0) +# define g_mapped_file_unref g_mapped_file_free +# endif +#endif +#include <stdlib.h> +#include <stdio.h> + +int +main (int argc, char **argv) +{ + hb_blob_t *blob = NULL; + + if (argc != 2) { + fprintf (stderr, "usage: %s font-file\n", argv[0]); + exit (1); + } + + /* Create the blob */ + { + const char *font_data; + unsigned int len; + hb_destroy_func_t destroy; + void *user_data; + hb_memory_mode_t mm; + +#ifdef HAVE_GLIB + GMappedFile *mf = g_mapped_file_new (argv[1], false, NULL); + font_data = g_mapped_file_get_contents (mf); + len = g_mapped_file_get_length (mf); + destroy = (hb_destroy_func_t) g_mapped_file_unref; + user_data = (void *) mf; + mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE; +#else + FILE *f = fopen (argv[1], "rb"); + fseek (f, 0, SEEK_END); + len = ftell (f); + fseek (f, 0, SEEK_SET); + font_data = (const char *) malloc (len); + if (!font_data) len = 0; + len = fread ((char *) font_data, 1, len, f); + destroy = free; + user_data = (void *) font_data; + fclose (f); + mm = HB_MEMORY_MODE_WRITABLE; +#endif + + blob = hb_blob_create (font_data, len, mm, user_data, destroy); + } + + hb_face_t *face = hb_face_create (blob, 0 /* first face */); + hb_blob_destroy (blob); + blob = NULL; + + unsigned int upem = hb_face_get_upem (face); + hb_font_t *font = hb_font_create (face); + hb_face_destroy (face); + hb_font_set_scale (font, upem, upem); +#ifdef HAVE_FREETYPE + hb_ft_font_set_funcs (font); +#endif + + hb_buffer_t *buf; + buf = hb_buffer_create (); + + bool ret = true; + char line[BUFSIZ], out[BUFSIZ]; + while (fgets (line, sizeof(line), stdin) != 0) + { + hb_buffer_clear_contents (buf); + + const char *p = line; + while (hb_buffer_deserialize_glyphs (buf, + p, -1, &p, + font, + HB_BUFFER_SERIALIZE_FORMAT_JSON)) + ; + if (*p && *p != '\n') + ret = false; + + hb_buffer_serialize_glyphs (buf, 0, hb_buffer_get_length (buf), + out, sizeof (out), NULL, + font, HB_BUFFER_SERIALIZE_FORMAT_JSON, + HB_BUFFER_SERIALIZE_FLAG_DEFAULT); + puts (out); + } + + hb_buffer_destroy (buf); + + hb_font_destroy (font); + + return !ret; +} diff --git a/src/test-size-params.cc b/src/test-size-params.cc index 947b566..35d9e3c 100644 --- a/src/test-size-params.cc +++ b/src/test-size-params.cc @@ -32,7 +32,10 @@ #include "hb-ot.h" #ifdef HAVE_GLIB -#include <glib.h> +# include <glib.h> +# if !GLIB_CHECK_VERSION (2, 22, 0) +# define g_mapped_file_unref g_mapped_file_free +# endif #endif #include <stdlib.h> #include <stdio.h> diff --git a/src/test-would-substitute.cc b/src/test-would-substitute.cc index 4731e26..8ea87cd 100644 --- a/src/test-would-substitute.cc +++ b/src/test-would-substitute.cc @@ -32,7 +32,10 @@ #include "hb-ot.h" #ifdef HAVE_GLIB -#include <glib.h> +# include <glib.h> +# if !GLIB_CHECK_VERSION (2, 22, 0) +# define g_mapped_file_unref g_mapped_file_free +# endif #endif #include <stdlib.h> #include <stdio.h> diff --git a/src/test.cc b/src/test.cc index 22108b8..a8fe046 100644 --- a/src/test.cc +++ b/src/test.cc @@ -31,7 +31,10 @@ #include "hb.h" #ifdef HAVE_GLIB -#include <glib.h> +# include <glib.h> +# if !GLIB_CHECK_VERSION (2, 22, 0) +# define g_mapped_file_unref g_mapped_file_free +# endif #endif #include <stdlib.h> #include <stdio.h> @@ -100,6 +103,7 @@ main (int argc, char **argv) hb_buffer_t *buffer = hb_buffer_create (); hb_buffer_add_utf8 (buffer, "\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\x95", -1, 0, -1); + hb_buffer_guess_segment_properties (buffer); hb_shape (font, buffer, NULL, 0); |