diff options
Diffstat (limited to 'src')
145 files changed, 8223 insertions, 4490 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index afa104b..9d5662e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,12 +12,9 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection TESTS = check_PROGRAMS = -# The following warning options are useful for debugging: -Wpadded -#AM_CXXFLAGS = - # Convenience targets: lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la -fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la +fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la lib_LTLIBRARIES = libharfbuzz.la @@ -31,15 +28,6 @@ HBSOURCES = $(HB_BASE_sources) HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources) HBHEADERS = $(HB_BASE_headers) -if WITH_LIBSTDCXX -HBNOLIBCXXCFLAGS = -else -# Make sure we don't link to libstdc++ -# No threadsafe statics in C++ as we do it ourselves -HBCFLAGS += -fno-exceptions -HBNOLIBCXXFLAGS = -fno-threadsafe-statics -fno-rtti -endif - if HAVE_OT HBSOURCES += $(HB_OT_sources) HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources) @@ -117,6 +105,17 @@ endif DIST_SUBDIRS += hb-ucdn +BUILT_SOURCES += \ + hb-version.h + +$(srcdir)/hb-version.h: hb-version.h.in $(top_srcdir)/configure.ac + $(AM_V_GEN) $(SED) \ + -e 's/[@]HB_VERSION_MAJOR@/$(HB_VERSION_MAJOR)/' \ + -e 's/[@]HB_VERSION_MINOR@/$(HB_VERSION_MINOR)/' \ + -e 's/[@]HB_VERSION_MICRO@/$(HB_VERSION_MICRO)/' \ + -e 's/[@]HB_VERSION@/$(HB_VERSION)/' \ + "$<" > "$@" || ($(RM) "$@"; false) + # Put the library together HBLIBS += $(HBNONPCLIBS) @@ -147,10 +146,10 @@ endif @CODE_COVERAGE_RULES@ base_link_flags = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined -libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) $(CODE_COVERAGE_LDFLAGS) +libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) -libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(CODE_COVERAGE_CFLAGS) -libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) +libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS) +libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) $(CODE_COVERAGE_LDFLAGS) libharfbuzz_la_LIBADD = $(HBLIBS) EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency) pkginclude_HEADERS = $(HBHEADERS) @@ -159,12 +158,12 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = harfbuzz.pc cmakedir = $(libdir)/cmake/harfbuzz cmake_DATA = harfbuzz-config.cmake -EXTRA_DIST += harfbuzz.pc.in harfbuzz-config.cmake.in +EXTRA_DIST += hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in lib_LTLIBRARIES += libharfbuzz-subset.la libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources) -libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) -libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) +libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS) +libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) $(CODE_COVERAGE_LDFLAGS) libharfbuzz_subset_la_LIBADD = libharfbuzz.la EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency) pkginclude_HEADERS += $(HB_SUBSET_headers) @@ -184,7 +183,8 @@ FUZZING_CPPFLAGS = \ -DHB_BUFFER_MAX_OPS_MIN=64 \ -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ $(NULL) -EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la +EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la + libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS) libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES) libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) @@ -193,6 +193,14 @@ libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) CLEANFILES += libharfbuzz-fuzzing.la +libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS) +libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES) +libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) +libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) +libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD) +EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) +CLEANFILES += libharfbuzz-subset-fuzzing.la + if HAVE_ICU if HAVE_ICU_BUILTIN HBCFLAGS += $(ICU_CFLAGS) @@ -202,8 +210,8 @@ HBHEADERS += $(HB_ICU_headers) else lib_LTLIBRARIES += libharfbuzz-icu.la libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources) -libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS) -libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) +libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS) $(CODE_COVERAGE_CFLAGS) +libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) $(CODE_COVERAGE_LDFLAGS) libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency) pkginclude_HEADERS += $(HB_ICU_headers) @@ -217,8 +225,8 @@ lib_LTLIBRARIES += libharfbuzz-gobject.la libharfbuzz_gobject_la_LINK = $(chosen_linker) $(libharfbuzz_gobject_la_LDFLAGS) libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_DIST_sources) nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_NODIST_sources) -libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS) -libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) +libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(GOBJECT_CFLAGS) $(CODE_COVERAGE_CFLAGS) +libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) $(CODE_COVERAGE_LDFLAGS) libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la EXTRA_libharfbuzz_gobject_la_DEPENDENCIES = $(harfbuzz_gobject_def_dependency) pkginclude_HEADERS += $(HB_GOBJECT_DIST_headers) @@ -234,7 +242,7 @@ DISTCLEANFILES += \ $(HB_GOBJECT_ENUM_headers) \ $(NULL) hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS) - $(AM_V_GEN) $(GLIB_MKENUMS) \ + $(AM_V_GEN) PYTHONIOENCODING=UTF-8 $(GLIB_MKENUMS) \ --identifier-prefix hb_ --symbol-prefix hb_gobject \ --template $^ | \ sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \ @@ -269,13 +277,13 @@ endif check: $(DEF_FILES) # For check-symbols.sh CLEANFILES += $(DEF_FILES) harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" harfbuzz-subset.def: $(HB_SUBSET_headers) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" harfbuzz-icu.def: $(HB_ICU_headers) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" harfbuzz-gobject.def: $(HB_GOBJECT_headers) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" GENERATORS = \ @@ -289,16 +297,16 @@ EXTRA_DIST += $(GENERATORS) unicode-tables: arabic-table indic-table use-table arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \ - || ($(RM) hb-ot-shape-complex-arabic-table.hh; false) + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \ + || ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false) -indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \ - || ($(RM) hb-ot-shape-complex-indic-table.cc; false) +indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \ + || ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false) use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \ - || ($(RM) hb-ot-shape-complex-use-table.cc; false) + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \ + || ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false) built-sources: $(BUILT_SOURCES) @@ -365,11 +373,15 @@ dist_check_SCRIPTS += \ endif check_PROGRAMS += \ + dump-fon \ dump-indic-data \ dump-khmer-data \ dump-myanmar-data \ dump-use-data \ $(NULL) +dump_fon_SOURCES = dump-fon.cc +dump_fon_CPPFLAGS = $(HBCFLAGS) +dump_fon_LDADD = libharfbuzz.la $(HBLIBS) dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc dump_indic_data_CPPFLAGS = $(HBCFLAGS) dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS) @@ -383,6 +395,15 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc dump_use_data_CPPFLAGS = $(HBCFLAGS) dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) +if HAVE_FREETYPE +if HAVE_CAIRO_FT +check_PROGRAMS += dump-emoji +dump_emoji_SOURCES = dump-emoji.cc +dump_emoji_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS) +dump_emoji_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS) +endif # HAVE_CAIRO_FT +endif # HAVE_FREETYPE + check_PROGRAMS += test-ot-tag test-unicode-ranges TESTS += test-ot-tag test-unicode-ranges diff --git a/src/Makefile.in b/src/Makefile.in index f2f5c6b..e3715e8 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -95,91 +95,90 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -TESTS = $(am__EXEEXT_3) test-ot-tag$(EXEEXT) \ +TESTS = $(am__EXEEXT_4) test-ot-tag$(EXEEXT) \ test-unicode-ranges$(EXEEXT) -check_PROGRAMS = dump-indic-data$(EXEEXT) dump-khmer-data$(EXEEXT) \ - dump-myanmar-data$(EXEEXT) dump-use-data$(EXEEXT) \ - $(am__EXEEXT_1) test-ot-tag$(EXEEXT) \ - test-unicode-ranges$(EXEEXT) -# Make sure we don't link to libstdc++ -# No threadsafe statics in C++ as we do it ourselves -@WITH_LIBSTDCXX_FALSE@am__append_1 = -fno-exceptions -@HAVE_OT_TRUE@am__append_2 = $(HB_OT_sources) \ +check_PROGRAMS = dump-fon$(EXEEXT) dump-indic-data$(EXEEXT) \ + dump-khmer-data$(EXEEXT) dump-myanmar-data$(EXEEXT) \ + dump-use-data$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \ + test-ot-tag$(EXEEXT) test-unicode-ranges$(EXEEXT) +@HAVE_OT_TRUE@am__append_1 = $(HB_OT_sources) \ @HAVE_OT_TRUE@ $(HB_OT_RAGEL_GENERATED_sources) -@HAVE_OT_TRUE@am__append_3 = $(HB_OT_headers) -@HAVE_FALLBACK_TRUE@am__append_4 = $(HB_FALLBACK_sources) -@HAVE_PTHREAD_TRUE@am__append_5 = $(PTHREAD_CFLAGS) -@HAVE_PTHREAD_TRUE@am__append_6 = $(PTHREAD_LIBS) -@HAVE_GLIB_TRUE@am__append_7 = $(GLIB_CFLAGS) -@HAVE_GLIB_TRUE@am__append_8 = $(GLIB_LIBS) -@HAVE_GLIB_TRUE@am__append_9 = $(GLIB_DEPS) -@HAVE_GLIB_TRUE@am__append_10 = $(HB_GLIB_sources) -@HAVE_GLIB_TRUE@am__append_11 = $(HB_GLIB_headers) -@HAVE_FREETYPE_TRUE@am__append_12 = $(FREETYPE_CFLAGS) -@HAVE_FREETYPE_TRUE@am__append_13 = $(FREETYPE_LIBS) +@HAVE_OT_TRUE@am__append_2 = $(HB_OT_headers) +@HAVE_FALLBACK_TRUE@am__append_3 = $(HB_FALLBACK_sources) +@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 = $(GLIB_DEPS) +@HAVE_GLIB_TRUE@am__append_9 = $(HB_GLIB_sources) +@HAVE_GLIB_TRUE@am__append_10 = $(HB_GLIB_headers) +@HAVE_FREETYPE_TRUE@am__append_11 = $(FREETYPE_CFLAGS) +@HAVE_FREETYPE_TRUE@am__append_12 = $(FREETYPE_LIBS) # XXX # The following creates a recursive dependency on FreeType if FreeType is # built with HarfBuzz support enabled. Newer pkg-config handles that just # fine but pkg-config 0.26 as shipped in Ubuntu 14.04 crashes. Remove # in a year or two, or otherwise work around it... #HBDEPS += $(FREETYPE_DEPS) -@HAVE_FREETYPE_TRUE@am__append_14 = $(HB_FT_sources) -@HAVE_FREETYPE_TRUE@am__append_15 = $(HB_FT_headers) -@HAVE_GRAPHITE2_TRUE@am__append_16 = $(GRAPHITE2_CFLAGS) -@HAVE_GRAPHITE2_TRUE@am__append_17 = $(GRAPHITE2_LIBS) -@HAVE_GRAPHITE2_TRUE@am__append_18 = $(GRAPHITE2_DEPS) -@HAVE_GRAPHITE2_TRUE@am__append_19 = $(HB_GRAPHITE2_sources) -@HAVE_GRAPHITE2_TRUE@am__append_20 = $(HB_GRAPHITE2_headers) -@HAVE_UNISCRIBE_TRUE@am__append_21 = $(UNISCRIBE_CFLAGS) -@HAVE_UNISCRIBE_TRUE@am__append_22 = $(UNISCRIBE_LIBS) -@HAVE_UNISCRIBE_TRUE@am__append_23 = $(HB_UNISCRIBE_sources) -@HAVE_UNISCRIBE_TRUE@am__append_24 = $(HB_UNISCRIBE_headers) -@HAVE_DIRECTWRITE_TRUE@am__append_25 = $(DIRECTWRITE_CXXFLAGS) -@HAVE_DIRECTWRITE_TRUE@am__append_26 = $(DIRECTWRITE_LIBS) -@HAVE_DIRECTWRITE_TRUE@am__append_27 = $(HB_DIRECTWRITE_sources) -@HAVE_DIRECTWRITE_TRUE@am__append_28 = $(HB_DIRECTWRITE_headers) -@HAVE_CORETEXT_TRUE@am__append_29 = $(CORETEXT_CFLAGS) -@HAVE_CORETEXT_TRUE@am__append_30 = $(CORETEXT_LIBS) -@HAVE_CORETEXT_TRUE@am__append_31 = $(HB_CORETEXT_sources) -@HAVE_CORETEXT_TRUE@am__append_32 = $(HB_CORETEXT_headers) -@HAVE_UCDN_TRUE@am__append_33 = hb-ucdn -@HAVE_UCDN_TRUE@am__append_34 = -I$(srcdir)/hb-ucdn -@HAVE_UCDN_TRUE@am__append_35 = hb-ucdn/libhb-ucdn.la -@HAVE_UCDN_TRUE@am__append_36 = $(HB_UCDN_sources) -@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_37 = $(ICU_CFLAGS) -@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_38 = $(ICU_LIBS) -@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_39 = $(HB_ICU_sources) -@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_40 = $(HB_ICU_headers) -@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_41 = libharfbuzz-icu.la -@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_42 = $(HB_ICU_headers) -@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_43 = harfbuzz-icu.pc -@HAVE_GOBJECT_TRUE@am__append_44 = libharfbuzz-gobject.la -@HAVE_GOBJECT_TRUE@am__append_45 = $(HB_GOBJECT_DIST_headers) -@HAVE_GOBJECT_TRUE@am__append_46 = $(HB_GOBJECT_NODIST_headers) -@HAVE_GOBJECT_TRUE@am__append_47 = harfbuzz-gobject.pc -@HAVE_GOBJECT_TRUE@am__append_48 = \ +@HAVE_FREETYPE_TRUE@am__append_13 = $(HB_FT_sources) +@HAVE_FREETYPE_TRUE@am__append_14 = $(HB_FT_headers) +@HAVE_GRAPHITE2_TRUE@am__append_15 = $(GRAPHITE2_CFLAGS) +@HAVE_GRAPHITE2_TRUE@am__append_16 = $(GRAPHITE2_LIBS) +@HAVE_GRAPHITE2_TRUE@am__append_17 = $(GRAPHITE2_DEPS) +@HAVE_GRAPHITE2_TRUE@am__append_18 = $(HB_GRAPHITE2_sources) +@HAVE_GRAPHITE2_TRUE@am__append_19 = $(HB_GRAPHITE2_headers) +@HAVE_UNISCRIBE_TRUE@am__append_20 = $(UNISCRIBE_CFLAGS) +@HAVE_UNISCRIBE_TRUE@am__append_21 = $(UNISCRIBE_LIBS) +@HAVE_UNISCRIBE_TRUE@am__append_22 = $(HB_UNISCRIBE_sources) +@HAVE_UNISCRIBE_TRUE@am__append_23 = $(HB_UNISCRIBE_headers) +@HAVE_DIRECTWRITE_TRUE@am__append_24 = $(DIRECTWRITE_CXXFLAGS) +@HAVE_DIRECTWRITE_TRUE@am__append_25 = $(DIRECTWRITE_LIBS) +@HAVE_DIRECTWRITE_TRUE@am__append_26 = $(HB_DIRECTWRITE_sources) +@HAVE_DIRECTWRITE_TRUE@am__append_27 = $(HB_DIRECTWRITE_headers) +@HAVE_CORETEXT_TRUE@am__append_28 = $(CORETEXT_CFLAGS) +@HAVE_CORETEXT_TRUE@am__append_29 = $(CORETEXT_LIBS) +@HAVE_CORETEXT_TRUE@am__append_30 = $(HB_CORETEXT_sources) +@HAVE_CORETEXT_TRUE@am__append_31 = $(HB_CORETEXT_headers) +@HAVE_UCDN_TRUE@am__append_32 = hb-ucdn +@HAVE_UCDN_TRUE@am__append_33 = -I$(srcdir)/hb-ucdn +@HAVE_UCDN_TRUE@am__append_34 = hb-ucdn/libhb-ucdn.la +@HAVE_UCDN_TRUE@am__append_35 = $(HB_UCDN_sources) +@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_36 = $(ICU_CFLAGS) +@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_37 = $(ICU_LIBS) +@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_38 = $(HB_ICU_sources) +@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_39 = $(HB_ICU_headers) +@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_40 = libharfbuzz-icu.la +@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_41 = $(HB_ICU_headers) +@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_42 = harfbuzz-icu.pc +@HAVE_GOBJECT_TRUE@am__append_43 = libharfbuzz-gobject.la +@HAVE_GOBJECT_TRUE@am__append_44 = $(HB_GOBJECT_DIST_headers) +@HAVE_GOBJECT_TRUE@am__append_45 = $(HB_GOBJECT_NODIST_headers) +@HAVE_GOBJECT_TRUE@am__append_46 = harfbuzz-gobject.pc +@HAVE_GOBJECT_TRUE@am__append_47 = \ @HAVE_GOBJECT_TRUE@ $(HB_GOBJECT_ENUM_sources) \ @HAVE_GOBJECT_TRUE@ $(HB_GOBJECT_ENUM_headers) \ @HAVE_GOBJECT_TRUE@ $(NULL) -@HAVE_GOBJECT_TRUE@am__append_49 = \ +@HAVE_GOBJECT_TRUE@am__append_48 = \ @HAVE_GOBJECT_TRUE@ $(HB_GOBJECT_ENUM_sources) \ @HAVE_GOBJECT_TRUE@ $(HB_GOBJECT_ENUM_headers) \ @HAVE_GOBJECT_TRUE@ $(NULL) -@HAVE_GOBJECT_TRUE@am__append_50 = harfbuzz-gobject.def +@HAVE_GOBJECT_TRUE@am__append_49 = harfbuzz-gobject.def noinst_PROGRAMS = main$(EXEEXT) test$(EXEEXT) \ test-buffer-serialize$(EXEEXT) test-size-params$(EXEEXT) \ test-would-substitute$(EXEEXT) $(am__EXEEXT_1) bin_PROGRAMS = -@WITH_LIBSTDCXX_FALSE@am__append_51 = \ +@WITH_LIBSTDCXX_FALSE@am__append_50 = \ @WITH_LIBSTDCXX_FALSE@ check-libstdc++.sh \ @WITH_LIBSTDCXX_FALSE@ $(NULL) +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am__append_51 = dump-emoji @HAVE_INTROSPECTION_TRUE@am__append_52 = $(gir_DATA) $(typelib_DATA) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(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 \ @@ -191,7 +190,7 @@ DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_check_SCRIPTS_DIST) \ $(am__pkginclude_HEADERS_DIST) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = hb-version.h harfbuzz-config.cmake +CONFIG_CLEAN_FILES = harfbuzz-config.cmake CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -238,38 +237,41 @@ am__DEPENDENCIES_9 = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_6) \ @HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__DEPENDENCIES_10 = \ @HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__DEPENDENCIES_1) am__DEPENDENCIES_11 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \ - $(am__DEPENDENCIES_4) $(am__append_35) $(am__DEPENDENCIES_9) \ + $(am__DEPENDENCIES_4) $(am__append_34) $(am__DEPENDENCIES_9) \ $(am__DEPENDENCIES_10) am__DEPENDENCIES_12 = $(am__DEPENDENCIES_11) libharfbuzz_fuzzing_la_DEPENDENCIES = $(am__DEPENDENCIES_12) am__libharfbuzz_fuzzing_la_SOURCES_DIST = hb-atomic-private.hh \ - hb-blob.cc hb-buffer-private.hh hb-buffer-serialize.cc \ - hb-buffer.cc hb-common.cc hb-debug.hh hb-dsalgs.hh \ - 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-color-cbdt-table.hh hb-ot-cmap-table.hh \ - hb-ot-glyf-table.hh hb-ot-hdmx-table.hh hb-ot-head-table.hh \ - hb-ot-hhea-table.hh hb-ot-hmtx-table.hh hb-ot-kern-table.hh \ - hb-ot-maxp-table.hh hb-ot-name-table.hh hb-ot-os2-table.hh \ - hb-ot-os2-unicode-ranges.hh hb-ot-post-macroman.hh \ - hb-ot-post-table.hh hb-ot-tag.cc hb-private.hh \ - hb-set-digest-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-string-array.hh \ - hb-unicode-private.hh hb-unicode.cc hb-utf-private.hh \ - hb-warning.cc hb-buffer-deserialize-json.hh \ + hb-blob-private.hh hb-blob.cc hb-buffer-private.hh \ + hb-buffer-serialize.cc hb-buffer.cc hb-common.cc hb-debug.hh \ + hb-dsalgs.hh hb-face-private.hh hb-face.cc hb-font-private.hh \ + hb-font.cc hb-map-private.hh hb-map.cc hb-mutex-private.hh \ + hb-object-private.hh hb-open-file-private.hh \ + hb-open-type-private.hh hb-ot-color-cbdt-table.hh \ + hb-ot-cmap-table.hh hb-ot-glyf-table.hh hb-ot-hdmx-table.hh \ + hb-ot-head-table.hh hb-ot-hhea-table.hh hb-ot-hmtx-table.hh \ + hb-ot-kern-table.hh hb-ot-maxp-table.hh hb-ot-name-table.hh \ + hb-ot-os2-table.hh hb-ot-os2-unicode-ranges.hh \ + hb-ot-post-macroman.hh hb-ot-post-table.hh hb-ot-tag.cc \ + hb-private.hh hb-set-digest-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-static.cc \ + hb-string-array.hh hb-unicode-private.hh hb-unicode.cc \ + hb-utf-private.hh hb-warning.cc hb-buffer-deserialize-json.hh \ hb-buffer-deserialize-text.hh hb-aat-layout.cc \ hb-aat-layout-common-private.hh hb-aat-layout-ankr-table.hh \ + hb-aat-layout-bsln-table.hh hb-aat-layout-feat-table.hh \ hb-aat-layout-kerx-table.hh hb-aat-layout-morx-table.hh \ hb-aat-layout-trak-table.hh hb-aat-layout-private.hh \ + hb-aat-fmtx-table.hh hb-aat-gcid-table.hh hb-aat-ltag-table.hh \ hb-ot-font.cc hb-ot-layout.cc hb-ot-layout-base-table.hh \ hb-ot-layout-common-private.hh hb-ot-layout-gdef-table.hh \ hb-ot-layout-gpos-table.hh 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-color.cc \ hb-ot-color-colr-table.hh hb-ot-color-cpal-table.hh \ + hb-ot-color-sbix-table.hh hb-ot-color-svg-table.hh \ hb-ot-map.cc hb-ot-map-private.hh hb-ot-math.cc \ hb-ot-math-table.hh hb-ot-shape.cc \ hb-ot-shape-complex-arabic.cc \ @@ -300,11 +302,11 @@ am__libharfbuzz_fuzzing_la_SOURCES_DIST = hb-atomic-private.hh \ hb-glib.cc hb-ft.cc hb-graphite2.cc hb-uniscribe.cc \ hb-directwrite.cc hb-coretext.cc hb-ucdn.cc hb-icu.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-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h hb-ot-math.h \ - hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h hb-ft.h \ - hb-graphite2.h hb-uniscribe.h hb-directwrite.h hb-coretext.h \ - hb-icu.h + hb-font.h hb-map.h hb-set.h hb-shape.h hb-shape-plan.h \ + hb-unicode.h hb-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h \ + hb-ot-math.h hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h \ + hb-ft.h hb-graphite2.h hb-uniscribe.h hb-directwrite.h \ + hb-coretext.h hb-icu.h am__objects_1 = am__objects_2 = libharfbuzz_fuzzing_la-hb-blob.lo \ libharfbuzz_fuzzing_la-hb-buffer-serialize.lo \ @@ -312,11 +314,13 @@ am__objects_2 = libharfbuzz_fuzzing_la-hb-blob.lo \ libharfbuzz_fuzzing_la-hb-common.lo \ libharfbuzz_fuzzing_la-hb-face.lo \ libharfbuzz_fuzzing_la-hb-font.lo \ + libharfbuzz_fuzzing_la-hb-map.lo \ libharfbuzz_fuzzing_la-hb-ot-tag.lo \ libharfbuzz_fuzzing_la-hb-set.lo \ libharfbuzz_fuzzing_la-hb-shape.lo \ libharfbuzz_fuzzing_la-hb-shape-plan.lo \ libharfbuzz_fuzzing_la-hb-shaper.lo \ + libharfbuzz_fuzzing_la-hb-static.lo \ libharfbuzz_fuzzing_la-hb-unicode.lo \ libharfbuzz_fuzzing_la-hb-warning.lo $(am__objects_1) am__objects_3 = $(am__objects_1) @@ -413,22 +417,36 @@ libharfbuzz_icu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(LDFLAGS) -o $@ @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am_libharfbuzz_icu_la_rpath = \ @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@ -rpath $(libdir) +libharfbuzz_subset_fuzzing_la_DEPENDENCIES = \ + $(libharfbuzz_subset_la_LIBADD) +am__objects_39 = libharfbuzz_subset_fuzzing_la-hb-static.lo \ + libharfbuzz_subset_fuzzing_la-hb-subset.lo \ + libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo \ + libharfbuzz_subset_fuzzing_la-hb-subset-input.lo \ + libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo \ + $(am__objects_1) +am__objects_40 = $(am__objects_39) +am_libharfbuzz_subset_fuzzing_la_OBJECTS = $(am__objects_40) +libharfbuzz_subset_fuzzing_la_OBJECTS = \ + $(am_libharfbuzz_subset_fuzzing_la_OBJECTS) libharfbuzz_subset_la_DEPENDENCIES = libharfbuzz.la -am__objects_39 = libharfbuzz_subset_la-hb-subset.lo \ +am__objects_41 = libharfbuzz_subset_la-hb-static.lo \ + libharfbuzz_subset_la-hb-subset.lo \ libharfbuzz_subset_la-hb-subset-glyf.lo \ libharfbuzz_subset_la-hb-subset-input.lo \ libharfbuzz_subset_la-hb-subset-plan.lo $(am__objects_1) -am_libharfbuzz_subset_la_OBJECTS = $(am__objects_39) +am_libharfbuzz_subset_la_OBJECTS = $(am__objects_41) libharfbuzz_subset_la_OBJECTS = $(am_libharfbuzz_subset_la_OBJECTS) libharfbuzz_subset_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libharfbuzz_subset_la_LDFLAGS) \ $(LDFLAGS) -o $@ libharfbuzz_la_DEPENDENCIES = $(am__DEPENDENCIES_11) -am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh hb-blob.cc \ - hb-buffer-private.hh hb-buffer-serialize.cc hb-buffer.cc \ - hb-common.cc hb-debug.hh hb-dsalgs.hh hb-face-private.hh \ - hb-face.cc hb-font-private.hh hb-font.cc hb-mutex-private.hh \ +am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh \ + hb-blob-private.hh hb-blob.cc hb-buffer-private.hh \ + hb-buffer-serialize.cc hb-buffer.cc hb-common.cc hb-debug.hh \ + hb-dsalgs.hh hb-face-private.hh hb-face.cc hb-font-private.hh \ + hb-font.cc hb-map-private.hh hb-map.cc hb-mutex-private.hh \ hb-object-private.hh hb-open-file-private.hh \ hb-open-type-private.hh hb-ot-color-cbdt-table.hh \ hb-ot-cmap-table.hh hb-ot-glyf-table.hh hb-ot-hdmx-table.hh \ @@ -439,19 +457,22 @@ am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh hb-blob.cc \ hb-private.hh hb-set-digest-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-string-array.hh \ - hb-unicode-private.hh hb-unicode.cc hb-utf-private.hh \ - hb-warning.cc hb-buffer-deserialize-json.hh \ + hb-shaper-private.hh hb-shaper.cc hb-static.cc \ + hb-string-array.hh hb-unicode-private.hh hb-unicode.cc \ + hb-utf-private.hh hb-warning.cc hb-buffer-deserialize-json.hh \ hb-buffer-deserialize-text.hh hb-aat-layout.cc \ hb-aat-layout-common-private.hh hb-aat-layout-ankr-table.hh \ + hb-aat-layout-bsln-table.hh hb-aat-layout-feat-table.hh \ hb-aat-layout-kerx-table.hh hb-aat-layout-morx-table.hh \ hb-aat-layout-trak-table.hh hb-aat-layout-private.hh \ + hb-aat-fmtx-table.hh hb-aat-gcid-table.hh hb-aat-ltag-table.hh \ hb-ot-font.cc hb-ot-layout.cc hb-ot-layout-base-table.hh \ hb-ot-layout-common-private.hh hb-ot-layout-gdef-table.hh \ hb-ot-layout-gpos-table.hh 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-color.cc \ hb-ot-color-colr-table.hh hb-ot-color-cpal-table.hh \ + hb-ot-color-sbix-table.hh hb-ot-color-svg-table.hh \ hb-ot-map.cc hb-ot-map-private.hh hb-ot-math.cc \ hb-ot-math-table.hh hb-ot-shape.cc \ hb-ot-shape-complex-arabic.cc \ @@ -482,20 +503,21 @@ am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh hb-blob.cc \ hb-glib.cc hb-ft.cc hb-graphite2.cc hb-uniscribe.cc \ hb-directwrite.cc hb-coretext.cc hb-ucdn.cc hb-icu.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-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h hb-ot-math.h \ - hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h hb-ft.h \ - hb-graphite2.h hb-uniscribe.h hb-directwrite.h hb-coretext.h \ - hb-icu.h -am__objects_40 = libharfbuzz_la-hb-blob.lo \ + hb-font.h hb-map.h hb-set.h hb-shape.h hb-shape-plan.h \ + hb-unicode.h hb-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h \ + hb-ot-math.h hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h \ + hb-ft.h hb-graphite2.h hb-uniscribe.h hb-directwrite.h \ + hb-coretext.h hb-icu.h +am__objects_42 = 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-unicode.lo \ + libharfbuzz_la-hb-map.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-static.lo libharfbuzz_la-hb-unicode.lo \ libharfbuzz_la-hb-warning.lo $(am__objects_1) -am__objects_41 = libharfbuzz_la-hb-aat-layout.lo \ +am__objects_43 = libharfbuzz_la-hb-aat-layout.lo \ libharfbuzz_la-hb-ot-font.lo libharfbuzz_la-hb-ot-layout.lo \ libharfbuzz_la-hb-ot-color.lo libharfbuzz_la-hb-ot-map.lo \ libharfbuzz_la-hb-ot-math.lo libharfbuzz_la-hb-ot-shape.lo \ @@ -514,34 +536,48 @@ am__objects_41 = libharfbuzz_la-hb-aat-layout.lo \ libharfbuzz_la-hb-ot-shape-normalize.lo \ libharfbuzz_la-hb-ot-shape-fallback.lo \ libharfbuzz_la-hb-ot-var.lo $(am__objects_1) -@HAVE_OT_TRUE@am__objects_42 = $(am__objects_41) $(am__objects_3) -am__objects_43 = libharfbuzz_la-hb-fallback-shape.lo $(am__objects_1) -@HAVE_FALLBACK_TRUE@am__objects_44 = $(am__objects_43) -am__objects_45 = libharfbuzz_la-hb-glib.lo -@HAVE_GLIB_TRUE@am__objects_46 = $(am__objects_45) -am__objects_47 = libharfbuzz_la-hb-ft.lo -@HAVE_FREETYPE_TRUE@am__objects_48 = $(am__objects_47) -am__objects_49 = libharfbuzz_la-hb-graphite2.lo -@HAVE_GRAPHITE2_TRUE@am__objects_50 = $(am__objects_49) -am__objects_51 = libharfbuzz_la-hb-uniscribe.lo -@HAVE_UNISCRIBE_TRUE@am__objects_52 = $(am__objects_51) -am__objects_53 = libharfbuzz_la-hb-directwrite.lo -@HAVE_DIRECTWRITE_TRUE@am__objects_54 = $(am__objects_53) -am__objects_55 = libharfbuzz_la-hb-coretext.lo -@HAVE_CORETEXT_TRUE@am__objects_56 = $(am__objects_55) -am__objects_57 = libharfbuzz_la-hb-ucdn.lo -@HAVE_UCDN_TRUE@am__objects_58 = $(am__objects_57) -am__objects_59 = libharfbuzz_la-hb-icu.lo -@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_60 = \ -@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__objects_59) -am__objects_61 = $(am__objects_40) $(am__objects_3) $(am__objects_42) \ - $(am__objects_44) $(am__objects_46) $(am__objects_48) \ - $(am__objects_50) $(am__objects_52) $(am__objects_54) \ - $(am__objects_56) $(am__objects_58) $(am__objects_60) -am_libharfbuzz_la_OBJECTS = $(am__objects_61) $(am__objects_33) +@HAVE_OT_TRUE@am__objects_44 = $(am__objects_43) $(am__objects_3) +am__objects_45 = libharfbuzz_la-hb-fallback-shape.lo $(am__objects_1) +@HAVE_FALLBACK_TRUE@am__objects_46 = $(am__objects_45) +am__objects_47 = libharfbuzz_la-hb-glib.lo +@HAVE_GLIB_TRUE@am__objects_48 = $(am__objects_47) +am__objects_49 = libharfbuzz_la-hb-ft.lo +@HAVE_FREETYPE_TRUE@am__objects_50 = $(am__objects_49) +am__objects_51 = libharfbuzz_la-hb-graphite2.lo +@HAVE_GRAPHITE2_TRUE@am__objects_52 = $(am__objects_51) +am__objects_53 = libharfbuzz_la-hb-uniscribe.lo +@HAVE_UNISCRIBE_TRUE@am__objects_54 = $(am__objects_53) +am__objects_55 = libharfbuzz_la-hb-directwrite.lo +@HAVE_DIRECTWRITE_TRUE@am__objects_56 = $(am__objects_55) +am__objects_57 = libharfbuzz_la-hb-coretext.lo +@HAVE_CORETEXT_TRUE@am__objects_58 = $(am__objects_57) +am__objects_59 = libharfbuzz_la-hb-ucdn.lo +@HAVE_UCDN_TRUE@am__objects_60 = $(am__objects_59) +am__objects_61 = libharfbuzz_la-hb-icu.lo +@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_62 = \ +@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__objects_61) +am__objects_63 = $(am__objects_42) $(am__objects_3) $(am__objects_44) \ + $(am__objects_46) $(am__objects_48) $(am__objects_50) \ + $(am__objects_52) $(am__objects_54) $(am__objects_56) \ + $(am__objects_58) $(am__objects_60) $(am__objects_62) +am_libharfbuzz_la_OBJECTS = $(am__objects_63) $(am__objects_33) libharfbuzz_la_OBJECTS = $(am_libharfbuzz_la_OBJECTS) am__EXEEXT_1 = +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am__EXEEXT_2 = \ +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@ dump-emoji$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am__dump_emoji_SOURCES_DIST = dump-emoji.cc +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am_dump_emoji_OBJECTS = dump_emoji-dump-emoji.$(OBJEXT) +dump_emoji_OBJECTS = $(am_dump_emoji_OBJECTS) +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_DEPENDENCIES = \ +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@ libharfbuzz.la \ +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@ $(am__DEPENDENCIES_11) \ +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@ $(am__DEPENDENCIES_1) +am_dump_fon_OBJECTS = dump_fon-dump-fon.$(OBJEXT) +dump_fon_OBJECTS = $(am_dump_fon_OBJECTS) +dump_fon_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11) am_dump_indic_data_OBJECTS = \ dump_indic_data-dump-indic-data.$(OBJEXT) \ dump_indic_data-hb-ot-shape-complex-indic-table.$(OBJEXT) @@ -647,20 +683,26 @@ am__v_CCLD_1 = SOURCES = $(libharfbuzz_fuzzing_la_SOURCES) \ $(libharfbuzz_gobject_la_SOURCES) \ $(nodist_libharfbuzz_gobject_la_SOURCES) \ - $(libharfbuzz_icu_la_SOURCES) $(libharfbuzz_subset_la_SOURCES) \ - $(libharfbuzz_la_SOURCES) $(dump_indic_data_SOURCES) \ - $(dump_khmer_data_SOURCES) $(dump_myanmar_data_SOURCES) \ - $(dump_use_data_SOURCES) $(main_SOURCES) $(test_SOURCES) \ + $(libharfbuzz_icu_la_SOURCES) \ + $(libharfbuzz_subset_fuzzing_la_SOURCES) \ + $(libharfbuzz_subset_la_SOURCES) $(libharfbuzz_la_SOURCES) \ + $(dump_emoji_SOURCES) $(dump_fon_SOURCES) \ + $(dump_indic_data_SOURCES) $(dump_khmer_data_SOURCES) \ + $(dump_myanmar_data_SOURCES) $(dump_use_data_SOURCES) \ + $(main_SOURCES) $(test_SOURCES) \ $(test_buffer_serialize_SOURCES) $(test_ot_tag_SOURCES) \ $(test_size_params_SOURCES) $(test_unicode_ranges_SOURCES) \ $(test_would_substitute_SOURCES) DIST_SOURCES = $(am__libharfbuzz_fuzzing_la_SOURCES_DIST) \ $(am__libharfbuzz_gobject_la_SOURCES_DIST) \ $(am__libharfbuzz_icu_la_SOURCES_DIST) \ + $(libharfbuzz_subset_fuzzing_la_SOURCES) \ $(libharfbuzz_subset_la_SOURCES) \ - $(am__libharfbuzz_la_SOURCES_DIST) $(dump_indic_data_SOURCES) \ - $(dump_khmer_data_SOURCES) $(dump_myanmar_data_SOURCES) \ - $(dump_use_data_SOURCES) $(main_SOURCES) $(test_SOURCES) \ + $(am__libharfbuzz_la_SOURCES_DIST) \ + $(am__dump_emoji_SOURCES_DIST) $(dump_fon_SOURCES) \ + $(dump_indic_data_SOURCES) $(dump_khmer_data_SOURCES) \ + $(dump_myanmar_data_SOURCES) $(dump_use_data_SOURCES) \ + $(main_SOURCES) $(test_SOURCES) \ $(test_buffer_serialize_SOURCES) $(test_ot_tag_SOURCES) \ $(test_size_params_SOURCES) $(test_unicode_ranges_SOURCES) \ $(test_would_substitute_SOURCES) @@ -679,13 +721,13 @@ am__can_run_installinfo = \ esac DATA = $(cmake_DATA) $(gir_DATA) $(pkgconfig_DATA) $(typelib_DATA) am__pkginclude_HEADERS_DIST = 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-version.h hb-ot.h hb-ot-font.h \ - hb-ot-layout.h hb-ot-math.h hb-ot-shape.h hb-ot-tag.h \ - hb-ot-var.h hb-glib.h hb-ft.h hb-graphite2.h hb-uniscribe.h \ - hb-directwrite.h hb-coretext.h hb-icu.h hb-subset.h \ - hb-subset-glyf.hh hb-subset-plan.hh hb-subset-private.hh \ - hb-gobject.h hb-gobject-structs.h + hb-deprecated.h hb-face.h hb-font.h hb-map.h hb-set.h \ + hb-shape.h hb-shape-plan.h hb-unicode.h hb-version.h hb-ot.h \ + hb-ot-font.h hb-ot-layout.h hb-ot-math.h hb-ot-shape.h \ + hb-ot-tag.h hb-ot-var.h hb-glib.h hb-ft.h hb-graphite2.h \ + hb-uniscribe.h hb-directwrite.h hb-coretext.h hb-icu.h \ + hb-subset.h hb-subset-glyf.hh hb-subset-plan.hh \ + hb-subset-private.hh 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 @@ -870,11 +912,11 @@ am__set_TESTS_bases = \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) -@WITH_LIBSTDCXX_FALSE@am__EXEEXT_2 = check-libstdc++.sh \ +@WITH_LIBSTDCXX_FALSE@am__EXEEXT_3 = check-libstdc++.sh \ @WITH_LIBSTDCXX_FALSE@ $(am__EXEEXT_1) -am__EXEEXT_3 = check-c-linkage-decls.sh check-externs.sh \ +am__EXEEXT_4 = check-c-linkage-decls.sh check-externs.sh \ check-header-guards.sh check-includes.sh check-static-inits.sh \ - check-symbols.sh $(am__EXEEXT_1) $(am__EXEEXT_2) + check-symbols.sh $(am__EXEEXT_1) $(am__EXEEXT_3) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver @@ -896,8 +938,8 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.sources \ - $(srcdir)/harfbuzz-config.cmake.in $(srcdir)/hb-version.h.in \ - $(top_srcdir)/depcomp $(top_srcdir)/test-driver + $(srcdir)/harfbuzz-config.cmake.in $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -1110,23 +1152,24 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ NULL = -SUBDIRS = $(am__append_33) +SUBDIRS = $(am__append_32) DIST_SUBDIRS = hb-ucdn -BUILT_SOURCES = $(am__append_48) $(RAGEL_GENERATED) -EXTRA_DIST = harfbuzz.pc.in harfbuzz-config.cmake.in \ +BUILT_SOURCES = hb-version.h $(am__append_47) $(RAGEL_GENERATED) +EXTRA_DIST = hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in \ harfbuzz-subset.pc.in harfbuzz-icu.pc.in \ harfbuzz-gobject.pc.in hb-gobject-enums.cc.tmpl \ hb-gobject-enums.h.tmpl $(NULL) $(GENERATORS) \ $(HB_BASE_RAGEL_sources) $(HB_OT_RAGEL_sources) $(NULL) -CLEANFILES = libharfbuzz-fuzzing.la $(pkgconfig_DATA) $(DEF_FILES) \ - $(am__append_52) -DISTCLEANFILES = $(am__append_49) +CLEANFILES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la \ + $(pkgconfig_DATA) $(DEF_FILES) $(am__append_52) +DISTCLEANFILES = $(am__append_48) MAINTAINERCLEANFILES = DISTCHECK_CONFIGURE_FLAGS = --enable-introspection lib_LTLIBRARIES = libharfbuzz.la libharfbuzz-subset.la \ - $(am__append_41) $(am__append_44) + $(am__append_40) $(am__append_43) HB_BASE_sources = \ hb-atomic-private.hh \ + hb-blob-private.hh \ hb-blob.cc \ hb-buffer-private.hh \ hb-buffer-serialize.cc \ @@ -1138,6 +1181,8 @@ HB_BASE_sources = \ hb-face.cc \ hb-font-private.hh \ hb-font.cc \ + hb-map-private.hh \ + hb-map.cc \ hb-mutex-private.hh \ hb-object-private.hh \ hb-open-file-private.hh \ @@ -1168,6 +1213,7 @@ HB_BASE_sources = \ hb-shaper-impl-private.hh \ hb-shaper-private.hh \ hb-shaper.cc \ + hb-static.cc \ hb-string-array.hh \ hb-unicode-private.hh \ hb-unicode.cc \ @@ -1193,6 +1239,7 @@ HB_BASE_headers = \ hb-deprecated.h \ hb-face.h \ hb-font.h \ + hb-map.h \ hb-set.h \ hb-shape.h \ hb-shape-plan.h \ @@ -1208,10 +1255,15 @@ HB_OT_sources = \ hb-aat-layout.cc \ hb-aat-layout-common-private.hh \ hb-aat-layout-ankr-table.hh \ + hb-aat-layout-bsln-table.hh \ + hb-aat-layout-feat-table.hh \ hb-aat-layout-kerx-table.hh \ hb-aat-layout-morx-table.hh \ hb-aat-layout-trak-table.hh \ hb-aat-layout-private.hh \ + hb-aat-fmtx-table.hh \ + hb-aat-gcid-table.hh \ + hb-aat-ltag-table.hh \ hb-ot-font.cc \ hb-ot-layout.cc \ hb-ot-layout-base-table.hh \ @@ -1225,6 +1277,8 @@ HB_OT_sources = \ hb-ot-color.cc \ hb-ot-color-colr-table.hh \ hb-ot-color-cpal-table.hh \ + hb-ot-color-sbix-table.hh \ + hb-ot-color-svg-table.hh \ hb-ot-map.cc \ hb-ot-map-private.hh \ hb-ot-math.cc \ @@ -1313,6 +1367,7 @@ HB_ICU_headers = hb-icu.h # Sources for libharfbuzz-subset HB_SUBSET_sources = \ + hb-static.cc \ hb-subset.cc \ hb-subset-glyf.cc \ hb-subset-input.cc \ @@ -1334,27 +1389,24 @@ HB_GOBJECT_NODIST_sources = $(HB_GOBJECT_ENUM_sources) HB_GOBJECT_NODIST_headers = $(HB_GOBJECT_ENUM_headers) HB_GOBJECT_sources = $(HB_GOBJECT_DIST_sources) $(HB_GOBJECT_NODIST_sources) HB_GOBJECT_headers = $(HB_GOBJECT_DIST_headers) $(HB_GOBJECT_NODIST_headers) -HBCFLAGS = $(am__append_1) $(am__append_5) $(am__append_7) \ - $(am__append_12) $(am__append_16) $(am__append_21) \ - $(am__append_25) $(am__append_29) $(am__append_34) \ - $(am__append_37) +HBCFLAGS = $(am__append_4) $(am__append_6) $(am__append_11) \ + $(am__append_15) $(am__append_20) $(am__append_24) \ + $(am__append_28) $(am__append_33) $(am__append_36) # Put the library together -HBLIBS = $(am__append_8) $(am__append_13) $(am__append_17) \ - $(am__append_35) $(HBNONPCLIBS) $(am__append_38) -HBNONPCLIBS = $(am__append_6) $(am__append_22) $(am__append_26) \ - $(am__append_30) -HBDEPS = $(am__append_9) $(am__append_18) +HBLIBS = $(am__append_7) $(am__append_12) $(am__append_16) \ + $(am__append_34) $(HBNONPCLIBS) $(am__append_37) +HBNONPCLIBS = $(am__append_5) $(am__append_21) $(am__append_25) \ + $(am__append_29) +HBDEPS = $(am__append_8) $(am__append_17) HBSOURCES = $(HB_BASE_sources) $(HB_BASE_RAGEL_GENERATED_sources) \ - $(am__append_2) $(am__append_4) $(am__append_10) \ + $(am__append_1) $(am__append_3) $(am__append_9) \ + $(am__append_13) $(am__append_18) $(am__append_22) \ + $(am__append_26) $(am__append_30) $(am__append_35) \ + $(am__append_38) +HBHEADERS = $(HB_BASE_headers) $(am__append_2) $(am__append_10) \ $(am__append_14) $(am__append_19) $(am__append_23) \ - $(am__append_27) $(am__append_31) $(am__append_36) \ - $(am__append_39) -HBHEADERS = $(HB_BASE_headers) $(am__append_3) $(am__append_11) \ - $(am__append_15) $(am__append_20) $(am__append_24) \ - $(am__append_28) $(am__append_32) $(am__append_40) -@WITH_LIBSTDCXX_TRUE@HBNOLIBCXXCFLAGS = -@WITH_LIBSTDCXX_FALSE@HBNOLIBCXXFLAGS = -fno-threadsafe-statics -fno-rtti + $(am__append_27) $(am__append_31) $(am__append_39) @OS_WIN32_TRUE@export_symbols = -export-symbols harfbuzz.def @OS_WIN32_TRUE@harfbuzz_def_dependency = harfbuzz.def @OS_WIN32_TRUE@export_symbols_subset = -export-symbols harfbuzz-subset.def @@ -1369,23 +1421,23 @@ HBHEADERS = $(HB_BASE_headers) $(am__append_3) $(am__append_11) \ @OS_WIN32_FALSE@@WITH_LIBSTDCXX_TRUE@chosen_linker = $(CXXLINK) @OS_WIN32_TRUE@chosen_linker = $(CXXLINK) base_link_flags = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined -libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) $(CODE_COVERAGE_LDFLAGS) +libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) -libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(CODE_COVERAGE_CFLAGS) -libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) +libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS) +libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) $(CODE_COVERAGE_LDFLAGS) libharfbuzz_la_LIBADD = $(HBLIBS) EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency) pkginclude_HEADERS = $(HBHEADERS) $(HB_SUBSET_headers) \ - $(am__append_42) $(am__append_45) -nodist_pkginclude_HEADERS = $(am__append_46) + $(am__append_41) $(am__append_44) +nodist_pkginclude_HEADERS = $(am__append_45) pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = harfbuzz.pc harfbuzz-subset.pc $(am__append_43) \ - $(am__append_47) +pkgconfig_DATA = harfbuzz.pc harfbuzz-subset.pc $(am__append_42) \ + $(am__append_46) cmakedir = $(libdir)/cmake/harfbuzz cmake_DATA = harfbuzz-config.cmake libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources) -libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) -libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) +libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS) +libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) $(CODE_COVERAGE_LDFLAGS) libharfbuzz_subset_la_LIBADD = libharfbuzz.la EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency) FUZZING_CPPFLAGS = \ @@ -1402,27 +1454,33 @@ FUZZING_CPPFLAGS = \ -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ $(NULL) -EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la +EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS) libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES) libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) libharfbuzz_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) +libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS) +libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES) +libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) +libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) +libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD) +EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources) -@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS) -@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) +@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS) $(CODE_COVERAGE_CFLAGS) +@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) $(CODE_COVERAGE_LDFLAGS) @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency) @HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LINK = $(chosen_linker) $(libharfbuzz_gobject_la_LDFLAGS) @HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_DIST_sources) @HAVE_GOBJECT_TRUE@nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_NODIST_sources) -@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS) -@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) +@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(GOBJECT_CFLAGS) $(CODE_COVERAGE_CFLAGS) +@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) $(CODE_COVERAGE_LDFLAGS) @HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la @HAVE_GOBJECT_TRUE@EXTRA_libharfbuzz_gobject_la_DEPENDENCIES = $(harfbuzz_gobject_def_dependency) DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def \ - $(am__append_50) + $(am__append_49) GENERATORS = \ gen-arabic-table.py \ gen-indic-table.py \ @@ -1452,7 +1510,10 @@ test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) dist_check_SCRIPTS = check-c-linkage-decls.sh check-externs.sh \ check-header-guards.sh check-includes.sh check-static-inits.sh \ - check-symbols.sh $(NULL) $(am__append_51) + check-symbols.sh $(NULL) $(am__append_50) +dump_fon_SOURCES = dump-fon.cc +dump_fon_CPPFLAGS = $(HBCFLAGS) +dump_fon_LDADD = libharfbuzz.la $(HBLIBS) dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc dump_indic_data_CPPFLAGS = $(HBCFLAGS) dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS) @@ -1465,6 +1526,9 @@ dump_myanmar_data_LDADD = libharfbuzz.la $(HBLIBS) dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc dump_use_data_CPPFLAGS = $(HBCFLAGS) dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_SOURCES = dump-emoji.cc +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS) +@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS) test_ot_tag_SOURCES = hb-ot-tag.cc test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS) @@ -1545,8 +1609,6 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -hb-version.h: $(top_builddir)/config.status $(srcdir)/hb-version.h.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ harfbuzz-config.cmake: $(top_builddir)/config.status $(srcdir)/harfbuzz-config.cmake.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ @@ -1594,6 +1656,9 @@ libharfbuzz-gobject.la: $(libharfbuzz_gobject_la_OBJECTS) $(libharfbuzz_gobject_ 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-subset-fuzzing.la: $(libharfbuzz_subset_fuzzing_la_OBJECTS) $(libharfbuzz_subset_fuzzing_la_DEPENDENCIES) $(EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES) + $(AM_V_GEN)$(libharfbuzz_subset_fuzzing_la_LINK) $(libharfbuzz_subset_fuzzing_la_OBJECTS) $(libharfbuzz_subset_fuzzing_la_LIBADD) $(LIBS) + libharfbuzz-subset.la: $(libharfbuzz_subset_la_OBJECTS) $(libharfbuzz_subset_la_DEPENDENCIES) $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) $(AM_V_CXXLD)$(libharfbuzz_subset_la_LINK) -rpath $(libdir) $(libharfbuzz_subset_la_OBJECTS) $(libharfbuzz_subset_la_LIBADD) $(LIBS) @@ -1683,6 +1748,14 @@ clean-noinstPROGRAMS: echo " rm -f" $$list; \ rm -f $$list +dump-emoji$(EXEEXT): $(dump_emoji_OBJECTS) $(dump_emoji_DEPENDENCIES) $(EXTRA_dump_emoji_DEPENDENCIES) + @rm -f dump-emoji$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(dump_emoji_OBJECTS) $(dump_emoji_LDADD) $(LIBS) + +dump-fon$(EXEEXT): $(dump_fon_OBJECTS) $(dump_fon_DEPENDENCIES) $(EXTRA_dump_fon_DEPENDENCIES) + @rm -f dump-fon$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(dump_fon_OBJECTS) $(dump_fon_LDADD) $(LIBS) + dump-indic-data$(EXEEXT): $(dump_indic_data_OBJECTS) $(dump_indic_data_DEPENDENCIES) $(EXTRA_dump_indic_data_DEPENDENCIES) @rm -f dump-indic-data$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(dump_indic_data_OBJECTS) $(dump_indic_data_LDADD) $(LIBS) @@ -1733,6 +1806,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_emoji-dump-emoji.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_fon-dump-fon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_indic_data-dump-indic-data.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_indic_data-hb-ot-shape-complex-indic-table.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_khmer_data-dump-khmer-data.Po@am__quote@ @@ -1755,6 +1830,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-glib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-graphite2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-icu.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-color.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-font.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-layout.Plo@am__quote@ @@ -1781,6 +1857,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-shape-plan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-shape.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-shaper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ucdn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-uniscribe.Plo@am__quote@ @@ -1802,6 +1879,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-glib.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.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-color.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@ @@ -1828,10 +1906,17 @@ 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-static.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)/libharfbuzz_subset_fuzzing_la-hb-static.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-plan.Plo@am__quote@ @@ -1907,6 +1992,13 @@ libharfbuzz_fuzzing_la-hb-font.lo: hb-font.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_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-font.lo `test -f 'hb-font.cc' || echo '$(srcdir)/'`hb-font.cc +libharfbuzz_fuzzing_la-hb-map.lo: hb-map.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-map.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Tpo -c -o libharfbuzz_fuzzing_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-map.cc' object='libharfbuzz_fuzzing_la-hb-map.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_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc + libharfbuzz_fuzzing_la-hb-ot-tag.lo: hb-ot-tag.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-ot-tag.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-tag.Tpo -c -o libharfbuzz_fuzzing_la-hb-ot-tag.lo `test -f 'hb-ot-tag.cc' || echo '$(srcdir)/'`hb-ot-tag.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-tag.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-tag.Plo @@ -1942,6 +2034,13 @@ libharfbuzz_fuzzing_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_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-shaper.lo `test -f 'hb-shaper.cc' || echo '$(srcdir)/'`hb-shaper.cc +libharfbuzz_fuzzing_la-hb-static.lo: hb-static.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Tpo -c -o libharfbuzz_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_fuzzing_la-hb-static.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_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc + libharfbuzz_fuzzing_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_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-unicode.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Tpo -c -o libharfbuzz_fuzzing_la-hb-unicode.lo `test -f 'hb-unicode.cc' || echo '$(srcdir)/'`hb-unicode.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Plo @@ -2194,6 +2293,48 @@ libharfbuzz_icu_la-hb-icu.lo: hb-icu.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_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_subset_fuzzing_la-hb-static.lo: hb-static.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-static.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-static.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_subset_fuzzing_la-hb-static.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_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc + +libharfbuzz_subset_fuzzing_la-hb-subset.lo: hb-subset.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset.lo `test -f 'hb-subset.cc' || echo '$(srcdir)/'`hb-subset.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-subset.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset.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_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset.lo `test -f 'hb-subset.cc' || echo '$(srcdir)/'`hb-subset.cc + +libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo: hb-subset-glyf.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo `test -f 'hb-subset-glyf.cc' || echo '$(srcdir)/'`hb-subset-glyf.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-subset-glyf.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset-glyf.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_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo `test -f 'hb-subset-glyf.cc' || echo '$(srcdir)/'`hb-subset-glyf.cc + +libharfbuzz_subset_fuzzing_la-hb-subset-input.lo: hb-subset-input.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset-input.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset-input.lo `test -f 'hb-subset-input.cc' || echo '$(srcdir)/'`hb-subset-input.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-subset-input.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset-input.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_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset-input.lo `test -f 'hb-subset-input.cc' || echo '$(srcdir)/'`hb-subset-input.cc + +libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo: hb-subset-plan.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo `test -f 'hb-subset-plan.cc' || echo '$(srcdir)/'`hb-subset-plan.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-subset-plan.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset-plan.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_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo `test -f 'hb-subset-plan.cc' || echo '$(srcdir)/'`hb-subset-plan.cc + +libharfbuzz_subset_la-hb-static.lo: hb-static.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-static.Tpo -c -o libharfbuzz_subset_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_subset_la-hb-static.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_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc + libharfbuzz_subset_la-hb-subset.lo: hb-subset.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-subset.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-subset.Tpo -c -o libharfbuzz_subset_la-hb-subset.lo `test -f 'hb-subset.cc' || echo '$(srcdir)/'`hb-subset.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-subset.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-subset.Plo @@ -2264,6 +2405,13 @@ libharfbuzz_la-hb-font.lo: hb-font.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-font.lo `test -f 'hb-font.cc' || echo '$(srcdir)/'`hb-font.cc +libharfbuzz_la-hb-map.lo: hb-map.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-map.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-map.Tpo -c -o libharfbuzz_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-map.Tpo $(DEPDIR)/libharfbuzz_la-hb-map.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-map.cc' object='libharfbuzz_la-hb-map.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-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc + libharfbuzz_la-hb-ot-tag.lo: hb-ot-tag.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-tag.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-tag.Tpo -c -o libharfbuzz_la-hb-ot-tag.lo `test -f 'hb-ot-tag.cc' || echo '$(srcdir)/'`hb-ot-tag.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-tag.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-tag.Plo @@ -2299,6 +2447,13 @@ 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-static.lo: hb-static.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-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-static.Tpo -c -o libharfbuzz_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_la-hb-static.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_la-hb-static.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-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.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 @@ -2530,6 +2685,34 @@ libharfbuzz_la-hb-icu.lo: hb-icu.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-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc +dump_emoji-dump-emoji.o: dump-emoji.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_emoji-dump-emoji.o -MD -MP -MF $(DEPDIR)/dump_emoji-dump-emoji.Tpo -c -o dump_emoji-dump-emoji.o `test -f 'dump-emoji.cc' || echo '$(srcdir)/'`dump-emoji.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dump_emoji-dump-emoji.Tpo $(DEPDIR)/dump_emoji-dump-emoji.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dump-emoji.cc' object='dump_emoji-dump-emoji.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) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_emoji-dump-emoji.o `test -f 'dump-emoji.cc' || echo '$(srcdir)/'`dump-emoji.cc + +dump_emoji-dump-emoji.obj: dump-emoji.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_emoji-dump-emoji.obj -MD -MP -MF $(DEPDIR)/dump_emoji-dump-emoji.Tpo -c -o dump_emoji-dump-emoji.obj `if test -f 'dump-emoji.cc'; then $(CYGPATH_W) 'dump-emoji.cc'; else $(CYGPATH_W) '$(srcdir)/dump-emoji.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dump_emoji-dump-emoji.Tpo $(DEPDIR)/dump_emoji-dump-emoji.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dump-emoji.cc' object='dump_emoji-dump-emoji.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) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_emoji-dump-emoji.obj `if test -f 'dump-emoji.cc'; then $(CYGPATH_W) 'dump-emoji.cc'; else $(CYGPATH_W) '$(srcdir)/dump-emoji.cc'; fi` + +dump_fon-dump-fon.o: dump-fon.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_fon-dump-fon.o -MD -MP -MF $(DEPDIR)/dump_fon-dump-fon.Tpo -c -o dump_fon-dump-fon.o `test -f 'dump-fon.cc' || echo '$(srcdir)/'`dump-fon.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dump_fon-dump-fon.Tpo $(DEPDIR)/dump_fon-dump-fon.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dump-fon.cc' object='dump_fon-dump-fon.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) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_fon-dump-fon.o `test -f 'dump-fon.cc' || echo '$(srcdir)/'`dump-fon.cc + +dump_fon-dump-fon.obj: dump-fon.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_fon-dump-fon.obj -MD -MP -MF $(DEPDIR)/dump_fon-dump-fon.Tpo -c -o dump_fon-dump-fon.obj `if test -f 'dump-fon.cc'; then $(CYGPATH_W) 'dump-fon.cc'; else $(CYGPATH_W) '$(srcdir)/dump-fon.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dump_fon-dump-fon.Tpo $(DEPDIR)/dump_fon-dump-fon.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dump-fon.cc' object='dump_fon-dump-fon.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) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_fon-dump-fon.obj `if test -f 'dump-fon.cc'; then $(CYGPATH_W) 'dump-fon.cc'; else $(CYGPATH_W) '$(srcdir)/dump-fon.cc'; fi` + dump_indic_data-dump-indic-data.o: dump-indic-data.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_indic_data_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_indic_data-dump-indic-data.o -MD -MP -MF $(DEPDIR)/dump_indic_data-dump-indic-data.Tpo -c -o dump_indic_data-dump-indic-data.o `test -f 'dump-indic-data.cc' || echo '$(srcdir)/'`dump-indic-data.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dump_indic_data-dump-indic-data.Tpo $(DEPDIR)/dump_indic_data-dump-indic-data.Po @@ -3389,19 +3572,24 @@ uninstall-am: uninstall-binPROGRAMS uninstall-cmakeDATA \ .PRECIOUS: Makefile -# The following warning options are useful for debugging: -Wpadded -#AM_CXXFLAGS = - # Convenience targets: lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la -fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la +fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la @HAVE_UCDN_TRUE@hb-ucdn/libhb-ucdn.la: ucdn @HAVE_UCDN_TRUE@ucdn: @HAVE_UCDN_TRUE@ @$(MAKE) $(AM_MAKEFLAGS) -C hb-ucdn +$(srcdir)/hb-version.h: hb-version.h.in $(top_srcdir)/configure.ac + $(AM_V_GEN) $(SED) \ + -e 's/[@]HB_VERSION_MAJOR@/$(HB_VERSION_MAJOR)/' \ + -e 's/[@]HB_VERSION_MINOR@/$(HB_VERSION_MINOR)/' \ + -e 's/[@]HB_VERSION_MICRO@/$(HB_VERSION_MICRO)/' \ + -e 's/[@]HB_VERSION@/$(HB_VERSION)/' \ + "$<" > "$@" || ($(RM) "$@"; false) + @CODE_COVERAGE_RULES@ @HAVE_GOBJECT_TRUE@hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS) -@HAVE_GOBJECT_TRUE@ $(AM_V_GEN) $(GLIB_MKENUMS) \ +@HAVE_GOBJECT_TRUE@ $(AM_V_GEN) PYTHONIOENCODING=UTF-8 $(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' > "$@" \ @@ -3420,27 +3608,27 @@ fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la || ($(RM) "$@"; false) check: $(DEF_FILES) # For check-symbols.sh harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" harfbuzz-subset.def: $(HB_SUBSET_headers) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" harfbuzz-icu.def: $(HB_ICU_headers) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" harfbuzz-gobject.def: $(HB_GOBJECT_headers) - $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@" unicode-tables: arabic-table indic-table use-table arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \ - || ($(RM) hb-ot-shape-complex-arabic-table.hh; false) + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \ + || ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false) -indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \ - || ($(RM) hb-ot-shape-complex-indic-table.cc; false) +indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \ + || ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false) use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \ - || ($(RM) hb-ot-shape-complex-use-table.cc; false) + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \ + || ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false) built-sources: $(BUILT_SOURCES) diff --git a/src/Makefile.sources b/src/Makefile.sources index 787c3c4..0bc9e58 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -2,6 +2,7 @@ HB_BASE_sources = \ hb-atomic-private.hh \ + hb-blob-private.hh \ hb-blob.cc \ hb-buffer-private.hh \ hb-buffer-serialize.cc \ @@ -13,6 +14,8 @@ HB_BASE_sources = \ hb-face.cc \ hb-font-private.hh \ hb-font.cc \ + hb-map-private.hh \ + hb-map.cc \ hb-mutex-private.hh \ hb-object-private.hh \ hb-open-file-private.hh \ @@ -43,6 +46,7 @@ HB_BASE_sources = \ hb-shaper-impl-private.hh \ hb-shaper-private.hh \ hb-shaper.cc \ + hb-static.cc \ hb-string-array.hh \ hb-unicode-private.hh \ hb-unicode.cc \ @@ -67,6 +71,7 @@ HB_BASE_headers = \ hb-deprecated.h \ hb-face.h \ hb-font.h \ + hb-map.h \ hb-set.h \ hb-shape.h \ hb-shape-plan.h \ @@ -82,10 +87,15 @@ HB_OT_sources = \ hb-aat-layout.cc \ hb-aat-layout-common-private.hh \ hb-aat-layout-ankr-table.hh \ + hb-aat-layout-bsln-table.hh \ + hb-aat-layout-feat-table.hh \ hb-aat-layout-kerx-table.hh \ hb-aat-layout-morx-table.hh \ hb-aat-layout-trak-table.hh \ hb-aat-layout-private.hh \ + hb-aat-fmtx-table.hh \ + hb-aat-gcid-table.hh \ + hb-aat-ltag-table.hh \ hb-ot-font.cc \ hb-ot-layout.cc \ hb-ot-layout-base-table.hh \ @@ -99,6 +109,8 @@ HB_OT_sources = \ hb-ot-color.cc \ hb-ot-color-colr-table.hh \ hb-ot-color-cpal-table.hh \ + hb-ot-color-sbix-table.hh \ + hb-ot-color-svg-table.hh \ hb-ot-map.cc \ hb-ot-map-private.hh \ hb-ot-math.cc \ @@ -191,6 +203,7 @@ HB_ICU_headers = hb-icu.h # Sources for libharfbuzz-subset HB_SUBSET_sources = \ + hb-static.cc \ hb-subset.cc \ hb-subset-glyf.cc \ hb-subset-input.cc \ diff --git a/src/check-symbols.sh b/src/check-symbols.sh index bfc93b3..d4eca50 100755 --- a/src/check-symbols.sh +++ b/src/check-symbols.sh @@ -30,7 +30,6 @@ for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'` - echo echo "Checking that $so does not expose internal symbols" if echo "$EXPORTED_SYMBOLS" | grep -v "^${prefix}\(_\|$\)"; then echo "Ouch, internal symbols exposed" @@ -41,7 +40,6 @@ for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do if ! test -f "$def"; then echo "'$def' not found; skipping" else - echo echo "Checking that $so has the same symbol list as $def" { echo EXPORTS diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc new file mode 100644 index 0000000..99e8ef9 --- /dev/null +++ b/src/dump-emoji.cc @@ -0,0 +1,263 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb-static.cc" +#include "hb-ot-color-cbdt-table.hh" +#include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-cpal-table.hh" +#include "hb-ot-color-sbix-table.hh" +#include "hb-ot-color-svg-table.hh" + +#include "hb-ft.h" + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_GLYPH_H + +#include <cairo.h> +#include <cairo-ft.h> +#include <cairo-svg.h> + +#ifdef HAVE_GLIB +#include <glib.h> +#endif +#include <stdlib.h> +#include <stdio.h> + +void cbdt_callback (const uint8_t* data, unsigned int length, + unsigned int group, unsigned int gid) +{ + char output_path[255]; + sprintf (output_path, "out/cbdt-%d-%d.png", group, gid); + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); +} + +void sbix_callback (const uint8_t* data, unsigned int length, + unsigned int group, unsigned int gid) +{ + char output_path[255]; + sprintf (output_path, "out/sbix-%d-%d.png", group, gid); + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); +} + +void svg_callback (const uint8_t* data, unsigned int length, + unsigned int start_glyph, unsigned int end_glyph) +{ + char output_path[255]; + if (start_glyph == end_glyph) + sprintf (output_path, "out/svg-%d.svg", start_glyph); + else + sprintf (output_path, "out/svg-%d-%d.svg", start_glyph, end_glyph); + + // append "z" if the content is gzipped + if ((data[0] == 0x1F) && (data[1] == 0x8B)) + strcat (output_path, "z"); + + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); +} + +void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs, + const OT::COLR *colr, const OT::CPAL *cpal) +{ + for (unsigned int i = 0; i < num_glyphs; ++i) + { + unsigned int first_layer_index, num_layers; + if (colr->get_base_glyph_record (i, &first_layer_index, &num_layers)) + { + // Measure + cairo_text_extents_t extents; + { + cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + + cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t)); + for (unsigned int j = 0; j < num_layers; ++j) + { + hb_codepoint_t glyph_id; + unsigned int color_index; + colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index); + glyphs[j].index = glyph_id; + } + cairo_glyph_extents (cr, glyphs, num_layers, &extents); + free (glyphs); + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + + // Add a slight margin + extents.width += extents.width / 10; + extents.height += extents.height / 10; + extents.x_bearing -= extents.width / 20; + extents.y_bearing -= extents.height / 20; + + // Render + unsigned int pallet_count = cpal->get_palette_count (); + for (unsigned int pallet = 0; pallet < pallet_count; ++pallet) { + char output_path[255]; + + // If we have more than one pallet, use a better namin + if (pallet_count == 1) + sprintf (output_path, "out/colr-%d.svg", i); + else + sprintf (output_path, "out/colr-%d-%d.svg", i, pallet); + + cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + + for (unsigned int j = 0; j < num_layers; ++j) + { + hb_codepoint_t glyph_id; + unsigned int color_index; + colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index); + + uint32_t color = cpal->get_color_record_argb (color_index, pallet); + int alpha = color & 0xFF; + int r = (color >> 8) & 0xFF; + int g = (color >> 16) & 0xFF; + int b = (color >> 24) & 0xFF; + cairo_set_source_rgba (cr, r / 255.f, g / 255.f, b / 255.f, alpha); + + cairo_glyph_t glyph; + glyph.index = glyph_id; + glyph.x = -extents.x_bearing; + glyph.y = -extents.y_bearing; + cairo_show_glyphs (cr, &glyph, 1); + } + + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + } + } +} + +void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs) +{ + // Dump every glyph available on the font + return; // disabled for now + for (unsigned int i = 0; i < num_glyphs; ++i) + { + cairo_text_extents_t extents; + cairo_glyph_t glyph = {0}; + glyph.index = i; + + // Measure + { + cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + + cairo_glyph_extents (cr, &glyph, 1, &extents); + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + + // Add a slight margin + extents.width += extents.width / 10; + extents.height += extents.height / 10; + extents.x_bearing -= extents.width / 20; + extents.y_bearing -= extents.height / 20; + + // Render + { + char output_path[255]; + sprintf (output_path, "out/%d.svg", i); + cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + glyph.x = -extents.x_bearing; + glyph.y = -extents.y_bearing; + cairo_show_glyphs (cr, &glyph, 1); + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + } +} + +int main (int argc, char **argv) +{ + if (argc != 2) { + fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); + exit (1); + } + + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + hb_face_t *face = hb_face_create (blob, 0); + hb_font_t *font = hb_font_create (face); + + OT::CBDT::accelerator_t cbdt; + cbdt.init (face); + cbdt.dump (cbdt_callback); + cbdt.fini (); + + OT::sbix::accelerator_t sbix; + sbix.init (face); + sbix.dump (sbix_callback); + sbix.fini (); + + OT::SVG::accelerator_t svg; + svg.init (face); + svg.dump (svg_callback); + svg.fini (); + + OT::Sanitizer<OT::COLR> sanitizerCOLR; + hb_blob_t* colr_blob = sanitizerCOLR.sanitize (face->reference_table (HB_OT_TAG_COLR)); + const OT::COLR *colr = colr_blob->as<OT::COLR> (); + + OT::Sanitizer<OT::CPAL> sanitizerCPAL; + hb_blob_t* cpal_blob = sanitizerCPAL.sanitize (face->reference_table (HB_OT_TAG_CPAL)); + const OT::CPAL *cpal = cpal_blob->as<OT::CPAL> (); + + cairo_font_face_t *cairo_face; + { + FT_Library library; + FT_Init_FreeType (&library); + FT_Face ftface; + FT_New_Face (library, argv[1], 0, &ftface); + cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0); + } + unsigned int num_glyphs = hb_face_get_glyph_count (face); + unsigned int upem = hb_face_get_upem (face); + colr_cpal_rendering (cairo_face, upem, num_glyphs, colr, cpal); + dump_glyphs (cairo_face, upem, num_glyphs); + + + hb_font_destroy (font); + hb_face_destroy (face); + hb_blob_destroy (blob); + + return 0; +} diff --git a/src/dump-fon.cc b/src/dump-fon.cc new file mode 100644 index 0000000..4015409 --- /dev/null +++ b/src/dump-fon.cc @@ -0,0 +1,555 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb-static.cc" +#include <stdio.h> +#include <stdlib.h> +#include "hb-open-type-private.hh" + +template <typename Type, int Bytes> struct LEInt; + +template <typename Type> +struct LEInt<Type, 1> +{ + public: + inline void set (Type V) + { + v = V; + } + inline operator Type (void) const + { + return v; + } + private: uint8_t v; +}; +template <typename Type> +struct LEInt<Type, 2> +{ + public: + inline void set (Type V) + { + v[1] = (V >> 8) & 0xFF; + v[0] = (V ) & 0xFF; + } + inline operator Type (void) const + { + return (v[1] << 8) + + (v[0] ); + } + private: uint8_t v[2]; +}; +template <typename Type> +struct LEInt<Type, 3> +{ + public: + inline void set (Type V) + { + v[2] = (V >> 16) & 0xFF; + v[1] = (V >> 8) & 0xFF; + v[0] = (V ) & 0xFF; + } + inline operator Type (void) const + { + return (v[2] << 16) + + (v[1] << 8) + + (v[0] ); + } + private: uint8_t v[3]; +}; +template <typename Type> +struct LEInt<Type, 4> +{ + public: + inline void set (Type V) + { + v[3] = (V >> 24) & 0xFF; + v[2] = (V >> 16) & 0xFF; + v[1] = (V >> 8) & 0xFF; + v[0] = (V ) & 0xFF; + } + inline operator Type (void) const + { + return (v[3] << 24) + + (v[2] << 16) + + (v[1] << 8) + + (v[0] ); + } + private: uint8_t v[4]; +}; + +template <typename Type, unsigned int Size> +struct LEIntType +{ + inline void set (Type i) { v.set (i); } + inline operator Type(void) const { return v; } + inline bool sanitize (OT::hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + protected: + LEInt<Type, Size> v; + public: + DEFINE_SIZE_STATIC (Size); +}; + +typedef LEIntType<uint8_t, 1> LEUINT8; /* 8-bit unsigned integer. */ +typedef LEIntType<int8_t, 1> LEINT8; /* 8-bit signed integer. */ +typedef LEIntType<uint16_t, 2> LEUINT16; /* 16-bit unsigned integer. */ +typedef LEIntType<int16_t, 2> LEINT16; /* 16-bit signed integer. */ +typedef LEIntType<uint32_t, 4> LEUINT32; /* 32-bit unsigned integer. */ +typedef LEIntType<int32_t, 4> LEINT32; /* 32-bit signed integer. */ +typedef LEIntType<uint32_t, 3> LEUINT24; /* 24-bit unsigned integer. */ + + +struct LE_FONTINFO16 +{ + inline bool sanitize (OT::hb_sanitize_context_t *c, unsigned int length) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && c->check_range (this, length))); + } + + // https://msdn.microsoft.com/en-us/library/cc194829.aspx + enum charset_t + { + // dfCharSet possible values and the codepage they are indicating to + ANSI = 0x00, // 1252 + DEFAULT = 0x01, // + SYMBOL = 0x02, // + SHIFTJIS = 0x80, // 932 + HANGUL = 0x81, // 949 + GB2312 = 0x86, // 936 + CHINESEBIG5 = 0x88, // 950 + GREEK = 0xA1, // 1253 + TURKISH = 0xA2, // 1254 + HEBREW = 0xB1, // 1255 + ARABIC = 0xB2, // 1256 + BALTIC = 0xBA, // 1257 + RUSSIAN = 0xCC, // 1251 + THAI = 0xDE, // 874 + EE = 0xEE, // 1250 + OEM = 0xFF // + }; + + inline const char* get_charset() const + { + switch (dfCharSet) { + case ANSI: return "ISO8859"; + case DEFAULT: return "WinDefault"; + case SYMBOL: return "Symbol"; + case SHIFTJIS: return "JISX0208.1983"; + case HANGUL: return "MSHangul"; + case GB2312: return "GB2312.1980"; + case CHINESEBIG5: return "Big5"; + case GREEK: return "CP1253"; + case TURKISH: return "CP1254"; + case HEBREW: return "CP1255"; + case ARABIC: return "CP1256"; + case BALTIC: return "CP1257"; + case RUSSIAN: return "CP1251"; + case THAI: return "CP874"; + case EE: return "CP1250"; + case OEM: return "OEM"; + default: return "Unknown"; + } + } + + inline unsigned int get_version () const + { + return dfVersion; + } + + inline unsigned int get_weight () const + { + return dfWeight; + } + + enum weight_t { + DONTCARE = 0, + THIN = 100, + EXTRALIGHT = 200, + ULTRALIGHT = 200, + LIGHT = 300, + NORMAL = 400, + REGULAR = 400, + MEDIUM = 500, + SEMIBOLD = 600, + DEMIBOLD = 600, + BOLD = 700, + EXTRABOLD = 800, + ULTRABOLD = 800, + HEAVY = 900, + BLACK = 900 + }; + + inline void dump () const + { + // With https://github.com/juanitogan/mkwinfont/blob/master/python/dewinfont.py help + // Should be implemented differently eventually, but for now + unsigned int ctstart; + unsigned int ctsize; + if (dfVersion == 0x200) + { + ctstart = 0x76; + ctsize = 4; + } + else + { + return; // must of ".fon"s are version 2 and even dewinfont V1 implmentation doesn't seem correct + ctstart = 0x94; + ctsize = 6; + } + // unsigned int maxwidth = 0; + for (unsigned int i = dfFirstChar; i < dfLastChar; ++i) + { + unsigned int entry = ctstart + ctsize * (i-dfFirstChar); + unsigned int w = (uint16_t) OT::StructAtOffset<LEUINT16> (this, entry); + + unsigned int off; + if (ctsize == 4) + off = (uint16_t) OT::StructAtOffset<LEUINT16> (this, entry+2); + else + off = (uint32_t) OT::StructAtOffset<LEUINT32> (this, entry+2); + + unsigned int widthbytes = (w + 7) / 8; + for (unsigned int j = 0; j < dfPixHeight; ++j) + { + for (unsigned int k = 0; k < widthbytes; ++k) + { + unsigned int bytepos = off + k * dfPixHeight + j; + const uint8_t b = (uint8_t) OT::StructAtOffset<LEINT8> (this, bytepos); + for (unsigned int a = 128; a > 0; a >>= 1) + printf (b & a ? "x" : "."); + } + printf ("\n"); + } + printf ("\n\n"); + } + } + + protected: + LEUINT16 dfVersion; + LEUINT32 dfSize; + LEUINT8 dfCopyright[60]; + LEUINT16 dfType; + LEUINT16 dfPoints; + LEUINT16 dfVertRes; + LEUINT16 dfHorizRes; + LEUINT16 dfAscent; + LEUINT16 dfInternalLeading; + LEUINT16 dfExternalLeading; + LEUINT8 dfItalic; + LEUINT8 dfUnderline; + LEUINT8 dfStrikeOut; + LEUINT16 dfWeight; // see weight_t + LEUINT8 dfCharSet; // see charset_t + LEUINT16 dfPixWidth; + LEUINT16 dfPixHeight; + LEUINT8 dfPitchAndFamily; + LEUINT16 dfAvgWidth; + LEUINT16 dfMaxWidth; + LEUINT8 dfFirstChar; + LEUINT8 dfLastChar; + LEUINT8 dfDefaultChar; + LEUINT8 dfBreakChar; + LEUINT16 dfWidthBytes; + LEUINT32 dfDevice; + LEUINT32 dfFace; + LEUINT32 dfBitsPointer; + LEUINT32 dfBitsOffset; + LEUINT8 dfReserved; +// LEUINT32 dfFlags; +// LEUINT16 dfAspace; +// LEUINT16 dfBspace; +// LEUINT16 dfCspace; +// LEUINT32 dfColorPointer; +// LEUINT32 dfReserved1[4]; + OT::UnsizedArrayOf<LEUINT8> + dataZ; + public: + DEFINE_SIZE_ARRAY (118, dataZ); +}; + +struct NE_NAMEINFO +{ + friend struct NE_TYPEINFO; + + inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + get_font (base, shift).sanitize (c, length << shift))); + } + + inline const LE_FONTINFO16& get_font (const void *base, int shift) const + { + return OT::StructAtOffset<LE_FONTINFO16> (base, offset << shift); + } + + enum resource_type_flag_t { + NONE = 0x0000, + MOVEABLE = 0x0010, + PURE = 0x0020, + PRELOAD = 0x0040 + }; + + protected: + LEUINT16 offset; // Should be shifted with alignmentShiftCount before use + LEUINT16 length; // Should be shifted with alignmentShiftCount before use + LEUINT16 flags; // resource_type_flag_t + LEUINT16 id; + LEUINT16 handle; + LEUINT16 usage; + public: + DEFINE_SIZE_STATIC (12); +}; + +struct NE_TYPEINFO +{ + inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && resources.sanitize (c, count, base, shift)); + } + + inline unsigned int get_size (void) const + { return 8 + count * NE_NAMEINFO::static_size; } + + inline const NE_TYPEINFO& next () const + { + const NE_TYPEINFO& next = OT::StructAfter<NE_TYPEINFO> (*this); + if (type_id == 0) + return Null(NE_TYPEINFO); + return next; + } + + inline const LE_FONTINFO16& get_font (unsigned int idx, const void *base, int shift) const + { + if (idx < count) + return resources[idx].get_font (base, shift); + return Null(LE_FONTINFO16); + } + + inline unsigned int get_count () const + { + return count; + } + + inline unsigned int get_type_id () const + { + return type_id; + } + + enum type_id_t { + CURSOR = 0x8001, + BITMAP = 0x8002, + ICON = 0x8003, + MENU = 0x8004, + DIALOG = 0x8005, + STRING = 0x8006, + FONT_DIRECTORY = 0x8007, + FONT = 0x8008, + ACCELERATOR_TABLE = 0x8009, + RESOURCE_DATA = 0x800a, + GROUP_CURSOR = 0x800c, + GROUP_ICON = 0x800e, + VERSION = 0x8010 + }; + + protected: + LEUINT16 type_id; // see type_id_t + LEUINT16 count; + LEUINT32 resloader; + OT::UnsizedArrayOf<NE_NAMEINFO> + resources; + public: + DEFINE_SIZE_ARRAY (8, resources); +}; + +struct NE_RESOURCE_TABLE +{ + inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + + if (!c->check_struct (this)) + return_trace (false); + + const NE_TYPEINFO* n = &chain; + while (n != &Null(NE_TYPEINFO) && c->check_struct (n) && n->get_type_id () != 0) + { + if (n->get_type_id () == NE_TYPEINFO::FONT) + return_trace (n->sanitize (c, base, alignmentShiftCount)); + n = &n->next(); + } + return_trace (false); + } + + inline unsigned int get_shift_value () const + { + return alignmentShiftCount; + } + + inline const NE_TYPEINFO& get_fonts_entry () const + { + const NE_TYPEINFO* n = &chain; + while (n != &Null(NE_TYPEINFO) && n->get_type_id () != 0) + { + if (n->get_type_id () == NE_TYPEINFO::FONT) + return *n; + n = &n->next(); + } + return Null(NE_TYPEINFO); + } + + protected: + LEUINT16 alignmentShiftCount; + NE_TYPEINFO chain; + // It is followed by an array of OT::ArrayOf<LEUINT8, LEUINT8> chars; + public: + DEFINE_SIZE_MIN (2); +}; + +// https://github.com/wine-mirror/wine/blob/master/include/winnt.h#L2467 +struct LE_IMAGE_OS2_HEADER +{ + inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && (this+rsrctab).sanitize (c, base))); + } + + inline const NE_RESOURCE_TABLE& get_resource_table () const + { + if (magic != 0x454E) // Only NE containers are support for now, NE == 0x454E + return Null(NE_RESOURCE_TABLE); + return this+rsrctab; + } + + protected: + LEUINT16 magic; /* 00 NE signature 'NE' */ + LEUINT8 ver; /* 02 Linker version number */ + LEUINT8 rev; /* 03 Linker revision number */ + LEUINT16 enttab; /* 04 Offset to entry table relative to NE */ + LEUINT16 cbenttab; /* 06 Length of entry table in bytes */ + LEUINT32 crc; /* 08 Checksum */ + LEUINT16 flags; /* 0c Flags about segments in this file */ + LEUINT16 autodata; /* 0e Automatic data segment number */ + LEUINT16 heap; /* 10 Initial size of local heap */ + LEUINT16 stack; /* 12 Initial size of stack */ + LEUINT32 csip; /* 14 Initial CS:IP */ + LEUINT32 sssp; /* 18 Initial SS:SP */ + LEUINT16 cseg; /* 1c # of entries in segment table */ + LEUINT16 cmod; /* 1e # of entries in module reference tab. */ + LEUINT16 cbnrestab; /* 20 Length of nonresident-name table */ + LEUINT16 segtab; /* 22 Offset to segment table */ + OT::OffsetTo<NE_RESOURCE_TABLE, LEUINT16> + rsrctab; /* 24 Offset to resource table */ + LEUINT16 restab; /* 26 Offset to resident-name table */ + LEUINT16 modtab; /* 28 Offset to module reference table */ + LEUINT16 imptab; /* 2a Offset to imported name table */ + LEUINT32 nrestab; /* 2c Offset to nonresident-name table */ + LEUINT16 cmovent; /* 30 # of movable entry points */ + LEUINT16 align; /* 32 Logical sector alignment shift count */ + LEUINT16 cres; /* 34 # of resource segments */ + LEUINT8 exetyp; /* 36 Flags indicating target OS */ + LEUINT8 flagsothers; /* 37 Additional information flags */ + LEUINT16 pretthunks; /* 38 Offset to return thunks */ + LEUINT16 psegrefbytes; /* 3a Offset to segment ref. bytes */ + LEUINT16 swaparea; /* 3c Reserved by Microsoft */ + LEUINT16 expver; /* 3e Expected Windows version number */ + public: + DEFINE_SIZE_STATIC (64); +}; + +struct LE_IMAGE_DOS_HEADER { + inline bool sanitize (OT::hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + get_os2_header ().sanitize (c, this))); + } + + inline const LE_IMAGE_OS2_HEADER& get_os2_header () const + { + return this+e_lfanew; + } + + protected: + LEUINT16 e_magic; // Magic number + LEUINT16 e_cblp; // Bytes on last page of file + LEUINT16 e_cp; // Pages in file + LEUINT16 e_crlc; // Relocations + LEUINT16 e_cparhdr; // Size of header in paragraphs + LEUINT16 e_minalloc; // Minimum extra paragraphs needed + LEUINT16 e_maxalloc; // Maximum extra paragraphs needed + LEUINT16 e_ss; // Initial (relative) SS value + LEUINT16 e_sp; // Initial SP value + LEUINT16 e_csum; // Checksum + LEUINT16 e_ip; // Initial IP value + LEUINT16 e_cs; // Initial (relative) CS value + LEUINT16 e_lfarlc; // File address of relocation table + LEUINT16 e_ovno; // Overlay number + LEUINT16 e_res_0; // Reserved words + LEUINT16 e_res_1; // Reserved words + LEUINT16 e_res_2; // Reserved words + LEUINT16 e_res_3; // Reserved words + LEUINT16 e_oemid; // OEM identifier (for e_oeminfo) + LEUINT16 e_oeminfo; // OEM information; e_oemid specific + LEUINT16 e_res2_0; // Reserved words + LEUINT16 e_res2_1; // Reserved words + LEUINT16 e_res2_2; // Reserved words + LEUINT16 e_res2_3; // Reserved words + LEUINT16 e_res2_4; // Reserved words + LEUINT16 e_res2_5; // Reserved words + LEUINT16 e_res2_6; // Reserved words + LEUINT16 e_res2_7; // Reserved words + LEUINT16 e_res2_8; // Reserved words + LEUINT16 e_res2_9; // Reserved words + OT::OffsetTo<LE_IMAGE_OS2_HEADER, LEUINT32> + e_lfanew; // File address of new exe header + public: + DEFINE_SIZE_STATIC (64); +}; + +int main (int argc, char** argv) { + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + + OT::Sanitizer<LE_IMAGE_DOS_HEADER> sanitizer; + hb_blob_t *font_blob = sanitizer.sanitize (blob); + const LE_IMAGE_DOS_HEADER* dos_header = font_blob->as<LE_IMAGE_DOS_HEADER> (); + + const NE_RESOURCE_TABLE &rtable = dos_header->get_os2_header ().get_resource_table (); + int shift = rtable.get_shift_value (); + const NE_TYPEINFO& entry = rtable.get_fonts_entry (); + for (unsigned int i = 0; i < entry.get_count (); ++i) + { + const LE_FONTINFO16& font = entry.get_font (i, dos_header, shift); + printf ("version: %x, weight: %d, charset: %s\n", font.get_version (), + font.get_weight (), font.get_charset ()); + // font.dump (); + } + return 0; +} diff --git a/src/gen-arabic-table.py b/src/gen-arabic-table.py index 59bd760..ccecb40 100755 --- a/src/gen-arabic-table.py +++ b/src/gen-arabic-table.py @@ -1,13 +1,14 @@ -#!/usr/bin/python +#!/usr/bin/env python -import sys -import os.path +from __future__ import print_function, division, absolute_import + +import io, os.path, sys if len (sys.argv) != 4: - print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt" + print ("usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt", file=sys.stderr) sys.exit (1) -files = [file (x) for x in sys.argv[1:]] +files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]] headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]] headers.append (["UnicodeData.txt does not have a header."]) @@ -65,9 +66,9 @@ def print_joining_table(f): 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) + print ("#define %s %s" % (short, value)) uu = sorted(values.keys()) num = len(values) @@ -82,15 +83,15 @@ def print_joining_table(f): ranges.append([u,u]) last = u - print - print "static const uint8_t joining_table[] =" - print "{" + print () + print ("static const uint8_t joining_table[] =") + print ("{") last_block = None offset = 0 for start,end in ranges: - print - print "#define joining_offset_0x%04xu %d" % (start, offset) + print () + print ("#define joining_offset_0x%04xu %d" % (start, offset)) for u in range(start, end+1): @@ -99,53 +100,53 @@ def print_joining_table(f): if block != last_block or u == start: if u != start: - print + print () if block in all_blocks: - print "\n /* %s */" % block + print ("\n /* %s */" % block) else: - print "\n /* FILLER */" + print ("\n /* FILLER */") last_block = block if u % 32 != 0: - print - print " /* %04X */" % (u//32*32), " " * (u % 32), + print () + print (" /* %04X */" % (u//32*32), " " * (u % 32), end="") if u % 32 == 0: - print - print " /* %04X */ " % u, - sys.stdout.write("%s," % short_value[value]) - print + print () + print (" /* %04X */ " % u, end="") + print ("%s," % short_value[value], end="") + print () offset += end - start + 1 - print + print () occupancy = num * 100. / offset - print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) - print + print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)) + print () page_bits = 12; - print - print "static unsigned int" - print "joining_type (hb_codepoint_t u)" - print "{" - print " switch (u >> %d)" % page_bits - print " {" + 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 + 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<hb_codepoint_t> (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 + print (" if (hb_in_range<hb_codepoint_t> (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 + print ("#undef %s" % (short)) + print () def print_shaping_table(f): @@ -186,9 +187,9 @@ def print_shaping_table(f): shapes[items[0]] = {} shapes[items[0]][shape] = c - print - print "static const uint16_t shaping_table[][4] =" - print "{" + print () + print ("static const uint16_t shaping_table[][4] =") + print ("{") keys = shapes.keys () min_u, max_u = min (keys), max (keys) @@ -196,13 +197,13 @@ def print_shaping_table(f): s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0 for shape in ['initial', 'medial', 'final', 'isolated']] value = ', '.join ("0x%04Xu" % c for c in s) - print " {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "") + print (" {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")) - print "};" - print - print "#define SHAPING_TABLE_FIRST 0x%04Xu" % min_u - print "#define SHAPING_TABLE_LAST 0x%04Xu" % max_u - print + print ("};") + print () + print ("#define SHAPING_TABLE_FIRST 0x%04Xu" % min_u) + print ("#define SHAPING_TABLE_LAST 0x%04Xu" % max_u) + print () ligas = {} for pair in ligatures.keys (): @@ -218,52 +219,49 @@ def print_shaping_table(f): ligas[liga[0]] = [] ligas[liga[0]].append ((liga[1], c)) max_i = max (len (ligas[l]) for l in ligas) - print - print "static const struct ligature_set_t {" - print " uint16_t first;" - print " struct ligature_pairs_t {" - print " uint16_t second;" - print " uint16_t ligature;" - print " } ligatures[%d];" % max_i - print "} ligature_table[] =" - print "{" - keys = ligas.keys () - keys.sort () - for first in keys: - - print " { 0x%04Xu, {" % (first) + print () + print ("static const struct ligature_set_t {") + print (" uint16_t first;") + print (" struct ligature_pairs_t {") + print (" uint16_t second;") + print (" uint16_t ligature;") + print (" } ligatures[%d];" % max_i) + print ("} ligature_table[] =") + print ("{") + for first in sorted (ligas.keys ()): + + print (" { 0x%04Xu, {" % (first)) for liga in ligas[first]: - print " { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]) - print " }}," + print (" { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])) + print (" }},") - print "};" - print + print ("};") + print () -print "/* == Start of generated table == */" -print "/*" -print " * The following table is generated by running:" -print " *" -print " * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt" -print " *" -print " * on files with these headers:" -print " *" +print ("/* == Start of generated table == */") +print ("/*") +print (" * The following table is generated by running:") +print (" *") +print (" * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt") +print (" *") +print (" * on files with these headers:") +print (" *") for h in headers: for l in h: - print " * %s" % (l.strip()) -print " */" -print -print "#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH" -print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH" -print + print (" * %s" % (l.strip())) +print (" */") +print () +print ("#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH") +print ("#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH") +print () read_blocks (files[2]) print_joining_table (files[0]) print_shaping_table (files[1]) -print -print "#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */" -print -print "/* == End of generated table == */" - +print () +print ("#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */") +print () +print ("/* == End of generated table == */") diff --git a/src/gen-def.py b/src/gen-def.py index 1673537..9a997d6 100755 --- a/src/gen-def.py +++ b/src/gen-def.py @@ -1,13 +1,13 @@ #!/usr/bin/env python -from __future__ import print_function +from __future__ import print_function, division, absolute_import import io, os, re, sys headers_content = [] for h in os.environ["headers"].split (' '): if h.endswith (".h"): - with io.open(h, encoding='utf8') as f: headers_content.append (f.read ()) + with io.open (h, encoding='utf-8') as f: headers_content.append (f.read ()) result = """EXPORTS %s diff --git a/src/gen-indic-table.py b/src/gen-indic-table.py index 735b901..6252664 100755 --- a/src/gen-indic-table.py +++ b/src/gen-indic-table.py @@ -1,9 +1,11 @@ -#!/usr/bin/python +#!/usr/bin/env python -import sys +from __future__ import print_function, division, absolute_import + +import io, sys if len (sys.argv) != 4: - print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" + print ("usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt", file=sys.stderr) sys.exit (1) ALLOWED_SINGLES = [0x00A0, 0x25CC] @@ -30,7 +32,7 @@ ALLOWED_BLOCKS = [ 'Myanmar Extended-A', ] -files = [file (x) for x in sys.argv[1:]] +files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]] headers = [[f.readline () for i in range (2)] for f in files] @@ -87,21 +89,21 @@ for u in ALLOWED_SINGLES: singles[u] = data[u] del data[u] -print "/* == Start of generated table == */" -print "/*" -print " * The following table is generated by running:" -print " *" -print " * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" -print " *" -print " * on files with these headers:" -print " *" +print ("/* == Start of generated table == */") +print ("/*") +print (" * The following table is generated by running:") +print (" *") +print (" * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt") +print (" *") +print (" * on files with these headers:") +print (" *") for h in headers: for l in h: - print " * %s" % (l.strip()) -print " */" -print -print '#include "hb-ot-shape-complex-indic-private.hh"' -print + print (" * %s" % (l.strip())) +print (" */") +print () +print ('#include "hb-ot-shape-complex-indic-private.hh"') +print () # Shorten values short = [{ @@ -130,9 +132,8 @@ for i in range (2): what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"] what_short = ["ISC", "IMC"] for i in range (2): - print - vv = values[i].keys () - vv.sort () + print () + vv = sorted (values[i].keys ()) for v in vv: v_no_and = v.replace ('_And_', '_') if v in short[i]: @@ -143,14 +144,14 @@ for i in range (2): raise Exception ("Duplicate short value alias", v, all_shorts[i][s]) all_shorts[i][s] = v short[i][v] = s - print "#define %s_%s %s_%s %s/* %3d chars; %s */" % \ - (what_short[i], s, what[i], v.upper (), \ - ' '* ((48-1 - len (what[i]) - 1 - len (v)) / 8), \ - values[i][v], v) -print -print "#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)" -print -print + print ("#define %s_%s %s_%s %s/* %3d chars; %s */" % + (what_short[i], s, what[i], v.upper (), + ' '* ((48-1 - len (what[i]) - 1 - len (v)) // 8), + values[i][v], v)) +print () +print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)") +print () +print () total = 0 used = 0 @@ -158,35 +159,34 @@ last_block = None def print_block (block, start, end, data): global total, used, last_block if block and block != last_block: - print - print - print " /* %s */" % block + print () + print () + print (" /* %s */" % block) num = 0 assert start % 8 == 0 assert (end+1) % 8 == 0 for u in range (start, end+1): if u % 8 == 0: - print - print " /* %04X */" % u, + print () + print (" /* %04X */" % u, end="") if u in data: num += 1 d = data.get (u, defaults) - sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]]))) + print ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])), end="") total += end - start + 1 used += num if block: last_block = block -uu = data.keys () -uu.sort () +uu = sorted (data.keys ()) last = -100000 num = 0 offset = 0 starts = [] ends = [] -print "static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {" +print ("static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {") for u in uu: if u <= last: continue @@ -206,54 +206,53 @@ for u in uu: if last >= 0: ends.append (last + 1) offset += ends[-1] - starts[-1] - print - print - print "#define indic_offset_0x%04xu %d" % (start, offset) + print () + print () + print ("#define indic_offset_0x%04xu %d" % (start, offset)) starts.append (start) print_block (block, start, end, data) last = end ends.append (last + 1) offset += ends[-1] - starts[-1] -print -print +print () +print () occupancy = used * 100. / total page_bits = 12 -print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) -print -print "INDIC_TABLE_ELEMENT_TYPE" -print "hb_indic_get_categories (hb_codepoint_t u)" -print "{" -print " switch (u >> %d)" % page_bits -print " {" -pages = set([u>>page_bits for u in starts+ends+singles.keys()]) +print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)) +print () +print ("INDIC_TABLE_ELEMENT_TYPE") +print ("hb_indic_get_categories (hb_codepoint_t u)") +print ("{") +print (" switch (u >> %d)" % page_bits) +print (" {") +pages = set ([u>>page_bits for u in starts+ends+list (singles.keys ())]) for p in sorted(pages): - print " case 0x%0Xu:" % p + print (" case 0x%0Xu:" % p) 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 (" if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])) 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<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) - print " break;" - print "" -print " default:" -print " break;" -print " }" -print " return _(x,x);" -print "}" -print -print "#undef _" + print (" if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)) + print (" break;") + print ("") +print (" default:") +print (" break;") +print (" }") +print (" return _(x,x);") +print ("}") +print () +print ("#undef _") for i in range (2): print - vv = values[i].keys () - vv.sort () + vv = sorted (values[i].keys ()) for v in vv: - print "#undef %s_%s" % \ - (what_short[i], short[i][v]) -print -print "/* == End of generated table == */" + print ("#undef %s_%s" % + (what_short[i], short[i][v])) +print () +print ("/* == End of generated table == */") # Maintain at least 30% occupancy in the table */ if occupancy < 30: diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 0681725..6aa5f88 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -1,14 +1,16 @@ -#!/usr/bin/python +#!/usr/bin/env python -import sys +from __future__ import print_function, division, absolute_import + +import io, sys if len (sys.argv) != 5: - print >>sys.stderr, "usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt" + print ("usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt", file=sys.stderr) sys.exit (1) BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"] -files = [file (x) for x in sys.argv[1:]] +files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]] headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 2] headers.append (["UnicodeData.txt does not have a header."]) @@ -93,6 +95,7 @@ property_names = [ 'Consonant_Medial', 'Consonant_Final', 'Consonant_Head_Letter', + 'Consonant_Initial_Postfixed', 'Modifying_Letter', 'Tone_Letter', 'Tone_Mark', @@ -124,6 +127,11 @@ property_names = [ 'Overstruck', ] +try: + basestring +except NameError: + basestring = str + class PropertyValue(object): def __init__(self, name_): self.name = name_ @@ -133,6 +141,8 @@ class PropertyValue(object): return self.name == (other if isinstance(other, basestring) else other.name) def __ne__(self, other): return not (self == other) + def __hash__(self): + return hash(str(self)) property_values = {} @@ -155,7 +165,7 @@ def is_BASE(U, UISC, UGC): def is_BASE_IND(U, UISC, UGC): #SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) return (UISC in [Consonant_Dead, Modifying_Letter] or - (UGC == Po and not U in [0x104E, 0x2022, 0x11A3F, 0x11A45]) or + (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x11A3F, 0x11A45]) or False # SPEC-DRAFT-OUTDATED! U == 0x002D ) def is_BASE_NUM(U, UISC, UGC): @@ -167,7 +177,9 @@ def is_BASE_OTHER(U, UISC, UGC): def is_CGJ(U, UISC, UGC): return U == 0x034F def is_CONS_FINAL(U, UISC, UGC): + # Consonant_Initial_Postfixed is new in Unicode 11; not in the spec. return ((UISC == Consonant_Final and UGC != Lo) or + UISC == Consonant_Initial_Postfixed or UISC == Consonant_Succeeding_Repha) def is_CONS_FINAL_MOD(U, UISC, UGC): #SPEC-DRAFT return UISC in [Consonant_Final_Modifier, Syllable_Modifier] @@ -325,17 +337,18 @@ def map_to_use(data): # TODO: These should die, but have UIPC in Unicode 8.0 if U in [0x953, 0x954]: UIPC = Not_Applicable - # TODO: In USE's override list but not in Unicode 8.0 + # TODO: In USE's override list but not in Unicode 11.0 if U == 0x103C: UIPC = Left - # TODO: These are not in USE's override list that we have, nor are they in Unicode 8.0 + # TODO: These are not in USE's override list that we have, nor are they in Unicode 11.0 if 0xA926 <= U <= 0xA92A: UIPC = Top if U == 0x111CA: UIPC = Bottom if U == 0x11300: UIPC = Top - if U == 0x1133C: UIPC = Bottom if U == 0x1171E: UIPC = Left # Correct?! if 0x1CF2 <= U <= 0x1CF3: UIPC = Right if 0x1CF8 <= U <= 0x1CF9: UIPC = Top + # https://github.com/roozbehp/unicode-data/issues/8 + if U == 0x0A51: UIPC = Bottom assert (UIPC in [Not_Applicable, Visual_Order_Left] or USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC) @@ -352,21 +365,21 @@ def map_to_use(data): defaults = ('O', 'No_Block') data = map_to_use(data) -print "/* == Start of generated table == */" -print "/*" -print " * The following table is generated by running:" -print " *" -print " * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt" -print " *" -print " * on files with these headers:" -print " *" +print ("/* == Start of generated table == */") +print ("/*") +print (" * The following table is generated by running:") +print (" *") +print (" * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt") +print (" *") +print (" * on files with these headers:") +print (" *") for h in headers: for l in h: - print " * %s" % (l.strip()) -print " */" -print -print '#include "hb-ot-shape-complex-use-private.hh"' -print + print (" * %s" % (l.strip())) +print (" */") +print () +print ('#include "hb-ot-shape-complex-use-private.hh"') +print () total = 0 used = 0 @@ -374,30 +387,29 @@ last_block = None def print_block (block, start, end, data): global total, used, last_block if block and block != last_block: - print - print - print " /* %s */" % block + print () + print () + print (" /* %s */" % block) if start % 16: - print ' ' * (20 + (start % 16 * 6)), + print (' ' * (20 + (start % 16 * 6)), end='') num = 0 assert start % 8 == 0 assert (end+1) % 8 == 0 for u in range (start, end+1): if u % 16 == 0: - print - print " /* %04X */" % u, + print () + print (" /* %04X */" % u, end='') if u in data: num += 1 d = data.get (u, defaults) - sys.stdout.write ("%6s," % d[0]) + print ("%6s," % d[0], end='') total += end - start + 1 used += num if block: last_block = block -uu = data.keys () -uu.sort () +uu = sorted (data.keys ()) last = -100000 num = 0 @@ -406,14 +418,14 @@ starts = [] ends = [] for k,v in sorted(use_mapping.items()): if k in use_positions and use_positions[k]: continue - print "#define %s USE_%s /* %s */" % (k, k, v.__name__[3:]) + print ("#define %s USE_%s /* %s */" % (k, k, v.__name__[3:])) for k,v in sorted(use_positions.items()): if not v: continue for suf in v.keys(): tag = k + suf - print "#define %s USE_%s" % (tag, tag) -print "" -print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {" + print ("#define %s USE_%s" % (tag, tag)) +print ("") +print ("static const USE_TABLE_ELEMENT_TYPE use_table[] = {") for u in uu: if u <= last: continue @@ -433,51 +445,51 @@ for u in uu: if last >= 0: ends.append (last + 1) offset += ends[-1] - starts[-1] - print - print - print "#define use_offset_0x%04xu %d" % (start, offset) + print () + print () + print ("#define use_offset_0x%04xu %d" % (start, offset)) starts.append (start) print_block (block, start, end, data) last = end ends.append (last + 1) offset += ends[-1] - starts[-1] -print -print +print () +print () occupancy = used * 100. / total page_bits = 12 -print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) -print -print "USE_TABLE_ELEMENT_TYPE" -print "hb_use_get_category (hb_codepoint_t u)" -print "{" -print " switch (u >> %d)" % page_bits -print " {" +print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)) +print () +print ("USE_TABLE_ELEMENT_TYPE") +print ("hb_use_get_category (hb_codepoint_t u)") +print ("{") +print (" switch (u >> %d)" % page_bits) +print (" {") pages = set([u>>page_bits for u in starts+ends]) for p in sorted(pages): - print " case 0x%0Xu:" % p + print (" case 0x%0Xu:" % p) for (start,end) in zip (starts, ends): if p not in [start>>page_bits, end>>page_bits]: continue offset = "use_offset_0x%04xu" % start - print " if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) - print " break;" - print "" -print " default:" -print " break;" -print " }" -print " return USE_O;" -print "}" -print + print (" if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)) + print (" break;") + print ("") +print (" default:") +print (" break;") +print (" }") +print (" return USE_O;") +print ("}") +print () for k in sorted(use_mapping.keys()): if k in use_positions and use_positions[k]: continue - print "#undef %s" % k + print ("#undef %s" % k) for k,v in sorted(use_positions.items()): if not v: continue for suf in v.keys(): tag = k + suf - print "#undef %s" % tag -print -print "/* == End of generated table == */" + print ("#undef %s" % tag) +print () +print ("/* == End of generated table == */") # Maintain at least 50% occupancy in the table */ if occupancy < 50: diff --git a/src/hb-aat-fmtx-table.hh b/src/hb-aat-fmtx-table.hh new file mode 100644 index 0000000..aa82c88 --- /dev/null +++ b/src/hb-aat-fmtx-table.hh @@ -0,0 +1,67 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_AAT_FMTX_TABLE_HH +#define HB_AAT_FMTX_TABLE_HH + +#include "hb-aat-layout-common-private.hh" + +/* + * fmtx -- Font Metrics + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fmtx.html + */ +#define HB_AAT_TAG_fmtx HB_TAG('f','m','t','x') + + +namespace AAT { + + +struct fmtx +{ + static const hb_tag_t tableTag = HB_AAT_TAG_fmtx; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + FixedVersion<>version; /* Version (set to 0x00020000). */ + HBUINT32 glyphIndex; /* The glyph whose points represent the metrics. */ + HBUINT8 horizontalBefore; /* Point number for the horizontal ascent. */ + HBUINT8 horizontalAfter; /* Point number for the horizontal descent. */ + HBUINT8 horizontalCaretHead; /* Point number for the horizontal caret head. */ + HBUINT8 horizontalCaretBase; /* Point number for the horizontal caret base. */ + HBUINT8 verticalBefore; /* Point number for the vertical ascent. */ + HBUINT8 verticalAfter; /* Point number for the vertical descent. */ + HBUINT8 verticalCaretHead; /* Point number for the vertical caret head. */ + HBUINT8 verticalCaretBase; /* Point number for the vertical caret base. */ + public: + DEFINE_SIZE_STATIC (16); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_FMTX_TABLE_HH */ diff --git a/src/hb-aat-gcid-table.hh b/src/hb-aat-gcid-table.hh new file mode 100644 index 0000000..b48a279 --- /dev/null +++ b/src/hb-aat-gcid-table.hh @@ -0,0 +1,73 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_AAT_GCID_TABLE_HH +#define HB_AAT_GCID_TABLE_HH + +#include "hb-aat-layout-common-private.hh" + +/* + * gcid -- Glyphs CIDs + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gcid.html + */ +#define HB_AAT_TAG_gcid HB_TAG('g','c','i','d') + + +namespace AAT { + + +struct gcid +{ + static const hb_tag_t tableTag = HB_AAT_TAG_gcid; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && CIDs.sanitize (c))); + } + + protected: + HBUINT16 version; /* Version number (set to 0) */ + HBUINT16 format; /* Data format (set to 0) */ + HBUINT32 size; /* Size of the table, including header */ + HBUINT16 registry; /* The registry ID */ + HBUINT8 registryName[64]; + /* The registry name in ASCII */ + HBUINT16 order; /* The order ID */ + HBUINT8 orderName[64]; /* The order name in ASCII */ + HBUINT16 supplementVersion; + /* The supplement version */ + ArrayOf<HBUINT16> + CIDs; /* The CIDs for the glyphs in the font, + * starting with glyph 0. If a glyph does not correspond + * to a CID in the identified collection, 0xFFFF is used. + * This should not exceed the number of glyphs in the font. */ + public: + DEFINE_SIZE_ARRAY (144, CIDs); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_GCID_TABLE_HH */ diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh index d0453bd..3b7912b 100644 --- a/src/hb-aat-layout-ankr-table.hh +++ b/src/hb-aat-layout-ankr-table.hh @@ -27,16 +27,16 @@ #include "hb-aat-layout-common-private.hh" +/* + * ankr -- Anchor Point + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ankr.html + */ #define HB_AAT_TAG_ankr HB_TAG('a','n','k','r') namespace AAT { -/* - * ankr -- Anchor point - */ - struct Anchor { inline bool sanitize (hb_sanitize_context_t *c) const @@ -58,17 +58,19 @@ struct ankr inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && version == 0 && - lookupTable.sanitize (c, this) && - anchors.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + version == 0 && + lookupTable.sanitize (c, this) && + anchors.sanitize (c, this))); } protected: - HBUINT16 version; /* Version number (set to zero) */ - HBUINT16 flags; /* Flags (currently unused; set to zero) */ - LOffsetTo<Lookup<HBUINT16> > lookupTable; /* Offset to the table's lookup table */ - LOffsetTo<ArrayOf<Anchor, HBUINT32> > - anchors; /* Offset to the glyph data table */ + HBUINT16 version; /* Version number (set to zero) */ + HBUINT16 flags; /* Flags (currently unused; set to zero) */ + LOffsetTo<Lookup<HBUINT16> > + lookupTable; /* Offset to the table's lookup table */ + LOffsetTo<LArrayOf<Anchor> > + anchors; /* Offset to the glyph data table */ public: DEFINE_SIZE_STATIC (12); diff --git a/src/hb-aat-layout-bsln-table.hh b/src/hb-aat-layout-bsln-table.hh new file mode 100644 index 0000000..df2bf5b --- /dev/null +++ b/src/hb-aat-layout-bsln-table.hh @@ -0,0 +1,157 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_AAT_LAYOUT_BSLN_TABLE_HH +#define HB_AAT_LAYOUT_BSLN_TABLE_HH + +#include "hb-aat-layout-common-private.hh" + +/* + * bsln -- Baseline + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bsln.html + */ +#define HB_AAT_TAG_bsln HB_TAG('b','s','l','n') + + +namespace AAT { + + +struct BaselineTableFormat0Part +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + // Roman, Ideographic centered, Ideographic low, Hanging and Math + // are the default defined ones, but any other maybe accessed also. + HBINT16 deltas[32]; /* These are the FUnit distance deltas from + * the font's natural baseline to the other + * baselines used in the font. */ + public: + DEFINE_SIZE_STATIC (64); +}; + +struct BaselineTableFormat1Part +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + lookupTable.sanitize (c))); + } + + protected: + HBINT16 deltas[32]; /* ditto */ + Lookup<HBUINT16> + lookupTable; /* Lookup table that maps glyphs to their + * baseline values. */ + public: + DEFINE_SIZE_MIN (66); +}; + +struct BaselineTableFormat2Part +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + GlyphID stdGlyph; /* The specific glyph index number in this + * font that is used to set the baseline values. + * This is the standard glyph. + * This glyph must contain a set of control points + * (whose numbers are contained in the ctlPoints field) + * that are used to determine baseline distances. */ + HBUINT16 ctlPoints[32]; /* Set of control point numbers, + * associated with the standard glyph. + * A value of 0xFFFF means there is no corresponding + * control point in the standard glyph. */ + public: + DEFINE_SIZE_STATIC (66); +}; + +struct BaselineTableFormat3Part +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && lookupTable.sanitize (c)); + } + + protected: + GlyphID stdGlyph; /* ditto */ + HBUINT16 ctlPoints[32]; /* ditto */ + Lookup<HBUINT16> + lookupTable; /* Lookup table that maps glyphs to their + * baseline values. */ + public: + DEFINE_SIZE_MIN (68); +}; + +struct bsln +{ + static const hb_tag_t tableTag = HB_AAT_TAG_bsln; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!(c->check_struct (this) && defaultBaseline < 32))) + return_trace (false); + + switch (format) { + case 0: return_trace (parts.format0.sanitize (c)); + case 1: return_trace (parts.format1.sanitize (c)); + case 2: return_trace (parts.format2.sanitize (c)); + case 3: return_trace (parts.format3.sanitize (c)); + default:return_trace (true); + } + } + + protected: + FixedVersion<>version; /* Version number of the Baseline table. */ + HBUINT16 format; /* Format of the baseline table. Only one baseline + * format may be selected for the font. */ + HBUINT16 defaultBaseline;/* Default baseline value for all glyphs. + * This value can be from 0 through 31. */ + union { + // Distance-Based Formats + BaselineTableFormat0Part format0; + BaselineTableFormat1Part format1; + // Control Point-based Formats + BaselineTableFormat2Part format2; + BaselineTableFormat3Part format3; + } parts; + public: + DEFINE_SIZE_MIN (8); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_LAYOUT_BSLN_TABLE_HH */ diff --git a/src/hb-aat-layout-common-private.hh b/src/hb-aat-layout-common-private.hh index 7c0dfa8..2825b18 100644 --- a/src/hb-aat-layout-common-private.hh +++ b/src/hb-aat-layout-common-private.hh @@ -67,11 +67,11 @@ struct BinSearchArrayOf inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= header.nUnits)) return Null(Type); - return StructAtOffset<Type> (bytes, i * header.unitSize); + return StructAtOffset<Type> (bytesZ, i * header.unitSize); } inline Type& operator [] (unsigned int i) { - return StructAtOffset<Type> (bytes, i * header.unitSize); + return StructAtOffset<Type> (bytesZ, i * header.unitSize); } inline unsigned int get_size (void) const { return header.static_size + header.nUnits * header.unitSize; } @@ -88,7 +88,7 @@ struct BinSearchArrayOf * pointed to do have a simple sanitize(), ie. they do not * reference other structs via offsets. */ - (void) (false && StructAtOffset<Type> (bytes, 0).sanitize (c)); + (void) (false && StructAtOffset<Type> (bytesZ, 0).sanitize (c)); return_trace (true); } @@ -111,7 +111,7 @@ struct BinSearchArrayOf while (min <= max) { int mid = (min + max) / 2; - const Type *p = (const Type *) (((const char *) bytes) + (mid * size)); + const Type *p = (const Type *) (((const char *) bytesZ) + (mid * size)); int c = p->cmp (key); if (c < 0) max = mid - 1; @@ -129,98 +129,14 @@ struct BinSearchArrayOf TRACE_SANITIZE (this); return_trace (header.sanitize (c) && Type::static_size >= header.unitSize && - c->check_array (bytes, header.unitSize, header.nUnits)); + c->check_array (bytesZ, header.unitSize, header.nUnits)); } protected: BinSearchHeader header; - HBUINT8 bytes[VAR]; + HBUINT8 bytesZ[VAR]; public: - DEFINE_SIZE_ARRAY (10, bytes); -}; - - -/* TODO Move this to hb-open-type-private.hh and use it in ArrayOf, HeadlessArrayOf, - * and other places around the code base?? */ -template <typename Type> -struct UnsizedArrayOf -{ - inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } - inline Type& operator [] (unsigned int i) { return arrayZ[i]; } - - inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - - /* Note: for structs that do not reference other structs, - * we do not need to call their sanitize() as we already did - * a bound check on the aggregate array size. We just include - * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not - * reference other structs via offsets. - */ - (void) (false && arrayZ[0].sanitize (c)); - - return_trace (true); - } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - template <typename T> - inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) - return_trace (false); - return_trace (true); - } - - private: - inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const - { - TRACE_SANITIZE (this); - return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count)); - } - - public: - Type arrayZ[VAR]; - public: - DEFINE_SIZE_ARRAY (0, arrayZ); -}; - -/* Unsized array of offset's */ -template <typename Type, typename OffsetType> -struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {}; - -/* Unsized array of offsets relative to the beginning of the array itself. */ -template <typename Type, typename OffsetType> -struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType> -{ - inline const Type& operator [] (unsigned int i) const - { - return this+this->arrayZ[i]; - } - - inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const - { - TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this))); - } - template <typename T> - inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const - { - TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data))); - } + DEFINE_SIZE_ARRAY (10, bytesZ); }; @@ -595,11 +511,11 @@ struct StateTable protected: HBUINT32 nClasses; /* Number of classes, which is the number of indices * in a single line in the state array. */ - OffsetTo<Lookup<HBUINT16>, HBUINT32> + LOffsetTo<Lookup<HBUINT16> > classTable; /* Offset to the class table. */ - OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32> + LOffsetTo<UnsizedArrayOf<HBUINT16> > stateArrayTable;/* Offset to the state array. */ - OffsetTo<UnsizedArrayOf<Entry<Extra> >, HBUINT32> + LOffsetTo<UnsizedArrayOf<Entry<Extra> > > entryTable; /* Offset to the entry array. */ public: diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh new file mode 100644 index 0000000..3e070d7 --- /dev/null +++ b/src/hb-aat-layout-feat-table.hh @@ -0,0 +1,120 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_AAT_LAYOUT_FEAT_TABLE_HH +#define HB_AAT_LAYOUT_FEAT_TABLE_HH + +#include "hb-aat-layout-common-private.hh" + +/* + * feat -- Feature Name + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html + */ +#define HB_AAT_TAG_feat HB_TAG('f','e','a','t') + + +namespace AAT { + + +struct SettingName +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + HBUINT16 setting; /* The setting. */ + NameID nameIndex; /* The name table index for the setting's name. */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct FeatureName +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (base+settingTable).sanitize (c, nSettings))); + } + + enum { + Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ + NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in + * the setting name array for this feature should + * be taken as the default for the feature + * (if one is required). If set, then bits 0-15 of this + * featureFlags field contain the index of the setting + * which is to be taken as the default. */ + IndexMask = 0x00FF /* If bits 30 and 31 are set, then these sixteen bits + * indicate the index of the setting in the setting name + * array for this feature which should be taken + * as the default. */ + }; + + protected: + HBUINT16 feature; /* Feature type. */ + HBUINT16 nSettings; /* The number of records in the setting name array. */ + LOffsetTo<UnsizedArrayOf<SettingName> > + settingTable; /* Offset in bytes from the beginning of this table to + * this feature's setting name array. The actual type of + * record this offset refers to will depend on the + * exclusivity value, as described below. */ + HBUINT16 featureFlags; /* Single-bit flags associated with the feature type. */ + HBINT16 nameIndex; /* The name table index for the feature's name. + * This index has values greater than 255 and + * less than 32768. */ + public: + DEFINE_SIZE_STATIC (12); +}; + +struct feat +{ + static const hb_tag_t tableTag = HB_AAT_TAG_feat; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + names.sanitize (c, featureNameCount, this))); + } + + protected: + FixedVersion<>version; /* Version number of the feature name table + * (0x00010000 for the current version). */ + HBUINT16 featureNameCount; + /* The number of entries in the feature name array. */ + HBUINT16 reserved1; /* Reserved (set to zero). */ + HBUINT32 reserved2; /* Reserved (set to zero). */ + UnsizedArrayOf<FeatureName> + names; /* The feature name array. */ + public: + DEFINE_SIZE_STATIC (24); +}; + +} /* namespace AAT */ + +#endif /* HB_AAT_LAYOUT_FEAT_TABLE_HH */ diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index ce7ca10..cc03d62 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -30,8 +30,13 @@ #include "hb-open-type-private.hh" #include "hb-aat-layout-common-private.hh" +#include "hb-aat-layout-ankr-table.hh" -#define HB_AAT_TAG_KERX HB_TAG('k','e','r','x') +/* + * kerx -- Extended Kerning + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html + */ +#define HB_AAT_TAG_kerx HB_TAG('k','e','r','x') namespace AAT { @@ -44,7 +49,7 @@ struct KerxFormat0Records inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (likely (c->check_struct (this))); } protected: @@ -70,22 +75,23 @@ struct KerxSubTableFormat0 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - c->check_array (records, records[0].static_size, nPairs)); + return_trace (likely (c->check_struct (this) && + recordsZ.sanitize (c, nPairs))); } protected: // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is // needed here to use HBUINT32 instead - HBUINT32 nPairs; /* The number of kerning pairs in this subtable */ - HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs, - * multiplied by the size in bytes of an entry in the subtable. */ - HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less - * than or equal to the value of nPairs. */ - HBUINT32 rangeShift; /* The value of nPairs minus the largest power of two less than or equal to nPairs. */ - KerxFormat0Records records[VAR]; /* VAR=nPairs */ + HBUINT32 nPairs; /* The number of kerning pairs in this subtable */ + HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs, + * multiplied by the size in bytes of an entry in the subtable. */ + HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less + * than or equal to the value of nPairs. */ + HBUINT32 rangeShift; /* The value of nPairs minus the largest power of two less than or equal to nPairs. */ + UnsizedArrayOf<KerxFormat0Records> + recordsZ; /* VAR=nPairs */ public: - DEFINE_SIZE_ARRAY (16, records); + DEFINE_SIZE_ARRAY (16, recordsZ); }; struct KerxSubTableFormat1 @@ -93,8 +99,8 @@ struct KerxSubTableFormat1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - stateHeader.sanitize (c)); + return_trace (likely (c->check_struct (this) && + stateHeader.sanitize (c))); } protected: @@ -112,7 +118,8 @@ struct KerxClassTable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (firstGlyph.sanitize (c) && classes.sanitize (c)); + return_trace (likely (firstGlyph.sanitize (c) && + classes.sanitize (c))); } protected: @@ -141,11 +148,11 @@ struct KerxSubTableFormat2 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - rowWidth.sanitize (c) && - leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this) && - array.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + rowWidth.sanitize (c) && + leftClassTable.sanitize (c, this) && + rightClassTable.sanitize (c, this) && + array.sanitize (c, this))); } protected: @@ -168,11 +175,11 @@ struct KerxSubTableFormat4 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - rowWidth.sanitize (c) && - leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this) && - array.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + rowWidth.sanitize (c) && + leftClassTable.sanitize (c, this) && + rightClassTable.sanitize (c, this) && + array.sanitize (c, this))); } protected: @@ -195,11 +202,11 @@ struct KerxSubTableFormat6 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - rowIndexTable.sanitize (c, this) && - columnIndexTable.sanitize (c, this) && - kerningArray.sanitize (c, this) && - kerningVector.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + rowIndexTable.sanitize (c, this) && + columnIndexTable.sanitize (c, this) && + kerningArray.sanitize (c, this) && + kerningVector.sanitize (c, this))); } protected: @@ -236,7 +243,7 @@ struct KerxTable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!c->check_struct (this)) + if (unlikely (!c->check_struct (this))) return_trace (false); switch (format) { @@ -271,7 +278,7 @@ struct SubtableGlyphCoverageArray inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (likely (c->check_struct (this))); } protected: @@ -284,7 +291,7 @@ struct SubtableGlyphCoverageArray struct kerx { - static const hb_tag_t tableTag = HB_AAT_TAG_KERX; + static const hb_tag_t tableTag = HB_AAT_TAG_kerx; inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const { @@ -296,18 +303,18 @@ struct kerx inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!(c->check_struct (this))) + if (unlikely (!(c->check_struct (this)))) return_trace (false); /* TODO: Something like `morx`s ChainSubtable should be done here instead */ const KerxTable *table = &StructAfter<KerxTable> (*this); - if (!(table->sanitize (c))) + if (unlikely (!(table->sanitize (c)))) return_trace (false); for (unsigned int i = 0; i < nTables - 1; ++i) { table = &StructAfter<KerxTable> (*table); - if (!(table->sanitize (c))) + if (unlikely (!(table->sanitize (c)))) return_trace (false); } @@ -327,7 +334,7 @@ struct kerx HBUINT16 version; HBUINT16 padding; HBUINT32 nTables; -/*KerxTable tables[VAR];*/ +/*KerxTable tablesZ[VAR]; XXX ArrayOf??? */ /*SubtableGlyphCoverageArray coverage_array;*/ public: DEFINE_SIZE_STATIC (8); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 4cc2824..f258424 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -29,8 +29,13 @@ #include "hb-open-type-private.hh" #include "hb-aat-layout-common-private.hh" +#include "hb-ot-layout-common-private.hh" -#define HB_AAT_TAG_MORX HB_TAG('m','o','r','x') +/* + * morx -- Extended Glyph Metamorphosis + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html + */ +#define HB_AAT_TAG_morx HB_TAG('m','o','r','x') namespace AAT { @@ -302,9 +307,10 @@ struct ContextualSubtable } protected: - StateTable<EntryData> machine; - OffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32>, HBUINT32> - substitutionTables; + StateTable<EntryData> + machine; + LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> > + substitutionTables; public: DEFINE_SIZE_STATIC (20); }; @@ -461,12 +467,13 @@ struct LigatureSubtable } protected: - StateTable<EntryData> machine; - OffsetTo<UnsizedArrayOf<HBUINT32>, HBUINT32> + StateTable<EntryData> + machine; + LOffsetTo<UnsizedArrayOf<HBUINT32> > ligAction; /* Offset to the ligature action table. */ - OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32> + LOffsetTo<UnsizedArrayOf<HBUINT16> > component; /* Offset to the component table. */ - OffsetTo<UnsizedArrayOf<GlyphID>, HBUINT32> + LOffsetTo<UnsizedArrayOf<GlyphID> > ligature; /* Offset to the actual ligature lists. */ public: DEFINE_SIZE_STATIC (28); @@ -663,8 +670,8 @@ struct Chain HBUINT32 subtableCount; /* The number of subtables in the chain. */ Feature featureZ[VAR]; /* Features. */ - ChainSubtable subtableX[VAR]; /* Subtables. */ - // subtableGlyphCoverageArray if major == 3 +/*ChainSubtable subtableX[VAR];*//* Subtables. */ +/*subtableGlyphCoverageArray*/ /* Only if major == 3. */ public: DEFINE_SIZE_MIN (16); @@ -677,12 +684,12 @@ struct Chain struct morx { - static const hb_tag_t tableTag = HB_AAT_TAG_MORX; + static const hb_tag_t tableTag = HB_AAT_TAG_morx; inline void apply (hb_aat_apply_context_t *c) const { c->set_lookup_index (0); - const Chain *chain = chains; + const Chain *chain = chainsZ; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { @@ -699,7 +706,7 @@ struct morx !chainCount.sanitize (c)) return_trace (false); - const Chain *chain = chains; + const Chain *chain = chainsZ; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { @@ -716,7 +723,7 @@ struct morx * 1 for mort, 2 or 3 for morx. */ HBUINT32 chainCount; /* Number of metamorphosis chains contained in this * table. */ - Chain chains[VAR]; /* Chains. */ + Chain chainsZ[VAR]; /* Chains. */ public: DEFINE_SIZE_MIN (8); diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index 5767b11..0617e23 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -29,8 +29,13 @@ #define HB_AAT_LAYOUT_TRAK_TABLE_HH #include "hb-aat-layout-common-private.hh" +#include "hb-ot-layout-private.hh" #include "hb-open-type-private.hh" +/* + * trak -- Tracking + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html + */ #define HB_AAT_TAG_trak HB_TAG('t','r','a','k') @@ -39,12 +44,17 @@ namespace AAT { struct TrackTableEntry { - inline bool sanitize (hb_sanitize_context_t *c, const void *base, unsigned int size) const + friend struct TrackData; + + inline bool sanitize (hb_sanitize_context_t *c, const void *base, + unsigned int size) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (values.sanitize (c, base, size))); + return_trace (likely (c->check_struct (this) && + (valuesZ.sanitize (c, base, size)))); } + private: inline float get_track_value () const { return track.to_float (); @@ -52,15 +62,15 @@ struct TrackTableEntry inline int get_value (const void *base, unsigned int index) const { - return (base+values)[index]; + return (base+valuesZ)[index]; } protected: - Fixed track; /* Track value for this record. */ - HBUINT16 trackNameID; /* The 'name' table index for this track */ + Fixed track; /* Track value for this record. */ + NameID trackNameID; /* The 'name' table index for this track */ OffsetTo<UnsizedArrayOf<FWORD> > - values; /* Offset from start of tracking table to - * per-size tracking values for this track. */ + valuesZ; /* Offset from start of tracking table to + * per-size tracking values for this track. */ public: DEFINE_SIZE_STATIC (8); @@ -94,7 +104,7 @@ struct TrackData const TrackTableEntry *trackTableEntry = nullptr; for (unsigned int i = 0; i < sizes; ++i) // For now we only seek for track entries with zero tracking value - if (trackTable[i].get_track_value () == 0.) + if (trackTable[i].get_track_value () == 0.f) trackTableEntry = &trackTable[0]; // We couldn't match any, exit @@ -117,17 +127,17 @@ struct TrackData float s0 = size_table[size_index - 1].to_float (); float s1 = size_table[size_index].to_float (); float t = (csspx - s0) / (s1 - s0); - return t * trackTableEntry->get_value (base, size_index) + - (1.0 - t) * trackTableEntry->get_value (base, size_index - 1); + return (float) t * trackTableEntry->get_value (base, size_index) + + ((float) 1.0 - t) * trackTableEntry->get_value (base, size_index - 1); } protected: - HBUINT16 nTracks; /* Number of separate tracks included in this table. */ - HBUINT16 nSizes; /* Number of point sizes included in this table. */ - LOffsetTo<UnsizedArrayOf<Fixed> > /* Offset to array[nSizes] of size values. */ - sizeTable; + HBUINT16 nTracks; /* Number of separate tracks included in this table. */ + HBUINT16 nSizes; /* Number of point sizes included in this table. */ + LOffsetTo<UnsizedArrayOf<Fixed> > + sizeTable; /* Offset to array[nSizes] of size values. */ UnsizedArrayOf<TrackTableEntry> - trackTable; /* Array[nTracks] of TrackTableEntry records. */ + trackTable; /* Array[nTracks] of TrackTableEntry records. */ public: DEFINE_SIZE_ARRAY (8, trackTable); @@ -141,9 +151,9 @@ struct trak { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - horizData.sanitize (c, this, this) && - vertData.sanitize (c, this, this)); + return_trace (unlikely (c->check_struct (this) && + horizData.sanitize (c, this, this) && + vertData.sanitize (c, this, this))); } inline bool apply (hb_aat_apply_context_t *c) const @@ -151,7 +161,7 @@ struct trak TRACE_APPLY (this); const float ptem = c->font->ptem; - if (ptem <= 0.f) + if (unlikely (ptem <= 0.f)) return_trace (false); hb_buffer_t *buffer = c->buffer; diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 45268e3..7784fae 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -31,14 +31,20 @@ #include "hb-aat-layout-private.hh" #include "hb-aat-layout-ankr-table.hh" +#include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-layout-feat-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" #include "hb-aat-layout-trak-table.hh" +#include "hb-aat-fmtx-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-gcid-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise. /* * morx/kerx/trak */ +#if 0 static inline const AAT::ankr& _get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr) { @@ -46,7 +52,7 @@ _get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr) { if (blob) *blob = hb_blob_get_empty (); - return OT::Null(AAT::ankr); + return Null(AAT::ankr); } hb_ot_layout_t * layout = hb_ot_layout_from_face (face); const AAT::ankr& ankr = *(layout->ankr.get ()); @@ -62,7 +68,7 @@ _get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr) { if (blob) *blob = hb_blob_get_empty (); - return OT::Null(AAT::kerx); + return Null(AAT::kerx); } hb_ot_layout_t * layout = hb_ot_layout_from_face (face); /* XXX this doesn't call set_num_glyphs on sanitizer. */ @@ -79,7 +85,7 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) { if (blob) *blob = hb_blob_get_empty (); - return OT::Null(AAT::morx); + return Null(AAT::morx); } hb_ot_layout_t * layout = hb_ot_layout_from_face (face); /* XXX this doesn't call set_num_glyphs on sanitizer. */ @@ -96,7 +102,7 @@ _get_trak (hb_face_t *face, hb_blob_t **blob = nullptr) { if (blob) *blob = hb_blob_get_empty (); - return OT::Null(AAT::trak); + return Null(AAT::trak); } hb_ot_layout_t * layout = hb_ot_layout_from_face (face); const AAT::trak& trak = *(layout->trak.get ()); @@ -104,34 +110,38 @@ _get_trak (hb_face_t *face, hb_blob_t **blob = nullptr) *blob = layout->trak.blob; return trak; } +#endif // static inline void // _hb_aat_layout_create (hb_face_t *face) // { // OT::Sanitizer<AAT::morx> sanitizer; // sanitizer.set_num_glyphs (face->get_num_glyphs ()); -// hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_MORX)); -// OT::Sanitizer<AAT::morx>::lock_instance (morx_blob); +// hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_morx)); +// morx_blob->as<AAT::morx> (); // if (0) // { -// OT::Sanitizer<AAT::Lookup<OT::GlyphID> >::lock_instance (morx_blob)->get_value (1, face->get_num_glyphs ()); +// morx_blob->as<AAT::Lookup<OT::GlyphID> > ()->get_value (1, face->get_num_glyphs ()); // } // } void hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer) { +#if 0 hb_blob_t *blob; const AAT::morx& morx = _get_morx (font->face, &blob); AAT::hb_aat_apply_context_t c (font, buffer, blob); morx.apply (&c); +#endif } void hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer) { +#if 0 hb_blob_t *blob; const AAT::ankr& ankr = _get_ankr (font->face, &blob); const AAT::kerx& kerx = _get_kerx (font->face, &blob); @@ -140,4 +150,5 @@ hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer) AAT::hb_aat_apply_context_t c (font, buffer, blob); kerx.apply (&c, &ankr); trak.apply (&c); +#endif } diff --git a/src/hb-aat-ltag-table.hh b/src/hb-aat-ltag-table.hh new file mode 100644 index 0000000..15c4e89 --- /dev/null +++ b/src/hb-aat-ltag-table.hh @@ -0,0 +1,79 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_AAT_LTAG_TABLE_HH +#define HB_AAT_LTAG_TABLE_HH + +#include "hb-aat-layout-common-private.hh" + +/* + * ltag -- Language Tag + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ltag.html + */ +#define HB_AAT_TAG_ltag HB_TAG('l','t','a','g') + + +namespace AAT { + + +struct FTStringRange +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && (base+tag).sanitize (c, length)); + } + + protected: + OffsetTo<UnsizedArrayOf<HBUINT8> > + tag; /* Offset from the start of the table to + * the beginning of the string */ + HBUINT16 length; /* String length (in bytes) */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct ltag +{ + static const hb_tag_t tableTag = HB_AAT_TAG_ltag; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && tagRanges.sanitize (c, this))); + } + + protected: + HBUINT32 version; /* Table version; currently 1 */ + HBUINT32 flags; /* Table flags; currently none defined */ + LArrayOf<FTStringRange> + tagRanges; /* Range for each tag's string */ + public: + DEFINE_SIZE_ARRAY (12, tagRanges); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_LTAG_TABLE_HH */ diff --git a/src/hb-atomic-private.hh b/src/hb-atomic-private.hh index a7e9b11..12caaca 100644 --- a/src/hb-atomic-private.hh +++ b/src/hb-atomic-private.hh @@ -63,7 +63,6 @@ static inline void _HBMemoryBarrier (void) { } typedef LONG hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) #define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) #define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P)) @@ -73,7 +72,6 @@ typedef LONG hb_atomic_int_impl_t; #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) typedef int hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) #define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) #define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) @@ -86,7 +84,6 @@ typedef int hb_atomic_int_impl_t; #include <mbarrier.h> typedef unsigned int hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) #define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) #define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) @@ -104,7 +101,6 @@ typedef unsigned int hb_atomic_int_impl_t; typedef int32_t hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) #define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) #define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P)) @@ -138,7 +134,6 @@ static inline int _hb_compare_and_swaplp(volatile long* P, long O, long N) { } typedef int hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) #define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add (&(AI), (V)) #define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P)) @@ -149,7 +144,6 @@ typedef int hb_atomic_int_impl_t; #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ typedef volatile int hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) #define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) #define hb_atomic_ptr_impl_get(P) ((void *) *(P)) @@ -159,7 +153,6 @@ typedef volatile int hb_atomic_int_impl_t; #else /* HB_NO_MT */ typedef int hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) #define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) #define hb_atomic_ptr_impl_get(P) ((void *) *(P)) @@ -169,7 +162,7 @@ typedef int hb_atomic_int_impl_t; #endif -#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)} +#define HB_ATOMIC_INT_INIT(V) {V} struct hb_atomic_int_t { diff --git a/src/hb-blob-private.hh b/src/hb-blob-private.hh new file mode 100644 index 0000000..b72fa72 --- /dev/null +++ b/src/hb-blob-private.hh @@ -0,0 +1,88 @@ +/* + * Copyright © 2009 Red Hat, Inc. + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BLOB_PRIVATE_HH +#define HB_BLOB_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-object-private.hh" + + +/* + * hb_blob_t + */ + +struct hb_blob_t +{ + inline void fini_shallow (void) + { + destroy_user_data (); + } + + inline void destroy_user_data (void) + { + if (destroy) + { + destroy (user_data); + user_data = nullptr; + destroy = nullptr; + } + } + + HB_INTERNAL bool try_make_writable (void); + HB_INTERNAL bool try_make_writable_inplace (void); + HB_INTERNAL bool try_make_writable_inplace_unix (void); + + inline void lock (void) + { + hb_blob_make_immutable (this); + } + + template <typename Type> + inline const Type* as (void) const + { + return unlikely (!data) ? &Null(Type) : reinterpret_cast<const Type *> (data); + } + + public: + hb_object_header_t header; + ASSERT_POD (); + + bool immutable; + + const char *data; + unsigned int length; + hb_memory_mode_t mode; + + void *user_data; + hb_destroy_func_t destroy; +}; + + +#endif /* HB_BLOB_PRIVATE_HH */ diff --git a/src/hb-blob.cc b/src/hb-blob.cc index b5291f6..c138648 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -1,5 +1,6 @@ /* * Copyright © 2009 Red Hat, Inc. + * Copyright © 2018 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -31,8 +32,7 @@ #include "hb-private.hh" #include "hb-debug.hh" - -#include "hb-object-private.hh" +#include "hb-blob-private.hh" #ifdef HAVE_SYS_MMAN_H #ifdef HAVE_UNISTD_H @@ -43,35 +43,9 @@ #include <stdio.h> #include <errno.h> +#include <stdlib.h> -struct hb_blob_t { - hb_object_header_t header; - ASSERT_POD (); - - bool immutable; - - const char *data; - unsigned int length; - hb_memory_mode_t mode; - - void *user_data; - hb_destroy_func_t destroy; -}; - - -static bool _try_writable (hb_blob_t *blob); - -static void -_hb_blob_destroy_user_data (hb_blob_t *blob) -{ - if (blob->destroy) { - blob->destroy (blob->user_data); - blob->user_data = nullptr; - blob->destroy = nullptr; - } -} - /** * hb_blob_create: (skip) * @data: Pointer to blob data. @@ -114,7 +88,7 @@ hb_blob_create (const char *data, if (blob->mode == HB_MEMORY_MODE_DUPLICATE) { blob->mode = HB_MEMORY_MODE_READONLY; - if (!_try_writable (blob)) { + if (!blob->try_make_writable ()) { hb_blob_destroy (blob); return hb_blob_get_empty (); } @@ -260,7 +234,7 @@ hb_blob_destroy (hb_blob_t *blob) { if (!hb_object_destroy (blob)) return; - _hb_blob_destroy_user_data (blob); + blob->fini_shallow (); free (blob); } @@ -273,7 +247,7 @@ hb_blob_destroy (hb_blob_t *blob) * @destroy: callback to call when @data is not needed anymore. * @replace: whether to replace an existing data with the same key. * - * Return value: + * Return value: * * Since: 0.9.2 **/ @@ -292,9 +266,9 @@ hb_blob_set_user_data (hb_blob_t *blob, * @blob: a blob. * @key: key for data to get. * - * * - * Return value: (transfer none): + * + * Return value: (transfer none): * * Since: 0.9.2 **/ @@ -310,7 +284,7 @@ hb_blob_get_user_data (hb_blob_t *blob, * hb_blob_make_immutable: * @blob: a blob. * - * + * * * Since: 0.9.2 **/ @@ -327,7 +301,7 @@ hb_blob_make_immutable (hb_blob_t *blob) * hb_blob_is_immutable: * @blob: a blob. * - * + * * * Return value: TODO * @@ -344,7 +318,7 @@ hb_blob_is_immutable (hb_blob_t *blob) * hb_blob_get_length: * @blob: a blob. * - * + * * * Return value: the length of blob data in bytes. * @@ -361,9 +335,9 @@ hb_blob_get_length (hb_blob_t *blob) * @blob: a blob. * @length: (out): * - * * - * Returns: (transfer none) (array length=length): + * + * Returns: (transfer none) (array length=length): * * Since: 0.9.2 **/ @@ -395,7 +369,7 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length) char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) { - if (!_try_writable (blob)) { + if (!blob->try_make_writable ()) { if (length) *length = 0; @@ -409,8 +383,8 @@ hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) } -static hb_bool_t -_try_make_writable_inplace_unix (hb_blob_t *blob) +bool +hb_blob_t::try_make_writable_inplace_unix (void) { #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT) uintptr_t pagesize = -1, mask, length; @@ -425,25 +399,25 @@ _try_make_writable_inplace_unix (hb_blob_t *blob) #endif if ((uintptr_t) -1L == pagesize) { - DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno)); + DEBUG_MSG_FUNC (BLOB, this, "failed to get pagesize: %s", strerror (errno)); return false; } - DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize); + DEBUG_MSG_FUNC (BLOB, this, "pagesize is %lu", (unsigned long) pagesize); mask = ~(pagesize-1); - addr = (const char *) (((uintptr_t) blob->data) & mask); - length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr; - DEBUG_MSG_FUNC (BLOB, blob, + addr = (const char *) (((uintptr_t) this->data) & mask); + length = (const char *) (((uintptr_t) this->data + this->length + pagesize-1) & mask) - addr; + DEBUG_MSG_FUNC (BLOB, this, "calling mprotect on [%p..%p] (%lu bytes)", addr, addr+length, (unsigned long) length); if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) { - DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno)); + DEBUG_MSG_FUNC (BLOB, this, "mprotect failed: %s", strerror (errno)); return false; } - blob->mode = HB_MEMORY_MODE_WRITABLE; + this->mode = HB_MEMORY_MODE_WRITABLE; - DEBUG_MSG_FUNC (BLOB, blob, + DEBUG_MSG_FUNC (BLOB, this, "successfully made [%p..%p] (%lu bytes) writable\n", addr, addr+length, (unsigned long) length); return true; @@ -452,53 +426,185 @@ _try_make_writable_inplace_unix (hb_blob_t *blob) #endif } -static bool -_try_writable_inplace (hb_blob_t *blob) +bool +hb_blob_t::try_make_writable_inplace (void) { - DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n"); + DEBUG_MSG_FUNC (BLOB, this, "making writable inplace\n"); - if (_try_make_writable_inplace_unix (blob)) + if (this->try_make_writable_inplace_unix ()) return true; - DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n"); + DEBUG_MSG_FUNC (BLOB, this, "making writable -> FAILED\n"); /* Failed to make writable inplace, mark that */ - blob->mode = HB_MEMORY_MODE_READONLY; + this->mode = HB_MEMORY_MODE_READONLY; return false; } -static bool -_try_writable (hb_blob_t *blob) +bool +hb_blob_t::try_make_writable (void) { - if (blob->immutable) + if (this->immutable) return false; - if (blob->mode == HB_MEMORY_MODE_WRITABLE) + if (this->mode == HB_MEMORY_MODE_WRITABLE) return true; - if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob)) + if (this->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && this->try_make_writable_inplace ()) return true; - if (blob->mode == HB_MEMORY_MODE_WRITABLE) + if (this->mode == HB_MEMORY_MODE_WRITABLE) return true; - DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data); + DEBUG_MSG_FUNC (BLOB, this, "current data is -> %p\n", this->data); char *new_data; - new_data = (char *) malloc (blob->length); + new_data = (char *) malloc (this->length); if (unlikely (!new_data)) return false; - DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data); + DEBUG_MSG_FUNC (BLOB, this, "dupped successfully -> %p\n", this->data); - memcpy (new_data, blob->data, blob->length); - _hb_blob_destroy_user_data (blob); - blob->mode = HB_MEMORY_MODE_WRITABLE; - blob->data = new_data; - blob->user_data = new_data; - blob->destroy = free; + memcpy (new_data, this->data, this->length); + this->destroy_user_data (); + this->mode = HB_MEMORY_MODE_WRITABLE; + this->data = new_data; + this->user_data = new_data; + this->destroy = free; return true; } + +/* + * Mmap + */ + +#ifdef HAVE_MMAP +# include <sys/types.h> +# include <sys/stat.h> +# include <fcntl.h> +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# include <windows.h> +#endif + +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#ifndef MAP_NORESERVE +# define MAP_NORESERVE 0 +#endif + +struct hb_mapped_file_t +{ + char *contents; + unsigned long length; +#if defined(_WIN32) || defined(__CYGWIN__) + HANDLE mapping; +#endif +}; + +static void +_hb_mapped_file_destroy (hb_mapped_file_t *file) +{ +#ifdef HAVE_MMAP + munmap (file->contents, file->length); +#elif defined(_WIN32) || defined(__CYGWIN__) + UnmapViewOfFile (file->contents); + CloseHandle (file->mapping); +#else + free (file->contents); +#endif + + free (file); +} + +/** + * hb_blob_create_from_file: + * @file_name: font filename. + * + * Returns: A hb_blob_t pointer with the content of the file + * + * Since: 1.7.7 + **/ +hb_blob_t * +hb_blob_create_from_file (const char *file_name) +{ + // Adopted from glib's gmappedfile.c with Matthias Clasen and + // Allison Lortie permission but changed a lot to suit our need. + bool writable = false; + hb_memory_mode_t mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE; + hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t)); + if (unlikely (!file)) return hb_blob_get_empty (); + +#ifdef HAVE_MMAP + int fd = open (file_name, (writable ? O_RDWR : O_RDONLY) | _O_BINARY, 0); +# define CLOSE close + if (unlikely (fd == -1)) goto fail_without_close; + + struct stat st; + if (unlikely (fstat (fd, &st) == -1)) goto fail; + + // See https://github.com/GNOME/glib/blob/f9faac7/glib/gmappedfile.c#L139-L142 + if (unlikely (st.st_size == 0 && S_ISREG (st.st_mode))) goto fail; + + file->length = (unsigned long) st.st_size; + file->contents = (char *) mmap (nullptr, file->length, + writable ? PROT_READ|PROT_WRITE : PROT_READ, + MAP_PRIVATE | MAP_NORESERVE, fd, 0); + + if (unlikely (file->contents == MAP_FAILED)) goto fail; + +#elif defined(_WIN32) || defined(__CYGWIN__) + HANDLE fd = CreateFile (file_name, + writable ? GENERIC_READ|GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr); +# define CLOSE CloseHandle + + if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close; + + file->length = (unsigned long) GetFileSize (fd, nullptr); + file->mapping = CreateFileMapping (fd, nullptr, + writable ? PAGE_WRITECOPY : PAGE_READONLY, + 0, 0, nullptr); + if (unlikely (file->mapping == nullptr)) goto fail; + + file->contents = (char *) MapViewOfFile (file->mapping, + writable ? FILE_MAP_COPY : FILE_MAP_READ, + 0, 0, 0); + if (unlikely (file->contents == nullptr)) goto fail; + +#else + mm = HB_MEMORY_MODE_WRITABLE; + + FILE *fd = fopen (file_name, "rb"); +# define CLOSE fclose + if (unlikely (!fd)) goto fail_without_close; + + fseek (fd, 0, SEEK_END); + file->length = ftell (fd); + rewind (fd); + file->contents = (char *) malloc (file->length); + if (unlikely (!file->contents)) goto fail; + + if (unlikely (fread (file->contents, 1, file->length, fd) != file->length)) + goto fail; + +#endif + + CLOSE (fd); + return hb_blob_create (file->contents, file->length, mm, (void *) file, + (hb_destroy_func_t) _hb_mapped_file_destroy); + +fail: + CLOSE (fd); +#undef CLOSE +fail_without_close: + free (file); + return hb_blob_get_empty (); +} diff --git a/src/hb-blob.h b/src/hb-blob.h index fd561f7..d1d9134 100644 --- a/src/hb-blob.h +++ b/src/hb-blob.h @@ -123,6 +123,8 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length); HB_EXTERN char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length); +HB_EXTERN hb_blob_t * +hb_blob_create_from_file (const char *file_name); HB_END_DECLS diff --git a/src/hb-buffer-deserialize-json.hh b/src/hb-buffer-deserialize-json.hh index be374c7..380f3c5 100644 --- a/src/hb-buffer-deserialize-json.hh +++ b/src/hb-buffer-deserialize-json.hh @@ -34,397 +34,397 @@ #line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, - 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, - 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, - 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 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, + 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, + 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, + 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, + 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, + 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 }; @@ -461,7 +461,7 @@ _hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; - + #line 466 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; @@ -503,7 +503,7 @@ _resume: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -554,7 +554,7 @@ _resume: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -566,7 +566,7 @@ _resume: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -578,7 +578,7 @@ _resume: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -590,7 +590,7 @@ _resume: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -602,7 +602,7 @@ _resume: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -614,7 +614,7 @@ _resume: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; diff --git a/src/hb-buffer-deserialize-json.rl b/src/hb-buffer-deserialize-json.rl index 0f7d48e..ec9bc7c 100644 --- a/src/hb-buffer-deserialize-json.rl +++ b/src/hb-buffer-deserialize-json.rl @@ -42,7 +42,7 @@ action clear_item { action add_item { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; diff --git a/src/hb-buffer-deserialize-text.hh b/src/hb-buffer-deserialize-text.hh index a6ab0bb..5bca369 100644 --- a/src/hb-buffer-deserialize-text.hh +++ b/src/hb-buffer-deserialize-text.hh @@ -34,274 +34,274 @@ #line 36 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { - 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, - 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, - 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, + 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, + 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, + 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, + 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, + 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, + 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, + 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 }; @@ -338,7 +338,7 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; - + #line 343 "hb-buffer-deserialize-text.hh" { cs = deserialize_text_start; @@ -422,7 +422,7 @@ _resume: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -434,7 +434,7 @@ _resume: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -446,7 +446,7 @@ _resume: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -458,7 +458,7 @@ _resume: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -470,7 +470,7 @@ _resume: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -499,7 +499,7 @@ _again: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -511,7 +511,7 @@ _again: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -523,7 +523,7 @@ _again: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -535,7 +535,7 @@ _again: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; @@ -547,7 +547,7 @@ _again: #line 43 "hb-buffer-deserialize-text.rl" { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; diff --git a/src/hb-buffer-deserialize-text.rl b/src/hb-buffer-deserialize-text.rl index fd9be42..1d90979 100644 --- a/src/hb-buffer-deserialize-text.rl +++ b/src/hb-buffer-deserialize-text.rl @@ -42,7 +42,7 @@ action clear_item { action add_item { buffer->add_info (info); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return false; buffer->pos[buffer->len - 1] = pos; *end_ptr = p; diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index af4767f..dd6f1dc 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -101,7 +101,7 @@ struct hb_buffer_t { hb_buffer_content_type_t content_type; hb_segment_properties_t props; /* Script, language, direction */ - bool in_error; /* Allocation failed */ + bool successful; /* Allocations successful */ bool have_output; /* Whether we have an output buffer going on */ bool have_positions; /* Whether we have positions */ diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index dc0639f..7b95aea 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -111,11 +111,11 @@ hb_segment_properties_hash (const hb_segment_properties_t *p) bool hb_buffer_t::enlarge (unsigned int size) { - if (unlikely (in_error)) + if (unlikely (!successful)) return false; if (unlikely (size > max_len)) { - in_error = true; + successful = false; return false; } @@ -139,7 +139,7 @@ hb_buffer_t::enlarge (unsigned int size) done: if (unlikely (!new_pos || !new_info)) - in_error = true; + successful = false; if (likely (new_pos)) pos = new_pos; @@ -148,10 +148,10 @@ done: info = new_info; out_info = separate_out ? (hb_glyph_info_t *) pos : info; - if (likely (!in_error)) + if (likely (successful)) allocated = new_allocated; - return likely (!in_error); + return likely (successful); } bool @@ -234,7 +234,7 @@ hb_buffer_t::clear (void) scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; content_type = HB_BUFFER_CONTENT_TYPE_INVALID; - in_error = false; + successful = true; have_output = false; have_positions = false; @@ -324,7 +324,7 @@ hb_buffer_t::clear_positions (void) void hb_buffer_t::swap_buffers (void) { - if (unlikely (in_error)) return; + if (unlikely (!successful)) return; assert (have_output); have_output = false; @@ -409,7 +409,7 @@ hb_buffer_t::move_to (unsigned int i) idx = i; return true; } - if (unlikely (in_error)) + if (unlikely (!successful)) return false; assert (i <= out_len + (len - idx)); @@ -687,6 +687,8 @@ hb_buffer_t::guess_segment_properties (void) /* If direction is set to INVALID, guess from script */ if (props.direction == HB_DIRECTION_INVALID) { props.direction = hb_script_get_horizontal_direction (props.script); + if (props.direction == HB_DIRECTION_INVALID) + props.direction = HB_DIRECTION_LTR; } /* If language is not set, use default language from locale */ @@ -754,7 +756,7 @@ hb_buffer_get_empty (void) HB_BUFFER_CONTENT_TYPE_INVALID, HB_SEGMENT_PROPERTIES_DEFAULT, - true, /* in_error */ + false, /* successful */ true, /* have_output */ true /* have_positions */ @@ -1269,7 +1271,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) hb_bool_t hb_buffer_allocation_successful (hb_buffer_t *buffer) { - return !buffer->in_error; + return buffer->successful; } /** @@ -1489,6 +1491,8 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) * 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(). + * If hb_script_get_horizontal_direction() returns %HB_DIRECTION_INVALID, + * then %HB_DIRECTION_LTR is used. * * 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 @@ -1750,13 +1754,13 @@ hb_buffer_append (hb_buffer_t *buffer, if (buffer->len + (end - start) < buffer->len) /* Overflows. */ { - buffer->in_error = true; + buffer->successful = false; return; } unsigned int orig_len = buffer->len; hb_buffer_set_length (buffer, buffer->len + (end - start)); - if (buffer->in_error) + if (unlikely (!buffer->successful)) return; memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); diff --git a/src/hb-common.cc b/src/hb-common.cc index d1fcf79..a67fcf8 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -60,12 +60,12 @@ _hb_options_init (void) /** * hb_tag_from_string: - * @str: (array length=len) (element-type uint8_t): - * @len: + * @str: (array length=len) (element-type uint8_t): + * @len: * - * * - * Return value: + * + * Return value: * * Since: 0.9.2 **/ @@ -90,10 +90,10 @@ hb_tag_from_string (const char *str, int len) /** * hb_tag_to_string: - * @tag: - * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): + * @tag: + * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): + * * - * * * Since: 0.9.5 **/ @@ -118,12 +118,12 @@ const char direction_strings[][4] = { /** * hb_direction_from_string: - * @str: (array length=len) (element-type uint8_t): - * @len: + * @str: (array length=len) (element-type uint8_t): + * @len: * - * * - * Return value: + * + * Return value: * * Since: 0.9.2 **/ @@ -146,11 +146,11 @@ hb_direction_from_string (const char *str, int len) /** * hb_direction_to_string: - * @direction: + * @direction: + * * - * * - * Return value: (transfer none): + * Return value: (transfer none): * * Since: 0.9.2 **/ @@ -225,7 +225,7 @@ struct hb_language_item_t { inline hb_language_item_t & operator = (const char *s) { /* If a custom allocated is used calling strdup() pairs - badly with a call to the custom free() in finish() below. + badly with a call to the custom free() in fini() below. Therefore don't call strdup(), implement its behavior. */ size_t len = strlen(s) + 1; @@ -240,7 +240,7 @@ struct hb_language_item_t { return *this; } - void finish (void) { free ((void *) lang); } + void fini (void) { free ((void *) lang); } }; @@ -252,11 +252,16 @@ static hb_language_item_t *langs; static void free_langs (void) { - while (langs) { - hb_language_item_t *next = langs->next; - langs->finish (); - free (langs); - langs = next; +retry: + hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs); + if (!hb_atomic_ptr_cmpexch (&langs, first_lang, nullptr)) + goto retry; + + while (first_lang) { + hb_language_item_t *next = first_lang->next; + first_lang->fini (); + free (first_lang); + first_lang = next; } } #endif @@ -284,7 +289,7 @@ retry: } if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) { - lang->finish (); + lang->fini (); free (lang); goto retry; } @@ -356,7 +361,7 @@ hb_language_to_string (hb_language_t language) /** * hb_language_get_default: * - * + * * * Return value: (transfer none): * @@ -385,7 +390,7 @@ hb_language_get_default (void) * * Converts an ISO 15924 script tag to a corresponding #hb_script_t. * - * Return value: + * Return value: * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 @@ -407,7 +412,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED; case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC; - /* Script variants from http://unicode.org/iso15924/ */ + /* Script variants from https://unicode.org/iso15924/ */ case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC; case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN; case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN; @@ -434,7 +439,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then * hb_script_from_iso15924_tag(). * - * Return value: + * Return value: * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 @@ -464,18 +469,18 @@ hb_script_to_iso15924_tag (hb_script_t script) /** * hb_script_get_horizontal_direction: - * @script: + * @script: + * * - * * - * Return value: + * Return value: * * Since: 0.9.2 **/ hb_direction_t hb_script_get_horizontal_direction (hb_script_t script) { - /* http://goo.gl/x9ilM */ + /* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ switch ((hb_tag_t) script) { /* Unicode-1.1 additions */ @@ -530,7 +535,18 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-9.0 additions */ case HB_SCRIPT_ADLAM: + /* Unicode-11.0 additions */ + case HB_SCRIPT_HANIFI_ROHINGYA: + case HB_SCRIPT_OLD_SOGDIAN: + case HB_SCRIPT_SOGDIAN: + return HB_DIRECTION_RTL; + + + /* https://github.com/harfbuzz/harfbuzz/issues/1000 */ + case HB_SCRIPT_OLD_ITALIC: + + return HB_DIRECTION_INVALID; } return HB_DIRECTION_LTR; @@ -608,13 +624,13 @@ hb_version_string (void) /** * hb_version_atleast: - * @major: - * @minor: - * @micro: + * @major: + * @minor: + * @micro: * - * * - * Return value: + * + * Return value: * * Since: 0.9.30 **/ @@ -719,8 +735,14 @@ static HB_LOCALE_T C_locale; static void free_C_locale (void) { - if (C_locale) - HB_FREE_LOCALE (C_locale); +retry: + HB_LOCALE_T locale = (HB_LOCALE_T) hb_atomic_ptr_get (&C_locale); + + if (!hb_atomic_ptr_cmpexch (&C_locale, locale, nullptr)) + goto retry; + + if (locale) + HB_FREE_LOCALE (locale); } #endif diff --git a/src/hb-common.h b/src/hb-common.h index 26200ce..5dc1ebc 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -49,6 +49,16 @@ # include <inttypes.h> #elif defined (_AIX) # include <sys/inttypes.h> +#elif defined (_MSC_VER) && _MSC_VER < 1600 +/* VS 2010 (_MSC_VER 1600) has stdint.h */ +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 @@ -142,8 +152,8 @@ hb_language_get_default (void); /* hb_script_t */ -/* http://unicode.org/iso15924/ */ -/* http://goo.gl/x9ilM */ +/* https://unicode.org/iso15924/ */ +/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ /* Unicode Character Database property: Script (sc) */ typedef enum { @@ -315,6 +325,17 @@ typedef enum /*10.0*/HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), + /* + * Since 1.8.0 + */ + /*11.0*/HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), + /*11.0*/HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), + /*11.0*/HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), + /*11.0*/HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), + /*11.0*/HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), + /*11.0*/HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), + /*11.0*/HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, @@ -323,7 +344,7 @@ typedef enum * 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 + * https://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 >*/ diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index aba7cf4..61f9c35 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -168,6 +168,10 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) || CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay"))) { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 +# define kCTFontUIFontSystem kCTFontSystemFontType +# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType +#endif CTFontUIFontType font_type = kCTFontUIFontSystem; if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold"))) font_type = kCTFontUIFontEmphasizedSystem; @@ -206,7 +210,18 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) return ct_font; } - CFURLRef original_url = (CFURLRef)CTFontCopyAttribute(ct_font, kCTFontURLAttribute); + CFURLRef original_url = nullptr; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + ATSFontRef atsFont; + FSRef fsref; + OSStatus status; + atsFont = CTFontGetPlatformFont (ct_font, NULL); + status = ATSFontGetFileReference (atsFont, &fsref); + if (status == noErr) + original_url = CFURLCreateFromFSRef (NULL, &fsref); +#else + original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute); +#endif /* Create font copy with cascade list that has LastResort first; this speeds up CoreText * font fallback which we don't need anyway. */ @@ -225,7 +240,15 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) * system locations that we cannot access from the sandboxed renderer * process in Blink. This can be detected by the new file URL location * that the newly found font points to. */ - CFURLRef new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); + CFURLRef new_url = nullptr; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + atsFont = CTFontGetPlatformFont (new_ct_font, NULL); + status = ATSFontGetFileReference (atsFont, &fsref); + if (status == noErr) + new_url = CFURLCreateFromFSRef (NULL, &fsref); +#else + new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); +#endif // Keep reconfigured font if URL cannot be retrieved (seems to be the case // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606 if (!original_url || !new_url || CFEqual (original_url, new_url)) { @@ -618,8 +641,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, 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; + hb_auto_t<hb_vector_t<feature_record_t> > feature_records; + hb_auto_t<hb_vector_t<range_record_t> > range_records; /* * Set up features. @@ -628,7 +651,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, if (num_features) { /* Sort features by start/end events. */ - hb_auto_array_t<feature_event_t> feature_events; + hb_auto_t<hb_vector_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, @@ -647,15 +670,11 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, 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; @@ -669,15 +688,13 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, 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; + hb_auto_t<hb_vector_t<active_feature_t> > active_features; unsigned int last_index = 0; for (unsigned int i = 0; i < feature_events.len; i++) { @@ -687,8 +704,6 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, { /* 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) { @@ -746,23 +761,16 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, last_index = event->index; } - if (event->start) { - active_feature_t *feature = active_features.push (); - if (unlikely (!feature)) - goto fail_features; - *feature = event->feature; + if (event->start) + { + active_features.push (event->feature); } else { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.array); + active_features.remove (feature - active_features.arrayZ); } } } - else - { - fail_features: - num_features = 0; - } unsigned int scratch_size; hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); @@ -944,6 +952,9 @@ resize_and_retry: int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level); +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel; +#endif CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault, (const void **) &kCTTypesetterOptionForcedEmbeddingLevel, (const void **) &level_number, @@ -979,7 +990,7 @@ resize_and_retry: /* For right-to-left runs, CoreText returns the glyphs positioned such that * any trailing whitespace is to the left of (0,0). Adjust coordinate system * to fix for that. Test with any RTL string with trailing spaces. - * https://code.google.com/p/chromium/issues/detail?id=469028 + * https://crbug.com/469028 */ if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) { @@ -1032,7 +1043,7 @@ resize_and_retry: * However, even that wouldn't work if we were passed in the CGFont to * construct a hb_face to begin with. * - * See: http://github.com/harfbuzz/harfbuzz/pull/36 + * See: https://github.com/harfbuzz/harfbuzz/pull/36 * * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098 */ @@ -1222,7 +1233,7 @@ resize_and_retry: * directions. As such, disable the assert... It wouldn't crash, but * cursoring will be off... * - * http://crbug.com/419769 + * https://crbug.com/419769 */ if (0) { diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 69a8aa2..187ab3f 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2015-2016 Ebrahim Byagowi + * Copyright © 2015-2018 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -32,8 +32,19 @@ #include "hb-directwrite.h" -HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, face) -HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, font) +HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, face) +HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, font) + + +/* + * hb-directwrite uses new/delete syntatically but as we let users + * to override malloc/free, we will redefine new/delete so users + * won't need to do that by their own. + */ +void* operator new (size_t size) { return malloc (size); } +void* operator new [] (size_t size) { return malloc (size); } +void operator delete (void* pointer) { free (pointer); } +void operator delete [] (void* pointer) { free (pointer); } /* @@ -48,18 +59,19 @@ class DWriteFontFileLoader : public IDWriteFontFileLoader private: IDWriteFontFileStream *mFontFileStream; public: - DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) { + DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) + { mFontFileStream = fontFileStream; } // IUnknown interface - IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; } - IFACEMETHOD_(ULONG, AddRef)() { return 1; } - IFACEMETHOD_(ULONG, Release)() { return 1; } + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () { return 1; } + IFACEMETHOD_ (ULONG, Release) () { return 1; } // IDWriteFontFileLoader methods - virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, - UINT32 fontFileReferenceKeySize, + virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey (void const* fontFileReferenceKey, + uint32_t fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFileStream) { *fontFileStream = mFontFileStream; @@ -73,27 +85,26 @@ private: uint8_t *mData; uint32_t mSize; public: - DWriteFontFileStream(uint8_t *aData, uint32_t aSize) + DWriteFontFileStream (uint8_t *aData, uint32_t aSize) { mData = aData; mSize = aSize; } // IUnknown interface - IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; } - IFACEMETHOD_(ULONG, AddRef)() { return 1; } - IFACEMETHOD_(ULONG, Release)() { return 1; } + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () { return 1; } + IFACEMETHOD_ (ULONG, Release) () { return 1; } // IDWriteFontFileStream methods - virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, + virtual HRESULT STDMETHODCALLTYPE ReadFileFragment (void const** fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext) { // We are required to do bounds checking. - if (fileOffset + fragmentSize > mSize) { + if (fileOffset + fragmentSize > mSize) return E_FAIL; - } // truncate the 64 bit fileOffset to size_t sized index into mData size_t index = static_cast<size_t> (fileOffset); @@ -104,15 +115,15 @@ public: return S_OK; } - virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext) { } + virtual void STDMETHODCALLTYPE ReleaseFileFragment (void* fragmentContext) { } - virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize) + virtual HRESULT STDMETHODCALLTYPE GetFileSize (OUT UINT64* fileSize) { *fileSize = mSize; return S_OK; } - virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime) + virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime (OUT UINT64* lastWriteTime) { return E_NOTIMPL; } @@ -123,7 +134,8 @@ public: * shaper face data */ -struct hb_directwrite_shaper_face_data_t { +struct hb_directwrite_shaper_face_data_t +{ IDWriteFactory *dwriteFactory; IDWriteFontFile *fontFile; IDWriteFontFileStream *fontFileStream; @@ -133,10 +145,9 @@ struct hb_directwrite_shaper_face_data_t { }; hb_directwrite_shaper_face_data_t * -_hb_directwrite_shaper_face_data_create(hb_face_t *face) +_hb_directwrite_shaper_face_data_create (hb_face_t *face) { - hb_directwrite_shaper_face_data_t *data = - (hb_directwrite_shaper_face_data_t *) malloc (sizeof (hb_directwrite_shaper_face_data_t)); + hb_directwrite_shaper_face_data_t *data = new hb_directwrite_shaper_face_data_t; if (unlikely (!data)) return nullptr; @@ -150,10 +161,11 @@ _hb_directwrite_shaper_face_data_create(hb_face_t *face) HRESULT hr; hb_blob_t *blob = hb_face_reference_blob (face); - IDWriteFontFileStream *fontFileStream = new DWriteFontFileStream ( - (uint8_t*) hb_blob_get_data (blob, nullptr), hb_blob_get_length (blob)); + DWriteFontFileStream *fontFileStream = new DWriteFontFileStream ( + (uint8_t *) hb_blob_get_data (blob, nullptr), + hb_blob_get_length (blob)); - IDWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream); + DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream); dwriteFactory->RegisterFontFileLoader (fontFileLoader); IDWriteFontFile *fontFile; @@ -164,23 +176,19 @@ _hb_directwrite_shaper_face_data_create(hb_face_t *face) #define FAIL(...) \ HB_STMT_START { \ DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ - return false; \ + return nullptr; \ } HB_STMT_END; - if (FAILED (hr)) { + if (FAILED (hr)) FAIL ("Failed to load font file from data!"); - return false; - } BOOL isSupported; DWRITE_FONT_FILE_TYPE fileType; DWRITE_FONT_FACE_TYPE faceType; - UINT32 numberOfFaces; + uint32_t numberOfFaces; hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces); - if (FAILED (hr) || !isSupported) { + if (FAILED (hr) || !isSupported) FAIL ("Font file is not supported."); - return false; - } #undef FAIL @@ -199,13 +207,14 @@ _hb_directwrite_shaper_face_data_create(hb_face_t *face) } void -_hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data) +_hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *data) { if (data->fontFace) data->fontFace->Release (); if (data->fontFile) data->fontFile->Release (); - if (data->dwriteFactory) { + if (data->dwriteFactory) + { if (data->fontFileLoader) data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader); data->dwriteFactory->Release (); @@ -217,7 +226,7 @@ _hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data if (data->faceBlob) hb_blob_destroy (data->faceBlob); if (data) - free (data); + delete data; } @@ -225,7 +234,8 @@ _hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data * shaper font data */ -struct hb_directwrite_shaper_font_data_t { +struct hb_directwrite_shaper_font_data_t +{ }; hb_directwrite_shaper_font_data_t * @@ -233,8 +243,7 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font) { if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr; - hb_directwrite_shaper_font_data_t *data = - (hb_directwrite_shaper_font_data_t *) malloc (sizeof (hb_directwrite_shaper_font_data_t)); + hb_directwrite_shaper_font_data_t *data = new hb_directwrite_shaper_font_data_t; if (unlikely (!data)) return nullptr; @@ -244,7 +253,7 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font) void _hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data) { - free (data); + delete data; } @@ -276,54 +285,57 @@ class TextAnalysis { public: - IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; } - IFACEMETHOD_(ULONG, AddRef)() { return 1; } - IFACEMETHOD_(ULONG, Release)() { return 1; } + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () { return 1; } + IFACEMETHOD_ (ULONG, Release) () { return 1; } - // A single contiguous run of characters containing the same analysis + // A single contiguous run of characters containing the same analysis // results. struct Run { uint32_t mTextStart; // starting text position of this run uint32_t mTextLength; // number of contiguous code units covered uint32_t mGlyphStart; // starting glyph in the glyphs array - uint32_t mGlyphCount; // number of glyphs associated with this run of + uint32_t mGlyphCount; // number of glyphs associated with this run // text DWRITE_SCRIPT_ANALYSIS mScript; uint8_t mBidiLevel; bool mIsSideways; - inline bool ContainsTextPosition(uint32_t aTextPosition) const + inline bool ContainsTextPosition (uint32_t aTextPosition) const { - return aTextPosition >= mTextStart - && aTextPosition < mTextStart + mTextLength; + return aTextPosition >= mTextStart && + aTextPosition < mTextStart + mTextLength; } Run *nextRun; }; public: - TextAnalysis(const wchar_t* text, + TextAnalysis (const wchar_t* text, uint32_t textLength, const wchar_t* localeName, DWRITE_READING_DIRECTION readingDirection) - : mText(text) - , mTextLength(textLength) - , mLocaleName(localeName) - , mReadingDirection(readingDirection) - , mCurrentRun(nullptr) { }; + : mText (text) + , mTextLength (textLength) + , mLocaleName (localeName) + , mReadingDirection (readingDirection) + , mCurrentRun (nullptr) { }; - ~TextAnalysis() { + ~TextAnalysis () + { // delete runs, except mRunHead which is part of the TextAnalysis object - for (Run *run = mRunHead.nextRun; run;) { + for (Run *run = mRunHead.nextRun; run;) + { Run *origRun = run; run = run->nextRun; - free (origRun); + delete origRun; } } - STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer, - Run **runHead) { + STDMETHODIMP GenerateResults (IDWriteTextAnalyzer* textAnalyzer, + Run **runHead) + { // Analyzes the text using the script analyzer and returns // the result as a series of runs. @@ -339,52 +351,55 @@ public: mCurrentRun = &mRunHead; // Call each of the analyzers in sequence, recording their results. - if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) { + if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) *runHead = &mRunHead; - } return hr; } // IDWriteTextAnalysisSource implementation - IFACEMETHODIMP GetTextAtPosition(uint32_t textPosition, + IFACEMETHODIMP GetTextAtPosition (uint32_t textPosition, OUT wchar_t const** textString, OUT uint32_t* textLength) { - if (textPosition >= mTextLength) { + if (textPosition >= mTextLength) + { // No text at this position, valid query though. *textString = nullptr; *textLength = 0; } - else { + else + { *textString = mText + textPosition; *textLength = mTextLength - textPosition; } return S_OK; } - IFACEMETHODIMP GetTextBeforePosition(uint32_t textPosition, + IFACEMETHODIMP GetTextBeforePosition (uint32_t textPosition, OUT wchar_t const** textString, OUT uint32_t* textLength) { - if (textPosition == 0 || textPosition > mTextLength) { + if (textPosition == 0 || textPosition > mTextLength) + { // Either there is no text before here (== 0), or this // is an invalid position. The query is considered valid though. *textString = nullptr; *textLength = 0; } - else { + else + { *textString = mText; *textLength = textPosition; } return S_OK; } - IFACEMETHODIMP_(DWRITE_READING_DIRECTION) - GetParagraphReadingDirection() { return mReadingDirection; } + IFACEMETHODIMP_ (DWRITE_READING_DIRECTION) + GetParagraphReadingDirection () { return mReadingDirection; } - IFACEMETHODIMP GetLocaleName(uint32_t textPosition, + IFACEMETHODIMP GetLocaleName (uint32_t textPosition, uint32_t* textLength, wchar_t const** localeName) { @@ -392,7 +407,7 @@ public: } IFACEMETHODIMP - GetNumberSubstitution(uint32_t textPosition, + GetNumberSubstitution (uint32_t textPosition, OUT uint32_t* textLength, OUT IDWriteNumberSubstitution** numberSubstitution) { @@ -406,15 +421,15 @@ public: // IDWriteTextAnalysisSink implementation IFACEMETHODIMP - SetScriptAnalysis(uint32_t textPosition, + SetScriptAnalysis (uint32_t textPosition, uint32_t textLength, DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) { - SetCurrentRun(textPosition); - SplitCurrentRun(textPosition); + SetCurrentRun (textPosition); + SplitCurrentRun (textPosition); while (textLength > 0) { - Run *run = FetchNextRun(&textLength); + Run *run = FetchNextRun (&textLength); run->mScript = *scriptAnalysis; } @@ -422,22 +437,22 @@ public: } IFACEMETHODIMP - SetLineBreakpoints(uint32_t textPosition, + SetLineBreakpoints (uint32_t textPosition, uint32_t textLength, const DWRITE_LINE_BREAKPOINT* lineBreakpoints) { return S_OK; } - IFACEMETHODIMP SetBidiLevel(uint32_t textPosition, + IFACEMETHODIMP SetBidiLevel (uint32_t textPosition, uint32_t textLength, uint8_t explicitLevel, uint8_t resolvedLevel) { return S_OK; } IFACEMETHODIMP - SetNumberSubstitution(uint32_t textPosition, + SetNumberSubstitution (uint32_t textPosition, uint32_t textLength, IDWriteNumberSubstitution* numberSubstitution) { return S_OK; } protected: - Run *FetchNextRun(IN OUT uint32_t* textLength) + Run *FetchNextRun (IN OUT uint32_t* textLength) { // Used by the sink setters, this returns a reference to the next run. // Position and length are adjusted to now point after the current run @@ -447,21 +462,17 @@ protected: // Split the tail if needed (the length remaining is less than the // current run's size). if (*textLength < mCurrentRun->mTextLength) - { SplitCurrentRun (mCurrentRun->mTextStart + *textLength); - } else - { // Just advance the current run. mCurrentRun = mCurrentRun->nextRun; - } *textLength -= origRun->mTextLength; // Return a reference to the run that was just current. return origRun; } - void SetCurrentRun(uint32_t textPosition) + void SetCurrentRun (uint32_t textPosition) { // Move the current run to the given position. // Since the analyzers generally return results in a forward manner, @@ -469,26 +480,22 @@ protected: // corresponding run for the text position. if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition)) - { return; - } - for (Run *run = &mRunHead; run; run = run->nextRun) { + for (Run *run = &mRunHead; run; run = run->nextRun) if (run->ContainsTextPosition (textPosition)) { - mCurrentRun = run; - return; + mCurrentRun = run; + return; } - } - //NS_NOTREACHED("We should always be able to find the text position in one \ - // of our runs"); + assert (0); // We should always be able to find the text position in one of our runs } - void SplitCurrentRun(uint32_t splitPosition) + void SplitCurrentRun (uint32_t splitPosition) { if (!mCurrentRun) { - //NS_ASSERTION(false, "SplitCurrentRun called without current run."); + assert (0); // SplitCurrentRun called without current run // Shouldn't be calling this when no current run is set! return; } @@ -499,7 +506,7 @@ protected: // or before it. Usually the first. return; } - Run *newRun = (Run*) malloc (sizeof (Run)); + Run *newRun = new Run; *newRun = *mCurrentRun; @@ -534,14 +541,14 @@ protected: static inline uint16_t hb_uint16_swap (const uint16_t v) { return (v >> 8) | (v << 8); } static inline uint32_t hb_uint32_swap (const uint32_t v) -{ return (hb_uint16_swap(v) << 16) | hb_uint16_swap(v >> 16); } +{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } /* * shaper */ static hb_bool_t -_hb_directwrite_shape_full(hb_shape_plan_t *shape_plan, +_hb_directwrite_shape_full (hb_shape_plan_t *shape_plan, hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, @@ -555,7 +562,7 @@ _hb_directwrite_shape_full(hb_shape_plan_t *shape_plan, IDWriteFontFace *fontFace = face_data->fontFace; IDWriteTextAnalyzer* analyzer; - dwriteFactory->CreateTextAnalyzer(&analyzer); + dwriteFactory->CreateTextAnalyzer (&analyzer); unsigned int scratch_size; hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); @@ -570,41 +577,39 @@ _hb_directwrite_shape_full(hb_shape_plan_t *shape_plan, #define utf16_index() var1.u32 - ALLOCATE_ARRAY(wchar_t, textString, buffer->len * 2); + ALLOCATE_ARRAY (wchar_t, textString, buffer->len * 2); unsigned int chars_len = 0; for (unsigned int i = 0; i < buffer->len; i++) { hb_codepoint_t c = buffer->info[i].codepoint; - buffer->info[i].utf16_index() = chars_len; - if (likely(c <= 0xFFFFu)) + buffer->info[i].utf16_index () = chars_len; + if (likely (c <= 0xFFFFu)) textString[chars_len++] = c; - else if (unlikely(c > 0x10FFFFu)) + else if (unlikely (c > 0x10FFFFu)) textString[chars_len++] = 0xFFFDu; - else { + else + { textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); } } - ALLOCATE_ARRAY(WORD, log_clusters, chars_len); - // if (num_features) + ALLOCATE_ARRAY (WORD, log_clusters, chars_len); + /* Need log_clusters to assign features. */ + chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) { - /* 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. */ - } + hb_codepoint_t c = buffer->info[i].codepoint; + unsigned int cluster = buffer->info[i].cluster; + log_clusters[chars_len++] = cluster; + if (hb_in_range (c, 0x10000u, 0x10FFFFu)) + log_clusters[chars_len++] = cluster; /* Surrogates. */ } // TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES - DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ? + DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; @@ -615,10 +620,10 @@ _hb_directwrite_shape_full(hb_shape_plan_t *shape_plan, */ uint32_t textLength = buffer->len; - TextAnalysis analysis(textString, textLength, nullptr, readingDirection); + TextAnalysis analysis (textString, textLength, nullptr, readingDirection); TextAnalysis::Run *runHead; HRESULT hr; - hr = analysis.GenerateResults(analyzer, &runHead); + hr = analysis.GenerateResults (analyzer, &runHead); #define FAIL(...) \ HB_STMT_START { \ @@ -627,10 +632,7 @@ _hb_directwrite_shape_full(hb_shape_plan_t *shape_plan, } HB_STMT_END; if (FAILED (hr)) - { FAIL ("Analyzer failed to generate results."); - return false; - } uint32_t maxGlyphCount = 3 * textLength / 2 + 16; uint32_t glyphCount; @@ -643,31 +645,31 @@ _hb_directwrite_shape_full(hb_shape_plan_t *shape_plan, hb_language_to_string (buffer->props.language), 20); } - DWRITE_TYPOGRAPHIC_FEATURES singleFeatures; - singleFeatures.featureCount = num_features; + // TODO: it does work but doesn't care about ranges + DWRITE_TYPOGRAPHIC_FEATURES typographic_features; + typographic_features.featureCount = num_features; if (num_features) { - DWRITE_FONT_FEATURE* dwfeatureArray = (DWRITE_FONT_FEATURE*) - malloc (sizeof (DWRITE_FONT_FEATURE) * num_features); + typographic_features.features = new DWRITE_FONT_FEATURE[num_features]; for (unsigned int i = 0; i < num_features; ++i) { - dwfeatureArray[i].nameTag = (DWRITE_FONT_FEATURE_TAG) - hb_uint32_swap (features[i].tag); - dwfeatureArray[i].parameter = features[i].value; + typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG) + hb_uint32_swap (features[i].tag); + typographic_features.features[i].parameter = features[i].value; } - singleFeatures.features = dwfeatureArray; } const DWRITE_TYPOGRAPHIC_FEATURES* dwFeatures = - (const DWRITE_TYPOGRAPHIC_FEATURES*) &singleFeatures; + (const DWRITE_TYPOGRAPHIC_FEATURES*) &typographic_features; const uint32_t featureRangeLengths[] = { textLength }; + // - uint16_t* clusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t)); - DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*) - malloc (textLength * sizeof (DWRITE_SHAPING_TEXT_PROPERTIES)); + uint16_t* clusterMap = new uint16_t[textLength]; + DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = + new DWRITE_SHAPING_TEXT_PROPERTIES[textLength]; retry_getglyphs: - uint16_t* glyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t)); - DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*) - malloc (maxGlyphCount * sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES)); + uint16_t* glyphIndices = new uint16_t[maxGlyphCount]; + DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = + new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount]; hr = analyzer->GetGlyphs (textString, textLength, fontFace, false, isRightToLeft, &runHead->mScript, localeName, nullptr, &dwFeatures, @@ -676,36 +678,32 @@ retry_getglyphs: if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))) { - free (glyphIndices); - free (glyphProperties); + delete [] glyphIndices; + delete [] glyphProperties; maxGlyphCount *= 2; goto retry_getglyphs; } if (FAILED (hr)) - { FAIL ("Analyzer failed to get glyphs."); - return false; - } - float* glyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float)); - DWRITE_GLYPH_OFFSET* glyphOffsets = (DWRITE_GLYPH_OFFSET*) - malloc(maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET)); + float* glyphAdvances = new float[maxGlyphCount]; + DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount]; /* The -2 in the following is to compensate for possible - * alignment needed after the WORD array. sizeof(WORD) == 2. */ - unsigned int glyphs_size = (scratch_size * sizeof(int) - 2) - / (sizeof(WORD) + - sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES) + - sizeof(int) + - sizeof(DWRITE_GLYPH_OFFSET) + - sizeof(uint32_t)); + * alignment needed after the WORD array. sizeof (WORD) == 2. */ + unsigned int glyphs_size = (scratch_size * sizeof (int) - 2) + / (sizeof (WORD) + + sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) + + sizeof (int) + + sizeof (DWRITE_GLYPH_OFFSET) + + sizeof (uint32_t)); ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); #undef ALLOCATE_ARRAY - int fontEmSize = font->face->get_upem(); + int fontEmSize = font->face->get_upem (); if (fontEmSize < 0) fontEmSize = -fontEmSize; @@ -722,10 +720,7 @@ retry_getglyphs: glyphAdvances, glyphOffsets); if (FAILED (hr)) - { FAIL ("Analyzer failed to get glyph placements."); - return false; - } IDWriteTextAnalyzer1* analyzer1; analyzer->QueryInterface (&analyzer1); @@ -734,77 +729,62 @@ retry_getglyphs: { DWRITE_JUSTIFICATION_OPPORTUNITY* justificationOpportunities = - (DWRITE_JUSTIFICATION_OPPORTUNITY*) - malloc (maxGlyphCount * sizeof (DWRITE_JUSTIFICATION_OPPORTUNITY)); + new DWRITE_JUSTIFICATION_OPPORTUNITY[maxGlyphCount]; hr = analyzer1->GetJustificationOpportunities (fontFace, fontEmSize, runHead->mScript, textLength, glyphCount, textString, clusterMap, glyphProperties, justificationOpportunities); if (FAILED (hr)) - { FAIL ("Analyzer failed to get justification opportunities."); - return false; - } - float* justifiedGlyphAdvances = - (float*) malloc (maxGlyphCount * sizeof (float)); - DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*) - malloc (glyphCount * sizeof (DWRITE_GLYPH_OFFSET)); + float* justifiedGlyphAdvances = new float[maxGlyphCount]; + DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = new DWRITE_GLYPH_OFFSET[glyphCount]; hr = analyzer1->JustifyGlyphAdvances (lineWidth, glyphCount, justificationOpportunities, glyphAdvances, glyphOffsets, justifiedGlyphAdvances, justifiedGlyphOffsets); if (FAILED (hr)) - { - FAIL("Analyzer failed to get justified glyph advances."); - return false; - } + FAIL ("Analyzer failed to get justified glyph advances."); DWRITE_SCRIPT_PROPERTIES scriptProperties; hr = analyzer1->GetScriptProperties (runHead->mScript, &scriptProperties); if (FAILED (hr)) - { - FAIL("Analyzer failed to get script properties."); - return false; - } + FAIL ("Analyzer failed to get script properties."); uint32_t justificationCharacter = scriptProperties.justificationCharacter; // if a script justificationCharacter is not space, it can have GetJustifiedGlyphs if (justificationCharacter != 32) { - uint16_t* modifiedClusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t)); + uint16_t* modifiedClusterMap = new uint16_t[textLength]; retry_getjustifiedglyphs: - uint16_t* modifiedGlyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t)); - float* modifiedGlyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float)); - DWRITE_GLYPH_OFFSET* modifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*) - malloc (maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET)); + uint16_t* modifiedGlyphIndices = new uint16_t[maxGlyphCount]; + float* modifiedGlyphAdvances = new float[maxGlyphCount]; + DWRITE_GLYPH_OFFSET* modifiedGlyphOffsets = + new DWRITE_GLYPH_OFFSET[maxGlyphCount]; uint32_t actualGlyphsCount; hr = analyzer1->GetJustifiedGlyphs (fontFace, fontEmSize, runHead->mScript, - textLength, glyphCount, maxGlyphCount, clusterMap, glyphIndices, - glyphAdvances, justifiedGlyphAdvances, justifiedGlyphOffsets, - glyphProperties, &actualGlyphsCount, modifiedClusterMap, modifiedGlyphIndices, - modifiedGlyphAdvances, modifiedGlyphOffsets); + textLength, glyphCount, maxGlyphCount, clusterMap, glyphIndices, + glyphAdvances, justifiedGlyphAdvances, justifiedGlyphOffsets, + glyphProperties, &actualGlyphsCount, modifiedClusterMap, modifiedGlyphIndices, + modifiedGlyphAdvances, modifiedGlyphOffsets); if (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)) { - maxGlyphCount = actualGlyphsCount; - free (modifiedGlyphIndices); - free (modifiedGlyphAdvances); - free (modifiedGlyphOffsets); + maxGlyphCount = actualGlyphsCount; + delete [] modifiedGlyphIndices; + delete [] modifiedGlyphAdvances; + delete [] modifiedGlyphOffsets; - maxGlyphCount = actualGlyphsCount; + maxGlyphCount = actualGlyphsCount; - goto retry_getjustifiedglyphs; + goto retry_getjustifiedglyphs; } if (FAILED (hr)) - { - FAIL ("Analyzer failed to get justified glyphs."); - return false; - } + FAIL ("Analyzer failed to get justified glyphs."); - free (clusterMap); - free (glyphIndices); - free (glyphAdvances); - free (glyphOffsets); + delete [] clusterMap; + delete [] glyphIndices; + delete [] glyphAdvances; + delete [] glyphOffsets; glyphCount = actualGlyphsCount; clusterMap = modifiedClusterMap; @@ -812,19 +792,19 @@ retry_getglyphs: glyphAdvances = modifiedGlyphAdvances; glyphOffsets = modifiedGlyphOffsets; - free (justifiedGlyphAdvances); - free (justifiedGlyphOffsets); + delete [] justifiedGlyphAdvances; + delete [] justifiedGlyphOffsets; } else { - free (glyphAdvances); - free (glyphOffsets); + delete [] glyphAdvances; + delete [] glyphOffsets; glyphAdvances = justifiedGlyphAdvances; glyphOffsets = justifiedGlyphOffsets; } - free (justificationOpportunities); + delete [] justificationOpportunities; } @@ -837,7 +817,7 @@ retry_getglyphs: for (unsigned int i = 0; i < buffer->len; i++) { uint32_t *p = - &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; + &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]]; *p = MIN (*p, buffer->info[i].cluster); } for (unsigned int i = 1; i < glyphCount; i++) @@ -883,28 +863,28 @@ retry_getglyphs: if (isRightToLeft) hb_buffer_reverse (buffer); - free (clusterMap); - free (glyphIndices); - free (textProperties); - free (glyphProperties); - free (glyphAdvances); - free (glyphOffsets); + delete [] clusterMap; + delete [] glyphIndices; + delete [] textProperties; + delete [] glyphProperties; + delete [] glyphAdvances; + delete [] glyphOffsets; if (num_features) - free (singleFeatures.features); + delete [] typographic_features.features; /* Wow, done! */ return true; } hb_bool_t -_hb_directwrite_shape(hb_shape_plan_t *shape_plan, +_hb_directwrite_shape (hb_shape_plan_t *shape_plan, hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features) { - return _hb_directwrite_shape_full(shape_plan, font, buffer, + return _hb_directwrite_shape_full (shape_plan, font, buffer, features, num_features, 0); } @@ -913,13 +893,13 @@ _hb_directwrite_shape(hb_shape_plan_t *shape_plan, */ hb_bool_t -hb_directwrite_shape_experimental_width(hb_font_t *font, +hb_directwrite_shape_experimental_width (hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features, float width) { - static char *shapers = "directwrite"; + static const char *shapers = "directwrite"; hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, &shapers); hb_bool_t res = _hb_directwrite_shape_full (shape_plan, font, buffer, diff --git a/src/hb-directwrite.h b/src/hb-directwrite.h index e743af2..9bfd1f7 100644 --- a/src/hb-directwrite.h +++ b/src/hb-directwrite.h @@ -30,8 +30,9 @@ HB_BEGIN_DECLS HB_EXTERN hb_bool_t -hb_directwrite_shape_experimental_width(hb_font_t *font, hb_buffer_t *buffer, - const hb_feature_t *features, unsigned int num_features, float width); +hb_directwrite_shape_experimental_width (hb_font_t *font, hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features, float width); HB_END_DECLS diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index e413847..9586871 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -49,7 +49,7 @@ hb_bsearch_r (const void *key, const void *base, else return (void *) p; } - return NULL; + return nullptr; } diff --git a/src/hb-face.cc b/src/hb-face.cc index d8af8c1..2fef09d 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -29,11 +29,35 @@ #include "hb-private.hh" #include "hb-face-private.hh" +#include "hb-blob-private.hh" #include "hb-open-file-private.hh" #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" + +/** + * hb_face_count: Get number of faces on the blob + * @blob: + * + * + * + * Return value: Number of faces on the blob + * + * Since: 1.7.7 + **/ +unsigned int +hb_face_count (hb_blob_t *blob) +{ + if (unlikely (!blob)) + return 0; + + hb_blob_t *sanitized = OT::Sanitizer<OT::OpenTypeFontFile> ().sanitize (blob); + const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> (); + + return ot.get_face_count (); +} + /* * hb_face_t */ @@ -64,10 +88,10 @@ const hb_face_t _hb_face_nil = { /** * hb_face_create_for_tables: * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @user_data: + * @destroy: + * * - * * * Return value: (transfer full) * @@ -134,7 +158,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void 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::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> (); const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); @@ -146,10 +170,10 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void /** * hb_face_create: (Xconstructor) - * @blob: - * @index: + * @blob: + * @index: + * * - * * * Return value: (transfer full): * @@ -181,7 +205,7 @@ hb_face_create (hb_blob_t *blob, /** * hb_face_get_empty: * - * + * * * Return value: (transfer full) * @@ -198,9 +222,9 @@ hb_face_get_empty (void) * hb_face_reference: (skip) * @face: a face. * - * * - * Return value: + * + * Return value: * * Since: 0.9.2 **/ @@ -214,7 +238,7 @@ hb_face_reference (hb_face_t *face) * hb_face_destroy: (skip) * @face: a face. * - * + * * * Since: 0.9.2 **/ @@ -244,14 +268,14 @@ hb_face_destroy (hb_face_t *face) /** * hb_face_set_user_data: (skip) * @face: a face. - * @key: - * @data: - * @destroy: - * @replace: + * @key: + * @data: + * @destroy: + * @replace: * - * * - * Return value: + * + * Return value: * * Since: 0.9.2 **/ @@ -268,9 +292,9 @@ hb_face_set_user_data (hb_face_t *face, /** * hb_face_get_user_data: (skip) * @face: a face. - * @key: + * @key: + * * - * * * Return value: (transfer none): * @@ -287,7 +311,7 @@ hb_face_get_user_data (hb_face_t *face, * hb_face_make_immutable: * @face: a face. * - * + * * * Since: 0.9.2 **/ @@ -304,9 +328,9 @@ hb_face_make_immutable (hb_face_t *face) * hb_face_is_immutable: * @face: a face. * - * * - * Return value: + * + * Return value: * * Since: 0.9.2 **/ @@ -320,9 +344,9 @@ hb_face_is_immutable (hb_face_t *face) /** * hb_face_reference_table: * @face: a face. - * @tag: + * @tag: + * * - * * * Return value: (transfer full): * @@ -339,7 +363,7 @@ hb_face_reference_table (hb_face_t *face, * hb_face_reference_blob: * @face: a face. * - * + * * * Return value: (transfer full): * @@ -354,9 +378,9 @@ hb_face_reference_blob (hb_face_t *face) /** * hb_face_set_index: * @face: a face. - * @index: + * @index: + * * - * * * Since: 0.9.2 **/ @@ -374,9 +398,9 @@ hb_face_set_index (hb_face_t *face, * hb_face_get_index: * @face: a face. * - * * - * Return value: + * + * Return value: * * Since: 0.9.2 **/ @@ -389,9 +413,9 @@ hb_face_get_index (hb_face_t *face) /** * hb_face_set_upem: * @face: a face. - * @upem: + * @upem: + * * - * * * Since: 0.9.2 **/ @@ -409,9 +433,9 @@ hb_face_set_upem (hb_face_t *face, * hb_face_get_upem: * @face: a face. * - * * - * Return value: + * + * Return value: * * Since: 0.9.2 **/ @@ -425,7 +449,7 @@ 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); + const OT::head *head_table = head_blob->as<OT::head> (); upem = head_table->get_upem (); hb_blob_destroy (head_blob); } @@ -433,9 +457,9 @@ hb_face_t::load_upem (void) const /** * hb_face_set_glyph_count: * @face: a face. - * @glyph_count: + * @glyph_count: + * * - * * * Since: 0.9.7 **/ @@ -453,9 +477,9 @@ hb_face_set_glyph_count (hb_face_t *face, * hb_face_get_glyph_count: * @face: a face. * - * * - * Return value: + * + * Return value: * * Since: 0.9.7 **/ @@ -469,7 +493,7 @@ 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); + const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> (); num_glyphs = maxp_table->get_num_glyphs (); hb_blob_destroy (maxp_blob); } @@ -490,7 +514,7 @@ hb_face_get_table_tags (hb_face_t *face, unsigned int *table_count, /* IN/OUT */ hb_tag_t *table_tags /* OUT */) { - if (face->destroy != _hb_face_for_data_closure_destroy) + if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy) { if (table_count) *table_count = 0; @@ -499,7 +523,7 @@ hb_face_get_table_tags (hb_face_t *face, hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data; - const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob); + const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> (); const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); return ot_face.get_table_tags (start_offset, table_count, table_tags); diff --git a/src/hb-face.h b/src/hb-face.h index 0ce8d04..983ee56 100644 --- a/src/hb-face.h +++ b/src/hb-face.h @@ -37,6 +37,10 @@ HB_BEGIN_DECLS +HB_EXTERN unsigned int +hb_face_count (hb_blob_t *blob); + + /* * hb_face_t */ diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 992152f..7ba16cd 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh @@ -83,7 +83,11 @@ struct hb_font_funcs_t { HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } f; - void (*array[VAR]) (void); + void (*array[0 +#define HB_FONT_FUNC_IMPLEMENT(name) +1 + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + ]) (void); } get; }; diff --git a/src/hb-font.cc b/src/hb-font.cc index f3534b6..4d62b9e 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -127,7 +127,7 @@ hb_font_get_variation_glyph_parent (hb_font_t *font, static hb_position_t -hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED, +hb_font_get_glyph_h_advance_nil (hb_font_t *font, void *font_data HB_UNUSED, hb_codepoint_t glyph, void *user_data HB_UNUSED) @@ -144,7 +144,7 @@ hb_font_get_glyph_h_advance_parent (hb_font_t *font, } static hb_position_t -hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED, +hb_font_get_glyph_v_advance_nil (hb_font_t *font, void *font_data HB_UNUSED, hb_codepoint_t glyph, void *user_data HB_UNUSED) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index fc4b112..7caafba 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -109,7 +109,7 @@ _hb_ft_font_destroy (void *data) * @font: * @load_flags: * - * + * * * Since: 1.0.5 **/ @@ -119,7 +119,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) if (font->immutable) return; - if (font->destroy != _hb_ft_font_destroy) + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) return; hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; @@ -131,7 +131,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) * hb_ft_font_get_load_flags: * @font: * - * + * * * Return value: * Since: 1.0.5 @@ -139,7 +139,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) int hb_ft_font_get_load_flags (hb_font_t *font) { - if (font->destroy != _hb_ft_font_destroy) + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) return 0; const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; @@ -150,7 +150,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) FT_Face hb_ft_font_get_face (hb_font_t *font) { - if (font->destroy != _hb_ft_font_destroy) + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) return nullptr; const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; @@ -177,7 +177,7 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, /* For symbol-encoded OpenType fonts, we duplicate the * U+F000..F0FF range at U+0000..U+00FF. That's what * Windows seems to do, and that's hinted about at: - * http://www.microsoft.com/typography/otspec/recom.htm + * https://docs.microsoft.com/en-us/typography/opentype/spec/recom * under "Non-Standard (Symbol) Fonts". */ g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode); if (!g) @@ -210,7 +210,7 @@ hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, } static hb_position_t -hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED, +hb_ft_get_glyph_h_advance (hb_font_t *font, void *font_data, hb_codepoint_t glyph, void *user_data HB_UNUSED) @@ -228,7 +228,7 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED, } static hb_position_t -hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED, +hb_ft_get_glyph_v_advance (hb_font_t *font, void *font_data, hb_codepoint_t glyph, void *user_data HB_UNUSED) @@ -248,7 +248,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED, } static hb_bool_t -hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED, +hb_ft_get_glyph_v_origin (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_position_t *x, @@ -292,7 +292,7 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font, } static hb_bool_t -hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED, +hb_ft_get_glyph_extents (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_glyph_extents_t *extents, @@ -423,7 +423,12 @@ static hb_font_funcs_t *static_ft_funcs = nullptr; static void free_static_ft_funcs (void) { - hb_font_funcs_destroy (static_ft_funcs); +retry: + hb_font_funcs_t *ft_funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ft_funcs); + if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, ft_funcs, nullptr)) + goto retry; + + hb_font_funcs_destroy (ft_funcs); } #endif @@ -502,12 +507,12 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) /** * hb_ft_face_create: - * @ft_face: (destroy destroy) (scope notified): + * @ft_face: (destroy destroy) (scope notified): * @destroy: * - * * - * Return value: (transfer full): + * + * Return value: (transfer full): * Since: 0.9.2 **/ hb_face_t * @@ -539,9 +544,9 @@ hb_ft_face_create (FT_Face ft_face, * hb_ft_face_create_referenced: * @ft_face: * - * * - * Return value: (transfer full): + * + * Return value: (transfer full): * Since: 0.9.38 **/ hb_face_t * @@ -559,11 +564,11 @@ hb_ft_face_finalize (FT_Face ft_face) /** * hb_ft_face_create_cached: - * @ft_face: + * @ft_face: * - * * - * Return value: (transfer full): + * + * Return value: (transfer full): * Since: 0.9.2 **/ hb_face_t * @@ -584,12 +589,12 @@ hb_ft_face_create_cached (FT_Face ft_face) /** * hb_ft_font_create: - * @ft_face: (destroy destroy) (scope notified): + * @ft_face: (destroy destroy) (scope notified): * @destroy: * - * * - * Return value: (transfer full): + * + * Return value: (transfer full): * Since: 0.9.2 **/ hb_font_t * @@ -610,7 +615,7 @@ hb_ft_font_create (FT_Face ft_face, void hb_ft_font_changed (hb_font_t *font) { - if (font->destroy != _hb_ft_font_destroy) + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) return; hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; @@ -664,9 +669,9 @@ hb_ft_font_changed (hb_font_t *font) * hb_ft_font_create_referenced: * @ft_face: * - * * - * Return value: (transfer full): + * + * Return value: (transfer full): * Since: 0.9.38 **/ hb_font_t * @@ -685,7 +690,12 @@ static FT_Library ft_library; static void free_ft_library (void) { - FT_Done_FreeType (ft_library); +retry: + FT_Library library = (FT_Library) hb_atomic_ptr_get (&ft_library); + if (!hb_atomic_ptr_cmpexch (&ft_library, library, nullptr)) + goto retry; + + FT_Done_FreeType (library); } #endif diff --git a/src/hb-glib.cc b/src/hb-glib.cc index 50c30e9..246380a 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -370,7 +370,12 @@ static hb_unicode_funcs_t *static_glib_funcs = nullptr; static void free_static_glib_funcs (void) { - hb_unicode_funcs_destroy (static_glib_funcs); +retry: + hb_unicode_funcs_t *glib_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_glib_funcs); + if (!hb_atomic_ptr_cmpexch (&static_glib_funcs, glib_funcs, nullptr)) + goto retry; + + hb_unicode_funcs_destroy (glib_funcs); } #endif diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index 46fe139..c20f6be 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -79,10 +79,12 @@ static const void *hb_graphite2_get_table (const void *data, unsigned int tag, s p->blob = blob; p->tag = tag; - /* TODO Not thread-safe, but fairly harmless. - * We can do the double-checked pointer cmpexch thing here. */ - p->next = face_data->tlist; - face_data->tlist = p; +retry: + hb_graphite2_tablelist_t *tlist = (hb_graphite2_tablelist_t *) hb_atomic_ptr_get (&face_data->tlist); + p->next = tlist; + + if (!hb_atomic_ptr_cmpexch (&face_data->tlist, tlist, p)) + goto retry; } unsigned int tlen; @@ -381,11 +383,11 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, pPos->x_offset = gr_slot_origin_X (is) * xscale - curradvx; pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy; if (info->cluster != currclus) { - pPos->x_advance = info->var1.i32 * xscale; - curradvx += pPos->x_advance; - currclus = info->cluster; + pPos->x_advance = info->var1.i32 * xscale; + curradvx += pPos->x_advance; + currclus = info->cluster; } else - pPos->x_advance = 0.; + pPos->x_advance = 0.; pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale; curradvy += pPos->y_advance; @@ -398,11 +400,11 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, { if (info->cluster != currclus) { - pPos->x_advance = info->var1.i32 * xscale; - curradvx -= pPos->x_advance; - currclus = info->cluster; + pPos->x_advance = info->var1.i32 * xscale; + curradvx -= pPos->x_advance; + currclus = info->cluster; } else - pPos->x_advance = 0.; + pPos->x_advance = 0.; pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale; curradvy -= pPos->y_advance; diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h index 82b1e64..05c55de 100644 --- a/src/hb-graphite2.h +++ b/src/hb-graphite2.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2011 Martin Hosken - * Copyright (C) 2011 SIL International + * Copyright © 2011 Martin Hosken + * Copyright © 2011 SIL International * * This is part of HarfBuzz, a text shaping library. * diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 552eaec..c52e165 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -351,7 +351,12 @@ static hb_unicode_funcs_t *static_icu_funcs = nullptr; static void free_static_icu_funcs (void) { - hb_unicode_funcs_destroy (static_icu_funcs); +retry: + hb_unicode_funcs_t *icu_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_icu_funcs); + if (!hb_atomic_ptr_cmpexch (&static_icu_funcs, icu_funcs, nullptr)) + goto retry; + + hb_unicode_funcs_destroy (icu_funcs); } #endif diff --git a/src/hb-map-private.hh b/src/hb-map-private.hh new file mode 100644 index 0000000..d3d4dde --- /dev/null +++ b/src/hb-map-private.hh @@ -0,0 +1,255 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_MAP_PRIVATE_HH +#define HB_MAP_PRIVATE_HH + +#include "hb-private.hh" +#include "hb-object-private.hh" + + +template <typename T> +inline uint32_t Hash (const T &v) +{ + /* Knuth's multiplicative method: */ + return (uint32_t) v * 2654435761u; +} + + +/* + * hb_map_t + */ + +struct hb_map_t +{ + struct item_t + { + hb_codepoint_t key; + hb_codepoint_t value; + + inline bool is_unused (void) const { return key == INVALID; } + inline bool is_tombstone (void) const { return key != INVALID && value == INVALID; } + }; + + hb_object_header_t header; + bool successful; /* Allocations successful */ + unsigned int population; /* Not including tombstones. */ + unsigned int occupancy; /* Including tombstones. */ + unsigned int mask; + unsigned int prime; + item_t *items; + + inline void init_shallow (void) + { + successful = true; + population = occupancy = 0; + mask = 0; + prime = 0; + items = nullptr; + } + inline void init (void) + { + hb_object_init (this); + init_shallow (); + } + inline void fini_shallow (void) + { + free (items); + } + inline void fini (void) + { + hb_object_fini (this); + fini_shallow (); + } + + inline bool resize (void) + { + if (unlikely (!successful)) return false; + + unsigned int power = _hb_bit_storage (population * 2 + 8); + unsigned int new_size = 1u << power; + item_t *new_items = (item_t *) malloc ((size_t) new_size * sizeof (item_t)); + if (unlikely (!new_items)) + { + successful = false; + return false; + } + memset (new_items, 0xFF, (size_t) new_size * sizeof (item_t)); + + unsigned int old_size = mask + 1; + item_t *old_items = items; + + /* Switch to new, empty, array. */ + population = occupancy = 0; + mask = new_size - 1; + prime = prime_for (power); + items = new_items; + + /* Insert back old items. */ + if (old_items) + for (unsigned int i = 0; i < old_size; i++) + if (old_items[i].key != INVALID && old_items[i].value != INVALID) + set (old_items[i].key, old_items[i].value); + + free (old_items); + + return true; + } + + inline void set (hb_codepoint_t key, hb_codepoint_t value) + { + if (unlikely (!successful)) return; + if (unlikely (key == INVALID)) return; + if ((occupancy + occupancy / 2) >= mask && !resize ()) return; + unsigned int i = bucket_for (key); + + if (value == INVALID && items[i].key != key) + return; /* Trying to delete non-existent key. */ + + if (!items[i].is_unused ()) + { + occupancy--; + if (items[i].is_tombstone ()) + population--; + } + + items[i].key = key; + items[i].value = value; + + occupancy++; + if (!items[i].is_tombstone ()) + population++; + + } + inline hb_codepoint_t get (hb_codepoint_t key) const + { + if (unlikely (!items)) return INVALID; + unsigned int i = bucket_for (key); + return items[i].key == key ? items[i].value : INVALID; + } + + inline void del (hb_codepoint_t key) + { + set (key, INVALID); + } + inline bool has (hb_codepoint_t key) const + { + return get (key) != INVALID; + } + + inline hb_codepoint_t operator [] (unsigned int key) const + { return get (key); } + + static const hb_codepoint_t INVALID = HB_MAP_VALUE_INVALID; + + inline void clear (void) + { + memset (items, 0xFF, ((size_t) mask + 1) * sizeof (item_t)); + population = occupancy = 0; + } + + inline bool is_empty (void) const + { + return population != 0; + } + + inline unsigned int get_population () const + { + return population; + } + + protected: + + inline unsigned int bucket_for (hb_codepoint_t key) const + { + unsigned int i = Hash (key) % prime; + unsigned int step = 0; + unsigned int tombstone = INVALID; + while (!items[i].is_unused ()) + { + if (items[i].key == key) + return i; + if (tombstone == INVALID && items[i].is_tombstone ()) + tombstone = i; + i = (i + ++step) & mask; + } + return tombstone == INVALID ? i : tombstone; + } + + static inline unsigned int prime_for (unsigned int shift) + { + /* Following comment and table copied from glib. */ + /* Each table size has an associated prime modulo (the first prime + * lower than the table size) used to find the initial bucket. Probing + * then works modulo 2^n. The prime modulo is necessary to get a + * good distribution with poor hash functions. + */ + /* Not declaring static to make all kinds of compilers happy... */ + /*static*/ const unsigned int prime_mod [32] = + { + 1, /* For 1 << 0 */ + 2, + 3, + 7, + 13, + 31, + 61, + 127, + 251, + 509, + 1021, + 2039, + 4093, + 8191, + 16381, + 32749, + 65521, /* For 1 << 16 */ + 131071, + 262139, + 524287, + 1048573, + 2097143, + 4194301, + 8388593, + 16777213, + 33554393, + 67108859, + 134217689, + 268435399, + 536870909, + 1073741789, + 2147483647 /* For 1 << 31 */ + }; + + if (unlikely (shift >= ARRAY_LENGTH (prime_mod))) + return prime_mod[ARRAY_LENGTH (prime_mod) - 1]; + + return prime_mod[shift]; + } +}; + + +#endif /* HB_MAP_PRIVATE_HH */ diff --git a/src/hb-map.cc b/src/hb-map.cc new file mode 100644 index 0000000..e3ddae4 --- /dev/null +++ b/src/hb-map.cc @@ -0,0 +1,261 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-map-private.hh" + + +/* Public API */ + + +/** + * hb_map_create: (Xconstructor) + * + * Return value: (transfer full): + * + * Since: 1.7.7 + **/ +hb_map_t * +hb_map_create (void) +{ + hb_map_t *map; + + if (!(map = hb_object_create<hb_map_t> ())) + return hb_map_get_empty (); + + map->init_shallow (); + + return map; +} + +/** + * hb_map_get_empty: + * + * Return value: (transfer full): + * + * Since: 1.7.7 + **/ +hb_map_t * +hb_map_get_empty (void) +{ + return const_cast<hb_map_t *> (&Null(hb_map_t)); +} + +/** + * hb_map_reference: (skip) + * @map: a map. + * + * Return value: (transfer full): + * + * Since: 1.7.7 + **/ +hb_map_t * +hb_map_reference (hb_map_t *map) +{ + return hb_object_reference (map); +} + +/** + * hb_map_destroy: (skip) + * @map: a map. + * + * Since: 1.7.7 + **/ +void +hb_map_destroy (hb_map_t *map) +{ + if (!hb_object_destroy (map)) return; + + map->fini_shallow (); + + free (map); +} + +/** + * hb_map_set_user_data: (skip) + * @map: a map. + * @key: + * @data: + * @destroy: + * @replace: + * + * Return value: + * + * Since: 1.7.7 + **/ +hb_bool_t +hb_map_set_user_data (hb_map_t *map, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (map, key, data, destroy, replace); +} + +/** + * hb_map_get_user_data: (skip) + * @map: a map. + * @key: + * + * Return value: (transfer none): + * + * Since: 1.7.7 + **/ +void * +hb_map_get_user_data (hb_map_t *map, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (map, key); +} + + +/** + * hb_map_allocation_successful: + * @map: a map. + * + * + * + * Return value: + * + * Since: 1.7.7 + **/ +hb_bool_t +hb_map_allocation_successful (const hb_map_t *map) +{ + return map->successful; +} + + +/** + * hb_map_set: + * @map: a map. + * @key: + * @value: + * + * + * + * Return value: + * + * Since: 1.7.7 + **/ +void +hb_map_set (hb_map_t *map, + hb_codepoint_t key, + hb_codepoint_t value) +{ + map->set (key, value); +} + +/** + * hb_map_get: + * @map: a map. + * @key: + * + * + * + * Since: 1.7.7 + **/ +hb_codepoint_t +hb_map_get (const hb_map_t *map, + hb_codepoint_t key) +{ + return map->get (key); +} + +/** + * hb_map_del: + * @map: a map. + * @codepoint: + * + * + * + * Since: 1.7.7 + **/ +void +hb_map_del (hb_map_t *map, + hb_codepoint_t key) +{ + map->del (key); +} + +/** + * hb_map_has: + * @map: a map. + * @codepoint: + * + * + * + * Since: 1.7.7 + **/ +hb_bool_t +hb_map_has (const hb_map_t *map, + hb_codepoint_t key) +{ + return map->has (key); +} + + +/** + * hb_map_clear: + * @map: a map. + * + * + * + * Since: 1.7.7 + **/ +void +hb_map_clear (hb_map_t *map) +{ + return map->clear (); +} + +/** + * hb_map_is_empty: + * @map: a map. + * + * + * + * Since: 1.7.7 + **/ +hb_bool_t +hb_map_is_empty (const hb_map_t *map) +{ + return map->is_empty (); +} + +/** + * hb_map_get_population: + * @map: a map. + * + * + * + * Since: 1.7.7 + **/ +unsigned int +hb_map_get_population (const hb_map_t *map) +{ + return map->get_population (); +} diff --git a/src/hb-map.h b/src/hb-map.h new file mode 100644 index 0000000..b77843c --- /dev/null +++ b/src/hb-map.h @@ -0,0 +1,104 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_H_IN +#error "Include <hb.h> instead." +#endif + +#ifndef HB_MAP_H +#define HB_MAP_H + +#include "hb-common.h" + +HB_BEGIN_DECLS + + +/* + * Since: 1.7.7 + */ +#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1) + +typedef struct hb_map_t hb_map_t; + + +HB_EXTERN hb_map_t * +hb_map_create (void); + +HB_EXTERN hb_map_t * +hb_map_get_empty (void); + +HB_EXTERN hb_map_t * +hb_map_reference (hb_map_t *map); + +HB_EXTERN void +hb_map_destroy (hb_map_t *map); + +HB_EXTERN hb_bool_t +hb_map_set_user_data (hb_map_t *map, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace); + +HB_EXTERN void * +hb_map_get_user_data (hb_map_t *map, + hb_user_data_key_t *key); + + +/* Returns false if allocation has failed before */ +HB_EXTERN hb_bool_t +hb_map_allocation_successful (const hb_map_t *map); + +HB_EXTERN void +hb_map_clear (hb_map_t *map); + +HB_EXTERN hb_bool_t +hb_map_is_empty (const hb_map_t *map); + +HB_EXTERN unsigned int +hb_map_get_population (const hb_map_t *map); + +HB_EXTERN void +hb_map_set (hb_map_t *map, + hb_codepoint_t key, + hb_codepoint_t value); + +HB_EXTERN hb_codepoint_t +hb_map_get (const hb_map_t *map, + hb_codepoint_t key); + +HB_EXTERN void +hb_map_del (hb_map_t *map, + hb_codepoint_t key); + +HB_EXTERN hb_bool_t +hb_map_has (const hb_map_t *map, + hb_codepoint_t key); + + +HB_END_DECLS + +#endif /* HB_MAP_H */ diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh index 49ed10e..14bde31 100644 --- a/src/hb-mutex-private.hh +++ b/src/hb-mutex-private.hh @@ -134,7 +134,7 @@ struct hb_mutex_t inline void init (void) { hb_mutex_impl_init (&m); } inline void lock (void) { hb_mutex_impl_lock (&m); } inline void unlock (void) { hb_mutex_impl_unlock (&m); } - inline void finish (void) { hb_mutex_impl_finish (&m); } + inline void fini (void) { hb_mutex_impl_finish (&m); } }; diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index baa1f8f..fc48a91 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -41,9 +41,9 @@ /* reference_count */ -#define HB_REFERENCE_COUNT_INERT_VALUE -1 +#define HB_REFERENCE_COUNT_INERT_VALUE 0 #define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD -#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)} +#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (HB_REFERENCE_COUNT_INERT_VALUE)} struct hb_reference_count_t { @@ -53,7 +53,7 @@ struct hb_reference_count_t inline int get_unsafe (void) const { return ref_count.get_unsafe (); } inline int inc (void) { return ref_count.inc (); } inline int dec (void) { return ref_count.dec (); } - inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); } + inline void fini (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); } inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; } inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; } @@ -62,7 +62,6 @@ struct hb_reference_count_t /* user_data */ -#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT} struct hb_user_data_array_t { struct hb_user_data_item_t { @@ -73,7 +72,7 @@ struct hb_user_data_array_t inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; } inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; } - void finish (void) { if (destroy) destroy (data); } + void fini (void) { if (destroy) destroy (data); } }; hb_mutex_t lock; @@ -88,7 +87,7 @@ struct hb_user_data_array_t HB_INTERNAL void *get (hb_user_data_key_t *key); - inline void finish (void) { items.finish (lock); lock.finish (); } + inline void fini (void) { items.fini (lock); lock.fini (); } }; @@ -97,9 +96,9 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - hb_user_data_array_t user_data; + hb_user_data_array_t *user_data; -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT} +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, nullptr} private: ASSERT_POD (); @@ -133,7 +132,7 @@ template <typename Type> static inline void hb_object_init (Type *obj) { obj->header.ref_count.init (1); - obj->header.user_data.init (); + obj->header.user_data = nullptr; } template <typename Type> static inline bool hb_object_is_inert (const Type *obj) @@ -165,11 +164,20 @@ static inline bool hb_object_destroy (Type *obj) if (obj->header.ref_count.dec () != 1) return false; - obj->header.ref_count.finish (); /* Do this before user_data */ - obj->header.user_data.finish (); + hb_object_fini (obj); return true; } template <typename Type> +static inline void hb_object_fini (Type *obj) +{ + obj->header.ref_count.fini (); /* Do this before user_data */ + if (obj->header.user_data) + { + obj->header.user_data->fini (); + free (obj->header.user_data); + } +} +template <typename Type> static inline bool hb_object_set_user_data (Type *obj, hb_user_data_key_t *key, void * data, @@ -179,17 +187,34 @@ static inline bool hb_object_set_user_data (Type *obj, if (unlikely (!obj || hb_object_is_inert (obj))) return false; assert (hb_object_is_valid (obj)); - return obj->header.user_data.set (key, data, destroy, replace); + +retry: + hb_user_data_array_t *user_data = (hb_user_data_array_t *) hb_atomic_ptr_get (&obj->header.user_data); + if (unlikely (!user_data)) + { + user_data = (hb_user_data_array_t *) calloc (sizeof (hb_user_data_array_t), 1); + if (unlikely (!user_data)) + return false; + user_data->init (); + if (unlikely (!hb_atomic_ptr_cmpexch (&obj->header.user_data, nullptr, user_data))) + { + user_data->fini (); + free (user_data); + goto retry; + } + } + + return user_data->set (key, data, destroy, replace); } template <typename Type> static inline void *hb_object_get_user_data (Type *obj, hb_user_data_key_t *key) { - if (unlikely (!obj || hb_object_is_inert (obj))) + if (unlikely (!obj || hb_object_is_inert (obj) || !obj->header.user_data)) return nullptr; assert (hb_object_is_valid (obj)); - return obj->header.user_data.get (key); + return obj->header.user_data->get (key); } diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh index e2644ea..2965b46 100644 --- a/src/hb-open-file-private.hh +++ b/src/hb-open-file-private.hh @@ -100,7 +100,7 @@ typedef struct OffsetTable else *table_count = MIN<unsigned int> (*table_count, tables.len - start_offset); - const TableRecord *sub_tables = tables.array + start_offset; + const TableRecord *sub_tables = tables.arrayZ + start_offset; unsigned int count = *table_count; for (unsigned int i = 0; i < count; i++) table_tags[i] = sub_tables[i].tag; @@ -148,7 +148,7 @@ typedef struct OffsetTable /* Write OffsetTables, alloc for and write actual table blobs. */ for (unsigned int i = 0; i < table_count; i++) { - TableRecord &rec = tables.array[i]; + TableRecord &rec = tables.arrayZ[i]; hb_blob_t *blob = blobs[i]; rec.tag.set (tags[i]); rec.length.set (hb_blob_get_length (blob)); @@ -188,7 +188,7 @@ typedef struct OffsetTable checksum.set_for_data (this, dir_end - (const char *) this); for (unsigned int i = 0; i < table_count; i++) { - TableRecord &rec = tables.array[i]; + TableRecord &rec = tables.arrayZ[i]; checksum.set (checksum + rec.checkSum); } @@ -234,7 +234,7 @@ struct TTCHeaderVersion1 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion<>version; /* Version of the TTC Header (1.0), * 0x00010000u */ - ArrayOf<LOffsetTo<OffsetTable>, HBUINT32> + LArrayOf<LOffsetTo<OffsetTable> > table; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ public: @@ -295,11 +295,13 @@ struct OpenTypeFontFile { static const hb_tag_t tableTag = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */ - static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */ - static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */ - static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); /* TrueType Collection */ - static const hb_tag_t TrueTag = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */ - static const hb_tag_t Typ1Tag = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */ + enum { + CFFTag = HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */ + TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */ + TTCTag = HB_TAG ('t','t','c','f'), /* TrueType Collection */ + TrueTag = HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */ + Typ1Tag = HB_TAG ('t','y','p','1') /* Obsolete Apple Type1 font in SFNT container */ + }; inline hb_tag_t get_tag (void) const { return u.tag; } diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 5d33199..8180287 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -31,6 +31,7 @@ #include "hb-private.hh" #include "hb-debug.hh" +#include "hb-blob-private.hh" #include "hb-face-private.hh" @@ -127,46 +128,6 @@ static inline Type& StructAfter(TObject &X) /* - * Null objects - */ - -/* Global nul-content Null pool. Enlarge as necessary. */ - -#define HB_NULL_POOL_SIZE 264 -static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE."); - -#ifdef HB_NO_VISIBILITY -static -#else -extern HB_INTERNAL -#endif -const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] -#ifdef HB_NO_VISIBILITY -= {} -#endif -; - -/* Generic nul-content Null objects. */ -template <typename Type> -static inline const Type& Null (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); - return *CastP<Type> (_hb_NullPool); -} - -/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ -#define DEFINE_NULL_DATA(Type, data) \ -static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \ -template <> \ -/*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 */ \ -static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.") - -/* Accessor macro. */ -#define Null(Type) Null<Type>() - - -/* * Dispatch */ @@ -225,7 +186,7 @@ struct hb_sanitize_context_t : inline void start_processing (void) { this->start = hb_blob_get_data (this->blob, nullptr); - this->end = this->start + hb_blob_get_length (this->blob); + this->end = this->start + this->blob->length; assert (this->start <= this->end); /* Must not overflow. */ this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); @@ -288,7 +249,7 @@ struct hb_sanitize_context_t : return likely (this->check_range (obj, obj->min_size)); } - inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED) + inline bool may_edit (const void *base, unsigned int len) { if (this->edit_count >= HB_SANITIZE_MAX_EDITS) return false; @@ -368,7 +329,7 @@ struct Sanitizer unsigned int edit_count = c->edit_count; if (edit_count && !c->writable) { c->start = hb_blob_get_data_writable (blob, nullptr); - c->end = c->start + hb_blob_get_length (blob); + c->end = c->start + blob->length; if (c->start) { c->writable = true; @@ -383,19 +344,17 @@ struct Sanitizer DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED"); if (sane) + { + blob->lock (); return blob; - else { + } + else + { hb_blob_destroy (blob); return hb_blob_get_empty (); } } - static const Type* lock_instance (hb_blob_t *blob) { - hb_blob_make_immutable (blob); - const char *base = hb_blob_get_data (blob, nullptr); - return unlikely (!base) ? &Null(Type) : CastP<Type> (base); - } - inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; } private: @@ -672,7 +631,7 @@ typedef IntType<uint16_t, 2> HBUINT16; /* 16-bit unsigned integer. */ typedef IntType<int16_t, 2> HBINT16; /* 16-bit signed integer. */ typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */ typedef IntType<int32_t, 4> HBINT32; /* 32-bit signed integer. */ -typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ +typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */ /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ typedef HBINT16 FWORD; @@ -683,17 +642,19 @@ typedef HBUINT16 UFWORD; /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ struct F2DOT14 : HBINT16 { - //inline float to_float (void) const { return ???; } - //inline void set_float (float f) { v.set (f * ???); } + // 16384 means 1<<14 + inline float to_float (void) const { return ((int32_t) v) / 16384.f; } + inline void set_float (float f) { v.set (round (f * 16384.f)); } public: DEFINE_SIZE_STATIC (2); }; /* 32-bit signed fixed-point number (16.16). */ -struct Fixed: HBINT32 +struct Fixed : HBINT32 { - inline float to_float (void) const { return ((int32_t) v) / 65536.0; } - inline void set_float (float f) { v.set (round (f * 65536.0)); } + // 65536 means 1<<16 + inline float to_float (void) const { return ((int32_t) v) / 65536.f; } + inline void set_float (float f) { v.set (round (f * 65536.f)); } public: DEFINE_SIZE_STATIC (4); }; @@ -724,16 +685,19 @@ struct Tag : HBUINT32 public: DEFINE_SIZE_STATIC (4); }; -DEFINE_NULL_DATA (Tag, " "); +DEFINE_NULL_DATA (OT, Tag, " "); /* Glyph index number, same as uint16 (length = 16 bits) */ typedef HBUINT16 GlyphID; +/* Name-table index, same as uint16 (length = 16 bits) */ +typedef HBUINT16 NameID; + /* Script/language-system/feature index */ struct Index : HBUINT16 { static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; }; -DEFINE_NULL_DATA (Index, "\xff\xff"); +DEFINE_NULL_DATA (OT, Index, "\xff\xff"); /* Offset, Null offset = 0 */ template <typename Type> @@ -815,6 +779,12 @@ struct OffsetTo : Offset<OffsetType> { unsigned int offset = *this; if (unlikely (!offset)) return Null(Type); + return StructAtOffset<const Type> (base, offset); + } + inline Type& operator () (void *base) const + { + unsigned int offset = *this; + if (unlikely (!offset)) return Crap(Type); return StructAtOffset<Type> (base, offset); } @@ -862,6 +832,89 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) * Array Types */ + +/* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */ +template <typename Type> +struct UnsizedArrayOf +{ + inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } + inline Type& operator [] (unsigned int i) { return arrayZ[i]; } + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c, count))) return_trace (false); + + /* Note: for structs that do not reference other structs, + * we do not need to call their sanitize() as we already did + * a bound check on the aggregate array size. We just include + * a small unreachable expression to make sure the structs + * pointed to do have a simple sanitize(), ie. they do not + * reference other structs via offsets. + */ + (void) (false && arrayZ[0].sanitize (c)); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c, count))) return_trace (false); + for (unsigned int i = 0; i < count; i++) + if (unlikely (!arrayZ[i].sanitize (c, base))) + return_trace (false); + return_trace (true); + } + template <typename T> + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c, count))) return_trace (false); + for (unsigned int i = 0; i < count; i++) + if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + return_trace (false); + return_trace (true); + } + + inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count)); + } + + public: + Type arrayZ[VAR]; + public: + DEFINE_SIZE_ARRAY (0, arrayZ); +}; + +/* Unsized array of offset's */ +template <typename Type, typename OffsetType> +struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {}; + +/* Unsized array of offsets relative to the beginning of the array itself. */ +template <typename Type, typename OffsetType> +struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType> +{ + inline const Type& operator [] (unsigned int i) const + { + return this+this->arrayZ[i]; + } + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this))); + } + template <typename T> + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const + { + TRACE_SANITIZE (this); + return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data))); + } +}; + + /* An array with a number of elements. */ template <typename Type, typename LenType=HBUINT16> struct ArrayOf @@ -875,17 +928,18 @@ struct ArrayOf count -= start_offset; count = MIN (count, *pcount); *pcount = count; - return array + start_offset; + return arrayZ + start_offset; } inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= len)) return Null(Type); - return array[i]; + return arrayZ[i]; } inline Type& operator [] (unsigned int i) { - return array[i]; + if (unlikely (i >= len)) return Crap(Type); + return arrayZ[i]; } inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } @@ -907,7 +961,7 @@ struct ArrayOf TRACE_SERIALIZE (this); if (unlikely (!serialize (c, items_len))) return_trace (false); for (unsigned int i = 0; i < items_len; i++) - array[i] = items[i]; + arrayZ[i] = items[i]; items += items_len; return_trace (true); } @@ -924,7 +978,7 @@ struct ArrayOf * pointed to do have a simple sanitize(), ie. they do not * reference other structs via offsets. */ - (void) (false && array[0].sanitize (c)); + (void) (false && arrayZ[0].sanitize (c)); return_trace (true); } @@ -934,7 +988,7 @@ struct ArrayOf if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!array[i].sanitize (c, base))) + if (unlikely (!arrayZ[i].sanitize (c, base))) return_trace (false); return_trace (true); } @@ -945,7 +999,7 @@ struct ArrayOf if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!array[i].sanitize (c, base, user_data))) + if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) return_trace (false); return_trace (true); } @@ -955,28 +1009,28 @@ struct ArrayOf { unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (!this->array[i].cmp (x)) + if (!this->arrayZ[i].cmp (x)) return i; return -1; } inline void qsort (void) { - ::qsort (array, len, sizeof (Type), Type::cmp); + ::qsort (arrayZ, len, sizeof (Type), Type::cmp); } private: inline bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len)); + return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len)); } public: LenType len; - Type array[VAR]; + Type arrayZ[VAR]; public: - DEFINE_SIZE_ARRAY (sizeof (LenType), array); + DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {}; @@ -991,7 +1045,12 @@ struct OffsetListOf : OffsetArrayOf<Type> inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= this->len)) return Null(Type); - return this+this->array[i]; + return this+this->arrayZ[i]; + } + inline const Type& operator [] (unsigned int i) + { + if (unlikely (i >= this->len)) return Crap(Type); + return this+this->arrayZ[i]; } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1015,7 +1074,12 @@ struct HeadlessArrayOf inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= len || !i)) return Null(Type); - return array[i-1]; + return arrayZ[i-1]; + } + inline Type& operator [] (unsigned int i) + { + if (unlikely (i >= len || !i)) return Crap(Type); + return arrayZ[i-1]; } inline unsigned int get_size (void) const { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } @@ -1030,7 +1094,7 @@ struct HeadlessArrayOf if (unlikely (!items_len)) return_trace (true); if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items_len - 1; i++) - array[i] = items[i]; + arrayZ[i] = items[i]; items += items_len - 1; return_trace (true); } @@ -1047,7 +1111,7 @@ struct HeadlessArrayOf * pointed to do have a simple sanitize(), ie. they do not * reference other structs via offsets. */ - (void) (false && array[0].sanitize (c)); + (void) (false && arrayZ[0].sanitize (c)); return_trace (true); } @@ -1057,14 +1121,14 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); return_trace (len.sanitize (c) && - (!len || c->check_array (array, Type::static_size, len - 1))); + (!len || c->check_array (arrayZ, Type::static_size, len - 1))); } public: LenType len; - Type array[VAR]; + Type arrayZ[VAR]; public: - DEFINE_SIZE_ARRAY (sizeof (LenType), array); + DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; @@ -1078,7 +1142,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType> inline int bsearch (const SearchType &x) const { /* Hand-coded bsearch here since this is in the hot inner loop. */ - const Type *arr = this->array; + const Type *arr = this->arrayZ; int min = 0, max = (int) this->len - 1; while (min <= max) { @@ -1113,18 +1177,18 @@ struct BinSearchHeader { len.set (v); assert (len == v); - entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1); - searchRangeZ.set (16 * (1u << entrySelectorZ)); - rangeShiftZ.set (v * 16 > searchRangeZ - ? 16 * v - searchRangeZ - : 0); + entrySelector.set (MAX (1u, _hb_bit_storage (v)) - 1); + searchRange.set (16 * (1u << entrySelector)); + rangeShift.set (v * 16 > searchRange + ? 16 * v - searchRange + : 0); } protected: HBUINT16 len; - HBUINT16 searchRangeZ; - HBUINT16 entrySelectorZ; - HBUINT16 rangeShiftZ; + HBUINT16 searchRange; + HBUINT16 entrySelector; + HBUINT16 rangeShift; public: DEFINE_SIZE_STATIC (8); @@ -1136,7 +1200,7 @@ struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {}; /* Lazy struct and blob loaders. */ -/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */ +/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */ template <typename T> struct hb_lazy_loader_t { @@ -1148,7 +1212,7 @@ struct hb_lazy_loader_t inline void fini (void) { - if (instance && instance != &OT::Null(T)) + if (instance && instance != &Null(T)) { instance->fini(); free (instance); @@ -1163,12 +1227,12 @@ struct hb_lazy_loader_t { p = (T *) calloc (1, sizeof (T)); if (unlikely (!p)) - p = const_cast<T *> (&OT::Null(T)); + p = const_cast<T *> (&Null(T)); else p->init (face); if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p))) { - if (p != &OT::Null(T)) + if (p != &Null(T)) p->fini (); goto retry; } @@ -1186,15 +1250,14 @@ struct hb_lazy_loader_t T *instance; }; -/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */ +/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */ template <typename T> -struct hb_lazy_table_loader_t +struct hb_table_lazy_loader_t { inline void init (hb_face_t *face_) { face = face_; blob = nullptr; - instance = nullptr; } inline void fini (void) @@ -1205,19 +1268,18 @@ struct hb_lazy_table_loader_t inline const T* get (void) const { retry: - T *p = (T *) hb_atomic_ptr_get (&instance); - if (unlikely (!p)) + hb_blob_t *blob_ = (hb_blob_t *) hb_atomic_ptr_get (&blob); + if (unlikely (!blob_)) { - hb_blob_t *blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag)); - p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_)); - if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)) + blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag)); + if (!hb_atomic_ptr_cmpexch (&blob, nullptr, blob_)) { hb_blob_destroy (blob_); goto retry; } blob = blob_; } - return p; + return blob_->as<T> (); } inline const T* operator-> (void) const @@ -1225,10 +1287,9 @@ struct hb_lazy_table_loader_t return get(); } + private: hb_face_t *face; mutable hb_blob_t *blob; - private: - mutable T *instance; }; diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 0207989..c1903f6 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -28,18 +28,19 @@ #define HB_OT_CMAP_TABLE_HH #include "hb-open-type-private.hh" +#include "hb-set-private.hh" #include "hb-subset-plan.hh" -namespace OT { - - /* - * cmap -- Character To Glyph Index Mapping Table + * cmap -- Character to Glyph Index Mapping + * https://docs.microsoft.com/en-us/typography/opentype/spec/cmap */ - #define HB_OT_TAG_cmap HB_TAG('c','m','a','p') +namespace OT { + + struct CmapSubtableFormat0 { inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const @@ -59,8 +60,8 @@ struct CmapSubtableFormat0 protected: HBUINT16 format; /* Format number is set to 0. */ - HBUINT16 lengthZ; /* Byte length of this subtable. */ - HBUINT16 languageZ; /* Ignore. */ + HBUINT16 length; /* Byte length of this subtable. */ + HBUINT16 language; /* Ignore. */ HBUINT8 glyphIdArray[256];/* An array that maps character * code to glyph index values. */ public: @@ -69,6 +70,158 @@ struct CmapSubtableFormat0 struct CmapSubtableFormat4 { + struct segment_plan + { + HBUINT16 start_code; + HBUINT16 end_code; + bool use_delta; + }; + + bool serialize (hb_serialize_context_t *c, + const hb_subset_plan_t *plan, + const hb_vector_t<segment_plan> &segments) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min (*this))) return_trace (false); + + this->format.set (4); + this->length.set (get_sub_table_size (segments)); + + this->segCountX2.set (segments.len * 2); + this->entrySelector.set (MAX (1u, _hb_bit_storage (segments.len)) - 1); + this->searchRange.set (2 * (1u << this->entrySelector)); + this->rangeShift.set (segments.len * 2 > this->searchRange + ? 2 * segments.len - this->searchRange + : 0); + + HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); + c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding. + HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); + HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.len); + HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); + + if (id_range_offset == nullptr) + return_trace (false); + + for (unsigned int i = 0; i < segments.len; i++) + { + end_count[i].set (segments[i].end_code); + start_count[i].set (segments[i].start_code); + if (segments[i].use_delta) + { + hb_codepoint_t cp = segments[i].start_code; + hb_codepoint_t start_gid = 0; + if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF)) + return_trace (false); + id_delta[i].set (start_gid - segments[i].start_code); + } else { + id_delta[i].set (0); + unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1; + HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints); + if (glyph_id_array == nullptr) + return_trace (false); + // From the cmap spec: + // + // id_range_offset[i]/2 + // + (cp - segments[i].start_code) + // + (id_range_offset + i) + // = + // glyph_id_array + (cp - segments[i].start_code) + // + // So, solve for id_range_offset[i]: + // + // id_range_offset[i] + // = + // 2 * (glyph_id_array - id_range_offset - i) + id_range_offset[i].set (2 * ( + glyph_id_array - id_range_offset - i)); + for (unsigned int j = 0; j < num_codepoints; j++) + { + hb_codepoint_t cp = segments[i].start_code + j; + hb_codepoint_t new_gid; + if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) + return_trace (false); + glyph_id_array[j].set (new_gid); + } + } + } + + return_trace (true); + } + + static inline size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments) + { + size_t segment_size = 0; + for (unsigned int i = 0; i < segments.len; i++) + { + // Parallel array entries + segment_size += + 2 // end count + + 2 // start count + + 2 // delta + + 2; // range offset + + if (!segments[i].use_delta) + // Add bytes for the glyph index array entries for this segment. + segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2; + } + + return min_size + + 2 // Padding + + segment_size; + } + + static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, + hb_vector_t<segment_plan> *segments) + { + segment_plan *segment = nullptr; + hb_codepoint_t last_gid = 0; + + hb_codepoint_t cp = HB_SET_VALUE_INVALID; + while (plan->unicodes->next (&cp)) { + hb_codepoint_t new_gid; + if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); + return false; + } + + if (cp > 0xFFFF) { + // We are now outside of unicode BMP, stop adding to this cmap. + break; + } + + if (!segment + || cp != segment->end_code + 1u) + { + segment = segments->push (); + segment->start_code.set (cp); + segment->end_code.set (cp); + segment->use_delta = true; + } else { + segment->end_code.set (cp); + if (last_gid + 1u != new_gid) + // gid's are not consecutive in this segment so delta + // cannot be used. + segment->use_delta = false; + } + + last_gid = new_gid; + } + + // There must be a final entry with end_code == 0xFFFF. Check if we need to add one. + if (segment == nullptr || segment->end_code != 0xFFFF) + { + segment = segments->push (); + segment->start_code.set (0xFFFF); + segment->end_code.set (0xFFFF); + segment->use_delta = true; + } + + return true; + } + struct accelerator_t { inline void init (const CmapSubtableFormat4 *subtable) @@ -127,6 +280,17 @@ struct CmapSubtableFormat4 return true; } + static inline void get_all_codepoints_func (const void *obj, hb_set_t *out) + { + const accelerator_t *thiz = (const accelerator_t *) obj; + for (unsigned int i = 0; i < thiz->segCount; i++) + { + if (thiz->startCount[i] != 0xFFFFu + || thiz->endCount[i] != 0xFFFFu) // Skip the last segment (0xFFFF) + hb_set_add_range (out, thiz->startCount[i], thiz->endCount[i]); + } + } + const HBUINT16 *endCount; const HBUINT16 *startCount; const HBUINT16 *idDelta; @@ -164,15 +328,17 @@ struct CmapSubtableFormat4 return_trace (16 + 4 * (unsigned int) segCountX2 <= length); } + + protected: HBUINT16 format; /* Format number is set to 4. */ HBUINT16 length; /* This is the length in bytes of the * subtable. */ - HBUINT16 languageZ; /* Ignore. */ + HBUINT16 language; /* Ignore. */ HBUINT16 segCountX2; /* 2 x segCount. */ - HBUINT16 searchRangeZ; /* 2 * (2**floor(log2(segCount))) */ - HBUINT16 entrySelectorZ; /* log2(searchRange/2) */ - HBUINT16 rangeShiftZ; /* 2 x segCount - searchRange */ + HBUINT16 searchRange; /* 2 * (2**floor(log2(segCount))) */ + HBUINT16 entrySelector; /* log2(searchRange/2) */ + HBUINT16 rangeShift; /* 2 x segCount - searchRange */ HBUINT16 values[VAR]; #if 0 @@ -193,6 +359,8 @@ struct CmapSubtableLongGroup { friend struct CmapSubtableFormat12; friend struct CmapSubtableFormat13; + template<typename U> + friend struct CmapSubtableLongSegmented; friend struct cmap; int cmp (hb_codepoint_t codepoint) const @@ -238,8 +406,8 @@ struct CmapSubtableTrimmed protected: UINT formatReserved; /* Subtable format and (maybe) padding. */ - UINT lengthZ; /* Byte length of this subtable. */ - UINT languageZ; /* Ignore. */ + UINT length; /* Byte length of this subtable. */ + UINT language; /* Ignore. */ UINT startCharCode; /* First character code covered. */ ArrayOf<GlyphID, UINT> glyphIdArray; /* Array of glyph index values for character @@ -265,6 +433,15 @@ struct CmapSubtableLongSegmented return true; } + inline void get_all_codepoints (hb_set_t *out) const + { + for (unsigned int i = 0; i < this->groups.len; i++) { + hb_set_add_range (out, + this->groups[i].startCharCode, + this->groups[i].endCharCode); + } + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -272,20 +449,20 @@ struct CmapSubtableLongSegmented } inline bool serialize (hb_serialize_context_t *c, - hb_prealloced_array_t<CmapSubtableLongGroup> &group_data) + const hb_vector_t<CmapSubtableLongGroup> &group_data) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - Supplier<CmapSubtableLongGroup> supplier (group_data.array, group_data.len); + Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ, group_data.len); if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false); return true; } protected: HBUINT16 format; /* Subtable format; set to 12. */ - HBUINT16 reservedZ; /* Reserved; set to 0. */ - HBUINT32 lengthZ; /* Byte length of this subtable. */ - HBUINT32 languageZ; /* Ignore. */ + HBUINT16 reserved; /* Reserved; set to 0. */ + HBUINT32 length; /* Byte length of this subtable. */ + HBUINT32 language; /* Ignore. */ SortedArrayOf<CmapSubtableLongGroup, HBUINT32> groups; /* Groupings. */ public: @@ -297,6 +474,69 @@ 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); } + + + bool serialize (hb_serialize_context_t *c, + const hb_vector_t<CmapSubtableLongGroup> &groups) + { + if (unlikely (!c->extend_min (*this))) return false; + + this->format.set (12); + this->reserved.set (0); + this->length.set (get_sub_table_size (groups)); + + return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups); + } + + static inline size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups) + { + return 16 + 12 * groups.len; + } + + static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, + hb_vector_t<CmapSubtableLongGroup> *groups) + { + CmapSubtableLongGroup *group = nullptr; + + hb_codepoint_t cp = HB_SET_VALUE_INVALID; + while (plan->unicodes->next (&cp)) { + hb_codepoint_t new_gid; + if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); + return false; + } + + if (!group || !_is_gid_consecutive (group, cp, new_gid)) + { + group = groups->push (); + group->startCharCode.set (cp); + group->endCharCode.set (cp); + group->glyphID.set (new_gid); + } else + { + group->endCharCode.set (cp); + } + } + + DEBUG_MSG(SUBSET, nullptr, "cmap"); + for (unsigned int i = 0; i < groups->len; i++) { + CmapSubtableLongGroup& group = (*groups)[i]; + DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); + } + + return true; + } + + private: + static inline bool _is_gid_consecutive (CmapSubtableLongGroup *group, + hb_codepoint_t cp, + hb_codepoint_t new_gid) + { + return (cp - 1 == group->endCharCode) && + new_gid == group->glyphID + (cp - group->startCharCode); + } + }; struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> @@ -328,7 +568,7 @@ struct UnicodeValueRange return_trace (c->check_struct (this)); } - UINT24 startUnicodeValue; /* First value in this range. */ + HBUINT24 startUnicodeValue; /* First value in this range. */ HBUINT8 additionalCount; /* Number of additional values in this * range. */ public: @@ -350,7 +590,7 @@ struct UVSMapping return_trace (c->check_struct (this)); } - UINT24 unicodeValue; /* Base Unicode value of the UVS */ + HBUINT24 unicodeValue; /* Base Unicode value of the UVS */ GlyphID glyphID; /* Glyph ID of the UVS */ public: DEFINE_SIZE_STATIC (5); @@ -392,7 +632,7 @@ struct VariationSelectorRecord nonDefaultUVS.sanitize (c, base)); } - UINT24 varSelector; /* Variation selector. */ + HBUINT24 varSelector; /* Variation selector. */ LOffsetTo<DefaultUVS> defaultUVS; /* Offset to Default UVS Table. May be 0. */ LOffsetTo<NonDefaultUVS> @@ -419,7 +659,7 @@ struct CmapSubtableFormat14 protected: HBUINT16 format; /* Format number is set to 14. */ - HBUINT32 lengthZ; /* Byte length of this subtable. */ + HBUINT32 length; /* Byte length of this subtable. */ SortedArrayOf<VariationSelectorRecord, HBUINT32> record; /* Variation selector records; sorted * in increasing order of `varSelector'. */ @@ -509,6 +749,33 @@ struct cmap { static const hb_tag_t tableTag = HB_OT_TAG_cmap; + struct subset_plan { + subset_plan(void) + { + format4_segments.init(); + format12_groups.init(); + } + + ~subset_plan(void) + { + format4_segments.fini(); + format12_groups.fini(); + } + + inline size_t final_size() const + { + return 4 // header + + 8 * 3 // 3 EncodingRecord + + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) + + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); + } + + // Format 4 + hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments; + // Format 12 + hb_vector_t<CmapSubtableLongGroup> format12_groups; + }; + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -517,41 +784,17 @@ struct cmap encodingRecord.sanitize (c, this)); } - inline bool populate_groups (hb_subset_plan_t *plan, - hb_prealloced_array_t<CmapSubtableLongGroup> *groups) const + inline bool _create_plan (const hb_subset_plan_t *plan, + subset_plan *cmap_plan) const { - CmapSubtableLongGroup *group = nullptr; - for (unsigned int i = 0; i < plan->codepoints.len; i++) { - - hb_codepoint_t cp = plan->codepoints[i]; - if (!group || cp - 1 != group->endCharCode) - { - group = groups->push (); - group->startCharCode.set (cp); - group->endCharCode.set (cp); - hb_codepoint_t new_gid; - if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid))) - { - DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); - return false; - } - group->glyphID.set (new_gid); - } else - { - group->endCharCode.set (cp); - } - } - - DEBUG_MSG(SUBSET, nullptr, "cmap"); - for (unsigned int i = 0; i < groups->len; i++) { - CmapSubtableLongGroup& group = (*groups)[i]; - DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); - } + if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments))) + return false; - return true; + return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups); } - inline bool _subset (hb_prealloced_array_t<CmapSubtableLongGroup> &groups, + inline bool _subset (const hb_subset_plan_t *plan, + const subset_plan &cmap_subset_plan, size_t dest_sz, void *dest) const { @@ -565,25 +808,46 @@ struct cmap cmap->version.set (0); - if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false; + if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3))) + return false; + + // TODO(grieger): Convert the below to a for loop - EncodingRecord &rec = cmap->encodingRecord[0]; - rec.platformID.set (3); // Windows - rec.encodingID.set (10); // Unicode UCS-4 + // Format 4, Plat 0 Encoding Record + EncodingRecord &format4_plat0_rec = cmap->encodingRecord[0]; + format4_plat0_rec.platformID.set (0); // Unicode + format4_plat0_rec.encodingID.set (3); - /* capture offset to subtable */ - CmapSubtable &subtable = rec.subtable.serialize (&c, cmap); + // Format 4, Plat 3 Encoding Record + EncodingRecord &format4_plat3_rec = cmap->encodingRecord[1]; + format4_plat3_rec.platformID.set (3); // Windows + format4_plat3_rec.encodingID.set (1); // Unicode BMP - subtable.u.format.set (12); + // Format 12 Encoding Record + EncodingRecord &format12_rec = cmap->encodingRecord[2]; + format12_rec.platformID.set (3); // Windows + format12_rec.encodingID.set (10); // Unicode UCS-4 - CmapSubtableFormat12 &format12 = subtable.u.format12; - if (unlikely (!c.extend_min (format12))) return false; + // Write out format 4 sub table + { + CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap); + format4_plat3_rec.subtable.set (format4_plat0_rec.subtable); + subtable.u.format.set (4); - format12.format.set (12); - format12.reservedZ.set (0); - format12.lengthZ.set (16 + 12 * groups.len); + CmapSubtableFormat4 &format4 = subtable.u.format4; + if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) + return false; + } - if (unlikely (!format12.serialize (&c, groups))) return false; + // Write out format 12 sub table. + { + CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap); + subtable.u.format.set (12); + + CmapSubtableFormat12 &format12 = subtable.u.format12; + if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) + return false; + } c.end_serialize (); @@ -592,24 +856,25 @@ struct cmap inline bool subset (hb_subset_plan_t *plan) const { - hb_auto_array_t<CmapSubtableLongGroup> groups; + subset_plan cmap_subset_plan; - if (unlikely (!populate_groups (plan, &groups))) return false; + if (unlikely (!_create_plan (plan, &cmap_subset_plan))) + { + DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan."); + return false; + } // We now know how big our blob needs to be - // TODO use APIs from the structs to get size? - size_t dest_sz = 4 // header - + 8 // 1 EncodingRecord - + 16 // Format 12 header - + 12 * groups.len; // SequentialMapGroup records + size_t dest_sz = cmap_subset_plan.final_size(); void *dest = malloc (dest_sz); if (unlikely (!dest)) { DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); return false; } - if (unlikely (!_subset (groups, dest_sz, dest))) + if (unlikely (!_subset (plan, cmap_subset_plan, dest_sz, dest))) { + DEBUG_MSG(SUBSET, nullptr, "Failed to perform subsetting of cmap."); free (dest); return false; } @@ -620,7 +885,7 @@ struct cmap HB_MEMORY_MODE_READONLY, dest, free); - bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime); + bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime); hb_blob_destroy (cmap_prime); return result; } @@ -630,7 +895,7 @@ struct cmap inline void init (hb_face_t *face) { this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap)); - const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); + const OT::cmap *cmap = this->blob->as<OT::cmap> (); const OT::CmapSubtable *subtable = nullptr; const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; @@ -651,7 +916,7 @@ struct cmap if (subtable) symbol = true; } /* Meh. */ - if (!subtable) subtable = &OT::Null(OT::CmapSubtable); + if (!subtable) subtable = &Null(OT::CmapSubtable); /* UVS subtable. */ if (!subtable_uvs) @@ -661,26 +926,36 @@ struct cmap subtable_uvs = &st->u.format14; } /* Meh. */ - if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14); + if (!subtable_uvs) subtable_uvs = &Null(OT::CmapSubtableFormat14); this->uvs_table = subtable_uvs; this->get_glyph_data = subtable; if (unlikely (symbol)) + { this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>; - else + this->get_all_codepoints_func = null_get_all_codepoints_func; + } else { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ - default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break; - case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break; + default: + this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; + this->get_all_codepoints_func = null_get_all_codepoints_func; + break; + case 12: + this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; + this->get_all_codepoints_func = get_all_codepoints_from<OT::CmapSubtableFormat12>; + break; case 4: { this->format4_accel.init (&subtable->u.format4); this->get_glyph_data = &this->format4_accel; this->get_glyph_func = this->format4_accel.get_glyph_func; + this->get_all_codepoints_func = this->format4_accel.get_all_codepoints_func; } break; } + } } inline void fini (void) @@ -710,10 +985,22 @@ struct cmap return get_nominal_glyph (unicode, glyph); } + inline void get_all_codepoints (hb_set_t *out) const + { + this->get_all_codepoints_func (get_glyph_data, out); + } + protected: typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); + typedef void (*hb_cmap_get_all_codepoints_func_t) (const void *obj, + hb_set_t *out); + + static inline void null_get_all_codepoints_func (const void *obj, hb_set_t *out) + { + // NOOP + } template <typename Type> static inline bool get_glyph_from (const void *obj, @@ -725,6 +1012,14 @@ struct cmap } template <typename Type> + static inline void get_all_codepoints_from (const void *obj, + hb_set_t *out) + { + const Type *typed_obj = (const Type *) obj; + typed_obj->get_all_codepoints (out); + } + + template <typename Type> static inline bool get_glyph_from_symbol (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) @@ -738,7 +1033,7 @@ struct cmap /* For symbol-encoded OpenType fonts, we duplicate the * U+F000..F0FF range at U+0000..U+00FF. That's what * Windows seems to do, and that's hinted about at: - * http://www.microsoft.com/typography/otspec/recom.htm + * https://docs.microsoft.com/en-us/typography/opentype/spec/recom * under "Non-Standard (Symbol) Fonts". */ return typed_obj->get_glyph (0xF000u + codepoint, glyph); } @@ -749,6 +1044,8 @@ struct cmap private: hb_cmap_get_glyph_func_t get_glyph_func; const void *get_glyph_data; + hb_cmap_get_all_codepoints_func_t get_all_codepoints_func; + OT::CmapSubtableFormat4::accelerator_t format4_accel; const OT::CmapSubtableFormat14 *uvs_table; diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index e7ab917..d1dd9de 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -29,6 +29,18 @@ #include "hb-open-type-private.hh" +/* + * CBLC -- Color Bitmap Location + * https://docs.microsoft.com/en-us/typography/opentype/spec/cblc + * https://docs.microsoft.com/en-us/typography/opentype/spec/eblc + * CBDT -- Color Bitmap Data + * https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt + * https://docs.microsoft.com/en-us/typography/opentype/spec/ebdt + */ +#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C') +#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T') + + namespace OT { struct SmallGlyphMetrics @@ -47,21 +59,21 @@ struct SmallGlyphMetrics extents->height = -height; } - HBUINT8 height; - HBUINT8 width; - HBINT8 bearingX; - HBINT8 bearingY; - HBUINT8 advance; - + HBUINT8 height; + HBUINT8 width; + HBINT8 bearingX; + HBINT8 bearingY; + HBUINT8 advance; + public: DEFINE_SIZE_STATIC(5); }; struct BigGlyphMetrics : SmallGlyphMetrics { - HBINT8 vertBearingX; - HBINT8 vertBearingY; - HBUINT8 vertAdvance; - + HBINT8 vertBearingX; + HBINT8 vertBearingY; + HBUINT8 vertAdvance; + public: DEFINE_SIZE_STATIC(8); }; @@ -73,19 +85,19 @@ struct SBitLineMetrics return_trace (c->check_struct (this)); } - HBINT8 ascender; - HBINT8 decender; - HBUINT8 widthMax; - HBINT8 caretSlopeNumerator; - HBINT8 caretSlopeDenominator; - HBINT8 caretOffset; - HBINT8 minOriginSB; - HBINT8 minAdvanceSB; - HBINT8 maxBeforeBL; - HBINT8 minAfterBL; - HBINT8 padding1; - HBINT8 padding2; - + HBINT8 ascender; + HBINT8 decender; + HBUINT8 widthMax; + HBINT8 caretSlopeNumerator; + HBINT8 caretSlopeDenominator; + HBINT8 caretOffset; + HBINT8 minOriginSB; + HBINT8 minAdvanceSB; + HBINT8 maxBeforeBL; + HBINT8 minAfterBL; + HBINT8 padding1; + HBINT8 padding2; + public: DEFINE_SIZE_STATIC(12); }; @@ -102,10 +114,10 @@ struct IndexSubtableHeader return_trace (c->check_struct (this)); } - HBUINT16 indexFormat; - HBUINT16 imageFormat; - HBUINT32 imageDataOffset; - + HBUINT16 indexFormat; + HBUINT16 imageFormat; + HBUINT32 imageDataOffset; + public: DEFINE_SIZE_STATIC(8); }; @@ -131,9 +143,9 @@ struct IndexSubtableFormat1Or3 return true; } - IndexSubtableHeader header; - Offset<OffsetType> offsetArrayZ[VAR]; - + IndexSubtableHeader header; + Offset<OffsetType> offsetArrayZ[VAR]; + public: DEFINE_SIZE_ARRAY(8, offsetArrayZ); }; @@ -214,15 +226,17 @@ struct IndexSubtableRecord offset, length, format); } - HBUINT16 firstGlyphIndex; - HBUINT16 lastGlyphIndex; - LOffsetTo<IndexSubtable> offsetToSubtable; - + GlyphID firstGlyphIndex; + GlyphID lastGlyphIndex; + LOffsetTo<IndexSubtable> offsetToSubtable; + public: DEFINE_SIZE_STATIC(8); }; struct IndexSubtableArray { + friend struct CBDT; + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); @@ -249,8 +263,7 @@ struct IndexSubtableArray } protected: - IndexSubtableRecord indexSubtablesZ[VAR]; - + IndexSubtableRecord indexSubtablesZ[VAR]; public: DEFINE_SIZE_ARRAY(0, indexSubtablesZ); }; @@ -258,6 +271,7 @@ struct IndexSubtableArray struct BitmapSizeTable { friend struct CBLC; + friend struct CBDT; inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { @@ -275,19 +289,19 @@ struct BitmapSizeTable } protected: - LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset; - HBUINT32 indexTablesSize; - HBUINT32 numberOfIndexSubtables; - HBUINT32 colorRef; - SBitLineMetrics horizontal; - SBitLineMetrics vertical; - HBUINT16 startGlyphIndex; - HBUINT16 endGlyphIndex; - HBUINT8 ppemX; - HBUINT8 ppemY; - HBUINT8 bitDepth; - HBINT8 flags; - + LOffsetTo<IndexSubtableArray> + indexSubtableArrayOffset; + HBUINT32 indexTablesSize; + HBUINT32 numberOfIndexSubtables; + HBUINT32 colorRef; + SBitLineMetrics horizontal; + SBitLineMetrics vertical; + GlyphID startGlyphIndex; + GlyphID endGlyphIndex; + HBUINT8 ppemX; + HBUINT8 ppemY; + HBUINT8 bitDepth; + HBINT8 flags; public: DEFINE_SIZE_STATIC(48); }; @@ -299,19 +313,26 @@ struct BitmapSizeTable struct GlyphBitmapDataFormat17 { - SmallGlyphMetrics glyphMetrics; - HBUINT32 dataLen; - HBUINT8 dataZ[VAR]; - - DEFINE_SIZE_ARRAY(9, dataZ); + SmallGlyphMetrics glyphMetrics; + LArrayOf<HBUINT8> data; + public: + DEFINE_SIZE_ARRAY(9, data); }; +struct GlyphBitmapDataFormat18 +{ + BigGlyphMetrics glyphMetrics; + LArrayOf<HBUINT8> data; + public: + DEFINE_SIZE_ARRAY(12, data); +}; -/* - * CBLC -- Color Bitmap Location Table - */ - -#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C') +struct GlyphBitmapDataFormat19 +{ + LArrayOf<HBUINT8> data; + public: + DEFINE_SIZE_ARRAY(4, data); +}; struct CBLC { @@ -336,8 +357,8 @@ struct CBLC unsigned int count = sizeTables.len; for (uint32_t i = 0; i < count; ++i) { - unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex; - unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex; + unsigned int startGlyphIndex = sizeTables.arrayZ[i].startGlyphIndex; + unsigned int endGlyphIndex = sizeTables.arrayZ[i].endGlyphIndex; if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) { *x_ppem = sizeTables[i].ppemX; @@ -352,16 +373,10 @@ struct CBLC protected: FixedVersion<> version; LArrayOf<BitmapSizeTable> sizeTables; - public: DEFINE_SIZE_ARRAY(8, sizeTables); }; -/* - * CBDT -- Color Bitmap Data Table - */ -#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T') - struct CBDT { static const hb_tag_t tableTag = HB_OT_TAG_CBDT; @@ -388,8 +403,8 @@ struct CBDT cbdt = nullptr; return; /* Not a bitmap font. */ } - cblc = Sanitizer<CBLC>::lock_instance (cblc_blob); - cbdt = Sanitizer<CBDT>::lock_instance (cbdt_blob); + cblc = cblc_blob->as<CBLC> (); + cbdt = cbdt_blob->as<CBDT> (); } @@ -447,6 +462,59 @@ struct CBDT return true; } + inline void dump (void (*callback) (const uint8_t* data, unsigned int length, + unsigned int group, unsigned int gid)) const + { + if (!cblc) + return; // Not a color bitmap font. + + for (unsigned int i = 0; i < cblc->sizeTables.len; ++i) + { + const BitmapSizeTable &sizeTable = cblc->sizeTables[i]; + const IndexSubtableArray &subtable_array = cblc+sizeTable.indexSubtableArrayOffset; + for (unsigned int j = 0; j < sizeTable.numberOfIndexSubtables; ++j) + { + const IndexSubtableRecord &subtable_record = subtable_array.indexSubtablesZ[j]; + for (unsigned int gid = subtable_record.firstGlyphIndex; + gid <= subtable_record.lastGlyphIndex; ++gid) + { + unsigned int image_offset = 0, image_length = 0, image_format = 0; + + if (!subtable_record.get_image_data (gid, + &image_offset, &image_length, &image_format)) + continue; + + switch (image_format) + { + case 17: { + const GlyphBitmapDataFormat17& glyphFormat17 = + StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset); + callback ((const uint8_t *) &glyphFormat17.data.arrayZ, + glyphFormat17.data.len, i, gid); + } + break; + case 18: { + const GlyphBitmapDataFormat18& glyphFormat18 = + StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset); + callback ((const uint8_t *) &glyphFormat18.data.arrayZ, + glyphFormat18.data.len, i, gid); + } + break; + case 19: { + const GlyphBitmapDataFormat19& glyphFormat19 = + StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset); + callback ((const uint8_t *) &glyphFormat19.data.arrayZ, + glyphFormat19.data.len, i, gid); + } + break; + default: + continue; + } + } + } + } + } + private: hb_blob_t *cblc_blob; hb_blob_t *cbdt_blob; @@ -459,9 +527,8 @@ struct CBDT protected: - FixedVersion<>version; - HBUINT8 dataZ[VAR]; - + FixedVersion<> version; + HBUINT8 dataZ[VAR]; public: DEFINE_SIZE_ARRAY(4, dataZ); }; diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 2c3b1cc..ce6702d 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -28,12 +28,12 @@ #include "hb-open-type-private.hh" /* - * Color Palette - * http://www.microsoft.com/typography/otspec/colr.htm + * COLR -- Color + * https://docs.microsoft.com/en-us/typography/opentype/spec/colr */ - #define HB_OT_TAG_COLR HB_TAG('C','O','L','R') + namespace OT { @@ -48,8 +48,8 @@ struct LayerRecord } protected: - GlyphID gID; /* Glyph ID of layer glyph */ - HBUINT16 paletteIndex; /* Index value to use with a selected color palette */ + GlyphID glyphid; /* Glyph ID of layer glyph */ + HBUINT16 colorIdx; /* Index value to use with a selected color palette */ public: DEFINE_SIZE_STATIC (4); }; @@ -61,17 +61,28 @@ struct BaseGlyphRecord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (likely (c->check_struct (this))); + } + + inline int cmp (hb_codepoint_t g) const { + return g < glyphid ? -1 : g > glyphid ? 1 : 0; } protected: - GlyphID gID; /* Glyph ID of reference glyph */ - HBUINT16 firstLayerIndex; /* Index to the layer record */ - HBUINT16 numLayers; /* Number of color layers associated with this glyph */ + GlyphID glyphid; /* Glyph ID of reference glyph */ + HBUINT16 firstLayerIdx; /* Index to the layer record */ + HBUINT16 numLayers; /* Number of color layers associated with this glyph */ public: DEFINE_SIZE_STATIC (6); }; +static int compare_bgr (const void *pa, const void *pb) +{ + const hb_codepoint_t *a = (const hb_codepoint_t *) pa; + const BaseGlyphRecord *b = (const BaseGlyphRecord *) pb; + return b->cmp (*a); +} + struct COLR { static const hb_tag_t tableTag = HB_OT_TAG_COLR; @@ -79,59 +90,50 @@ struct COLR inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!(c->check_struct (this) && - c->check_array ((const void*) &layerRecordsOffsetZ, sizeof (LayerRecord), numLayerRecords) && - c->check_array ((const void*) &baseGlyphRecordsZ, sizeof (BaseGlyphRecord), numBaseGlyphRecords))) - return_trace (false); - - const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this); - for (unsigned int i = 0; i < numBaseGlyphRecords; ++i) - if (base_glyph_records[i].firstLayerIndex + - base_glyph_records[i].numLayers > numLayerRecords) - return_trace (false); - - return_trace (true); + return_trace (likely (c->check_struct (this) && + (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && + (this+layersZ).sanitize (c, numLayers))); } - inline bool get_base_glyph_record ( - hb_codepoint_t glyph_id, unsigned int &first_layer, unsigned int &num_layers) const + inline bool get_base_glyph_record (hb_codepoint_t glyph_id, + unsigned int *first_layer /* OUT */, + unsigned int *num_layers /* OUT */) const { - const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this); - unsigned int min = 0, max = numBaseGlyphRecords - 1; - while (min <= max) - { - unsigned int mid = (min + max) / 2; - hb_codepoint_t gID = base_glyph_records[mid].gID; - if (gID > glyph_id) - max = mid - 1; - else if (gID < glyph_id) - min = mid + 1; - else - { - first_layer = base_glyph_records[mid].firstLayerIndex; - num_layers = base_glyph_records[mid].numLayers; - return true; - } - } - return false; + const BaseGlyphRecord* record; + record = (BaseGlyphRecord *) bsearch (&glyph_id, &(this+baseGlyphsZ), numBaseGlyphs, + sizeof (BaseGlyphRecord), compare_bgr); + if (unlikely (!record)) + return false; + + *first_layer = record->firstLayerIdx; + *num_layers = record->numLayers; + return true; } - inline void get_layer_record (int layer, - hb_codepoint_t &glyph_id, unsigned int &palette_index) const + inline bool get_layer_record (unsigned int record, + hb_codepoint_t *glyph_id /* OUT */, + unsigned int *palette_index /* OUT */) const { - const LayerRecord* records = &layerRecordsOffsetZ (this); - glyph_id = records[layer].gID; - palette_index = records[layer].paletteIndex; + if (unlikely (record >= numLayers)) + { + *glyph_id = 0; + *palette_index = 0xFFFF; + return false; + } + const LayerRecord &layer = (this+layersZ)[record]; + *glyph_id = layer.glyphid; + *palette_index = layer.colorIdx; + return true; } protected: - HBUINT16 version; /* Table version number */ - HBUINT16 numBaseGlyphRecords; /* Number of Base Glyph Records */ - LOffsetTo<BaseGlyphRecord> - baseGlyphRecordsZ; /* Offset to Base Glyph records. */ - LOffsetTo<LayerRecord> - layerRecordsOffsetZ; /* Offset to Layer Records */ - HBUINT16 numLayerRecords; /* Number of Layer Records */ + HBUINT16 version; /* Table version number */ + HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records */ + LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> > + baseGlyphsZ; /* Offset to Base Glyph records. */ + LOffsetTo<UnsizedArrayOf<LayerRecord> > + layersZ; /* Offset to Layer Records */ + HBUINT16 numLayers; /* Number of Layer Records */ public: DEFINE_SIZE_STATIC (14); }; diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index e364c8a..2c31274 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -79,12 +79,12 @@ typedef enum { /*< flags >*/ /* - * Color Palette - * http://www.microsoft.com/typography/otspec/cpal.htm + * CPAL -- Color Palette + * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal */ - #define HB_OT_TAG_CPAL HB_TAG('C','P','A','L') + namespace OT { @@ -92,35 +92,44 @@ struct CPALV1Tail { friend struct CPAL; - inline bool sanitize (hb_sanitize_context_t *c, unsigned int palettes) const + inline bool + sanitize (hb_sanitize_context_t *c, const void *base, unsigned int palettes) const { TRACE_SANITIZE (this); - return_trace ( - c->check_struct (this) && - c->check_array ((const void*) &paletteFlags, sizeof (HBUINT32), palettes) && - c->check_array ((const void*) &paletteLabel, sizeof (HBUINT16), palettes) && - c->check_array ((const void*) &paletteEntryLabel, sizeof (HBUINT16), palettes)); + return_trace (c->check_struct (this) && + (base+paletteFlagsZ).sanitize (c, palettes) && + (base+paletteLabelZ).sanitize (c, palettes) && + (base+paletteEntryLabelZ).sanitize (c, palettes)); } private: inline hb_ot_color_palette_flags_t get_palette_flags (const void *base, unsigned int palette) const { - const HBUINT32* flags = &paletteFlags (base); - return (hb_ot_color_palette_flags_t) (uint32_t) flags[palette]; + // range checked at the CPAL caller + return (hb_ot_color_palette_flags_t) (uint32_t) (base+paletteFlagsZ)[palette]; } inline unsigned int get_palette_name_id (const void *base, unsigned int palette) const { - const HBUINT16* name_ids = &paletteLabel (base); - return name_ids[palette]; + // range checked at the CPAL caller + return (base+paletteLabelZ)[palette]; } protected: - LOffsetTo<HBUINT32> paletteFlags; - LOffsetTo<HBUINT16> paletteLabel; - LOffsetTo<HBUINT16> paletteEntryLabel; + LOffsetTo<UnsizedArrayOf<HBUINT32> > + paletteFlagsZ; /* Offset from the beginning of CPAL table to + * the Palette Type Array. Set to 0 if no array + * is provided. */ + LOffsetTo<UnsizedArrayOf<HBUINT16> > + paletteLabelZ; /* Offset from the beginning of CPAL table to + * the Palette Labels Array. Set to 0 if no + * array is provided. */ + LOffsetTo<UnsizedArrayOf<HBUINT16> > + paletteEntryLabelZ; /* Offset from the beginning of CPAL table to + * the Palette Entry Label Array. Set to 0 + * if no array is provided. */ public: DEFINE_SIZE_STATIC (12); }; @@ -134,21 +143,22 @@ struct CPAL inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!(c->check_struct (this) && // This checks colorRecordIndicesX sanity also, see #get_size - c->check_array ((const void*) &colorRecordsZ, sizeof (BGRAColor), numColorRecords))) + if (unlikely (!(c->check_struct (this) && // it checks colorRecordIndices also + // see #get_size + (this+colorRecordsZ).sanitize (c, numColorRecords)))) return_trace (false); // Check for indices sanity so no need for doing it runtime for (unsigned int i = 0; i < numPalettes; ++i) - if (colorRecordIndicesX[i] + numPaletteEntries > numColorRecords) - return_trace (false); + if (unlikely (colorRecordIndicesZ[i] + numPaletteEntries > numColorRecords)) + return_trace (false); // If version is zero, we are done here; otherwise we need to check tail also if (version == 0) return_trace (true); const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this); - return_trace (v1.sanitize (c, numPalettes)); + return_trace (likely (v1.sanitize (c, this, numPalettes))); } inline unsigned int get_size (void) const @@ -158,7 +168,7 @@ struct CPAL inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const { - if (version == 0 || palette >= numPalettes) + if (unlikely (version == 0 || palette >= numPalettes)) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); @@ -167,7 +177,7 @@ struct CPAL inline unsigned int get_palette_name_id (unsigned int palette) const { - if (version == 0 || palette >= numPalettes) + if (unlikely (version == 0 || palette >= numPalettes)) return 0xFFFF; const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); @@ -179,27 +189,33 @@ struct CPAL return numPalettes; } - inline hb_ot_color_t get_color_record_argb (unsigned int color_index, unsigned int palette) const + inline hb_ot_color_t + get_color_record_argb (unsigned int color_index, unsigned int palette) const { - if (color_index >= numPaletteEntries || palette >= numPalettes) + if (unlikely (color_index >= numPaletteEntries || palette >= numPalettes)) return 0; - const BGRAColor* records = &colorRecordsZ(this); // No need for more range check as it is already done on #sanitize - return records[colorRecordIndicesX[palette] + color_index]; + const UnsizedArrayOf<BGRAColor>& color_records = this+colorRecordsZ; + return color_records[colorRecordIndicesZ[palette] + color_index]; } protected: - HBUINT16 version; + HBUINT16 version; /* Table version number */ /* Version 0 */ - HBUINT16 numPaletteEntries; - HBUINT16 numPalettes; - HBUINT16 numColorRecords; - LOffsetTo<HBUINT32> colorRecordsZ; - HBUINT16 colorRecordIndicesX[VAR]; // VAR=numPalettes -/*CPALV1Tail v1[VAR];*/ + HBUINT16 numPaletteEntries; /* Number of palette entries in each palette. */ + HBUINT16 numPalettes; /* Number of palettes in the table. */ + HBUINT16 numColorRecords; /* Total number of color records, combined for + * all palettes. */ + LOffsetTo<UnsizedArrayOf<BGRAColor> > + colorRecordsZ; /* Offset from the beginning of CPAL table to + * the first ColorRecord. */ + UnsizedArrayOf<HBUINT16> + colorRecordIndicesZ; /* Index of each palette’s first color record in + * the combined color record array. */ +/*CPALV1Tail v1;*/ public: - DEFINE_SIZE_ARRAY (12, colorRecordIndicesX); + DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ); }; } /* namespace OT */ diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh new file mode 100644 index 0000000..09a9517 --- /dev/null +++ b/src/hb-ot-color-sbix-table.hh @@ -0,0 +1,153 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_OT_COLOR_SBIX_TABLE_HH +#define HB_OT_COLOR_SBIX_TABLE_HH + +#include "hb-open-type-private.hh" + +/* + * sbix -- Standard Bitmap Graphics + * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html + */ +#define HB_OT_TAG_sbix HB_TAG('s','b','i','x') + + +namespace OT { + + +struct SBIXGlyph +{ + HBINT16 xOffset; /* The horizontal (x-axis) offset from the left + * edge of the graphic to the glyph’s origin. + * That is, the x-coordinate of the point on the + * baseline at the left edge of the glyph. */ + HBINT16 yOffset; /* The vertical (y-axis) offset from the bottom + * edge of the graphic to the glyph’s origin. + * That is, the y-coordinate of the point on the + * baseline at the left edge of the glyph. */ + Tag graphicType; /* Indicates the format of the embedded graphic + * data: one of 'jpg ', 'png ' or 'tiff', or the + * special format 'dupe'. */ + UnsizedArrayOf<HBUINT8> + data; /* The actual embedded graphic data. The total + * length is inferred from sequential entries in + * the glyphDataOffsets array and the fixed size + * (8 bytes) of the preceding fields. */ + public: + DEFINE_SIZE_ARRAY (8, data); +}; + +struct SBIXStrike +{ + friend struct sbix; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + imageOffsetsZ.sanitize_shallow (c, c->num_glyphs + 1)); + } + + protected: + HBUINT16 ppem; /* The PPEM size for which this strike was designed. */ + HBUINT16 resolution; /* The device pixel density (in PPI) for which this + * strike was designed. (E.g., 96 PPI, 192 PPI.) */ + UnsizedArrayOf<LOffsetTo<SBIXGlyph> > + imageOffsetsZ; /* Offset from the beginning of the strike data header + * to bitmap data for an individual glyph ID. */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct sbix +{ + static const hb_tag_t tableTag = HB_OT_TAG_sbix; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && strikes.sanitize (c, this))); + } + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + num_glyphs = hb_face_get_glyph_count (face); + + OT::Sanitizer<OT::sbix> sanitizer; + sanitizer.set_num_glyphs (num_glyphs); + sbix_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_sbix)); + sbix_len = hb_blob_get_length (sbix_blob); + sbix_table = sbix_blob->as<OT::sbix> (); + + } + + inline void fini (void) + { + hb_blob_destroy (sbix_blob); + } + + inline void dump (void (*callback) (const uint8_t* data, unsigned int length, + unsigned int group, unsigned int gid)) const + { + for (unsigned group = 0; group < sbix_table->strikes.len; ++group) + { + const SBIXStrike &strike = sbix_table->strikes[group](sbix_table); + for (unsigned int glyph = 0; glyph < num_glyphs; ++glyph) + if (strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] > 0) + { + const SBIXGlyph &sbixGlyph = strike.imageOffsetsZ[glyph]((const void *) &strike); + callback ((const uint8_t*) &sbixGlyph.data, + strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] - 8, + group, glyph); + } + } + } + + private: + hb_blob_t *sbix_blob; + const sbix *sbix_table; + + unsigned int sbix_len; + unsigned int num_glyphs; + + }; + + protected: + HBUINT16 version; /* Table version number — set to 1 */ + HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. + * Bits 2 to 15: reserved (set to 0). */ + LArrayOf<LOffsetTo<SBIXStrike> > + strikes; /* Offsets from the beginning of the 'sbix' + * table to data for each individual bitmap strike. */ + public: + DEFINE_SIZE_ARRAY (8, strikes); +}; + +} /* namespace OT */ + +#endif /* HB_OT_COLOR_SBIX_TABLE_HH */ diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh new file mode 100644 index 0000000..ed6cf97 --- /dev/null +++ b/src/hb-ot-color-svg-table.hh @@ -0,0 +1,145 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_OT_COLOR_SVG_TABLE_HH +#define HB_OT_COLOR_SVG_TABLE_HH + +#include "hb-open-type-private.hh" + +/* + * SVG -- SVG (Scalable Vector Graphics) + * https://docs.microsoft.com/en-us/typography/opentype/spec/svg + */ + +#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ') + + +namespace OT { + + +struct SVGDocumentIndexEntry +{ + friend struct SVG; + + inline bool sanitize (hb_sanitize_context_t *c, const void* base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + (base+svgDoc).sanitize (c, svgDocLength)); + } + + protected: + HBUINT16 startGlyphID; /* The first glyph ID in the range described by + * this index entry. */ + HBUINT16 endGlyphID; /* The last glyph ID in the range described by + * this index entry. Must be >= startGlyphID. */ + LOffsetTo<UnsizedArrayOf<HBUINT8> > + svgDoc; /* Offset from the beginning of the SVG Document Index + * to an SVG document. Must be non-zero. */ + HBUINT32 svgDocLength; /* Length of the SVG document. + * Must be non-zero. */ + public: + DEFINE_SIZE_STATIC (12); +}; + +struct SVGDocumentIndex +{ + friend struct SVG; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + entries.sanitize (c, this)); + } + + protected: + ArrayOf<SVGDocumentIndexEntry> + entries; /* Array of SVG Document Index Entries. */ + public: + DEFINE_SIZE_ARRAY (2, entries); +}; + +struct SVG +{ + static const hb_tag_t tableTag = HB_OT_TAG_SVG; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (this+svgDocIndex).sanitize (c))); + } + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + OT::Sanitizer<OT::SVG> sanitizer; + svg_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_SVG)); + svg_len = hb_blob_get_length (svg_blob); + svg = svg_blob->as<OT::SVG> (); + + } + + inline void fini (void) + { + hb_blob_destroy (svg_blob); + } + + inline void + dump (void (*callback) (const uint8_t* data, unsigned int length, + unsigned int start_glyph, unsigned int end_glyph)) const + { + const SVGDocumentIndex &index = svg+svg->svgDocIndex; + const ArrayOf<SVGDocumentIndexEntry> &entries = index.entries; + for (unsigned int i = 0; i < entries.len; ++i) + { + const SVGDocumentIndexEntry &entry = entries[i]; + callback ((const uint8_t*) &entry.svgDoc (&index), entry.svgDocLength, + entry.startGlyphID, entry.endGlyphID); + } + } + + private: + hb_blob_t *svg_blob; + const SVG *svg; + + unsigned int svg_len; + }; + + protected: + HBUINT16 version; /* Table version (starting at 0). */ + LOffsetTo<SVGDocumentIndex> + svgDocIndex; /* Offset (relative to the start of the SVG table) to the + * SVG Documents Index. Must be non-zero. */ + HBUINT32 reserved; /* Set to 0. */ + public: + DEFINE_SIZE_STATIC (10); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_COLOR_SVG_TABLE_HH */ diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index ceebe0b..86171c6 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -44,7 +44,7 @@ HB_MARK_AS_FLAG_T (hb_ot_color_palette_flags_t) static inline const OT::COLR& _get_colr (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::COLR); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::COLR); hb_ot_layout_t * layout = hb_ot_layout_from_face (face); return *(layout->colr.get ()); } @@ -52,7 +52,7 @@ _get_colr (hb_face_t *face) static inline const OT::CPAL& _get_cpal (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::CPAL); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CPAL); hb_ot_layout_t * layout = hb_ot_layout_from_face (face); return *(layout->cpal.get ()); } diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 0e373d3..8310230 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -143,7 +143,7 @@ hb_ot_get_glyph_h_kerning (hb_font_t *font, } static hb_bool_t -hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, +hb_ot_get_glyph_extents (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_glyph_extents_t *extents, @@ -184,7 +184,7 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, } static hb_bool_t -hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, +hb_ot_get_font_h_extents (hb_font_t *font, void *font_data, hb_font_extents_t *metrics, void *user_data HB_UNUSED) @@ -198,7 +198,7 @@ hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, } static hb_bool_t -hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED, +hb_ot_get_font_v_extents (hb_font_t *font, void *font_data, hb_font_extents_t *metrics, void *user_data HB_UNUSED) @@ -217,7 +217,12 @@ static hb_font_funcs_t *static_ot_funcs = nullptr; static void free_static_ot_funcs (void) { - hb_font_funcs_destroy (static_ot_funcs); +retry: + hb_font_funcs_t *ot_funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_funcs); + if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, ot_funcs, nullptr)) + goto retry; + + hb_font_funcs_destroy (ot_funcs); } #endif diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index d62f24b..89c867d 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -38,8 +38,8 @@ namespace OT { /* * loca -- Index to Location + * https://docs.microsoft.com/en-us/typography/opentype/spec/loca */ - #define HB_OT_TAG_loca HB_TAG('l','o','c','a') @@ -56,15 +56,15 @@ struct loca } protected: - HBUINT8 dataX[VAR]; /* Location data. */ - DEFINE_SIZE_ARRAY (0, dataX); + HBUINT8 dataZ[VAR]; /* Location data. */ + DEFINE_SIZE_ARRAY (0, dataZ); }; /* * glyf -- TrueType Glyph Data + * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf */ - #define HB_OT_TAG_glyf HB_TAG('g','l','y','f') @@ -88,9 +88,9 @@ struct glyf bool success = true; bool use_short_loca = false; if (hb_subset_glyf_and_loca (plan, &use_short_loca, &glyf_prime, &loca_prime)) { - success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_glyf, glyf_prime); - success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_loca, loca_prime); - success = success && _add_head_and_set_loca_version (plan->source, use_short_loca, plan->dest); + success = success && plan->add_table (HB_OT_TAG_glyf, glyf_prime); + success = success && plan->add_table (HB_OT_TAG_loca, loca_prime); + success = success && _add_head_and_set_loca_version (plan, use_short_loca); } else { success = false; } @@ -101,9 +101,9 @@ struct glyf } static bool - _add_head_and_set_loca_version (hb_face_t *source, bool use_short_loca, hb_face_t *dest) + _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca) { - hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (source, HB_OT_TAG_head)); + hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_head)); hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); hb_blob_destroy (head_blob); @@ -112,7 +112,7 @@ struct glyf OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr); head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1); - bool success = hb_subset_face_add_table (dest, HB_OT_TAG_head, head_prime_blob); + bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob); hb_blob_destroy (head_prime_blob); return success; @@ -134,18 +134,20 @@ struct glyf struct CompositeGlyphHeader { - static const uint16_t ARG_1_AND_2_ARE_WORDS = 0x0001; - static const uint16_t ARGS_ARE_XY_VALUES = 0x0002; - static const uint16_t ROUND_XY_TO_GRID = 0x0004; - static const uint16_t WE_HAVE_A_SCALE = 0x0008; - static const uint16_t MORE_COMPONENTS = 0x0020; - static const uint16_t WE_HAVE_AN_X_AND_Y_SCALE = 0x0040; - static const uint16_t WE_HAVE_A_TWO_BY_TWO = 0x0080; - static const uint16_t WE_HAVE_INSTRUCTIONS = 0x0100; - static const uint16_t USE_MY_METRICS = 0x0200; - static const uint16_t OVERLAP_COMPOUND = 0x0400; - static const uint16_t SCALED_COMPONENT_OFFSET = 0x0800; - static const uint16_t UNSCALED_COMPONENT_OFFSET = 0x1000; + enum composite_glyph_flag_t { + ARG_1_AND_2_ARE_WORDS = 0x0001, + ARGS_ARE_XY_VALUES = 0x0002, + ROUND_XY_TO_GRID = 0x0004, + WE_HAVE_A_SCALE = 0x0008, + MORE_COMPONENTS = 0x0020, + WE_HAVE_AN_X_AND_Y_SCALE = 0x0040, + WE_HAVE_A_TWO_BY_TWO = 0x0080, + WE_HAVE_INSTRUCTIONS = 0x0100, + USE_MY_METRICS = 0x0200, + OVERLAP_COMPOUND = 0x0400, + SCALED_COMPONENT_OFFSET = 0x0800, + UNSCALED_COMPONENT_OFFSET = 0x1000 + }; HBUINT16 flags; HBUINT16 glyphIndex; @@ -232,11 +234,13 @@ struct glyf { inline void init (hb_face_t *face) { + memset (this, 0, sizeof (accelerator_t)); + hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head)); - const head *head_table = Sanitizer<head>::lock_instance (head_blob); - if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) + const head *head_table = head_blob->as<head> (); + if (head_table == &Null(head) || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) { - /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + /* head table is not present, or in an unknown format. Leave num_glyphs=0, that takes care of disabling us. */ hb_blob_destroy (head_blob); return; } @@ -244,9 +248,9 @@ struct glyf hb_blob_destroy (head_blob); loca_blob = Sanitizer<loca>().sanitize (face->reference_table (HB_OT_TAG_loca)); - loca_table = Sanitizer<loca>::lock_instance (loca_blob); + loca_table = loca_blob->as<loca> (); glyf_blob = Sanitizer<glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf)); - glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob); + glyf_table = glyf_blob->as<glyf> (); num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1; glyf_len = hb_blob_get_length (glyf_blob); @@ -266,6 +270,9 @@ struct glyf inline bool get_composite (hb_codepoint_t glyph, CompositeGlyphHeader::Iterator *composite /* OUT */) const { + if (this->glyf_table == &Null(glyf) || !num_glyphs) + return false; + unsigned int start_offset, end_offset; if (!get_offsets (glyph, &start_offset, &end_offset)) return false; /* glyph not found */ @@ -275,16 +282,18 @@ struct glyf composite); } + enum simple_glyph_flag_t { + FLAG_X_SHORT = 0x02, + FLAG_Y_SHORT = 0x04, + FLAG_REPEAT = 0x08, + FLAG_X_SAME = 0x10, + FLAG_Y_SAME = 0x20 + }; + /* based on FontTools _g_l_y_f.py::trim */ inline bool remove_padding(unsigned int start_offset, unsigned int *end_offset) const { - static const int FLAG_X_SHORT = 0x02; - static const int FLAG_Y_SHORT = 0x04; - static const int FLAG_REPEAT = 0x08; - static const int FLAG_X_SAME = 0x10; - static const int FLAG_Y_SAME = 0x20; - if (*end_offset - start_offset < GlyphHeader::static_size) return true; @@ -368,13 +377,13 @@ struct glyf if (short_offset) { - const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataX; + const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ; *start_offset = 2 * offsets[glyph]; *end_offset = 2 * offsets[glyph + 1]; } else { - const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX; + const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ; *start_offset = offsets[glyph]; *end_offset = offsets[glyph + 1]; @@ -411,7 +420,7 @@ struct glyf } while (composite_it.move_to_next()); if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS) - *instruction_start = ((char *) last - (char *) glyf_table->dataX) + last->get_size(); + *instruction_start = ((char *) last - (char *) glyf_table->dataZ) + last->get_size(); else *instruction_start = end_offset; *instruction_end = end_offset; @@ -424,9 +433,23 @@ struct glyf else { unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours; + if (unlikely (instruction_length_offset + 2 > end_offset)) + { + DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength."); + return false; + } + const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset); - *instruction_start = instruction_length_offset + 2; - *instruction_end = *instruction_start + (uint16_t) instruction_length; + unsigned int start = instruction_length_offset + 2; + unsigned int end = start + (uint16_t) instruction_length; + if (unlikely (end > end_offset)) // Out of bounds of the current glyph + { + DEBUG_MSG(SUBSET, nullptr, "The instructions array overruns the glyph's boundaries."); + return false; + } + + *instruction_start = start; + *instruction_end = end; } return true; } @@ -462,9 +485,9 @@ struct glyf }; protected: - HBUINT8 dataX[VAR]; /* Glyphs data. */ + HBUINT8 dataZ[VAR]; /* Glyphs data. */ - DEFINE_SIZE_ARRAY (0, dataX); + DEFINE_SIZE_ARRAY (0, dataZ); }; } /* namespace OT */ diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index f08fe39..d406e3e 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -28,40 +28,51 @@ #define HB_OT_HDMX_TABLE_HH #include "hb-open-type-private.hh" - -namespace OT { - +#include "hb-subset-plan.hh" /* - * hdmx - Horizontal Device Metric + * hdmx -- Horizontal Device Metrics + * https://docs.microsoft.com/en-us/typography/opentype/spec/hdmx */ - #define HB_OT_TAG_hdmx HB_TAG('h','d','m','x') + +namespace OT { + + struct DeviceRecord { struct SubsetView { const DeviceRecord *source_device_record; + unsigned int size_device_record; hb_subset_plan_t *subset_plan; inline void init(const DeviceRecord *source_device_record, + unsigned int size_device_record, hb_subset_plan_t *subset_plan) { this->source_device_record = source_device_record; + this->size_device_record = size_device_record; this->subset_plan = subset_plan; } inline unsigned int len () const { - return this->subset_plan->gids_to_retain_sorted.len; + return this->subset_plan->glyphs.len; } - inline const HBUINT8& operator [] (unsigned int i) const + inline const HBUINT8* operator [] (unsigned int i) const { - if (unlikely (i >= len())) return Null(HBUINT8); - hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; - return this->source_device_record->widths[gid]; + if (unlikely (i >= len())) return nullptr; + hb_codepoint_t gid = this->subset_plan->glyphs [i]; + + const HBUINT8* width = &(this->source_device_record->widths[gid]); + + if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record) + return width; + else + return nullptr; } }; @@ -85,7 +96,15 @@ struct DeviceRecord this->max_width.set (subset_view.source_device_record->max_width); for (unsigned int i = 0; i < subset_view.len(); i++) - widths[i].set (subset_view[i]); + { + const HBUINT8 *width = subset_view[i]; + if (!width) + { + DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i); + return_trace (false); + } + widths[i].set (*width); + } return_trace (true); } @@ -117,7 +136,7 @@ struct hdmx inline const DeviceRecord& operator [] (unsigned int i) const { if (unlikely (i >= num_records)) return Null(DeviceRecord); - return StructAtOffset<DeviceRecord> (this, min_size + i * size_device_record); + return StructAtOffset<DeviceRecord> (this->data, i * size_device_record); } inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan) @@ -128,14 +147,15 @@ struct hdmx this->version.set (source_hdmx->version); this->num_records.set (source_hdmx->num_records); - this->size_device_record.set (DeviceRecord::get_size (plan->gids_to_retain_sorted.len)); + this->size_device_record.set (DeviceRecord::get_size (plan->glyphs.len)); for (unsigned int i = 0; i < source_hdmx->num_records; i++) { DeviceRecord::SubsetView subset_view; - subset_view.init (&(*source_hdmx)[i], plan); + subset_view.init (&(*source_hdmx)[i], source_hdmx->size_device_record, plan); - c->start_embed<DeviceRecord> ()->serialize (c, subset_view); + if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view)) + return_trace (false); } return_trace (true); @@ -143,7 +163,7 @@ struct hdmx static inline size_t get_subsetted_size (hb_subset_plan_t *plan) { - return min_size + DeviceRecord::get_size (plan->gids_to_retain_sorted.len); + return min_size + DeviceRecord::get_size (plan->glyphs.len); } inline bool subset (hb_subset_plan_t *plan) const @@ -169,7 +189,7 @@ struct hdmx HB_MEMORY_MODE_READONLY, dest, free); - bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_hdmx, hdmx_prime_blob); + bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob); hb_blob_destroy (hdmx_prime_blob); return result; @@ -180,6 +200,7 @@ struct hdmx TRACE_SANITIZE (this); return_trace (c->check_struct (this) && version == 0 && !_hb_unsigned_int_mul_overflows (num_records, size_device_record) && + size_device_record >= DeviceRecord::min_size && c->check_range (this, get_size())); } diff --git a/src/hb-ot-head-table.hh b/src/hb-ot-head-table.hh index 1d45840..965e30a 100644 --- a/src/hb-ot-head-table.hh +++ b/src/hb-ot-head-table.hh @@ -31,16 +31,16 @@ #include "hb-open-type-private.hh" - -namespace OT { - - /* * head -- Font Header + * https://docs.microsoft.com/en-us/typography/opentype/spec/head */ - #define HB_OT_TAG_head HB_TAG('h','e','a','d') + +namespace OT { + + struct head { friend struct OffsetTable; diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh index 97952b4..efb42b6 100644 --- a/src/hb-ot-hhea-table.hh +++ b/src/hb-ot-hhea-table.hh @@ -29,18 +29,19 @@ #include "hb-open-type-private.hh" - -namespace OT { - - /* - * hhea -- The Horizontal Header Table - * vhea -- The Vertical Header Table + * hhea -- Horizontal Header + * https://docs.microsoft.com/en-us/typography/opentype/spec/hhea + * vhea -- Vertical Header + * https://docs.microsoft.com/en-us/typography/opentype/spec/vhea */ - #define HB_OT_TAG_hhea HB_TAG('h','h','e','a') #define HB_OT_TAG_vhea HB_TAG('v','h','e','a') + +namespace OT { + + template <typename T> struct _hea { diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 3cd48a6..2c62664 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -31,20 +31,21 @@ #include "hb-ot-hhea-table.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-var-hvar-table.hh" - - -namespace OT { - +#include "hb-subset-plan.hh" /* - * hmtx -- The Horizontal Metrics Table - * vmtx -- The Vertical Metrics Table + * hmtx -- Horizontal Metrics + * https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx + * vmtx -- Vertical Metrics + * https://docs.microsoft.com/en-us/typography/opentype/spec/vmtx */ - #define HB_OT_TAG_hmtx HB_TAG('h','m','t','x') #define HB_OT_TAG_vmtx HB_TAG('v','m','t','x') +namespace OT { + + struct LongMetric { UFWORD advance; /* Advance width/height. */ @@ -80,7 +81,7 @@ struct hmtxvmtx H *table = (H *) hb_blob_get_data (dest_blob, &length); table->numberOfLongMetrics.set (num_hmetrics); - bool result = hb_subset_plan_add_table (plan, H::tableTag, dest_blob); + bool result = plan->add_table (H::tableTag, dest_blob); hb_blob_destroy (dest_blob); return result; @@ -93,7 +94,7 @@ struct hmtxvmtx /* All the trailing glyphs with the same advance can use one LongMetric * and just keep LSB */ - hb_prealloced_array_t<hb_codepoint_t> &gids = plan->gids_to_retain_sorted; + hb_vector_t<hb_codepoint_t> &gids = plan->glyphs; unsigned int num_advances = gids.len; unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]); while (num_advances > 1 @@ -118,6 +119,8 @@ struct hmtxvmtx LongMetric * old_metrics = (LongMetric *) source_table; FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances); char * dest_pos = (char *) dest; + + bool failed = false; for (unsigned int i = 0; i < gids.len; i++) { /* the last metric or the one for gids[i] */ @@ -138,7 +141,14 @@ struct hmtxvmtx } else { - FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); + if (gids[i] >= _mtx.num_metrics) + { + DEBUG_MSG(SUBSET, nullptr, "gid %d is >= number of source metrics %d", + gids[i], _mtx.num_metrics); + failed = true; + break; + } + FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); if (i < num_advances) { /* dest needs a full LongMetric */ @@ -157,7 +167,7 @@ struct hmtxvmtx _mtx.fini (); // Amend header num hmetrics - if (unlikely (!subset_update_header (plan, num_advances))) + if (failed || unlikely (!subset_update_header (plan, num_advances))) { free (dest); return false; @@ -168,7 +178,7 @@ struct hmtxvmtx HB_MEMORY_MODE_READONLY, dest, free); - bool success = hb_subset_plan_add_table (plan, T::tableTag, result); + bool success = plan->add_table (T::tableTag, result); hb_blob_destroy (result); return success; } @@ -186,7 +196,7 @@ struct hmtxvmtx if (T::os2Tag) { hb_blob_t *os2_blob = Sanitizer<os2> ().sanitize (face->reference_table (T::os2Tag)); - const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob); + const os2 *os2_table = os2_blob->as<os2> (); #define USE_TYPO_METRICS (1u<<7) if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) { @@ -199,7 +209,7 @@ struct hmtxvmtx } hb_blob_t *_hea_blob = Sanitizer<H> ().sanitize (face->reference_table (H::tableTag)); - const H *_hea_table = Sanitizer<H>::lock_instance (_hea_blob); + const H *_hea_table = _hea_blob->as<H> (); num_advances = _hea_table->numberOfLongMetrics; if (!got_font_extents) { @@ -228,10 +238,10 @@ struct hmtxvmtx hb_blob_destroy (blob); blob = hb_blob_get_empty (); } - table = Sanitizer<hmtxvmtx>::lock_instance (blob); + table = blob->as<hmtxvmtx> (); var_blob = Sanitizer<HVARVVAR> ().sanitize (face->reference_table (T::variationsTag)); - var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob); + var_table = var_blob->as<HVARVVAR> (); } inline void fini (void) @@ -264,7 +274,7 @@ struct hmtxvmtx { advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! } - return advance; + return advance; } public: diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 368f547..b0fdea4 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -29,15 +29,17 @@ #include "hb-open-type-private.hh" -namespace OT { - - /* * kern -- Kerning + * https://docs.microsoft.com/en-us/typography/opentype/spec/kern + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html */ - #define HB_OT_TAG_kern HB_TAG('k','e','r','n') + +namespace OT { + + struct hb_glyph_pair_t { hb_codepoint_t left; @@ -205,7 +207,7 @@ struct KernSubTableWrapper { TRACE_SANITIZE (this); return_trace (c->check_struct (thiz()) && - thiz()->length >= thiz()->min_size && + thiz()->length >= T::min_size && c->check_array (thiz(), 1, thiz()->length) && thiz()->subtable.sanitize (c, thiz()->format)); } @@ -361,8 +363,8 @@ struct kern inline void init (hb_face_t *face) { blob = Sanitizer<kern>().sanitize (face->reference_table (HB_OT_TAG_kern)); - table = Sanitizer<kern>::lock_instance (blob); - table_length = hb_blob_get_length (blob); + table = blob->as<kern> (); + table_length = blob->length; } inline void fini (void) { diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index 20b8bd7..33dce89 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -36,7 +36,8 @@ namespace OT { #define NOT_INDEXED ((unsigned int) -1) /* - * BASE -- The BASE Table + * BASE -- Baseline + * https://docs.microsoft.com/en-us/typography/opentype/spec/base */ struct BaseCoordFormat1 diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index c5e7f52..763ea92 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -165,7 +165,7 @@ struct RangeRecord public: DEFINE_SIZE_STATIC (6); }; -DEFINE_NULL_DATA (RangeRecord, "\000\001"); +DEFINE_NULL_DATA (OT, RangeRecord, "\000\001"); struct IndexArray : ArrayOf<Index> @@ -225,7 +225,7 @@ struct LangSys public: DEFINE_SIZE_ARRAY (6, featureIndex); }; -DEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF"); +DEFINE_NULL_DATA (OT, LangSys, "\0\0\xFF\xFF"); struct Script @@ -270,7 +270,7 @@ struct Script typedef RecordListOf<Script> ScriptList; -/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ +/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */ struct FeatureParamsSize { inline bool sanitize (hb_sanitize_context_t *c) const @@ -292,7 +292,7 @@ struct FeatureParamsSize * * The specification for this feature tag is in the "OpenType Layout Tag * Registry". You can see a copy of this at: - * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size + * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size * * Here is one set of rules to determine if the 'size' feature is built * correctly, or as by the older versions of MakeOTF. You may be able to do @@ -382,7 +382,7 @@ struct FeatureParamsSize DEFINE_SIZE_STATIC (10); }; -/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ +/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#ssxx */ struct FeatureParamsStylisticSet { inline bool sanitize (hb_sanitize_context_t *c) const @@ -398,7 +398,7 @@ struct FeatureParamsStylisticSet * added to the end of this Feature Parameters * table in the future. */ - HBUINT16 uiNameID; /* The 'name' table name ID that specifies a + NameID uiNameID; /* The 'name' table name ID that specifies a * string (or strings, for multiple languages) * for a user-interface label for this * feature. The values of uiLabelNameId and @@ -416,7 +416,7 @@ struct FeatureParamsStylisticSet DEFINE_SIZE_STATIC (4); }; -/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ +/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99 */ struct FeatureParamsCharacterVariants { inline bool sanitize (hb_sanitize_context_t *c) const @@ -427,29 +427,29 @@ struct FeatureParamsCharacterVariants } HBUINT16 format; /* Format number is set to 0. */ - HBUINT16 featUILableNameID; /* The ‘name’ table name ID that + NameID featUILableNameID; /* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) for a * user-interface label for this * feature. (May be nullptr.) */ - HBUINT16 featUITooltipTextNameID;/* The ‘name’ table name ID that + NameID featUITooltipTextNameID;/* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) that an * application can use for tooltip * text for this feature. (May be * nullptr.) */ - HBUINT16 sampleTextNameID; /* The ‘name’ table name ID that + NameID sampleTextNameID; /* The ‘name’ table name ID that * specifies sample text that * illustrates the effect of this * feature. (May be nullptr.) */ HBUINT16 numNamedParameters; /* Number of named parameters. (May * be zero.) */ - HBUINT16 firstParamUILabelNameID;/* The first ‘name’ table name ID + NameID firstParamUILabelNameID;/* The first ‘name’ table name ID * used to specify strings for * user-interface labels for the * feature parameters. (Must be zero * if numParameters is zero.) */ - ArrayOf<UINT24> + ArrayOf<HBUINT24> characters; /* Array of the Unicode Scalar Value * of the characters for which this * feature provides glyph variants. @@ -716,7 +716,7 @@ struct CoverageFormat1 template <typename set_t> inline bool add_coverage (set_t *glyphs) const { - return glyphs->add_sorted_array (glyphArray.array, glyphArray.len); + return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len); } public: @@ -1272,7 +1272,7 @@ struct VarRegionList if (unlikely (region_index >= regionCount)) return 0.; - const VarRegionAxis *axes = axesZ + (region_index * axisCount); + const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); float v = 1.; unsigned int count = axisCount; @@ -1280,7 +1280,7 @@ struct VarRegionList { int coord = i < coord_len ? coords[i] : 0; float factor = axes[i].evaluate (coord); - if (factor == 0.) + if (factor == 0.f) return 0.; v *= factor; } @@ -1291,14 +1291,14 @@ struct VarRegionList { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - c->check_array (axesZ, axesZ[0].static_size, - (unsigned int) axisCount * (unsigned int) regionCount)); + axesZ.sanitize (c, (unsigned int) axisCount * (unsigned int) regionCount)); } protected: HBUINT16 axisCount; HBUINT16 regionCount; - VarRegionAxis axesZ[VAR]; + UnsizedArrayOf<VarRegionAxis> + axesZ; public: DEFINE_SIZE_ARRAY (4, axesZ); }; @@ -1330,13 +1330,13 @@ struct VarData const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row); for (; i < scount; i++) { - float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count); delta += scalar * *scursor++; } const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor); for (; i < count; i++) { - float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count); delta += scalar * *bcursor++; } @@ -1357,7 +1357,7 @@ struct VarData HBUINT16 itemCount; HBUINT16 shortCount; ArrayOf<HBUINT16> regionIndices; - HBUINT8 bytesX[VAR]; + HBUINT8 bytesX[VAR]; public: DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); }; @@ -1465,7 +1465,7 @@ struct ConditionSet { unsigned int count = conditions.len; for (unsigned int i = 0; i < count; i++) - if (!(this+conditions.array[i]).evaluate (coords, coord_len)) + if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len)) return false; return true; } @@ -1506,7 +1506,7 @@ struct FeatureTableSubstitution unsigned int count = substitutions.len; for (unsigned int i = 0; i < count; i++) { - const FeatureTableSubstitutionRecord &record = substitutions.array[i]; + const FeatureTableSubstitutionRecord &record = substitutions.arrayZ[i]; if (record.featureIndex == feature_index) return &(this+record.feature); } @@ -1559,7 +1559,7 @@ struct FeatureVariations unsigned int count = varRecords.len; for (unsigned int i = 0; i < count; i++) { - const FeatureVariationRecord &record = varRecords.array[i]; + const FeatureVariationRecord &record = varRecords.arrayZ[i]; if ((this+record.conditions).evaluate (coords, coord_len)) { *index = i; diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 2d6c66e..60a8d3a 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -333,7 +333,8 @@ struct MarkGlyphSets /* - * GDEF -- The Glyph Definition Table + * GDEF -- Glyph Definition + * https://docs.microsoft.com/en-us/typography/opentype/spec/gdef */ struct GDEF diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 46ffcc6..bc8a5fd 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -262,7 +262,7 @@ struct AnchorFormat2 hb_font_t *font = c->font; unsigned int x_ppem = font->x_ppem; unsigned int y_ppem = font->y_ppem; - hb_position_t cx, cy; + hb_position_t cx = 0, cy = 0; hb_bool_t ret; ret = (x_ppem || y_ppem) && @@ -1497,7 +1497,8 @@ struct PosLookup : Lookup typedef OffsetListOf<PosLookup> PosLookupList; /* - * GPOS -- The Glyph Positioning Table + * GPOS -- Glyph Positioning + * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos */ struct GPOS : GSUBGPOS diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 5f67aed..bd72fe6 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -269,7 +269,7 @@ struct Sequence inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - c->output->add_array (substitute.array, substitute.len); + c->output->add_array (substitute.arrayZ, substitute.len); } inline bool apply (hb_ot_apply_context_t *c) const @@ -281,7 +281,7 @@ struct Sequence * as a "multiplied" substitution. */ if (unlikely (count == 1)) { - c->replace_glyph (substitute.array[0]); + c->replace_glyph (substitute.arrayZ[0]); return_trace (true); } /* Spec disallows this, but Uniscribe allows it. @@ -297,7 +297,7 @@ struct Sequence for (unsigned int i = 0; i < count; i++) { _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); - c->output_glyph_for_component (substitute.array[i], klass); + c->output_glyph_for_component (substitute.arrayZ[i], klass); } c->buffer->skip_glyph (); @@ -480,7 +480,7 @@ struct AlternateSubstFormat1 if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; - c->output->add_array (alt_set.array, alt_set.len); + c->output->add_array (alt_set.arrayZ, alt_set.len); } } @@ -611,7 +611,7 @@ struct Ligature inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - c->input->add_array (component.array, component.len ? component.len - 1 : 0); + c->input->add_array (component.arrayZ, component.len ? component.len - 1 : 0); c->output->add (ligGlyph); } @@ -979,7 +979,7 @@ struct ReverseChainSingleSubstFormat1 const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); count = substitute.len; - c->output->add_array (substitute.array, substitute.len); + c->output->add_array (substitute.arrayZ, substitute.len); } inline const Coverage &get_coverage (void) const @@ -1007,11 +1007,11 @@ struct ReverseChainSingleSubstFormat1 unsigned int start_index = 0, end_index = 0; if (match_backtrack (c, - backtrack.len, (HBUINT16 *) backtrack.array, + backtrack.len, (HBUINT16 *) backtrack.arrayZ, match_coverage, this, &start_index) && match_lookahead (c, - lookahead.len, (HBUINT16 *) lookahead.array, + lookahead.len, (HBUINT16 *) lookahead.arrayZ, match_coverage, this, 1, &end_index)) { @@ -1156,10 +1156,13 @@ struct SubstLookup : Lookup return_trace (dispatch (c)); } - inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const + inline hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const { TRACE_CLOSURE (this); - c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); + if (!c->should_visit_lookup (this_index)) + return_trace (HB_VOID); + + c->set_recurse_func (dispatch_closure_recurse_func); return_trace (dispatch (c)); } @@ -1258,6 +1261,13 @@ struct SubstLookup : Lookup template <typename context_t> static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); + static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) + { + if (!c->should_visit_lookup (lookup_index)) + return HB_VOID; + return dispatch_recurse_func (c, lookup_index); + } + template <typename context_t> inline typename context_t::return_t dispatch (context_t *c) const { return Lookup::dispatch<SubstLookupSubTable> (c); } @@ -1287,7 +1297,8 @@ struct SubstLookup : Lookup typedef OffsetListOf<SubstLookup> SubstLookupList; /* - * GSUB -- The Glyph Substitution Table + * GSUB -- Glyph Substitution + * https://docs.microsoft.com/en-us/typography/opentype/spec/gsub */ struct GSUB : GSUBGPOS diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 9054634..661085d 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -32,6 +32,7 @@ #include "hb-private.hh" #include "hb-debug.hh" #include "hb-buffer-private.hh" +#include "hb-map-private.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-set-private.hh" @@ -59,6 +60,20 @@ struct hb_closure_context_t : return HB_VOID; } + bool should_visit_lookup (unsigned int lookup_index) + { + if (is_lookup_done (lookup_index)) + return false; + done_lookups->set (lookup_index, glyphs->get_population ()); + return true; + } + + bool is_lookup_done (unsigned int lookup_index) + { + // Have we visited this lookup with the current set of glyphs? + return done_lookups->get (lookup_index) == glyphs->get_population (); + } + hb_face_t *face; hb_set_t *glyphs; recurse_func_t recurse_func; @@ -67,14 +82,19 @@ struct hb_closure_context_t : hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, + hb_map_t *done_lookups_, unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), recurse_func (nullptr), nesting_level_left (nesting_level_left_), - debug_depth (0) {} + debug_depth (0), + done_lookups (done_lookups_) {} void set_recurse_func (recurse_func_t func) { recurse_func = func; } + + private: + hb_map_t *done_lookups; }; @@ -855,7 +875,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, for (unsigned int i = 1; i < count; i++) { - while (buffer->idx < match_positions[i] && !buffer->in_error) + while (buffer->idx < match_positions[i] && buffer->successful) { if (!is_mark_ligature) { unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); @@ -990,7 +1010,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, match_positions[j] += delta; } - for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++) + for (unsigned int i = 0; i < lookupCount && buffer->successful; i++) { unsigned int idx = lookupRecord[i].sequenceIndex; if (idx >= count) @@ -1713,10 +1733,10 @@ struct ChainRule const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_closure_lookup (c, - backtrack.len, backtrack.array, - input.len, input.array, - lookahead.len, lookahead.array, - lookup.len, lookup.array, + backtrack.len, backtrack.arrayZ, + input.len, input.arrayZ, + lookahead.len, lookahead.arrayZ, + lookup.len, lookup.arrayZ, lookup_context); } @@ -1727,10 +1747,10 @@ struct ChainRule const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_collect_glyphs_lookup (c, - backtrack.len, backtrack.array, - input.len, input.array, - lookahead.len, lookahead.array, - lookup.len, lookup.array, + backtrack.len, backtrack.arrayZ, + input.len, input.arrayZ, + lookahead.len, lookahead.arrayZ, + lookup.len, lookup.arrayZ, lookup_context); } @@ -1741,10 +1761,10 @@ struct ChainRule const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_would_apply_lookup (c, - backtrack.len, backtrack.array, - input.len, input.array, - lookahead.len, lookahead.array, lookup.len, - lookup.array, lookup_context)); + backtrack.len, backtrack.arrayZ, + input.len, input.arrayZ, + lookahead.len, lookahead.arrayZ, lookup.len, + lookup.arrayZ, lookup_context)); } inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const @@ -1754,10 +1774,10 @@ struct ChainRule const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_apply_lookup (c, - backtrack.len, backtrack.array, - input.len, input.array, - lookahead.len, lookahead.array, lookup.len, - lookup.array, lookup_context)); + backtrack.len, backtrack.arrayZ, + input.len, input.arrayZ, + lookahead.len, lookahead.arrayZ, lookup.len, + lookup.arrayZ, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -2072,10 +2092,10 @@ struct ChainContextFormat3 {this, this, this} }; chain_context_closure_lookup (c, - backtrack.len, (const HBUINT16 *) backtrack.array, - input.len, (const HBUINT16 *) input.array + 1, - lookahead.len, (const HBUINT16 *) lookahead.array, - lookup.len, lookup.array, + backtrack.len, (const HBUINT16 *) backtrack.arrayZ, + input.len, (const HBUINT16 *) input.arrayZ + 1, + lookahead.len, (const HBUINT16 *) lookahead.arrayZ, + lookup.len, lookup.arrayZ, lookup_context); } @@ -2093,10 +2113,10 @@ struct ChainContextFormat3 {this, this, this} }; chain_context_collect_glyphs_lookup (c, - backtrack.len, (const HBUINT16 *) backtrack.array, - input.len, (const HBUINT16 *) input.array + 1, - lookahead.len, (const HBUINT16 *) lookahead.array, - lookup.len, lookup.array, + backtrack.len, (const HBUINT16 *) backtrack.arrayZ, + input.len, (const HBUINT16 *) input.arrayZ + 1, + lookahead.len, (const HBUINT16 *) lookahead.arrayZ, + lookup.len, lookup.arrayZ, lookup_context); } @@ -2112,10 +2132,10 @@ struct ChainContextFormat3 {this, this, this} }; return_trace (chain_context_would_apply_lookup (c, - backtrack.len, (const HBUINT16 *) backtrack.array, - input.len, (const HBUINT16 *) input.array + 1, - lookahead.len, (const HBUINT16 *) lookahead.array, - lookup.len, lookup.array, lookup_context)); + backtrack.len, (const HBUINT16 *) backtrack.arrayZ, + input.len, (const HBUINT16 *) input.arrayZ + 1, + lookahead.len, (const HBUINT16 *) lookahead.arrayZ, + lookup.len, lookup.arrayZ, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -2139,10 +2159,10 @@ struct ChainContextFormat3 {this, this, this} }; return_trace (chain_context_apply_lookup (c, - backtrack.len, (const HBUINT16 *) backtrack.array, - input.len, (const HBUINT16 *) input.array + 1, - lookahead.len, (const HBUINT16 *) lookahead.array, - lookup.len, lookup.array, lookup_context)); + backtrack.len, (const HBUINT16 *) backtrack.arrayZ, + input.len, (const HBUINT16 *) input.arrayZ + 1, + lookahead.len, (const HBUINT16 *) lookahead.arrayZ, + lookup.len, lookup.arrayZ, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-layout-jstf-table.hh b/src/hb-ot-layout-jstf-table.hh index adbaad6..7fabdeb 100644 --- a/src/hb-ot-layout-jstf-table.hh +++ b/src/hb-ot-layout-jstf-table.hh @@ -189,7 +189,8 @@ struct JstfScript /* - * JSTF -- The Justification Table + * JSTF -- Justification + * https://docs.microsoft.com/en-us/typography/opentype/spec/jstf */ struct JSTF diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 870ba73..b2f974b 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -105,12 +105,12 @@ HB_INTERNAL void hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer); -/* Should be called after all the position_lookup's are done, to finish advances. */ +/* Should be called after all the position_lookup's are done, to fini advances. */ HB_INTERNAL void hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); -/* Should be called after hb_ot_layout_position_finish_advances, to finish offsets. */ +/* Should be called after hb_ot_layout_position_finish_advances, to fini offsets. */ HB_INTERNAL void hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer); @@ -172,16 +172,10 @@ struct hb_ot_layout_t const struct OT::GPOS *gpos; /* TODO Move the following out of this struct. */ - OT::hb_lazy_table_loader_t<struct OT::BASE> base; - OT::hb_lazy_table_loader_t<struct OT::COLR> colr; - OT::hb_lazy_table_loader_t<struct OT::CPAL> cpal; - OT::hb_lazy_table_loader_t<struct OT::MATH> math; - OT::hb_lazy_table_loader_t<struct OT::fvar> fvar; - OT::hb_lazy_table_loader_t<struct OT::avar> avar; - OT::hb_lazy_table_loader_t<struct AAT::ankr> ankr; - OT::hb_lazy_table_loader_t<struct AAT::kerx> kerx; - OT::hb_lazy_table_loader_t<struct AAT::morx> morx; - OT::hb_lazy_table_loader_t<struct AAT::trak> trak; + OT::hb_table_lazy_loader_t<struct OT::BASE> base; + OT::hb_table_lazy_loader_t<struct OT::MATH> math; + OT::hb_table_lazy_loader_t<struct OT::fvar> fvar; + OT::hb_table_lazy_loader_t<struct OT::avar> avar; unsigned int gsub_lookup_count; unsigned int gpos_lookup_count; @@ -309,7 +303,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) * processing on. */ /* Only Mn and Mc can have non-zero ccc: - * http://www.unicode.org/policies/stability_policy.html#Property_Value + * https://unicode.org/policies/stability_policy.html#Property_Value * """ * Canonical_Combining_Class, General_Category * All characters other than those with General_Category property values diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 1c9e950..655c36c 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -30,22 +30,21 @@ #include "hb-open-type-private.hh" #include "hb-ot-layout-private.hh" +#include "hb-ot-map-private.hh" -#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise. -#include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise. + +// Just so we compile them; unused otherwise: +#include "hb-ot-layout-base-table.hh" +#include "hb-ot-layout-jstf-table.hh" #include "hb-ot-color-colr-table.hh" #include "hb-ot-color-cpal-table.hh" - -#include "hb-ot-map-private.hh" - - -#ifndef HB_NO_VISIBILITY -const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; -#endif +#include "hb-ot-color-sbix-table.hh" +#include "hb-ot-color-svg-table.hh" +#include "hb-ot-name-table.hh" +#include "hb-map-private.hh" hb_ot_layout_t * @@ -56,24 +55,17 @@ _hb_ot_layout_create (hb_face_t *face) return nullptr; layout->gdef_blob = OT::Sanitizer<OT::GDEF>().sanitize (face->reference_table (HB_OT_TAG_GDEF)); - layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob); + layout->gdef = layout->gdef_blob->as<OT::GDEF> (); layout->gsub_blob = OT::Sanitizer<OT::GSUB>().sanitize (face->reference_table (HB_OT_TAG_GSUB)); - layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob); + layout->gsub = layout->gsub_blob->as<OT::GSUB> (); layout->gpos_blob = OT::Sanitizer<OT::GPOS>().sanitize (face->reference_table (HB_OT_TAG_GPOS)); - layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob); + layout->gpos = layout->gpos_blob->as<OT::GPOS> (); - layout->base.init (face); - layout->colr.init (face); - layout->cpal.init (face); layout->math.init (face); layout->fvar.init (face); layout->avar.init (face); - layout->ankr.init (face); - layout->kerx.init (face); - layout->morx.init (face); - layout->trak.init (face); { /* @@ -81,9 +73,9 @@ _hb_ot_layout_create (hb_face_t *face) * See this thread for why we finally had to bend in and do this: * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html */ - unsigned int gdef_len = hb_blob_get_length (layout->gdef_blob); - unsigned int gsub_len = hb_blob_get_length (layout->gsub_blob); - unsigned int gpos_len = hb_blob_get_length (layout->gpos_blob); + unsigned int gdef_len = layout->gdef_blob->length; + unsigned int gsub_len = layout->gsub_blob->length; + unsigned int gpos_len = layout->gpos_blob->length; if (0 /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */ || (442 == gdef_len && 42038 == gpos_len && 2874 == gsub_len) @@ -106,7 +98,7 @@ _hb_ot_layout_create (hb_face_t *face) * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html */ if (3 == layout->gdef->get_glyph_class (5)) - layout->gdef = &OT::Null(OT::GDEF); + layout->gdef = &Null(OT::GDEF); } else if (0 /* sha1sum:96eda93f7d33e79962451c6c39a6b51ee893ce8c tahoma.ttf from Windows 8 */ @@ -178,7 +170,7 @@ _hb_ot_layout_create (hb_face_t *face) * https://bugzilla.mozilla.org/show_bug.cgi?id=1279693 * https://bugzilla.mozilla.org/show_bug.cgi?id=1279875 */ - layout->gdef = &OT::Null(OT::GDEF); + layout->gdef = &Null(OT::GDEF); } } @@ -220,16 +212,9 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); - layout->base.fini (); - layout->colr.fini (); - layout->cpal.fini (); layout->math.fini (); layout->fvar.fini (); layout->avar.fini (); - layout->ankr.fini (); - layout->kerx.fini (); - layout->morx.fini (); - layout->trak.fini (); free (layout); } @@ -237,7 +222,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) // static inline const OT::BASE& // _get_base (hb_face_t *face) // { -// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE); +// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); // hb_ot_layout_t * layout = hb_ot_layout_from_face (face); // return *(layout->base.get ()); // } @@ -245,19 +230,19 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) static inline const OT::GDEF& _get_gdef (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF); return *hb_ot_layout_from_face (face)->gdef; } static inline const OT::GSUB& _get_gsub (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GSUB); return *hb_ot_layout_from_face (face)->gsub; } static inline const OT::GPOS& _get_gpos (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GPOS); return *hb_ot_layout_from_face (face)->gpos; } @@ -329,7 +314,7 @@ get_gsubgpos_table (hb_face_t *face, switch (table_tag) { case HB_OT_TAG_GSUB: return _get_gsub (face); case HB_OT_TAG_GPOS: return _get_gpos (face); - default: return OT::Null(OT::GSUBGPOS); + default: return Null(OT::GSUBGPOS); } } @@ -909,7 +894,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, hb_bool_t hb_ot_layout_has_substitution (hb_face_t *face) { - return &_get_gsub (face) != &OT::Null(OT::GSUB); + return &_get_gsub (face) != &Null(OT::GSUB); } /** @@ -959,11 +944,46 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, unsigned int lookup_index, hb_set_t *glyphs) { - OT::hb_closure_context_t c (face, glyphs); + hb_auto_t<hb_map_t> done_lookups; + OT::hb_closure_context_t c (face, glyphs, &done_lookups); const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); - l.closure (&c); + l.closure (&c, lookup_index); +} + +/** + * hb_ot_layout_lookups_substitute_closure: + * + * Compute the transitive closure of glyphs needed for all of the + * provided lookups. + * + * Since: 1.8.1 + **/ +void +hb_ot_layout_lookups_substitute_closure (hb_face_t *face, + const hb_set_t *lookups, + hb_set_t *glyphs) +{ + hb_auto_t<hb_map_t> done_lookups; + OT::hb_closure_context_t c (face, glyphs, &done_lookups); + const OT::GSUB& gsub = _get_gsub (face); + + unsigned int glyphs_length; + do + { + glyphs_length = glyphs->get_population (); + if (lookups != nullptr) + { + for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);) + gsub.get_lookup (lookup_index).closure (&c, lookup_index); + } + else + { + for (unsigned int i = 0; i < gsub.get_lookup_count (); i++) + gsub.get_lookup (i).closure (&c, i); + } + } while (glyphs_length != glyphs->get_population ()); } /* @@ -973,7 +993,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, hb_bool_t hb_ot_layout_has_positioning (hb_face_t *face) { - return &_get_gpos (face) != &OT::Null(OT::GPOS); + return &_get_gpos (face) != &Null(OT::GPOS); } void @@ -1107,7 +1127,7 @@ struct hb_get_subtables_context_t : hb_apply_func_t apply_func; }; - typedef hb_auto_array_t<hb_applicable_t> array_t; + typedef hb_auto_t<hb_vector_t<hb_applicable_t> > array_t; /* Dispatch interface. */ inline const char *get_name (void) { return "GET_SUBTABLES"; } @@ -1115,8 +1135,7 @@ struct hb_get_subtables_context_t : inline return_t dispatch (const T &obj) { hb_applicable_t *entry = array.push(); - if (likely (entry)) - entry->init (&obj, apply_to<T>); + entry->init (&obj, apply_to<T>); return HB_VOID; } static return_t default_return_value (void) { return HB_VOID; } @@ -1137,7 +1156,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, { bool ret = false; hb_buffer_t *buffer = c->buffer; - while (buffer->idx < buffer->len && !buffer->in_error) + while (buffer->idx < buffer->len && buffer->successful) { bool applied = false; if (accel.may_have (buffer->cur().codepoint) && @@ -1309,5 +1328,5 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, // hb_bool_t // hb_ot_base_has_data (hb_face_t *face) // { -// return &_get_base (face) != &OT::Null(OT::BASE); +// return &_get_base (face) != &Null(OT::BASE); // } diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 85938ba..0278796 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -277,6 +277,12 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, hb_set_t *glyphs /*TODO , hb_bool_t inclusive */); +HB_EXTERN void +hb_ot_layout_lookups_substitute_closure (hb_face_t *face, + const hb_set_t *lookups, + hb_set_t *glyphs); + + #ifdef HB_NOT_IMPLEMENTED /* Note: You better have GDEF when using this API, or marks won't do much. */ HB_EXTERN hb_bool_t @@ -307,7 +313,7 @@ Xhb_ot_layout_lookup_position (hb_font_t *font, #endif /* Optical 'size' feature info. Returns true if found. - * http://www.microsoft.com/typography/otspec/features_pt.htm#size */ + * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */ HB_EXTERN hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *design_size, /* OUT. May be NULL */ diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index e6bd8ea..4aaf328 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -78,8 +78,26 @@ struct hb_ot_map_t pause_func_t pause_func; }; + inline void init (void) + { + memset (this, 0, sizeof (*this)); - hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); } + features.init (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + lookups[table_index].init (); + stages[table_index].init (); + } + } + inline void fini (void) + { + features.fini (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + lookups[table_index].fini (); + stages[table_index].fini (); + } + } inline hb_mask_t get_global_mask (void) const { return global_mask; } @@ -130,15 +148,6 @@ struct hb_ot_map_t HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; - inline void finish (void) { - features.finish (); - for (unsigned int table_index = 0; table_index < 2; table_index++) - { - lookups[table_index].finish (); - stages[table_index].finish (); - } - } - public: hb_tag_t chosen_script[2]; bool found_script[2]; @@ -147,9 +156,9 @@ struct hb_ot_map_t hb_mask_t global_mask; - hb_prealloced_array_t<feature_map_t, 8> features; - hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */ - hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */ + hb_vector_t<feature_map_t, 8> features; + hb_vector_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */ + hb_vector_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */ }; enum hb_ot_map_feature_flags_t { @@ -172,6 +181,8 @@ 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 ~hb_ot_map_builder_t (void); + HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, hb_ot_map_feature_flags_t flags); @@ -187,14 +198,6 @@ struct hb_ot_map_builder_t const int *coords, unsigned int num_coords); - inline void finish (void) { - feature_infos.finish (); - for (unsigned int table_index = 0; table_index < 2; table_index++) - { - stages[table_index].finish (); - } - } - private: HB_INTERNAL void add_lookups (hb_ot_map_t &m, @@ -241,8 +244,8 @@ struct hb_ot_map_builder_t private: unsigned int current_stage[2]; /* GSUB/GPOS */ - hb_prealloced_array_t<feature_info_t, 32> feature_infos; - hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */ + hb_vector_t<feature_info_t, 32> feature_infos; + hb_vector_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */ }; diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 54b0ce3..46bf2db 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -43,6 +43,10 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, { memset (this, 0, sizeof (*this)); + feature_infos.init (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + stages[table_index].init (); + face = face_; props = *props_; @@ -63,11 +67,17 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, } } +hb_ot_map_builder_t::~hb_ot_map_builder_t (void) +{ + feature_infos.fini (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + stages[table_index].fini (); +} + 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; @@ -108,8 +118,6 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, if (lookup_indices[i] >= table_lookup_count) continue; hb_ot_map_t::lookup_map_t *lookup = m.lookups[table_index].push (); - if (unlikely (!lookup)) - return; lookup->mask = mask; lookup->index = lookup_indices[i]; lookup->auto_zwnj = auto_zwnj; @@ -124,10 +132,8 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func) { stage_info_t *s = stages[table_index].push (); - if (likely (s)) { - s->index = current_stage[table_index]; - s->pause_func = pause_func; - } + s->index = current_stage[table_index]; + s->pause_func = pause_func; current_stage[table_index]++; } @@ -164,9 +170,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, &required_feature_tag[table_index]); } - if (!feature_infos.len) - return; - /* Sort features and merge duplicates */ { feature_infos.qsort (); @@ -241,8 +244,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, hb_ot_map_t::feature_map_t *map = m.features.push (); - if (unlikely (!map)) - break; map->tag = info->tag; map->index[0] = feature_index[0]; @@ -324,10 +325,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) { hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push (); - if (likely (stage_map)) { - stage_map->last_lookup = last_num_lookups; - stage_map->pause_func = stages[table_index][stage_index].pause_func; - } + stage_map->last_lookup = last_num_lookups; + stage_map->pause_func = stages[table_index][stage_index].pause_func; stage_index++; } diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index 571ce01..5fef2d2 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -678,7 +678,8 @@ struct MathVariants /* - * MATH -- The MATH Table + * MATH -- Mathematical typesetting + * https://docs.microsoft.com/en-us/typography/opentype/spec/math */ struct MATH diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index f82a073..1667a7d 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -32,7 +32,7 @@ static inline const OT::MATH& _get_math (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::MATH); hb_ot_layout_t * layout = hb_ot_layout_from_face (face); return *(layout->math.get ()); } @@ -55,7 +55,7 @@ _get_math (hb_face_t *face) hb_bool_t hb_ot_math_has_data (hb_face_t *face) { - return &_get_math (face) != &OT::Null(OT::MATH); + return &_get_math (face) != &Null(OT::MATH); } /** diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh index 881deda..390b60d 100644 --- a/src/hb-ot-maxp-table.hh +++ b/src/hb-ot-maxp-table.hh @@ -34,7 +34,8 @@ namespace OT { /* - * maxp -- The Maximum Profile Table + * maxp -- Maximum Profile + * https://docs.microsoft.com/en-us/typography/opentype/spec/maxp */ #define HB_OT_TAG_maxp HB_TAG('m','a','x','p') @@ -108,11 +109,11 @@ struct maxp } OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr); - maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len); + maxp_prime->set_num_glyphs (plan->glyphs.len); if (plan->drop_hints) drop_hint_fields (plan, maxp_prime); - bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_maxp, maxp_prime_blob); + bool result = plan->add_table (HB_OT_TAG_maxp, maxp_prime_blob); hb_blob_destroy (maxp_prime_blob); return result; } diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index eb01333..bff85df 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -34,9 +34,9 @@ namespace OT { /* - * name -- The Naming Table + * name -- Naming + * https://docs.microsoft.com/en-us/typography/opentype/spec/name */ - #define HB_OT_TAG_name HB_TAG('n','a','m','e') diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh index 6cb8d49..c52b7eb 100644 --- a/src/hb-ot-os2-table.hh +++ b/src/hb-ot-os2-table.hh @@ -29,14 +29,14 @@ #include "hb-open-type-private.hh" #include "hb-ot-os2-unicode-ranges.hh" +#include "hb-subset-plan.hh" namespace OT { /* * OS/2 and Windows Metrics - * http://www.microsoft.com/typography/otspec/os2.htm + * https://docs.microsoft.com/en-us/typography/opentype/spec/os2 */ - #define HB_OT_TAG_os2 HB_TAG('O','S','/','2') struct os2 @@ -63,26 +63,25 @@ struct os2 } uint16_t min_cp, max_cp; - find_min_and_max_codepoint (plan->codepoints, &min_cp, &max_cp); + find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp); os2_prime->usFirstCharIndex.set (min_cp); os2_prime->usLastCharIndex.set (max_cp); - _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange); - bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob); + _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange); + bool result = plan->add_table (HB_OT_TAG_os2, os2_prime_blob); hb_blob_destroy (os2_prime_blob); return result; } - inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, + inline void _update_unicode_ranges (const hb_set_t *codepoints, HBUINT32 ulUnicodeRange[4]) const { for (unsigned int i = 0; i < 4; i++) ulUnicodeRange[i].set (0); - for (unsigned int i = 0; i < codepoints.len; i++) - { - hb_codepoint_t cp = codepoints[i]; + hb_codepoint_t cp = HB_SET_VALUE_INVALID; + while (codepoints->next (&cp)) { unsigned int bit = hb_get_unicode_range_bit (cp); if (bit < 128) { @@ -101,28 +100,30 @@ struct os2 } } - static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, + static inline void find_min_and_max_codepoint (const hb_set_t *codepoints, uint16_t *min_cp, /* OUT */ uint16_t *max_cp /* OUT */) { - hb_codepoint_t min = -1, max = 0; - - for (unsigned int i = 0; i < codepoints.len; i++) - { - hb_codepoint_t cp = codepoints[i]; - if (cp < min) - min = cp; - if (cp > max) - max = cp; - } - - if (min > 0xFFFF) - min = 0xFFFF; - if (max > 0xFFFF) - max = 0xFFFF; + *min_cp = codepoints->get_min (); + *max_cp = codepoints->get_max (); + } - *min_cp = min; - *max_cp = max; + enum font_page_t { + HEBREW_FONT_PAGE = 0xB100, // Hebrew Windows 3.1 font page + SIMP_ARABIC_FONT_PAGE = 0xB200, // Simplified Arabic Windows 3.1 font page + TRAD_ARABIC_FONT_PAGE = 0xB300, // Traditional Arabic Windows 3.1 font page + OEM_ARABIC_FONT_PAGE = 0xB400, // OEM Arabic Windows 3.1 font page + SIMP_FARSI_FONT_PAGE = 0xBA00, // Simplified Farsi Windows 3.1 font page + TRAD_FARSI_FONT_PAGE = 0xBB00, // Traditional Farsi Windows 3.1 font page + THAI_FONT_PAGE = 0xDE00 // Thai Windows 3.1 font page + }; + + // https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 + inline font_page_t get_font_page () const + { + if (version != 0) + return (font_page_t) 0; + return (font_page_t) (fsSelection & 0xFF00); } public: diff --git a/src/hb-ot-os2-unicode-ranges.hh b/src/hb-ot-os2-unicode-ranges.hh index 2cf168f..9b32cfa 100644 --- a/src/hb-ot-os2-unicode-ranges.hh +++ b/src/hb-ot-os2-unicode-ranges.hh @@ -237,7 +237,7 @@ hb_get_unicode_range_bit (hb_codepoint_t cp) sizeof (os2UnicodeRangesSorted) / sizeof(Range), sizeof(Range), _compare_range, nullptr); - if (range != NULL) + if (range != nullptr) return range->bit; return -1; } diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 9e47921..5f42751 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -29,6 +29,7 @@ #include "hb-open-type-private.hh" #include "hb-dsalgs.hh" +#include "hb-subset-plan.hh" #define HB_STRING_ARRAY_NAME format1_names #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh" @@ -38,16 +39,16 @@ #define NUM_FORMAT1_NAMES 258 -namespace OT { - - /* * post -- PostScript + * https://docs.microsoft.com/en-us/typography/opentype/spec/post */ - #define HB_OT_TAG_post HB_TAG('p','o','s','t') +namespace OT { + + struct postV2Tail { inline bool sanitize (hb_sanitize_context_t *c) const @@ -82,16 +83,39 @@ struct post return_trace (true); } + inline bool subset (hb_subset_plan_t *plan) const + { + unsigned int post_prime_length; + hb_blob_t *post_blob = OT::Sanitizer<post>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_post)); + hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size); + post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length); + hb_blob_destroy (post_blob); + + if (unlikely (!post_prime || post_prime_length != post::static_size)) + { + hb_blob_destroy (post_prime_blob); + DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length); + return false; + } + + post_prime->version.major.set (3); // Version 3 does not have any glyph names. + bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob); + hb_blob_destroy (post_prime_blob); + + return result; + } + struct accelerator_t { inline void init (hb_face_t *face) { + index_to_offset.init (); + blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post)); - const post *table = Sanitizer<post>::lock_instance (blob); - unsigned int table_length = hb_blob_get_length (blob); + const post *table = blob->as<post> (); + unsigned int table_length = blob->length; version = table->version.to_int (); - index_to_offset.init (); if (version != 0x00020000) return; @@ -102,23 +126,18 @@ struct post const uint8_t *end = (uint8_t *) table + table_length; for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data) - { - uint32_t *offset = index_to_offset.push (); - if (unlikely (!offset)) - break; - *offset = data - pool; - } + index_to_offset.push (data - pool); } inline void fini (void) { - index_to_offset.finish (); + index_to_offset.fini (); free (gids_sorted_by_name); } inline bool get_glyph_name (hb_codepoint_t glyph, char *buf, unsigned int buf_len) const { - hb_string_t s = find_glyph_name (glyph); + hb_bytes_t s = find_glyph_name (glyph); if (!s.len) return false; if (!buf_len) @@ -162,7 +181,7 @@ struct post } } - hb_string_t st (name, len); + hb_bytes_t st (name, len); const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this); if (gid) { @@ -197,45 +216,45 @@ struct post static inline int cmp_key (const void *pk, const void *po, void *arg) { const accelerator_t *thiz = (const accelerator_t *) arg; - const hb_string_t *key = (const hb_string_t *) pk; + const hb_bytes_t *key = (const hb_bytes_t *) pk; uint16_t o = * (const uint16_t *) po; return thiz->find_glyph_name (o).cmp (*key); } - inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const + inline hb_bytes_t find_glyph_name (hb_codepoint_t glyph) const { if (version == 0x00010000) { if (glyph >= NUM_FORMAT1_NAMES) - return hb_string_t (); + return hb_bytes_t (); return format1_names (glyph); } if (version != 0x00020000 || glyph >= glyphNameIndex->len) - return hb_string_t (); + return hb_bytes_t (); - unsigned int index = glyphNameIndex->array[glyph]; + unsigned int index = glyphNameIndex->arrayZ[glyph]; if (index < NUM_FORMAT1_NAMES) return format1_names (index); index -= NUM_FORMAT1_NAMES; if (index >= index_to_offset.len) - return hb_string_t (); - unsigned int offset = index_to_offset.array[index]; + return hb_bytes_t (); + unsigned int offset = index_to_offset.arrayZ[index]; const uint8_t *data = pool + offset; unsigned int name_length = *data; data++; - return hb_string_t ((const char *) data, name_length); + return hb_bytes_t ((const char *) data, name_length); } private: hb_blob_t *blob; uint32_t version; const ArrayOf<HBUINT16> *glyphNameIndex; - hb_prealloced_array_t<uint32_t, 1> index_to_offset; + hb_vector_t<uint32_t, 1> index_to_offset; const uint8_t *pool; mutable uint16_t *gids_sorted_by_name; }; diff --git a/src/hb-ot-shape-complex-arabic-table.hh b/src/hb-ot-shape-complex-arabic-table.hh index cd6e405..9459aad 100644 --- a/src/hb-ot-shape-complex-arabic-table.hh +++ b/src/hb-ot-shape-complex-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-10.0.0.txt - * # Date: 2017-02-16, 00:00:00 GMT [RP, KW] - * # Blocks-10.0.0.txt - * # Date: 2017-04-12, 17:30:00 GMT [KW] + * # ArabicShaping-11.0.0.txt + * # Date: 2018-02-21, 14:50:00 GMT [KW, RP] + * # Blocks-11.0.0.txt + * # Date: 2017-10-16, 24:39:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -45,7 +45,7 @@ static const uint8_t joining_table[] = /* 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, + /* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,T,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, @@ -91,7 +91,7 @@ static const uint8_t joining_table[] = /* 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, + /* 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,D,X,X,X,X,X,X,X, /* 1880 */ U,U,U,U,U,T,T,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D, @@ -125,7 +125,28 @@ static const uint8_t joining_table[] = /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U, -#define joining_offset_0x1e900u 1146 +#define joining_offset_0x10d00u 1146 + + /* Hanifi Rohingya */ + + /* 10D00 */ L,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, + /* 10D20 */ D,D,R,D, + +#define joining_offset_0x10f30u 1182 + + /* Sogdian */ + + /* 10F20 */ D,D,D,R,D,D,D,D,D,D,D,D,D,D,D,D, + /* 10F40 */ D,D,D,D,D,U,X,X,X,X,X,X,X,X,X,X,X,D,D,D,R, + +#define joining_offset_0x110bdu 1219 + + /* Kaithi */ + + /* 110A0 */ U,X,X, + /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, + +#define joining_offset_0x1e900u 1236 /* Adlam */ @@ -133,7 +154,7 @@ static const uint8_t joining_table[] = /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1E940 */ D,D,D,D, -}; /* Table items: 1214; occupancy: 55% */ +}; /* Table items: 1304; occupancy: 56% */ static unsigned int @@ -160,6 +181,12 @@ joining_type (hb_codepoint_t u) case 0x10u: if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F54u)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; + break; + + case 0x11u: + if (hb_in_range<hb_codepoint_t> (u, 0x110BDu, 0x110CDu)) return joining_table[u - 0x110BDu + joining_offset_0x110bdu]; break; case 0x1Eu: diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index 47961bf..124a67f 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -421,7 +421,7 @@ retry: /* * Stretch feature: "stch". * See example here: - * https://www.microsoft.com/typography/OpenTypeDev/syriac/intro.htm + * https://docs.microsoft.com/en-us/typography/script-development/syriac * We implement this in a generic way, such that the Arabic subtending * marks can use it as well. */ @@ -611,7 +611,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } -/* http://www.unicode.org/reports/tr53/tr53-1.pdf */ +/* https://unicode.org/reports/tr53/tr53-1.pdf */ static hb_codepoint_t modifier_combining_marks[] = diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc index 7508c22..7420c5d 100644 --- a/src/hb-ot-shape-complex-hangul.cc +++ b/src/hb-ot-shape-complex-hangul.cc @@ -151,8 +151,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, * - <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. + * - Only the <L,V> sequences for some of the U+11xx ranges combine. + * - Only <LV,T> sequences for some of the Ts in U+11xx range combine. * * Here is what we want to accomplish in this shaper: * @@ -188,7 +188,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, */ unsigned int count = buffer->len; - for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;) + for (buffer->idx = 0; buffer->idx < count && buffer->successful;) { hb_codepoint_t u = buffer->cur().codepoint; @@ -269,7 +269,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, if (font->has_glyph (s)) { buffer->replace_glyphs (t ? 3 : 2, 1, &s); - if (unlikely (buffer->in_error)) + if (unlikely (!buffer->successful)) return; end = start + 1; continue; @@ -319,7 +319,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, if (font->has_glyph (new_s)) { buffer->replace_glyphs (2, 1, &new_s); - if (unlikely (buffer->in_error)) + if (unlikely (!buffer->successful)) return; end = start + 1; continue; @@ -345,7 +345,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, { unsigned int s_len = tindex ? 3 : 2; buffer->replace_glyphs (1, s_len, decomposed); - if (unlikely (buffer->in_error)) + if (unlikely (!buffer->successful)) return; /* We decomposed S: apply jamo features to the individual glyphs diff --git a/src/hb-ot-shape-complex-indic-machine.hh b/src/hb-ot-shape-complex-indic-machine.hh index f3cea22..73f9d58 100644 --- a/src/hb-ot-shape-complex-indic-machine.hh +++ b/src/hb-ot-shape-complex-indic-machine.hh @@ -1129,7 +1129,7 @@ static const int indic_syllable_machine_en_main = 166; static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + unsigned int p, pe, eof, ts HB_UNUSED, te, act; int cs; hb_glyph_info_t *info = buffer->info; diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl index 0ea91c0..35e7ce9 100644 --- a/src/hb-ot-shape-complex-indic-machine.rl +++ b/src/hb-ot-shape-complex-indic-machine.rl @@ -104,7 +104,7 @@ main := |* static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + unsigned int p, pe, eof, ts HB_UNUSED, te, act; 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 867b936..9554994 100644 --- a/src/hb-ot-shape-complex-indic-private.hh +++ b/src/hb-ot-shape-complex-indic-private.hh @@ -42,7 +42,7 @@ #define INDIC_TABLE_ELEMENT_TYPE uint16_t /* Cateories used in the OpenType spec: - * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx + * https://docs.microsoft.com/en-us/typography/script-development/devanagari */ /* Note: This enum is duplicated in the -machine.rl source file. * Not sure how to avoid duplication. */ diff --git a/src/hb-ot-shape-complex-indic-table.cc b/src/hb-ot-shape-complex-indic-table.cc index 867cfb3..54291bc 100644 --- a/src/hb-ot-shape-complex-indic-table.cc +++ b/src/hb-ot-shape-complex-indic-table.cc @@ -6,62 +6,63 @@ * * on files with these headers: * - * # IndicSyllabicCategory-10.0.0.txt - * # Date: 2017-05-31, 01:07:00 GMT [KW, RP] - * # IndicPositionalCategory-10.0.0.txt - * # Date: 2017-05-31, 01:07:00 GMT [RP] - * # Blocks-10.0.0.txt - * # Date: 2017-04-12, 17:30:00 GMT [KW] + * # IndicSyllabicCategory-11.0.0.txt + * # Date: 2018-05-21, 18:33:00 GMT [KW, RP] + * # IndicPositionalCategory-11.0.0.txt + * # Date: 2018-02-05, 16:21:00 GMT [KW, RP] + * # Blocks-11.0.0.txt + * # Date: 2017-10-16, 24:39:00 GMT [KW] */ #include "hb-ot-shape-complex-indic-private.hh" -#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 15 chars; Avagraha */ -#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 80 chars; Bindu */ +#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 16 chars; Avagraha */ +#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 83 chars; Bindu */ #define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ -#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 57 chars; Cantillation_Mark */ -#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2024 chars; Consonant */ +#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 58 chars; Cantillation_Mark */ +#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2110 chars; Consonant */ #define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 10 chars; Consonant_Dead */ -#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 68 chars; Consonant_Final */ +#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 67 chars; Consonant_Final */ #define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ +#define ISC_CIP INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /* 1 chars; Consonant_Initial_Postfixed */ #define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */ -#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 27 chars; Consonant_Medial */ -#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 18 chars; Consonant_Placeholder */ +#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 28 chars; Consonant_Medial */ +#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 21 chars; Consonant_Placeholder */ #define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 2 chars; Consonant_Preceding_Repha */ #define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 7 chars; Consonant_Prefixed */ #define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 95 chars; Consonant_Subjoined */ -#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 5 chars; Consonant_Succeeding_Repha */ -#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 4 chars; Consonant_With_Stacker */ +#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */ +#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 6 chars; Consonant_With_Stacker */ #define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */ -#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 10 chars; Invisible_Stacker */ +#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 11 chars; Invisible_Stacker */ #define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */ #define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */ #define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ -#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 28 chars; Nukta */ -#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 469 chars; Number */ +#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 30 chars; Nukta */ +#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 480 chars; Number */ #define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */ #define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */ #define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 21 chars; Pure_Killer */ #define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */ -#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 22 chars; Syllable_Modifier */ +#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 25 chars; Syllable_Modifier */ #define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ #define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */ -#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 24 chars; Virama */ -#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 34 chars; Visarga */ +#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 25 chars; Virama */ +#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 36 chars; Visarga */ #define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ -#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 633 chars; Vowel_Dependent */ -#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 443 chars; Vowel_Independent */ +#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 660 chars; Vowel_Dependent */ +#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 464 chars; Vowel_Independent */ -#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 330 chars; Bottom */ +#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 340 chars; Bottom */ #define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */ #define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */ -#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 57 chars; Left */ +#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 59 chars; Left */ #define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */ #define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */ #define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */ -#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 262 chars; Right */ -#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 380 chars; Top */ +#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 276 chars; Right */ +#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 393 chars; Top */ #define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */ #define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */ #define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */ @@ -119,7 +120,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Bengali */ - /* 0980 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0980 */ _(CP,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), /* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -134,7 +135,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 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), _(Bi,x), _(x,x), _(x,x), _(x,x), + /* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(Bi,x), _(x,x), _(SM,T), _(x,x), /* Gurmukhi */ @@ -148,7 +149,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(x,x), _(M,R), _(M,L), /* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), /* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x), - /* 0A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0A50 */ _(x,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), /* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), @@ -214,7 +215,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Telugu */ - /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(Bi,T), _(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), @@ -301,7 +302,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,T), _(TM,B), /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B), _(C,x), /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x), + /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(CP,x), _(x,x), _(x,x), _(CP,x), _(x,x), /* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), /* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,B), _(CM,B), /* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R), @@ -342,7 +343,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B), /* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), /* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x), - /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(Ca,R), + /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T),_(CWS,x),_(CWS,x), _(Ca,R), /* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), #define indic_offset_0x2008u 1656 @@ -370,8 +371,9 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), /* A8F0 */ _(Ca,T), _(Ca,T), _(Bi,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(M,T), -#define indic_offset_0xa9e0u 1720 +#define indic_offset_0xa9e0u 1728 /* Myanmar Extended-B */ @@ -381,7 +383,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), -#define indic_offset_0xaa60u 1752 +#define indic_offset_0xaa60u 1760 /* Myanmar Extended-A */ @@ -391,7 +393,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x), -}; /* Table items: 1784; occupancy: 70% */ +}; /* Table items: 1792; occupancy: 70% */ INDIC_TABLE_ELEMENT_TYPE hb_indic_get_categories (hb_codepoint_t u) @@ -418,7 +420,7 @@ hb_indic_get_categories (hb_codepoint_t u) break; case 0xAu: - if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8F7u)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u]; + if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8FFu)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u]; if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u]; if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u]; break; @@ -430,7 +432,6 @@ hb_indic_get_categories (hb_codepoint_t u) } #undef _ - #undef ISC_A #undef ISC_Bi #undef ISC_BJN @@ -439,6 +440,7 @@ hb_indic_get_categories (hb_codepoint_t u) #undef ISC_CD #undef ISC_CF #undef ISC_CHL +#undef ISC_CIP #undef ISC_CK #undef ISC_CM #undef ISC_CP @@ -466,7 +468,6 @@ hb_indic_get_categories (hb_codepoint_t u) #undef ISC_Vo #undef ISC_M #undef ISC_VI - #undef IMC_B #undef IMC_BL #undef IMC_BR diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 32ad86a..447e36c 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -86,7 +86,7 @@ static const indic_config_t indic_configs[] = {HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY}, {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST}, {HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA, - REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST}, + REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST}, }; @@ -435,7 +435,7 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan, /* Rules from: - * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */ + * https://docs.microsqoft.com/en-us/typography/script-development/devanagari */ static void initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, @@ -974,7 +974,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx = 0; unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && !buffer->in_error) + while (buffer->idx < buffer->len && buffer->successful) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); @@ -989,7 +989,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && !buffer->in_error && + while (buffer->idx < buffer->len && buffer->successful && last_syllable == buffer->cur().syllable() && buffer->cur().indic_category() == OT_Repha) buffer->next_glyph (); @@ -1470,6 +1470,9 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, { /* Don't decompose these. */ case 0x0931u : return false; /* DEVANAGARI LETTER RRA */ + // https://github.com/harfbuzz/harfbuzz/issues/779 + case 0x09DCu : return false; /* BENGALI LETTER RRA */ + case 0x09DDu : return false; /* BENGALI LETTER RHA */ case 0x0B94u : return false; /* TAMIL LETTER AU */ @@ -1512,7 +1515,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, * The Uniscribe behavior is now documented in the newly published Sinhala * spec in 2012: * - * http://www.microsoft.com/typography/OpenTypeDev/sinhala/intro.htm#shaping + * https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping */ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data; diff --git a/src/hb-ot-shape-complex-khmer-machine.hh b/src/hb-ot-shape-complex-khmer-machine.hh index 380705a..d001021 100644 --- a/src/hb-ot-shape-complex-khmer-machine.hh +++ b/src/hb-ot-shape-complex-khmer-machine.hh @@ -173,7 +173,7 @@ static const int khmer_syllable_machine_en_main = 10; static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + unsigned int p, pe, eof, ts HB_UNUSED, te, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; diff --git a/src/hb-ot-shape-complex-khmer-machine.rl b/src/hb-ot-shape-complex-khmer-machine.rl index 8b00c37..54644d8 100644 --- a/src/hb-ot-shape-complex-khmer-machine.rl +++ b/src/hb-ot-shape-complex-khmer-machine.rl @@ -86,7 +86,7 @@ main := |* static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + unsigned int p, pe, eof, ts HB_UNUSED, te, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; %%{ diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 304879d..18e3c94 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -275,7 +275,7 @@ compare_khmer_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) /* Rules from: - * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */ + * https://docs.microsoft.com/en-us/typography/script-development/devanagari */ static void initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, @@ -317,7 +317,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, if ((FLAG_UNSAFE (info[i].khmer_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_Coeng)))) { info[i].khmer_position() = last_pos; - if (unlikely (info[i].khmer_category() == OT_H && + if (unlikely (info[i].khmer_category() == OT_Coeng && info[i].khmer_position() == POS_PRE_M)) { /* @@ -485,7 +485,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx = 0; unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && !buffer->in_error) + while (buffer->idx < buffer->len && buffer->successful) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); @@ -500,7 +500,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && !buffer->in_error && + while (buffer->idx < buffer->len && buffer->successful && last_syllable == buffer->cur().syllable() && buffer->cur().khmer_category() == OT_Repha) buffer->next_glyph (); @@ -538,7 +538,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * and possibly multiple 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. */ + * class of OT_Coeng is desired but has been lost. */ if (khmer_plan->virama_glyph) { unsigned int virama_glyph = khmer_plan->virama_glyph; @@ -548,7 +548,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, _hb_glyph_info_multiplied (&info[i])) { /* This will make sure that this glyph passes is_coeng() test. */ - info[i].khmer_category() = OT_H; + info[i].khmer_category() = OT_Coeng; _hb_glyph_info_clear_ligated_and_multiplied (&info[i]); } } diff --git a/src/hb-ot-shape-complex-myanmar-private.hh b/src/hb-ot-shape-complex-myanmar-private.hh index 04f81bd..14d011d 100644 --- a/src/hb-ot-shape-complex-myanmar-private.hh +++ b/src/hb-ot-shape-complex-myanmar-private.hh @@ -68,7 +68,7 @@ set_myanmar_properties (hb_glyph_info_t &info) indic_position_t pos = (indic_position_t) (type >> 8); /* Myanmar - * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze + * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze */ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu))) cat = (indic_category_t) OT_VS; diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index 3c57bc1..e4214b8 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -161,7 +161,7 @@ compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) /* Rules from: - * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */ + * https://docs.microsoft.com/en-us/typography/script-development/myanmar */ static void initial_reordering_consonant_syllable (hb_buffer_t *buffer, @@ -312,7 +312,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx = 0; unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && !buffer->in_error) + while (buffer->idx < buffer->len && buffer->successful) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 08b6fe9..ed6849b 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -205,6 +205,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-9.0 additions */ case HB_SCRIPT_ADLAM: + /* Unicode-11.0 additions */ + case HB_SCRIPT_HANIFI_ROHINGYA: + case HB_SCRIPT_SOGDIAN: + /* 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). * But note that Arabic shaping is applicable only to horizontal layout; for @@ -380,6 +384,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_SOYOMBO: case HB_SCRIPT_ZANABAZAR_SQUARE: + /* Unicode-11.0 additions */ + case HB_SCRIPT_DOGRA: + case HB_SCRIPT_GUNJALA_GONDI: + case HB_SCRIPT_MAKASAR: + /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. * Otherwise, use the specific shaper. diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc index 6ba925c..02d78ac 100644 --- a/src/hb-ot-shape-complex-thai.cc +++ b/src/hb-ot-shape-complex-thai.cc @@ -260,7 +260,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, { /* This function implements the shaping logic documented here: * - * http://linux.thai.net/~thep/th-otf/shaping.html + * https://linux.thai.net/~thep/th-otf/shaping.html * * The first shaping rule listed there is needed even if the font has Thai * OpenType tables. The rest do fallback positioning based on PUA codepoints. @@ -315,7 +315,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, buffer->clear_output (); unsigned int count = buffer->len; - for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;) + for (buffer->idx = 0; buffer->idx < count && buffer->successful;) { hb_codepoint_t u = buffer->cur().codepoint; if (likely (!IS_SARA_AM (u))) { @@ -327,7 +327,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)), hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))}; buffer->replace_glyphs (1, 2, decomposed); - if (unlikely (buffer->in_error)) + if (unlikely (!buffer->successful)) return; /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ diff --git a/src/hb-ot-shape-complex-use-machine.hh b/src/hb-ot-shape-complex-use-machine.hh index 0bf3ad3..0ec805a 100644 --- a/src/hb-ot-shape-complex-use-machine.hh +++ b/src/hb-ot-shape-complex-use-machine.hh @@ -331,7 +331,7 @@ static const int use_syllable_machine_en_main = 4; static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + unsigned int p, pe, eof, ts HB_UNUSED, te, act; int cs; hb_glyph_info_t *info = buffer->info; diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl index 11fb470..7ec8a7f 100644 --- a/src/hb-ot-shape-complex-use-machine.rl +++ b/src/hb-ot-shape-complex-use-machine.rl @@ -89,7 +89,7 @@ SMBlw = 42; # SYM_MOD_BELOW CS = 43; # CONS_WITH_STACKER -# Override: Adjoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729 +# Override: Adhoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729 consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.H.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*; # Override: Allow two MBlw. https://github.com/harfbuzz/harfbuzz/issues/376 medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?; @@ -153,7 +153,7 @@ main := |* static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + unsigned int p, pe, eof, ts HB_UNUSED, te, act; int cs; hb_glyph_info_t *info = buffer->info; %%{ diff --git a/src/hb-ot-shape-complex-use-private.hh b/src/hb-ot-shape-complex-use-private.hh index f7ded13..b4bda8b 100644 --- a/src/hb-ot-shape-complex-use-private.hh +++ b/src/hb-ot-shape-complex-use-private.hh @@ -38,7 +38,7 @@ #define USE_TABLE_ELEMENT_TYPE uint8_t /* Cateories used in the Universal Shaping Engine spec: - * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + * https://docs.microsoft.com/en-us/typography/script-development/use */ /* Note: This enum is duplicated in the -machine.rl source file. * Not sure how to avoid duplication. */ diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 6823392..1431533 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-10.0.0.txt - * # Date: 2017-05-31, 01:07:00 GMT [KW, RP] - * # IndicPositionalCategory-10.0.0.txt - * # Date: 2017-05-31, 01:07:00 GMT [RP] - * # Blocks-10.0.0.txt - * # Date: 2017-04-12, 17:30:00 GMT [KW] + * # IndicSyllabicCategory-11.0.0.txt + * # Date: 2018-05-21, 18:33:00 GMT [KW, RP] + * # IndicPositionalCategory-11.0.0.txt + * # Date: 2018-02-05, 16:21:00 GMT [KW, RP] + * # Blocks-11.0.0.txt + * # Date: 2017-10-16, 24:39:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -97,14 +97,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Bengali */ - /* 0980 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B, + /* 0980 */ GB, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B, /* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre, /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O, /* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B, /* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, - /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, O, O, + /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FM, O, /* Gurmukhi */ @@ -113,7 +113,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0A20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0A30 */ B, O, B, B, O, B, B, O, B, B, O, O, CMBlw, O, VPst, VPre, /* 0A40 */ VPst, VBlw, VBlw, O, O, O, O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O, - /* 0A50 */ O, O, O, O, O, O, O, O, O, B, B, B, B, O, B, O, + /* 0A50 */ O, VMBlw, O, O, O, O, O, O, O, B, B, B, B, O, B, O, /* 0A60 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0A70 */ VMAbv, CMAbv, GB, GB, O, MBlw, O, O, O, O, O, O, O, O, O, O, @@ -152,7 +152,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Telugu */ - /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B, + /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, VMAbv, B, B, B, B, B, B, B, B, O, B, B, /* 0C10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, VAbv, VAbv, @@ -203,7 +203,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1020 */ B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VAbv, VAbv, VBlw, /* 1030 */ VBlw, VPre, VAbv, VAbv, VAbv, VAbv, VMAbv, VMBlw, VMPst, H, VAbv, MPst, MPre, MBlw, MBlw, B, - /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, GB, O, + /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, GB, O, O, GB, O, /* 1050 */ B, B, B, B, B, B, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw, /* 1060 */ MBlw, B, VPst, VMPst, VMPst, B, B, VPst, VPst, VMPst, VMPst, VMPst, VMPst, VMPst, B, B, /* 1070 */ B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, B, B, B, B, B, B, @@ -330,7 +330,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw, /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, - /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, VMPst, VMAbv, VMAbv, O, O, O, O, O, O, + /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, O, O, O, O, O, O, #define use_offset_0x1df8u 2560 @@ -396,7 +396,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Devanagari Extended */ /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, - /* A8F0 */ VMAbv, VMAbv, B, B, O, O, O, O, O, O, O, O, O, O, O, O, + /* A8F0 */ VMAbv, VMAbv, B, B, O, O, O, O, O, O, O, O, O, O, B, VAbv, /* Kayah Li */ @@ -479,10 +479,10 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VBlw, VBlw, VMBlw, VMAbv, /* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B, /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10A30 */ B, B, B, B, O, O, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, - /* 10A40 */ B, B, B, B, B, B, B, B, + /* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, + /* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, -#define use_offset_0x11000u 3552 +#define use_offset_0x11000u 3560 /* Brahmi */ @@ -503,7 +503,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, -#define use_offset_0x11100u 3744 +#define use_offset_0x11100u 3752 /* Chakma */ @@ -512,7 +512,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11120 */ B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, /* 11130 */ VAbv, VBlw, VBlw, H, VAbv, O, B, B, B, B, B, B, B, B, B, B, - /* 11140 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11140 */ O, O, O, O, B, VPst, VPst, O, O, O, O, O, O, O, O, O, /* Mahajani */ @@ -526,7 +526,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, - /* 111C0 */ H, B, R, R, O, O, O, O, O, O, CMBlw, VAbv, VBlw, O, O, O, + /* 111C0 */ H, B, R, R, O, O, O, O, O, FM, CMBlw, VAbv, VBlw, O, O, O, /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Sinhala Archaic Numbers */ @@ -541,7 +541,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O, -#define use_offset_0x11280u 4064 +#define use_offset_0x11280u 4072 /* Multani */ @@ -563,13 +563,13 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11300 */ VMAbv, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B, /* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPst, + /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, CMBlw, CMBlw, B, VPst, VPst, /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B, /* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, -#define use_offset_0x11400u 4312 +#define use_offset_0x11400u 4320 /* Newa */ @@ -579,7 +579,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11430 */ B, B, B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, /* 11440 */ VPst, VPst, H, VMAbv, VMAbv, VMPst, CMBlw, B, O, O, O, O, O, O, O, O, - /* 11450 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 11450 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, FM, O, /* 11460 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 11470 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -592,7 +592,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x11580u 4536 +#define use_offset_0x11580u 4544 /* Siddham */ @@ -631,11 +631,21 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Ahom */ /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11710 */ B, B, B, B, B, B, B, B, B, B, O, O, O, MBlw, MPre, MAbv, + /* 11710 */ B, B, B, B, B, B, B, B, B, B, B, O, O, MBlw, MPre, MAbv, /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O, /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, -#define use_offset_0x11a00u 4984 +#define use_offset_0x11800u 4992 + + + /* Dogra */ + + /* 11800 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw, + /* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O, + +#define use_offset_0x11a00u 5056 /* Zanabazar Square */ @@ -652,9 +662,9 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11A60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11A70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11A80 */ B, B, B, B, O, O, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, - /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, O, O, O, + /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O, -#define use_offset_0x11c00u 5144 +#define use_offset_0x11c00u 5216 /* Bhaiksuki */ @@ -675,7 +685,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O, -#define use_offset_0x11d00u 5328 +#define use_offset_0x11d00u 5400 /* Masaram Gondi */ @@ -687,7 +697,23 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11D40 */ VMAbv, VMAbv, CMBlw, VAbv, VBlw, H, R, MBlw, O, O, O, O, O, O, O, O, /* 11D50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -}; /* Table items: 5424; occupancy: 73% */ + /* Gunjala Gondi */ + + /* 11D60 */ B, B, B, B, B, B, O, B, B, O, B, B, B, B, B, B, + /* 11D70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11D80 */ B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VPst, VPst, O, + /* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O, + /* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x11ee0u 5576 + + + /* Makasar */ + + /* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O, + +}; /* Table items: 5600; occupancy: 73% */ USE_TABLE_ELEMENT_TYPE hb_use_get_category (hb_codepoint_t u) @@ -727,7 +753,7 @@ hb_use_get_category (hb_codepoint_t u) break; case 0x10u: - if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; break; case 0x11u: @@ -736,9 +762,11 @@ hb_use_get_category (hb_codepoint_t u) if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u]; if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; + if (hb_in_range<hb_codepoint_t> (u, 0x11800u, 0x1183Fu)) return use_table[u - 0x11800u + use_offset_0x11800u]; if (hb_in_range<hb_codepoint_t> (u, 0x11A00u, 0x11A9Fu)) return use_table[u - 0x11A00u + use_offset_0x11a00u]; if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11D5Fu)) return use_table[u - 0x11D00u + use_offset_0x11d00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11DAFu)) return use_table[u - 0x11D00u + use_offset_0x11d00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x11EE0u, 0x11EF7u)) return use_table[u - 0x11EE0u + use_offset_0x11ee0u]; break; default: diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index ee7653b..66b9571 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -35,7 +35,7 @@ /* * Universal Shaping Engine. - * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + * https://docs.microsoft.com/en-us/typography/script-development/use */ static const hb_tag_t @@ -511,7 +511,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx = 0; unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && !buffer->in_error) + while (buffer->idx < buffer->len && buffer->successful) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); @@ -526,7 +526,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && !buffer->in_error && + while (buffer->idx < buffer->len && buffer->successful && last_syllable == buffer->cur().syllable() && buffer->cur().use_category() == USE_R) buffer->next_glyph (); diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index c7b4605..fbf31ab 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -548,7 +548,7 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan, case t::SPACE_NARROW: /* Half-space? - * Unicode doc http://www.unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM. + * Unicode doc https://unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM. * However, in my testing, many fonts have their regular space being about that * size. To me, a percentage of the space width makes more sense. Half is as * good as any. */ diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index 62cbb9d..358450e 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -119,7 +119,7 @@ skip_char (hb_buffer_t *buffer) 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_codepoint_t a = 0, b = 0, a_glyph = 0, b_glyph = 0; hb_buffer_t * const buffer = c->buffer; hb_font_t * const font = c->font; @@ -164,7 +164,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor { hb_buffer_t * const buffer = c->buffer; hb_codepoint_t u = buffer->cur().codepoint; - hb_codepoint_t glyph; + hb_codepoint_t glyph = 0; if (shortest && c->font->get_nominal_glyph (u, &glyph)) { @@ -218,7 +218,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, uns /* 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 && !buffer->in_error;) { + for (; buffer->idx < end - 1 && buffer->successful;) { if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { /* The next two lines are some ugly lines... But work. */ if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) @@ -254,13 +254,13 @@ 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; - for (unsigned int i = buffer->idx; i < end && !buffer->in_error; i++) + for (unsigned int i = buffer->idx; i < end && buffer->successful; i++) if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) { handle_variation_selector_cluster (c, end, short_circuit); return; } - while (buffer->idx < end && !buffer->in_error) + while (buffer->idx < end && buffer->successful) decompose_current_character (c, short_circuit); } @@ -320,7 +320,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer->clear_output (); count = buffer->len; - for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;) + for (buffer->idx = 0; buffer->idx < count && buffer->successful;) { unsigned int end; for (end = buffer->idx + 1; end < count; end++) @@ -373,7 +373,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, count = buffer->len; unsigned int starter = 0; buffer->next_glyph (); - while (buffer->idx < count && !buffer->in_error) + while (buffer->idx < count && buffer->successful) { hb_codepoint_t composed, glyph; if (/* We don't try to compose a non-mark character with it's preceding starter. @@ -396,7 +396,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, { /* Composes. */ buffer->next_glyph (); /* Copy to out-buffer. */ - if (unlikely (buffer->in_error)) + if (unlikely (!buffer->successful)) return; buffer->merge_out_clusters (starter, buffer->out_len); buffer->out_len--; /* Remove the second composable. */ diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh index fe5d2b7..d689826 100644 --- a/src/hb-ot-shape-private.hh +++ b/src/hb-ot-shape-private.hh @@ -59,7 +59,14 @@ struct hb_ot_shape_plan_t inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); } inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); } - void finish (void) { map.finish (); } + void init (void) + { + memset (this, 0, sizeof (*this)); + map.init (); + } + void fini (void) { + map.fini (); + } }; struct hb_ot_shape_planner_t @@ -75,7 +82,6 @@ struct hb_ot_shape_planner_t props (master_plan->props), shaper (nullptr), map (face, &props) {} - ~hb_ot_shape_planner_t (void) { map.finish (); } inline void compile (hb_ot_shape_plan_t &plan, const int *coords, @@ -99,9 +105,7 @@ struct hb_ot_shape_planner_t } private: - /* No copy. */ - hb_ot_shape_planner_t (const hb_ot_shape_planner_t &); - hb_ot_shape_planner_t &operator = (const hb_ot_shape_planner_t &); + HB_DISALLOW_COPY_AND_ASSIGN (hb_ot_shape_planner_t); }; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 263d65c..36e0bf9 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -180,6 +180,8 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, if (unlikely (!plan)) return nullptr; + plan->init (); + hb_ot_shape_planner_t planner (shape_plan); planner.shaper = hb_ot_shape_complex_categorize (&planner); @@ -204,7 +206,7 @@ _hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan) if (plan->shaper->data_destroy) plan->shaper->data_destroy (const_cast<void *> (plan->data)); - plan->finish (); + plan->fini (); free (plan); } @@ -268,7 +270,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) info.cluster = buffer->cur().cluster; info.mask = buffer->cur().mask; buffer->output_info (info); - while (buffer->idx < buffer->len && !buffer->in_error) + while (buffer->idx < buffer->len && buffer->successful) buffer->next_glyph (); buffer->swap_buffers (); @@ -306,13 +308,16 @@ static void hb_ensure_native_direction (hb_buffer_t *buffer) { hb_direction_t direction = buffer->props.direction; + hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script); /* TODO vertical: * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType * Ogham fonts are supposed to be implemented BTT or not. Need to research that * first. */ - if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) || - (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) + if ((HB_DIRECTION_IS_HORIZONTAL (direction) && + direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) || + (HB_DIRECTION_IS_VERTICAL (direction) && + direction != HB_DIRECTION_TTB)) { /* Same loop as hb_form_clusters(). * Since form_clusters() merged clusters already, we don't merge. */ @@ -939,8 +944,6 @@ hb_ot_shape_glyphs_closure (hb_font_t *font, unsigned int num_features, hb_set_t *glyphs) { - hb_ot_shape_plan_t plan; - const char *shapers[] = {"ot", nullptr}; hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shapers); @@ -954,15 +957,7 @@ hb_ot_shape_glyphs_closure (hb_font_t *font, hb_set_t *lookups = hb_set_create (); hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups); - - /* And find transitive closure. */ - hb_set_t *copy = hb_set_create (); - do { - copy->set (glyphs); - for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);) - hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); - } while (!copy->is_equal (glyphs)); - hb_set_destroy (copy); + hb_ot_layout_lookups_substitute_closure (font->face, lookups, glyphs); hb_set_destroy (lookups); diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index 1338c31..991d8e7 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -116,8 +116,7 @@ hb_ot_new_tag_to_script (hb_tag_t tag) /* * Complete list at: - * https://www.microsoft.com/typography/otspec/scripttags.htm - * https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm + * https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags * * Most of the script tags are the same as the ISO 15924 tag but lowercased. * So we just do that, and handle the exceptional cases in a switch. @@ -159,7 +158,7 @@ typedef struct { /* * Complete list at: - * http://www.microsoft.com/typography/otspec/languagetags.htm + * https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags * * Generated by intersecting the OpenType language tag list from * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from @@ -176,7 +175,7 @@ typedef struct { * Updated as of 2015-05-06: OT1.7 on MS website has some newer * items that we don't have here, eg. Zazaki. This is the new * items in OpenType 1.7 (red items), most of which we have: - * http://www.microsoft.com/typography/otspec170/languagetags.htm + * https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags */ static const LangTag ot_languages[] = { @@ -1010,7 +1009,7 @@ hb_ot_tag_from_language (hb_language_t language) /** * hb_ot_tag_to_language: * - * + * * * Return value: (transfer none): * diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh index e305a67..ad063d3 100644 --- a/src/hb-ot-var-avar-table.hh +++ b/src/hb-ot-var-avar-table.hh @@ -29,6 +29,14 @@ #include "hb-open-type-private.hh" +/* + * avar -- Axis Variations + * https://docs.microsoft.com/en-us/typography/opentype/spec/avar + */ + +#define HB_OT_TAG_avar HB_TAG('a','v','a','r') + + namespace OT { @@ -62,38 +70,32 @@ struct SegmentMaps : ArrayOf<AxisValueMap> if (!len) return value; else /* len == 1*/ - return value - array[0].fromCoord + array[0].toCoord; + return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; } - if (value <= array[0].fromCoord) - return value - array[0].fromCoord + array[0].toCoord; + if (value <= arrayZ[0].fromCoord) + return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; unsigned int i; unsigned int count = len; - for (i = 1; i < count && value > array[i].fromCoord; i++) + for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) ; - if (value >= array[i].fromCoord) - return value - array[i].fromCoord + array[i].toCoord; + if (value >= arrayZ[i].fromCoord) + return value - arrayZ[i].fromCoord + arrayZ[i].toCoord; - if (unlikely (array[i-1].fromCoord == array[i].fromCoord)) - return array[i-1].toCoord; + if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord)) + return arrayZ[i-1].toCoord; - int denom = array[i].fromCoord - array[i-1].fromCoord; - return array[i-1].toCoord + - ((array[i].toCoord - array[i-1].toCoord) * - (value - array[i-1].fromCoord) + denom/2) / denom; + int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; + return arrayZ[i-1].toCoord + + ((arrayZ[i].toCoord - arrayZ[i-1].toCoord) * + (value - arrayZ[i-1].fromCoord) + denom/2) / denom; } - DEFINE_SIZE_ARRAY (2, array); + DEFINE_SIZE_ARRAY (2, arrayZ); }; -/* - * avar — Axis Variations Table - */ - -#define HB_OT_TAG_avar HB_TAG('a','v','a','r') - struct avar { static const hb_tag_t tableTag = HB_OT_TAG_avar; @@ -106,7 +108,7 @@ struct avar c->check_struct (this)))) return_trace (false); - const SegmentMaps *map = &axisSegmentMapsZ; + const SegmentMaps *map = axisSegmentMapsZ; unsigned int count = axisCount; for (unsigned int i = 0; i < count; i++) { @@ -122,7 +124,7 @@ struct avar { unsigned int count = MIN<unsigned int> (coords_length, axisCount); - const SegmentMaps *map = &axisSegmentMapsZ; + const SegmentMaps *map = axisSegmentMapsZ; for (unsigned int i = 0; i < count; i++) { coords[i] = map->map (coords[i]); @@ -137,7 +139,7 @@ struct avar HBUINT16 axisCount; /* The number of variation axes in the font. This * must be the same number as axisCount in the * 'fvar' table. */ - SegmentMaps axisSegmentMapsZ; + SegmentMaps axisSegmentMapsZ[VAR]; public: DEFINE_SIZE_MIN (8); diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 999b723..82d2996 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -29,6 +29,14 @@ #include "hb-open-type-private.hh" +/* + * fvar -- Font Variations + * https://docs.microsoft.com/en-us/typography/opentype/spec/fvar + */ + +#define HB_OT_TAG_fvar HB_TAG('f','v','a','r') + + namespace OT { @@ -42,11 +50,11 @@ struct InstanceRecord } protected: - HBUINT16 subfamilyNameID;/* The name ID for entries in the 'name' table + NameID subfamilyNameID;/* The name ID for entries in the 'name' table * that provide subfamily names for this instance. */ HBUINT16 reserved; /* Reserved for future use — set to 0. */ Fixed coordinates[VAR];/* The coordinates array for this instance. */ - //HBUINT16 postScriptNameIDX;/*Optional. The name ID for entries in the 'name' + //NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name' // * table that provide PostScript names for this // * instance. */ @@ -68,20 +76,13 @@ struct AxisRecord Fixed defaultValue; /* The default coordinate value for the axis. */ Fixed maxValue; /* The maximum coordinate value for the axis. */ HBUINT16 reserved; /* Reserved for future use — set to 0. */ - HBUINT16 axisNameID; /* The name ID for entries in the 'name' table that + NameID axisNameID; /* The name ID for entries in the 'name' table that * provide a display name for this axis. */ public: DEFINE_SIZE_STATIC (20); }; - -/* - * fvar — Font Variations Table - */ - -#define HB_OT_TAG_fvar HB_TAG('f','v','a','r') - struct fvar { static const hb_tag_t tableTag = HB_OT_TAG_fvar; diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index e20131b..2b384db 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -89,10 +89,11 @@ struct DeltaSetIndexMap /* - * HVAR -- The Horizontal Metrics Variations Table - * VVAR -- The Vertical Metrics Variations Table + * HVAR -- Horizontal Metrics Variations + * https://docs.microsoft.com/en-us/typography/opentype/spec/hvar + * VVAR -- Vertical Metrics Variations + * https://docs.microsoft.com/en-us/typography/opentype/spec/vvar */ - #define HB_OT_TAG_HVAR HB_TAG('H','V','A','R') #define HB_OT_TAG_VVAR HB_TAG('V','V','A','R') diff --git a/src/hb-ot-var-mvar-table.hh b/src/hb-ot-var-mvar-table.hh index e835768..dfde782 100644 --- a/src/hb-ot-var-mvar-table.hh +++ b/src/hb-ot-var-mvar-table.hh @@ -51,9 +51,9 @@ struct VariationValueRecord /* - * MVAR -- Metrics Variations Table + * MVAR -- Metrics Variations + * https://docs.microsoft.com/en-us/typography/opentype/spec/mvar */ - #define HB_OT_TAG_MVAR HB_TAG('M','V','A','R') struct MVAR diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 90ba0bd..f0612a6 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -39,14 +39,14 @@ static inline const OT::fvar& _get_fvar (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::fvar); hb_ot_layout_t * layout = hb_ot_layout_from_face (face); return *(layout->fvar.get ()); } static inline const OT::avar& _get_avar (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::avar); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::avar); hb_ot_layout_t * layout = hb_ot_layout_from_face (face); return *(layout->avar.get ()); } @@ -65,7 +65,7 @@ _get_avar (hb_face_t *face) hb_bool_t hb_ot_var_has_data (hb_face_t *face) { - return &_get_fvar (face) != &OT::Null(OT::fvar); + return &_get_fvar (face) != &Null(OT::fvar); } /** diff --git a/src/hb-private.hh b/src/hb-private.hh index daa496e..32e3354 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -51,7 +51,7 @@ #include <stdio.h> #include <stdarg.h> -#if defined(_MSC_VER) || defined(__MINGW32__) +#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) #include <intrin.h> #endif @@ -90,6 +90,14 @@ extern "C" void hb_free_impl(void *ptr); HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1] #endif // static_assert +#ifdef __GNUC__ +#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) +#define thread_local __thread +#endif +#else +#define thread_local +#endif + #endif // __cplusplus < 201103L #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__) @@ -139,7 +147,7 @@ extern "C" void hb_free_impl(void *ptr); #define HB_FUNC __func__ #endif -#ifdef __SUNPRO_CC +#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140) /* https://github.com/harfbuzz/harfbuzz/issues/630 */ #define __restrict #endif @@ -221,16 +229,14 @@ static int errno = 0; /* Use something better? */ # 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 + * https://msdn.microsoft.com/en-us/library/tze57ck3.aspx + * https://msdn.microsoft.com/en-us/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 +# elif defined(__ANDROID__) +/* This is available since Android NKD r8 or r8b: + * https://issuetracker.google.com/code/p/android/issues/detail?id=6455 */ # define HB_USE_ATEXIT 1 # elif defined(__APPLE__) @@ -241,6 +247,9 @@ static int errno = 0; /* Use something better? */ # define HB_USE_ATEXIT 1 # endif #endif +#ifdef HB_NO_ATEXIT +# undef HB_USE_ATEXIT +#endif /* Basics */ @@ -314,7 +323,7 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); -/* Misc */ +/* Tiny functions */ /* * Void! @@ -360,6 +369,7 @@ _hb_popcount (T v) } assert (0); + return 0; /* Shut up stupid compiler. */ } /* Returns the number of bits needed to store number */ @@ -380,7 +390,7 @@ _hb_bit_storage (T v) return sizeof (unsigned long long) * 8 - __builtin_clzll (v); #endif -#if defined(_MSC_VER) || defined(__MINGW32__) +#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) if (sizeof (T) <= sizeof (unsigned int)) { unsigned long where; @@ -414,7 +424,7 @@ _hb_bit_storage (T v) if (sizeof (T) <= 8) { /* "bithacks" */ - const uint64_t b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000}; + const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL}; const unsigned int S[] = {1, 2, 4, 8, 16, 32}; unsigned int r = 0; for (int i = 5; i >= 0; i--) @@ -428,11 +438,12 @@ _hb_bit_storage (T v) if (sizeof (T) == 16) { unsigned int shift = 64; - return (v >> shift) ? _hb_bit_storage<uint64_t> ((uint64_t) v >> shift) + shift : + return (v >> shift) ? _hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift : _hb_bit_storage<uint64_t> ((uint64_t) v); } assert (0); + return 0; /* Shut up stupid compiler. */ } /* Returns the number of zero bits in the least significant side of v */ @@ -453,7 +464,7 @@ _hb_ctz (T v) return __builtin_ctzll (v); #endif -#if defined(_MSC_VER) || defined(__MINGW32__) +#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) if (sizeof (T) <= sizeof (unsigned int)) { unsigned long where; @@ -489,12 +500,12 @@ _hb_ctz (T v) unsigned int c = 64; v &= - (int64_t) (v); if (v) c--; - if (v & 0x00000000FFFFFFFF) c -= 32; - if (v & 0x0000FFFF0000FFFF) c -= 16; - if (v & 0x00FF00FF00FF00FF) c -= 8; - if (v & 0x0F0F0F0F0F0F0F0F) c -= 4; - if (v & 0x3333333333333333) c -= 2; - if (v & 0x5555555555555555) c -= 1; + if (v & 0x00000000FFFFFFFFULL) c -= 32; + if (v & 0x0000FFFF0000FFFFULL) c -= 16; + if (v & 0x00FF00FF00FF00FFULL) c -= 8; + if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4; + if (v & 0x3333333333333333ULL) c -= 2; + if (v & 0x5555555555555555ULL) c -= 1; return c; } if (sizeof (T) == 16) @@ -505,6 +516,7 @@ _hb_ctz (T v) } assert (0); + return 0; /* Shut up stupid compiler. */ } static inline bool @@ -521,39 +533,147 @@ _hb_ceil_to_4 (unsigned int v) +/* + * + * Utility types + * + */ + +#define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +/* + * Static pools + */ + +/* Global nul-content Null pool. Enlarge as necessary. */ + +#define HB_NULL_POOL_SIZE 264 +static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE."); + +#ifdef HB_NO_VISIBILITY +static +#else +extern HB_INTERNAL +#endif +void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] +#ifdef HB_NO_VISIBILITY += {} +#endif +; +/* Generic nul-content Null objects. */ +template <typename Type> +static inline Type const & Null (void) { + static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + return *reinterpret_cast<Type const *> (_hb_NullPool); +} +#define Null(Type) Null<Type>() + +/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ +#define DEFINE_NULL_DATA(Namespace, Type, data) \ +} /* Close namespace. */ \ +static const char _Null##Type[sizeof (Namespace::Type) + 1] = data; /* +1 is for nul-termination in data */ \ +template <> \ +/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \ + return *reinterpret_cast<const Namespace::Type *> (_Null##Type); \ +} \ +namespace Namespace { \ +/* The following line really exists such that we end in a place needing semicolon */ \ +static_assert (Namespace::Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.") + + +/* Global writable pool. Enlarge as necessary. */ + +/* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool + * for correct operation. It only exist to catch and divert program logic bugs instead of + * causing bad memory access. So, races there are not actually introducing incorrectness + * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */ +#ifdef HB_NO_VISIBILITY +static +#else +extern HB_INTERNAL +#endif +/*thread_local*/ void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] +#ifdef HB_NO_VISIBILITY += {} +#endif +; +/* CRAP pool: Common Region for Access Protection. */ +template <typename Type> +static inline Type& Crap (void) { + static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + Type *obj = reinterpret_cast<Type *> (_hb_CrapPool); + *obj = Null(Type); + return *obj; +} +#define Crap(Type) Crap<Type>() + +template <typename Type> +struct CrapOrNull { + static inline Type & get (void) { return Crap(Type); } +}; +template <typename Type> +struct CrapOrNull<const Type> { + static inline Type const & get (void) { return Null(Type); } +}; +#define CrapOrNull(Type) CrapOrNull<Type>::get () + + + /* arrays and maps */ #define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr} -template <typename Type, unsigned int StaticSize=16> -struct hb_prealloced_array_t +template <typename Type, unsigned int StaticSize=8> +struct hb_vector_t { unsigned int len; unsigned int allocated; - Type *array; + bool successful; + Type *arrayZ; Type static_array[StaticSize]; void init (void) { len = 0; allocated = ARRAY_LENGTH (static_array); - array = static_array; + successful = true; + arrayZ = static_array; } - inline Type& operator [] (unsigned int i) { return array[i]; } - inline const Type& operator [] (unsigned int i) const { return array[i]; } + inline Type& operator [] (unsigned int i) + { + if (unlikely (i >= len)) + return Crap (Type); + return arrayZ[i]; + } + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i >= len)) + return Null(Type); + return arrayZ[i]; + } inline Type *push (void) { if (unlikely (!resize (len + 1))) - return nullptr; - - return &array[len - 1]; + return &Crap(Type); + return &arrayZ[len - 1]; + } + inline Type *push (const Type& v) + { + Type *p = push (); + *p = v; + return p; } /* Allocate for size but don't adjust len. */ - inline bool alloc(unsigned int size) + inline bool alloc (unsigned int size) { + if (unlikely (!successful)) + return false; + if (likely (size <= allocated)) return true; @@ -565,37 +685,47 @@ struct hb_prealloced_array_t Type *new_array = nullptr; - if (array == static_array) { + if (arrayZ == static_array) + { new_array = (Type *) calloc (new_allocated, sizeof (Type)); if (new_array) - memcpy (new_array, array, len * sizeof (Type)); - } else { + memcpy (new_array, arrayZ, len * sizeof (Type)); + } + else + { bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type)); - if (likely (!overflows)) { - new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); - } + if (likely (!overflows)) + new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type)); } if (unlikely (!new_array)) + { + successful = false; return false; + } - array = new_array; + arrayZ = new_array; allocated = new_allocated; return true; } - inline bool resize (unsigned int size) + inline bool resize (int size_) { + unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; if (!alloc (size)) return false; + if (size > len) + memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ)); + len = size; return true; } inline void pop (void) { + if (!len) return; len--; } @@ -603,54 +733,55 @@ struct hb_prealloced_array_t { if (unlikely (i >= len)) return; - memmove (static_cast<void *> (&array[i]), - static_cast<void *> (&array[i + 1]), + memmove (static_cast<void *> (&arrayZ[i]), + static_cast<void *> (&arrayZ[i + 1]), (len - i - 1) * sizeof (Type)); len--; } - inline void shrink (unsigned int l) + inline void shrink (int size_) { - if (l < len) - len = l; + unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; + if (size < len) + len = size; } template <typename T> inline Type *find (T v) { for (unsigned int i = 0; i < len; i++) - if (array[i] == v) - return &array[i]; + if (arrayZ[i] == v) + return &arrayZ[i]; return nullptr; } template <typename T> inline const Type *find (T v) const { for (unsigned int i = 0; i < len; i++) - if (array[i] == v) - return &array[i]; + if (arrayZ[i] == v) + return &arrayZ[i]; return nullptr; } inline void qsort (int (*cmp)(const void*, const void*)) { - ::qsort (array, len, sizeof (Type), cmp); + ::qsort (arrayZ, len, sizeof (Type), cmp); } inline void qsort (void) { - ::qsort (array, len, sizeof (Type), Type::cmp); + ::qsort (arrayZ, len, sizeof (Type), Type::cmp); } inline void qsort (unsigned int start, unsigned int end) { - ::qsort (array + start, end - start, sizeof (Type), Type::cmp); + ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp); } template <typename T> inline Type *lsearch (const T &x) { for (unsigned int i = 0; i < len; i++) - if (0 == this->array[i].cmp (&x)) - return &array[i]; + if (0 == this->arrayZ[i].cmp (&x)) + return &arrayZ[i]; return nullptr; } @@ -658,13 +789,13 @@ struct hb_prealloced_array_t inline Type *bsearch (const T &x) { unsigned int i; - return bfind (x, &i) ? &array[i] : nullptr; + return bfind (x, &i) ? &arrayZ[i] : nullptr; } template <typename T> inline const Type *bsearch (const T &x) const { unsigned int i; - return bfind (x, &i) ? &array[i] : nullptr; + return bfind (x, &i) ? &arrayZ[i] : nullptr; } template <typename T> inline bool bfind (const T &x, unsigned int *i) const @@ -673,7 +804,7 @@ struct hb_prealloced_array_t while (min <= max) { int mid = (min + max) / 2; - int c = this->array[mid].cmp (&x); + int c = this->arrayZ[mid].cmp (&x); if (c < 0) max = mid - 1; else if (c > 0) @@ -684,34 +815,39 @@ struct hb_prealloced_array_t return true; } } - if (max < 0 || (max < (int) this->len && this->array[max].cmp (&x) > 0)) + if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0)) max++; *i = max; return false; } - inline void finish (void) + inline void fini (void) { - if (array != static_array) - free (array); - array = nullptr; + if (arrayZ != static_array) + free (arrayZ); + arrayZ = nullptr; allocated = len = 0; } }; template <typename Type> -struct hb_auto_array_t : hb_prealloced_array_t <Type> +struct hb_auto_t : Type { - hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); } - ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); } + hb_auto_t (void) { Type::init (); } + ~hb_auto_t (void) { Type::fini (); } + private: /* Hide */ + void init (void) {} + void fini (void) {} }; +template <typename Type> +struct hb_auto_array_t : hb_auto_t <hb_vector_t <Type> > {}; #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} template <typename item_t, typename lock_t> struct hb_lockable_set_t { - hb_prealloced_array_t <item_t, 1> items; + hb_vector_t <item_t, 1> items; inline void init (void) { items.init (); } @@ -725,16 +861,14 @@ struct hb_lockable_set_t item_t old = *item; *item = v; l.unlock (); - old.finish (); + old.fini (); } else { item = nullptr; l.unlock (); } } else { - item = items.push (); - if (likely (item)) - *item = v; + item = items.push (v); l.unlock (); } return item; @@ -750,7 +884,7 @@ struct hb_lockable_set_t *item = items[items.len - 1]; items.pop (); l.unlock (); - old.finish (); + old.fini (); } else { l.unlock (); } @@ -773,19 +907,17 @@ struct hb_lockable_set_t l.lock (); item_t *item = items.find (v); if (!item) { - item = items.push (); - if (likely (item)) - *item = v; + item = items.push (v); } l.unlock (); return item; } - inline void finish (lock_t &l) + inline void fini (lock_t &l) { if (!items.len) { /* No need for locking. */ - items.finish (); + items.fini (); return; } l.lock (); @@ -793,10 +925,10 @@ struct hb_lockable_set_t item_t old = items[items.len - 1]; items.pop (); l.unlock (); - old.finish (); + old.fini (); l.lock (); } - items.finish (); + items.fini (); l.unlock (); } @@ -823,7 +955,7 @@ static inline unsigned char TOLOWER (unsigned char c) * light-weight) to be enabled, then HB_DEBUG can be defined to disable * the costlier checks. */ #ifdef NDEBUG -#define HB_NDEBUG +#define HB_NDEBUG 1 #endif @@ -972,19 +1104,35 @@ struct HbOpXor template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; } }; + +/* Compiler-assisted vectorization. */ + +/* The `vector_size' attribute was introduced in gcc 3.1. */ +#if defined( __GNUC__ ) && ( __GNUC__ >= 4 ) +#define HB_VECTOR_SIZE 128 +#elif !defined(HB_VECTOR_SIZE) +#define HB_VECTOR_SIZE 0 +#endif + /* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))). */ template <typename elt_t, unsigned int byte_size> struct hb_vector_size_t { - elt_t& operator [] (unsigned int i) { return v[i]; } - const elt_t& operator [] (unsigned int i) const { return v[i]; } + elt_t& operator [] (unsigned int i) { return u.v[i]; } + const elt_t& operator [] (unsigned int i) const { return u.v[i]; } template <class Op> inline hb_vector_size_t process (const hb_vector_size_t &o) const { hb_vector_size_t r; - for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) - Op::process (r.v[i], v[i], o.v[i]); +#if HB_VECTOR_SIZE + if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE) + for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++) + Op::process (r.u.vec[i], u.vec[i], o.u.vec[i]); + else +#endif + for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++) + Op::process (r.u.v[i], u.v[i], o.u.v[i]); return r; } inline hb_vector_size_t operator | (const hb_vector_size_t &o) const @@ -996,20 +1144,27 @@ struct hb_vector_size_t inline hb_vector_size_t operator ~ () const { hb_vector_size_t r; - for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) - r.v[i] = ~v[i]; +#if HB_VECTOR_SIZE && 0 + if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE) + for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++) + r.u.vec[i] = ~u.vec[i]; + else +#endif + for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++) + r.u.v[i] = ~u.v[i]; return r; } private: static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, ""); - elt_t v[byte_size / sizeof (elt_t)]; -}; - -/* The `vector_size' attribute was introduced in gcc 3.1. */ -#if defined( __GNUC__ ) && ( __GNUC__ >= 4 ) -#define HAVE_VECTOR_SIZE 1 + union { + elt_t v[byte_size / sizeof (elt_t)]; +#if HB_VECTOR_SIZE + typedef unsigned long vec_t __attribute__((vector_size (HB_VECTOR_SIZE / 8))); + vec_t vec[byte_size / sizeof (vec_t)]; #endif + } u; +}; /* Global runtime options. */ @@ -1046,12 +1201,12 @@ hb_options (void) /* String type. */ -struct hb_string_t +struct hb_bytes_t { - inline hb_string_t (void) : bytes (nullptr), len (0) {} - inline hb_string_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {} + inline hb_bytes_t (void) : bytes (nullptr), len (0) {} + inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {} - inline int cmp (const hb_string_t &a) const + inline int cmp (const hb_bytes_t &a) const { if (len != a.len) return (int) a.len - (int) len; @@ -1060,8 +1215,8 @@ struct hb_string_t } static inline int cmp (const void *pa, const void *pb) { - hb_string_t *a = (hb_string_t *) pa; - hb_string_t *b = (hb_string_t *) pb; + hb_bytes_t *a = (hb_bytes_t *) pa; + hb_bytes_t *b = (hb_bytes_t *) pb; return b->cmp (*a); } @@ -1070,4 +1225,17 @@ struct hb_string_t }; +/* fallback for round() */ +#if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND) +static inline double +round (double x) +{ + if (x >= 0) + return floor (x + 0.5); + else + return ceil (x - 0.5); +} +#endif + + #endif /* HB_PRIVATE_HH */ diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index 3615c50..ccd4d8d 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -158,21 +158,13 @@ struct hb_set_t } typedef unsigned long long elt_t; - static const unsigned int PAGE_BITS = 1024; + static const unsigned int PAGE_BITS = 512; static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, ""); static inline unsigned int elt_get_min (const elt_t &elt) { return _hb_ctz (elt); } static inline unsigned int elt_get_max (const elt_t &elt) { return _hb_bit_storage (elt) - 1; } -#if 0 && HAVE_VECTOR_SIZE - /* The vectorized version does not work with clang as non-const - * elt() errs "non-const reference cannot bind to vector element". */ - typedef elt_t vector_t __attribute__((vector_size (PAGE_BITS / 8))); -#else typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t; -#endif - - vector_t v; static const unsigned int ELT_BITS = sizeof (elt_t) * 8; static const unsigned int ELT_MASK = ELT_BITS - 1; @@ -183,34 +175,47 @@ struct hb_set_t elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; } elt_t const &elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; } elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & ELT_MASK); } + + vector_t v; }; static_assert (page_t::PAGE_BITS == sizeof (page_t) * 8, ""); hb_object_header_t header; - ASSERT_POD (); - bool in_error; - hb_prealloced_array_t<page_map_t, 8> page_map; - hb_prealloced_array_t<page_t, 1> pages; + bool successful; /* Allocations successful */ + mutable unsigned int population; + hb_vector_t<page_map_t, 1> page_map; + hb_vector_t<page_t, 1> pages; - inline void init (void) + inline void init_shallow (void) { - in_error = false; + successful = true; + population = 0; page_map.init (); pages.init (); } - inline void finish (void) + inline void init (void) + { + hb_object_init (this); + init_shallow (); + } + inline void fini_shallow (void) + { + page_map.fini (); + pages.fini (); + } + inline void fini (void) { - page_map.finish (); - pages.finish (); + hb_object_fini (this); + fini_shallow (); } inline bool resize (unsigned int count) { - if (unlikely (in_error)) return false; + if (unlikely (!successful)) return false; if (!pages.resize (count) || !page_map.resize (count)) { pages.resize (page_map.len); - in_error = true; + successful = false; return false; } return true; @@ -219,7 +224,8 @@ struct hb_set_t inline void clear (void) { if (unlikely (hb_object_is_inert (this))) return; - in_error = false; + successful = true; + population = 0; page_map.resize (0); pages.resize (0); } @@ -231,17 +237,21 @@ struct hb_set_t return true; } + inline void dirty (void) { population = (unsigned int) -1; } + inline void add (hb_codepoint_t g) { - if (unlikely (in_error)) return; + if (unlikely (!successful)) return; if (unlikely (g == INVALID)) return; + dirty (); page_t *page = page_for_insert (g); if (unlikely (!page)) return; page->add (g); } inline bool add_range (hb_codepoint_t a, hb_codepoint_t b) { - if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ + if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ if (unlikely (a > b || a == INVALID || b == INVALID)) return false; + dirty (); unsigned int ma = get_major (a); unsigned int mb = get_major (b); if (ma == mb) @@ -269,8 +279,9 @@ struct hb_set_t template <typename T> inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) { - if (unlikely (in_error)) return; + if (unlikely (!successful)) return; if (!count) return; + dirty (); hb_codepoint_t g = *array; while (count) { @@ -294,8 +305,9 @@ struct hb_set_t template <typename T> inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) { - if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ + if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ if (!count) return true; + dirty (); hb_codepoint_t g = *array; hb_codepoint_t last_g = g; while (count) @@ -321,16 +333,19 @@ struct hb_set_t inline void del (hb_codepoint_t g) { - if (unlikely (in_error)) return; + /* TODO perform op even if !successful. */ + if (unlikely (!successful)) return; page_t *p = page_for (g); if (!p) return; + dirty (); p->del (g); } inline void del_range (hb_codepoint_t a, hb_codepoint_t b) { + /* TODO perform op even if !successful. */ /* TODO Optimize, like add_range(). */ - if (unlikely (in_error)) return; + if (unlikely (!successful)) return; for (unsigned int i = a; i < b + 1; i++) del (i); } @@ -349,17 +364,20 @@ struct hb_set_t } inline void set (const hb_set_t *other) { - if (unlikely (in_error)) return; + if (unlikely (!successful)) return; unsigned int count = other->pages.len; if (!resize (count)) return; - - memcpy (pages.array, other->pages.array, count * sizeof (pages.array[0])); - memcpy (page_map.array, other->page_map.array, count * sizeof (page_map.array[0])); + population = other->population; + memcpy (pages.arrayZ, other->pages.arrayZ, count * sizeof (pages.arrayZ[0])); + memcpy (page_map.arrayZ, other->page_map.arrayZ, count * sizeof (page_map.arrayZ[0])); } inline bool is_equal (const hb_set_t *other) const { + if (get_population () != other->get_population ()) + return false; + unsigned int na = pages.len; unsigned int nb = other->pages.len; @@ -382,16 +400,31 @@ struct hb_set_t return true; } + inline bool is_subset (const hb_set_t *larger_set) const + { + if (get_population () > larger_set->get_population ()) + return false; + + hb_codepoint_t c = INVALID; + while (next (&c)) + if (!larger_set->has (c)) + return false; + + return true; + } + template <class Op> inline void process (const hb_set_t *other) { - if (unlikely (in_error)) return; + if (unlikely (!successful)) return; + + dirty (); unsigned int na = pages.len; unsigned int nb = other->pages.len; unsigned int next_page = na; - unsigned int count = 0; + unsigned int count = 0, newCount = 0; unsigned int a = 0, b = 0; for (; a < na && b < nb; ) { @@ -419,8 +452,10 @@ struct hb_set_t if (Op::passthru_right) count += nb - b; - if (!resize (count)) - return; + if (count > pages.len) + if (!resize (count)) + return; + newCount = count; /* Process in-place backward. */ a = na; @@ -473,6 +508,8 @@ struct hb_set_t page_at (count).v = other->page_at (b).v; } assert (!count); + if (pages.len > newCount) + resize (newCount); } inline void union_ (const hb_set_t *other) @@ -592,10 +629,15 @@ struct hb_set_t inline unsigned int get_population (void) const { + if (population != (unsigned int) -1) + return population; + unsigned int pop = 0; unsigned int count = pages.len; for (unsigned int i = 0; i < count; i++) pop += pages[i].get_population (); + + population = pop; return pop; } inline hb_codepoint_t get_min (void) const diff --git a/src/hb-set.cc b/src/hb-set.cc index 07cf9d0..25027e6 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -45,18 +45,11 @@ hb_set_create (void) if (!(set = hb_object_create<hb_set_t> ())) return hb_set_get_empty (); - set->init (); + set->init_shallow (); return set; } -static const hb_set_t _hb_set_nil = { - HB_OBJECT_HEADER_STATIC, - true, /* in_error */ - - {0} /* elts */ -}; - /** * hb_set_get_empty: * @@ -67,7 +60,7 @@ static const hb_set_t _hb_set_nil = { hb_set_t * hb_set_get_empty (void) { - return const_cast<hb_set_t *> (&_hb_set_nil); + return const_cast<hb_set_t *> (&Null(hb_set_t)); } /** @@ -95,7 +88,7 @@ hb_set_destroy (hb_set_t *set) { if (!hb_object_destroy (set)) return; - set->finish (); + set->fini_shallow (); free (set); } @@ -150,9 +143,9 @@ hb_set_get_user_data (hb_set_t *set, * Since: 0.9.2 **/ hb_bool_t -hb_set_allocation_successful (const hb_set_t *set HB_UNUSED) +hb_set_allocation_successful (const hb_set_t *set) { - return !set->in_error; + return set->successful; } /** @@ -274,11 +267,11 @@ hb_set_del_range (hb_set_t *set, /** * hb_set_is_equal: * @set: a set. - * @other: + * @other: other set. * * * - * Return value: + * Return value: %TRUE if the two sets are equal, %FALSE otherwise. * * Since: 0.9.7 **/ @@ -290,6 +283,24 @@ hb_set_is_equal (const hb_set_t *set, } /** + * hb_set_is_subset: + * @set: a set. + * @larger_set: other set. + * + * + * + * Return value: %TRUE if the @set is a subset of (or equal to) @larger_set, %FALSE otherwise. + * + * Since: 1.8.1 + **/ +hb_bool_t +hb_set_is_subset (const hb_set_t *set, + const hb_set_t *larger_set) +{ + return set->is_subset (larger_set); +} + +/** * hb_set_set: * @set: a set. * @other: diff --git a/src/hb-set.h b/src/hb-set.h index b0f82f8..ed0e05d 100644 --- a/src/hb-set.h +++ b/src/hb-set.h @@ -82,8 +82,6 @@ HB_EXTERN hb_bool_t hb_set_has (const hb_set_t *set, hb_codepoint_t codepoint); -/* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1 - * which we will use as a sentinel. */ HB_EXTERN void hb_set_add (hb_set_t *set, hb_codepoint_t codepoint); @@ -106,6 +104,10 @@ HB_EXTERN hb_bool_t hb_set_is_equal (const hb_set_t *set, const hb_set_t *other); +HB_EXTERN hb_bool_t +hb_set_is_subset (const hb_set_t *set, + const hb_set_t *larger_set); + HB_EXTERN void hb_set_set (hb_set_t *set, const hb_set_t *other); diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 39355b3..c1e7365 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -51,7 +51,12 @@ static const char **static_shaper_list; static void free_static_shaper_list (void) { - free (static_shaper_list); +retry: + const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list); + if (!hb_atomic_ptr_cmpexch (&static_shaper_list, shaper_list, nullptr)) + goto retry; + + free (shaper_list); } #endif diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc index 2c44cf2..d44d8c9 100644 --- a/src/hb-shaper.cc +++ b/src/hb-shaper.cc @@ -44,8 +44,13 @@ static const hb_shaper_pair_t *static_shapers; static void free_static_shapers (void) { - if (unlikely (static_shapers != all_shapers)) - free ((void *) static_shapers); +retry: + hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers); + if (!hb_atomic_ptr_cmpexch (&static_shapers, shapers, nullptr)) + goto retry; + + if (unlikely (shapers != all_shapers)) + free ((void *) shapers); } #endif diff --git a/src/hb-static.cc b/src/hb-static.cc new file mode 100644 index 0000000..e26e5c8 --- /dev/null +++ b/src/hb-static.cc @@ -0,0 +1,32 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-private.hh" + +#ifndef HB_NO_VISIBILITY +void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +/*thread_local*/ void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +#endif diff --git a/src/hb-string-array.hh b/src/hb-string-array.hh index ba829b0..679841c 100644 --- a/src/hb-string-array.hh +++ b/src/hb-string-array.hh @@ -42,7 +42,7 @@ static const union HB_STRING_ARRAY_TYPE_NAME { struct { /* I like to avoid storing the nul-termination byte since we don't need it, * but C++ does not allow that. - * https://stackoverflow.com/questions/28433862/why-initializer-string-for-array-of-chars-is-too-long-compiles-fine-in-c-not + * https://stackoverflow.com/q/28433862 */ #define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; #include HB_STRING_ARRAY_LIST @@ -66,12 +66,12 @@ static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] = sizeof (HB_STRING_ARRAY_TYPE_NAME) }; -static inline hb_string_t +static inline hb_bytes_t HB_STRING_ARRAY_NAME (unsigned int i) { assert (i < ARRAY_LENGTH (HB_STRING_ARRAY_OFFS_NAME) - 1); - return hb_string_t (HB_STRING_ARRAY_POOL_NAME.str + HB_STRING_ARRAY_OFFS_NAME[i], - HB_STRING_ARRAY_OFFS_NAME[i + 1] - HB_STRING_ARRAY_OFFS_NAME[i] - 1); + return hb_bytes_t (HB_STRING_ARRAY_POOL_NAME.str + HB_STRING_ARRAY_OFFS_NAME[i], + HB_STRING_ARRAY_OFFS_NAME[i + 1] - HB_STRING_ARRAY_OFFS_NAME[i] - 1); } #undef HB_STRING_ARRAY_TYPE_NAME diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index 0b84c85..c8fa39b 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -32,20 +32,25 @@ static bool _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, - hb_prealloced_array_t<hb_codepoint_t> &glyph_ids, + hb_vector_t<hb_codepoint_t> &glyph_ids, hb_bool_t drop_hints, bool *use_short_loca /* OUT */, unsigned int *glyf_size /* OUT */, unsigned int *loca_size /* OUT */, - hb_prealloced_array_t<unsigned int> *instruction_ranges /* OUT */) + hb_vector_t<unsigned int> *instruction_ranges /* OUT */) { unsigned int total = 0; for (unsigned int i = 0; i < glyph_ids.len; i++) { hb_codepoint_t next_glyph = glyph_ids[i]; - unsigned int *instruction_start = instruction_ranges->push(); - unsigned int *instruction_end = instruction_ranges->push(); + if (!instruction_ranges->resize (instruction_ranges->len + 2)) + { + DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges."); + return false; + } + unsigned int *instruction_start = &(*instruction_ranges)[instruction_ranges->len - 2]; *instruction_start = 0; + unsigned int *instruction_end = &(*instruction_ranges)[instruction_ranges->len - 1]; *instruction_end = 0; unsigned int start_offset, end_offset; @@ -116,7 +121,6 @@ static void _update_components (hb_subset_plan_t * plan, char * glyph_start, unsigned int length) - { OT::glyf::CompositeGlyphHeader::Iterator iterator; if (OT::glyf::CompositeGlyphHeader::get_iterator (glyph_start, @@ -126,9 +130,8 @@ _update_components (hb_subset_plan_t * plan, do { hb_codepoint_t new_gid; - if (!hb_subset_plan_new_gid_for_old_id (plan, - iterator.current->glyphIndex, - &new_gid)) + if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex, + &new_gid)) continue; ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid); @@ -155,13 +158,13 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan, const OT::glyf::accelerator_t &glyf, const char *glyf_data, bool use_short_loca, - hb_prealloced_array_t<unsigned int> &instruction_ranges, + hb_vector_t<unsigned int> &instruction_ranges, unsigned int glyf_prime_size, char *glyf_prime_data /* OUT */, unsigned int loca_prime_size, char *loca_prime_data /* OUT */) { - hb_prealloced_array_t<hb_codepoint_t> &glyph_ids = plan->gids_to_retain_sorted; + hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs; char *glyf_prime_data_next = glyf_prime_data; bool success = true; @@ -171,11 +174,11 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan, if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset) && glyf.remove_padding(start_offset, &end_offset)))) end_offset = start_offset = 0; + unsigned int instruction_start = instruction_ranges[i * 2]; unsigned int instruction_end = instruction_ranges[i * 2 + 1]; int length = end_offset - start_offset - (instruction_end - instruction_start); - length += length % 2; if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size) { @@ -209,7 +212,8 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan, loca_prime_size); _update_components (plan, glyf_prime_data_next, length); - glyf_prime_data_next += length; + // TODO: don't align to two bytes if using long loca. + glyf_prime_data_next += length + (length % 2); // Align to 2 bytes for short loca. } success = success && _write_loca_entry (glyph_ids.len, @@ -229,11 +233,11 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, hb_blob_t **loca_prime /* OUT */) { // TODO(grieger): Sanity check allocation size for the new table. - hb_prealloced_array_t<hb_codepoint_t> &glyphs_to_retain = plan->gids_to_retain_sorted; + hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->glyphs; unsigned int glyf_prime_size; unsigned int loca_prime_size; - hb_prealloced_array_t<unsigned int> instruction_ranges; + hb_vector_t<unsigned int> instruction_ranges; instruction_ranges.init(); if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf, @@ -243,7 +247,7 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, &glyf_prime_size, &loca_prime_size, &instruction_ranges))) { - instruction_ranges.finish(); + instruction_ranges.fini(); return false; } @@ -256,10 +260,10 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, loca_prime_size, loca_prime_data))) { free (glyf_prime_data); free (loca_prime_data); - instruction_ranges.finish(); + instruction_ranges.fini(); return false; } - instruction_ranges.finish(); + instruction_ranges.fini(); *glyf_prime = hb_blob_create (glyf_prime_data, glyf_prime_size, diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc index c4003dd..39c5ac4 100644 --- a/src/hb-subset-input.cc +++ b/src/hb-subset-input.cc @@ -45,6 +45,7 @@ hb_subset_input_create_or_fail (void) input->unicodes = hb_set_create (); input->glyphs = hb_set_create (); + input->drop_ot_layout = true; return input; } @@ -117,3 +118,19 @@ hb_subset_input_drop_hints (hb_subset_input_t *subset_input) { return &subset_input->drop_hints; } + +/** + * hb_subset_input_drop_ot_layout: + * @subset_input: a subset_input. + * + * If enabled ot layout tables will be dropped as part of + * the subsetting operation. Currently this defaults to + * true. + * + * Since: REPLACEME + **/ +HB_EXTERN hb_bool_t * +hb_subset_input_drop_ot_layout (hb_subset_input_t *subset_input) +{ + return &subset_input->drop_ot_layout; +} diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index f8a09ef..55c4e3f 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -24,80 +24,14 @@ * Google Author(s): Garret Rieger, Roderick Sheeter */ +#include "hb-map-private.hh" #include "hb-subset-private.hh" +#include "hb-set-private.hh" #include "hb-subset-plan.hh" #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" -static int -_hb_codepoint_t_cmp (const void *pa, const void *pb) -{ - hb_codepoint_t a = * (hb_codepoint_t *) pa; - hb_codepoint_t b = * (hb_codepoint_t *) pb; - - return a < b ? -1 : a > b ? +1 : 0; -} - -hb_bool_t -hb_subset_plan_new_gid_for_codepoint (hb_subset_plan_t *plan, - hb_codepoint_t codepoint, - hb_codepoint_t *new_gid) -{ - // TODO actual map, delete this garbage. - for (unsigned int i = 0; i < plan->codepoints.len; i++) - { - if (plan->codepoints[i] != codepoint) continue; - if (!hb_subset_plan_new_gid_for_old_id(plan, plan->gids_to_retain[i], new_gid)) - { - return false; - } - return true; - } - return false; -} - -hb_bool_t -hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan, - hb_codepoint_t old_gid, - hb_codepoint_t *new_gid) -{ - // the index in old_gids is the new gid; only up to codepoints.len are valid - for (unsigned int i = 0; i < plan->gids_to_retain_sorted.len; i++) - { - if (plan->gids_to_retain_sorted[i] == old_gid) - { - *new_gid = i; - return true; - } - } - return false; -} - -hb_bool_t -hb_subset_plan_add_table (hb_subset_plan_t *plan, - hb_tag_t tag, - hb_blob_t *contents) -{ - hb_blob_t *source_blob = plan->source->reference_table (tag); - DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", HB_UNTAG(tag), hb_blob_get_length (contents), hb_blob_get_length (source_blob)); - hb_blob_destroy (source_blob); - return hb_subset_face_add_table(plan->dest, tag, contents); -} - -static void -_populate_codepoints (hb_set_t *input_codepoints, - hb_prealloced_array_t<hb_codepoint_t>& plan_codepoints) -{ - plan_codepoints.alloc (hb_set_get_population (input_codepoints)); - hb_codepoint_t cp = -1; - while (hb_set_next (input_codepoints, &cp)) { - hb_codepoint_t *wr = plan_codepoints.push(); - *wr = cp; - } - plan_codepoints.qsort (_hb_codepoint_t_cmp); -} - static void _add_gid_and_children (const OT::glyf::accelerator_t &glyf, hb_codepoint_t gid, @@ -120,59 +54,80 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf, } static void +_gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) +{ + // TODO(grieger): This uses all lookups, instead collect + // the set of lookups that are relevant. + // See fontTools implementation. + hb_ot_layout_lookups_substitute_closure (face, + nullptr, + gids_to_retain); +} + + +static void _populate_gids_to_retain (hb_face_t *face, - hb_prealloced_array_t<hb_codepoint_t>& codepoints, - hb_prealloced_array_t<hb_codepoint_t>& old_gids, - hb_prealloced_array_t<hb_codepoint_t>& old_gids_sorted) + const hb_set_t *unicodes, + bool close_over_gsub, + hb_set_t *unicodes_to_retain, + hb_map_t *codepoint_to_glyph, + hb_vector_t<hb_codepoint_t> *glyphs) { OT::cmap::accelerator_t cmap; OT::glyf::accelerator_t glyf; cmap.init (face); glyf.init (face); - hb_auto_array_t<unsigned int> bad_indices; + hb_set_t *initial_gids_to_retain = hb_set_create (); + initial_gids_to_retain->add (0); // Not-def - old_gids.alloc (codepoints.len); - for (unsigned int i = 0; i < codepoints.len; i++) + hb_codepoint_t cp = HB_SET_VALUE_INVALID; + while (unicodes->next (&cp)) { hb_codepoint_t gid; - if (!cmap.get_nominal_glyph (codepoints[i], &gid)) + if (!cmap.get_nominal_glyph (cp, &gid)) { - gid = -1; - *(bad_indices.push ()) = i; + DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); + continue; } - *(old_gids.push ()) = gid; + unicodes_to_retain->add (cp); + codepoint_to_glyph->set (cp, gid); + initial_gids_to_retain->add (gid); } - /* Generally there shouldn't be any */ - while (bad_indices.len > 0) - { - unsigned int i = bad_indices[bad_indices.len - 1]; - bad_indices.pop (); - DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", codepoints[i]); - codepoints.remove (i); - old_gids.remove (i); - } + if (close_over_gsub) + // Add all glyphs needed for GSUB substitutions. + _gsub_closure (face, initial_gids_to_retain); // Populate a full set of glyphs to retain by adding all referenced // composite glyphs. - // TODO expand with glyphs reached by G* - hb_set_t * all_gids_to_retain = hb_set_create (); - _add_gid_and_children (glyf, 0, all_gids_to_retain); - for (unsigned int i = 0; i < old_gids.len; i++) - _add_gid_and_children (glyf, old_gids[i], all_gids_to_retain); - - // Transfer to a sorted list. - old_gids_sorted.alloc (hb_set_get_population (all_gids_to_retain)); hb_codepoint_t gid = HB_SET_VALUE_INVALID; - while (hb_set_next (all_gids_to_retain, &gid)) - *(old_gids_sorted.push ()) = gid; + hb_set_t *all_gids_to_retain = hb_set_create (); + while (initial_gids_to_retain->next (&gid)) + { + _add_gid_and_children (glyf, gid, all_gids_to_retain); + } + hb_set_destroy (initial_gids_to_retain); + + glyphs->alloc (all_gids_to_retain->get_population ()); + gid = HB_SET_VALUE_INVALID; + while (all_gids_to_retain->next (&gid)) + glyphs->push (gid); hb_set_destroy (all_gids_to_retain); glyf.fini (); cmap.fini (); } +static void +_create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs, + hb_map_t *glyph_map) +{ + for (unsigned int i = 0; i < glyphs.len; i++) { + glyph_map->set (glyphs[i], i); + } +} + /** * hb_subset_plan_create: * Computes a plan for subsetting the supplied face according @@ -190,18 +145,23 @@ hb_subset_plan_create (hb_face_t *face, { hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> (); - plan->codepoints.init(); - plan->gids_to_retain.init(); - plan->gids_to_retain_sorted.init(); + plan->drop_hints = input->drop_hints; + plan->drop_ot_layout = input->drop_ot_layout; + plan->unicodes = hb_set_create(); + plan->glyphs.init(); plan->source = hb_face_reference (face); plan->dest = hb_subset_face_create (); - plan->drop_hints = input->drop_hints; + plan->codepoint_to_glyph = hb_map_create(); + plan->glyph_map = hb_map_create(); - _populate_codepoints (input->unicodes, plan->codepoints); _populate_gids_to_retain (face, - plan->codepoints, - plan->gids_to_retain, - plan->gids_to_retain_sorted); + input->unicodes, + !plan->drop_ot_layout, + plan->unicodes, + plan->codepoint_to_glyph, + &plan->glyphs); + _create_old_gid_to_new_gid_map (plan->glyphs, + plan->glyph_map); return plan; } @@ -216,12 +176,12 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) { if (!hb_object_destroy (plan)) return; - plan->codepoints.finish (); - plan->gids_to_retain.finish (); - plan->gids_to_retain_sorted.finish (); - + hb_set_destroy (plan->unicodes); + plan->glyphs.fini(); hb_face_destroy (plan->source); hb_face_destroy (plan->dest); + hb_map_destroy (plan->codepoint_to_glyph); + hb_map_destroy (plan->glyph_map); free (plan); } diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index d1b66b4..f4b261d 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -30,31 +30,68 @@ #include "hb-private.hh" #include "hb-subset.h" +#include "hb-subset-private.hh" #include "hb-object-private.hh" +#include "hb-map-private.hh" -struct hb_subset_plan_t { +struct hb_subset_plan_t +{ hb_object_header_t header; ASSERT_POD (); hb_bool_t drop_hints; + hb_bool_t drop_ot_layout; - // TODO(Q1) actual map, drop this crap - // Look at me ma, I'm a poor mans map codepoint : new gid - // codepoints is sorted and aligned with gids_to_retain. - - // These first two lists provide a mapping from cp -> gid - // As a result it does not list the full set of glyphs to retain. - hb_prealloced_array_t<hb_codepoint_t> codepoints; - hb_prealloced_array_t<hb_codepoint_t> gids_to_retain; + // For each cp that we'd like to retain maps to the corresponding gid. + hb_set_t *unicodes; // This list contains the complete set of glyphs to retain and may contain // more glyphs then the lists above. - hb_prealloced_array_t<hb_codepoint_t> gids_to_retain_sorted; + hb_vector_t<hb_codepoint_t> glyphs; + + hb_map_t *codepoint_to_glyph; + hb_map_t *glyph_map; // Plan is only good for a specific source/dest so keep them with it hb_face_t *source; hb_face_t *dest; + + inline hb_bool_t + new_gid_for_codepoint (hb_codepoint_t codepoint, + hb_codepoint_t *new_gid) const + { + hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint); + if (old_gid == HB_MAP_VALUE_INVALID) + return false; + + return new_gid_for_old_gid (old_gid, new_gid); + } + + inline hb_bool_t + new_gid_for_old_gid (hb_codepoint_t old_gid, + hb_codepoint_t *new_gid) const + { + hb_codepoint_t gid = glyph_map->get (old_gid); + if (gid == HB_MAP_VALUE_INVALID) + return false; + + *new_gid = gid; + return true; + } + + inline hb_bool_t + add_table (hb_tag_t tag, + hb_blob_t *contents) + { + hb_blob_t *source_blob = source->reference_table (tag); + DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", + HB_UNTAG(tag), + hb_blob_get_length (contents), + hb_blob_get_length (source_blob)); + hb_blob_destroy (source_blob); + return hb_subset_face_add_table(dest, tag, contents); + } }; typedef struct hb_subset_plan_t hb_subset_plan_t; @@ -64,21 +101,6 @@ hb_subset_plan_create (hb_face_t *face, hb_subset_profile_t *profile, hb_subset_input_t *input); -HB_INTERNAL hb_bool_t -hb_subset_plan_new_gid_for_old_id(hb_subset_plan_t *plan, - hb_codepoint_t old_gid, - hb_codepoint_t *new_gid /* OUT */); - -HB_INTERNAL hb_bool_t -hb_subset_plan_new_gid_for_codepoint(hb_subset_plan_t *plan, - hb_codepoint_t codepont, - hb_codepoint_t *new_gid /* OUT */); - -HB_INTERNAL hb_bool_t -hb_subset_plan_add_table(hb_subset_plan_t *plan, - hb_tag_t tag, - hb_blob_t *contents); - HB_INTERNAL void hb_subset_plan_destroy (hb_subset_plan_t *plan); diff --git a/src/hb-subset-private.hh b/src/hb-subset-private.hh index 5fa7252..6b2b207 100644 --- a/src/hb-subset-private.hh +++ b/src/hb-subset-private.hh @@ -44,6 +44,7 @@ struct hb_subset_input_t { hb_set_t *glyphs; hb_bool_t drop_hints; + hb_bool_t drop_ot_layout; /* TODO * * features diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 9ebe5d3..b97c763 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -41,11 +41,7 @@ #include "hb-ot-hmtx-table.hh" #include "hb-ot-maxp-table.hh" #include "hb-ot-os2-table.hh" - - -#ifndef HB_NO_VISIBILITY -const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; -#endif +#include "hb-ot-post-table.hh" struct hb_subset_profile_t { @@ -86,14 +82,18 @@ _subset (hb_subset_plan_t *plan) OT::Sanitizer<TableType> sanitizer; hb_blob_t *source_blob = sanitizer.sanitize (plan->source->reference_table (TableType::tableTag)); - const TableType *table = OT::Sanitizer<TableType>::lock_instance (source_blob); + const TableType *table = source_blob->as<TableType> (); + hb_tag_t tag = TableType::tableTag; hb_bool_t result = false; - if (table != &OT::Null(TableType)) + if (table != &Null(TableType)) + { result = table->subset(plan); + } else { + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag)); + } hb_blob_destroy (source_blob); - hb_tag_t tag = TableType::tableTag; DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); return result; } @@ -118,7 +118,7 @@ struct hb_subset_face_data_t hb_blob_t *blob; }; - hb_prealloced_array_t<table_entry_t, 32> tables; + hb_vector_t<table_entry_t, 32> tables; }; static hb_subset_face_data_t * @@ -128,6 +128,8 @@ _hb_subset_face_data_create (void) if (unlikely (!data)) return nullptr; + data->tables.init (); + return data; } @@ -139,7 +141,7 @@ _hb_subset_face_data_destroy (void *user_data) for (unsigned int i = 0; i < data->tables.len; i++) hb_blob_destroy (data->tables[i].blob); - data->tables.finish (); + data->tables.fini (); free (data); } @@ -152,7 +154,7 @@ _hb_subset_face_data_reference_blob (hb_subset_face_data_t *data) unsigned int face_length = table_count * 16 + 12; for (unsigned int i = 0; i < table_count; i++) - face_length += _hb_ceil_to_4 (hb_blob_get_length (data->tables.array[i].blob)); + face_length += _hb_ceil_to_4 (hb_blob_get_length (data->tables.arrayZ[i].blob)); char *buf = (char *) malloc (face_length); if (unlikely (!buf)) @@ -214,13 +216,11 @@ hb_subset_face_create (void) hb_bool_t hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) { - if (unlikely (face->destroy != _hb_subset_face_data_destroy)) + if (unlikely (face->destroy != (hb_destroy_func_t) _hb_subset_face_data_destroy)) return false; hb_subset_face_data_t *data = (hb_subset_face_data_t *) face->user_data; hb_subset_face_data_t::table_entry_t *entry = data->tables.push (); - if (unlikely (!entry)) - return false; entry->tag = tag; entry->blob = hb_blob_reference (blob); @@ -252,6 +252,12 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_hmtx: result = _subset<const OT::hmtx> (plan); break; + case HB_OT_TAG_vhea: + DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx"); + return true; + case HB_OT_TAG_vmtx: + result = _subset<const OT::vmtx> (plan); + break; case HB_OT_TAG_maxp: result = _subset<const OT::maxp> (plan); break; @@ -264,10 +270,13 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_os2: result = _subset<const OT::os2> (plan); break; + case HB_OT_TAG_post: + result = _subset<const OT::post> (plan); + break; default: hb_blob_t *source_table = hb_face_reference_table(plan->source, tag); if (likely (source_table)) - result = hb_subset_plan_add_table(plan, tag, source_table); + result = plan->add_table(tag, source_table); else result = false; hb_blob_destroy (source_table); @@ -280,21 +289,41 @@ _subset_table (hb_subset_plan_t *plan, static bool _should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag) { - switch (tag) { - case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */ - case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */ - case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */ - case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */ - case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */ - case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */ - return plan->drop_hints; - case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */ - case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */ - case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */ - case HB_TAG ('D', 'S', 'I', 'G'): - return true; - default: - return false; + switch (tag) { + case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */ + case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */ + case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */ + case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */ + case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */ + case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */ + return plan->drop_hints; + // Drop Layout Tables if requested. + case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */ + case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */ + case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */ + return plan->drop_ot_layout; + // Drop these tables below by default, list pulled + // from fontTools: + case HB_TAG ('B', 'A', 'S', 'E'): + case HB_TAG ('J', 'S', 'T', 'F'): + case HB_TAG ('D', 'S', 'I', 'G'): + case HB_TAG ('E', 'B', 'D', 'T'): + case HB_TAG ('E', 'B', 'L', 'C'): + case HB_TAG ('E', 'B', 'S', 'C'): + case HB_TAG ('S', 'V', 'G', ' '): + case HB_TAG ('P', 'C', 'L', 'T'): + case HB_TAG ('L', 'T', 'S', 'H'): + // Graphite tables: + case HB_TAG ('F', 'e', 'a', 't'): + case HB_TAG ('G', 'l', 'a', 't'): + case HB_TAG ('G', 'l', 'o', 'c'): + case HB_TAG ('S', 'i', 'l', 'f'): + case HB_TAG ('S', 'i', 'l', 'l'): + // Colour + case HB_TAG ('s', 'b', 'i', 'x'): + return true; + default: + return false; } } @@ -331,9 +360,24 @@ hb_subset (hb_face_t *source, } success = success && _subset_table (plan, tag); } + offset += count; } while (count == ARRAY_LENGTH (table_tags)); hb_face_t *result = success ? hb_face_reference(plan->dest) : hb_face_get_empty(); hb_subset_plan_destroy (plan); return result; } + +/** + * hb_subset_get_all_codepoints: + * @source: font face data to load. + * @out: set to add the all codepoints covered by font face, source. + */ +void +hb_subset_get_all_codepoints (hb_face_t *source, hb_set_t *out) +{ + OT::cmap::accelerator_t cmap; + cmap.init (source); + cmap.get_all_codepoints (out); + cmap.fini(); +} diff --git a/src/hb-subset.h b/src/hb-subset.h index 55ce25b..f6d2ae0 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -71,13 +71,19 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input); HB_EXTERN hb_bool_t * hb_subset_input_drop_hints (hb_subset_input_t *subset_input); -/* hb_subset() */ +HB_EXTERN hb_bool_t * +hb_subset_input_drop_ot_layout (hb_subset_input_t *subset_input); +/* hb_subset() */ HB_EXTERN hb_face_t * hb_subset (hb_face_t *source, hb_subset_profile_t *profile, hb_subset_input_t *input); +/* hb_subset_get_all_codepoints */ +HB_EXTERN void +hb_subset_get_all_codepoints (hb_face_t *source, hb_set_t *out); + HB_END_DECLS #endif /* HB_SUBSET_H */ diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index 9515bda..2c08718 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -164,6 +164,13 @@ static const hb_script_t ucdn_script_translate[] = HB_SCRIPT_NUSHU, HB_SCRIPT_SOYOMBO, HB_SCRIPT_ZANABAZAR_SQUARE, + HB_SCRIPT_DOGRA, + HB_SCRIPT_GUNJALA_GONDI, + HB_SCRIPT_HANIFI_ROHINGYA, + HB_SCRIPT_MAKASAR, + HB_SCRIPT_MEDEFAIDRIN, + HB_SCRIPT_OLD_SOGDIAN, + HB_SCRIPT_SOGDIAN, }; static hb_unicode_combining_class_t @@ -237,7 +244,12 @@ static hb_unicode_funcs_t *static_ucdn_funcs = nullptr; static void free_static_ucdn_funcs (void) { - hb_unicode_funcs_destroy (static_ucdn_funcs); +retry: + hb_unicode_funcs_t *ucdn_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_ucdn_funcs); + if (!hb_atomic_ptr_cmpexch (&static_ucdn_funcs, ucdn_funcs, nullptr)) + goto retry; + + hb_unicode_funcs_destroy (ucdn_funcs); } #endif diff --git a/src/hb-ucdn/Makefile.in b/src/hb-ucdn/Makefile.in index 22d7d14..59bbf55 100644 --- a/src/hb-ucdn/Makefile.in +++ b/src/hb-ucdn/Makefile.in @@ -90,7 +90,8 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/hb-ucdn ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(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 \ diff --git a/src/hb-ucdn/ucdn.h b/src/hb-ucdn/ucdn.h index 2d5fc35..9b0f9d4 100644 --- a/src/hb-ucdn/ucdn.h +++ b/src/hb-ucdn/ucdn.h @@ -42,6 +42,16 @@ HB_BEGIN_HEADER # include <inttypes.h> #elif defined (_AIX) # include <sys/inttypes.h> +#elif defined (_MSC_VER) && _MSC_VER < 1600 +/* VS 2010 (_MSC_VER 1600) has stdint.h */ +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 diff --git a/src/hb-ucdn/ucdn_db.h b/src/hb-ucdn/ucdn_db.h index 8d2d8de..87872b7 100644 --- a/src/hb-ucdn/ucdn_db.h +++ b/src/hb-ucdn/ucdn_db.h @@ -1,6 +1,6 @@ /* this file was generated by makeunicodedata.py 3.2 */ -#define UNIDATA_VERSION "10.0.0" +#define UNIDATA_VERSION "11.0.0" /* a list of unique database records */ static const UCDRecord ucd_records[] = { {2, 0, 18, 5, 102, 39}, @@ -185,6 +185,7 @@ static const UCDRecord ucd_records[] = { {21, 0, 18, 5, 65, 12}, {21, 0, 18, 5, 65, 8}, {21, 0, 18, 5, 65, 6}, + {23, 0, 3, 5, 65, 9}, {7, 0, 3, 5, 81, 12}, {12, 230, 13, 5, 81, 21}, {6, 0, 3, 5, 81, 12}, @@ -217,12 +218,14 @@ static const UCDRecord ucd_records[] = { {26, 0, 0, 5, 10, 12}, {23, 0, 10, 5, 10, 9}, {21, 0, 0, 5, 10, 12}, + {12, 230, 13, 5, 10, 21}, {12, 0, 13, 5, 11, 21}, {10, 0, 0, 5, 11, 21}, {7, 0, 0, 5, 11, 12}, {12, 7, 13, 5, 11, 21}, {12, 9, 13, 5, 11, 21}, {13, 0, 0, 5, 11, 11}, + {21, 0, 0, 5, 11, 12}, {12, 0, 13, 5, 12, 21}, {10, 0, 0, 5, 12, 21}, {7, 0, 0, 5, 12, 12}, @@ -259,6 +262,7 @@ static const UCDRecord ucd_records[] = { {7, 0, 0, 5, 16, 12}, {12, 0, 13, 5, 16, 21}, {10, 0, 0, 5, 16, 21}, + {21, 0, 0, 5, 16, 18}, {12, 7, 13, 5, 16, 21}, {12, 0, 0, 5, 16, 21}, {12, 9, 13, 5, 16, 21}, @@ -328,7 +332,7 @@ static const UCDRecord ucd_records[] = { {12, 220, 13, 5, 22, 36}, {26, 0, 0, 5, 22, 36}, {9, 0, 0, 5, 23, 12}, - {7, 0, 0, 5, 23, 12}, + {5, 0, 0, 5, 23, 12}, {21, 0, 0, 5, 0, 12}, {6, 0, 0, 5, 23, 12}, {7, 0, 0, 2, 24, 25}, @@ -547,7 +551,6 @@ static const UCDRecord ucd_records[] = { {21, 0, 18, 5, 54, 6}, {21, 0, 18, 5, 54, 17}, {15, 0, 18, 5, 54, 12}, - {5, 0, 0, 5, 23, 12}, {7, 0, 0, 5, 57, 12}, {6, 0, 0, 5, 57, 12}, {21, 0, 0, 5, 57, 17}, @@ -803,7 +806,17 @@ static const UCDRecord ucd_records[] = { {9, 0, 3, 5, 130, 12}, {5, 0, 3, 5, 130, 12}, {15, 0, 3, 5, 130, 12}, + {7, 0, 4, 5, 144, 12}, + {12, 230, 13, 5, 144, 21}, + {13, 0, 11, 5, 144, 11}, {15, 0, 11, 5, 6, 12}, + {7, 0, 3, 5, 147, 12}, + {15, 0, 3, 5, 147, 12}, + {7, 0, 4, 5, 148, 12}, + {12, 220, 13, 5, 148, 21}, + {12, 230, 13, 5, 148, 21}, + {15, 0, 4, 5, 148, 12}, + {21, 0, 4, 5, 148, 12}, {10, 0, 0, 5, 93, 21}, {12, 0, 13, 5, 93, 21}, {7, 0, 0, 5, 93, 12}, @@ -861,6 +874,7 @@ static const UCDRecord ucd_records[] = { {12, 0, 13, 5, 107, 21}, {10, 0, 0, 5, 107, 21}, {7, 0, 0, 5, 107, 12}, + {12, 7, 13, 5, 40, 21}, {12, 7, 13, 5, 107, 21}, {10, 9, 0, 5, 107, 21}, {12, 230, 13, 5, 107, 21}, @@ -872,6 +886,7 @@ static const UCDRecord ucd_records[] = { {21, 0, 0, 5, 135, 17}, {21, 0, 0, 5, 135, 12}, {13, 0, 0, 5, 135, 11}, + {12, 230, 13, 5, 135, 21}, {7, 0, 0, 5, 124, 12}, {10, 0, 0, 5, 124, 21}, {12, 0, 13, 5, 124, 21}, @@ -910,6 +925,12 @@ static const UCDRecord ucd_records[] = { {15, 0, 0, 5, 126, 36}, {21, 0, 0, 5, 126, 17}, {26, 0, 0, 5, 126, 36}, + {7, 0, 0, 5, 142, 12}, + {10, 0, 0, 5, 142, 21}, + {12, 0, 13, 5, 142, 21}, + {12, 9, 13, 5, 142, 21}, + {12, 7, 13, 5, 142, 21}, + {21, 0, 0, 5, 142, 12}, {9, 0, 0, 5, 125, 12}, {5, 0, 0, 5, 125, 12}, {13, 0, 0, 5, 125, 11}, @@ -917,8 +938,9 @@ static const UCDRecord ucd_records[] = { {7, 0, 0, 5, 125, 12}, {7, 0, 0, 5, 141, 12}, {12, 0, 13, 5, 141, 21}, - {10, 0, 0, 5, 141, 21}, + {12, 0, 0, 5, 141, 21}, {12, 9, 13, 5, 141, 21}, + {10, 0, 0, 5, 141, 21}, {21, 0, 0, 5, 141, 18}, {21, 0, 0, 5, 141, 12}, {21, 0, 0, 5, 141, 17}, @@ -946,6 +968,15 @@ static const UCDRecord ucd_records[] = { {12, 7, 13, 5, 138, 21}, {12, 9, 13, 5, 138, 21}, {13, 0, 0, 5, 138, 11}, + {7, 0, 0, 5, 143, 12}, + {10, 0, 0, 5, 143, 21}, + {12, 0, 13, 5, 143, 21}, + {12, 9, 13, 5, 143, 21}, + {13, 0, 0, 5, 143, 11}, + {7, 0, 0, 5, 145, 12}, + {12, 0, 13, 5, 145, 21}, + {10, 0, 0, 5, 145, 21}, + {21, 0, 0, 5, 145, 12}, {7, 0, 0, 5, 62, 12}, {14, 0, 0, 5, 62, 12}, {21, 0, 0, 5, 62, 17}, @@ -969,6 +1000,11 @@ static const UCDRecord ucd_records[] = { {6, 0, 0, 5, 119, 12}, {13, 0, 0, 5, 119, 11}, {15, 0, 0, 5, 119, 12}, + {9, 0, 0, 5, 146, 12}, + {5, 0, 0, 5, 146, 12}, + {15, 0, 0, 5, 146, 12}, + {21, 0, 0, 5, 146, 17}, + {21, 0, 0, 5, 146, 12}, {7, 0, 0, 5, 98, 12}, {10, 0, 0, 5, 98, 21}, {12, 0, 13, 5, 98, 21}, @@ -1001,6 +1037,9 @@ static const UCDRecord ucd_records[] = { {12, 7, 13, 5, 132, 21}, {13, 0, 3, 5, 132, 11}, {21, 0, 3, 5, 132, 0}, + {15, 0, 4, 5, 0, 12}, + {26, 0, 4, 5, 0, 10}, + {23, 0, 4, 5, 0, 10}, {2, 0, 18, 5, 102, 14}, {26, 0, 0, 2, 0, 29}, {26, 0, 0, 5, 0, 28}, @@ -1009,7 +1048,7 @@ static const UCDRecord ucd_records[] = { {26, 0, 18, 5, 0, 5}, }; -#define BIDI_MIRROR_LEN 364 +#define BIDI_MIRROR_LEN 420 static const MirrorPair mirror_pairs[] = { {40, 41}, {41, 40}, @@ -1042,9 +1081,16 @@ static const MirrorPair mirror_pairs[] = { {8716, 8713}, {8717, 8714}, {8725, 10741}, + {8735, 11262}, + {8736, 10659}, + {8737, 10651}, + {8738, 10656}, + {8740, 10990}, {8764, 8765}, {8765, 8764}, {8771, 8909}, + {8773, 8780}, + {8780, 8773}, {8786, 8787}, {8787, 8786}, {8788, 8789}, @@ -1106,6 +1152,7 @@ static const MirrorPair mirror_pairs[] = { {8885, 8884}, {8886, 8887}, {8887, 8886}, + {8888, 10204}, {8905, 8906}, {8906, 8905}, {8907, 8908}, @@ -1179,6 +1226,7 @@ static const MirrorPair mirror_pairs[] = { {10189, 10187}, {10197, 10198}, {10198, 10197}, + {10204, 8888}, {10205, 10206}, {10206, 10205}, {10210, 10211}, @@ -1217,6 +1265,19 @@ static const MirrorPair mirror_pairs[] = { {10646, 10645}, {10647, 10648}, {10648, 10647}, + {10651, 8737}, + {10656, 8738}, + {10659, 8736}, + {10660, 10661}, + {10661, 10660}, + {10664, 10665}, + {10665, 10664}, + {10666, 10667}, + {10667, 10666}, + {10668, 10669}, + {10669, 10668}, + {10670, 10671}, + {10671, 10670}, {10680, 8856}, {10688, 10689}, {10689, 10688}, @@ -1232,6 +1293,8 @@ static const MirrorPair mirror_pairs[] = { {10713, 10712}, {10714, 10715}, {10715, 10714}, + {10728, 10729}, + {10729, 10728}, {10741, 8725}, {10744, 10745}, {10745, 10744}, @@ -1249,6 +1312,8 @@ static const MirrorPair mirror_pairs[] = { {10853, 10852}, {10873, 10874}, {10874, 10873}, + {10875, 10876}, + {10876, 10875}, {10877, 10878}, {10878, 10877}, {10879, 10880}, @@ -1257,8 +1322,18 @@ static const MirrorPair mirror_pairs[] = { {10882, 10881}, {10883, 10884}, {10884, 10883}, + {10885, 10886}, + {10886, 10885}, + {10887, 10888}, + {10888, 10887}, + {10889, 10890}, + {10890, 10889}, {10891, 10892}, {10892, 10891}, + {10893, 10894}, + {10894, 10893}, + {10895, 10896}, + {10896, 10895}, {10897, 10898}, {10898, 10897}, {10899, 10900}, @@ -1271,6 +1346,10 @@ static const MirrorPair mirror_pairs[] = { {10906, 10905}, {10907, 10908}, {10908, 10907}, + {10909, 10910}, + {10910, 10909}, + {10911, 10912}, + {10912, 10911}, {10913, 10914}, {10914, 10913}, {10918, 10919}, @@ -1283,8 +1362,16 @@ static const MirrorPair mirror_pairs[] = { {10925, 10924}, {10927, 10928}, {10928, 10927}, + {10929, 10930}, + {10930, 10929}, {10931, 10932}, {10932, 10931}, + {10933, 10934}, + {10934, 10933}, + {10935, 10936}, + {10936, 10935}, + {10937, 10938}, + {10938, 10937}, {10939, 10940}, {10940, 10939}, {10941, 10942}, @@ -1297,6 +1384,12 @@ static const MirrorPair mirror_pairs[] = { {10948, 10947}, {10949, 10950}, {10950, 10949}, + {10951, 10952}, + {10952, 10951}, + {10953, 10954}, + {10954, 10953}, + {10955, 10956}, + {10956, 10955}, {10957, 10958}, {10958, 10957}, {10959, 10960}, @@ -1313,10 +1406,12 @@ static const MirrorPair mirror_pairs[] = { {10981, 8875}, {10988, 10989}, {10989, 10988}, + {10990, 8740}, {10999, 11000}, {11000, 10999}, {11001, 11002}, {11002, 11001}, + {11262, 8735}, {11778, 11779}, {11779, 11778}, {11780, 11781}, @@ -1910,6 +2005,13 @@ static const Reindex nfc_last[] = { #define UCDN_SCRIPT_NUSHU 139 #define UCDN_SCRIPT_SOYOMBO 140 #define UCDN_SCRIPT_ZANABAZAR_SQUARE 141 +#define UCDN_SCRIPT_DOGRA 142 +#define UCDN_SCRIPT_GUNJALA_GONDI 143 +#define UCDN_SCRIPT_HANIFI_ROHINGYA 144 +#define UCDN_SCRIPT_MAKASAR 145 +#define UCDN_SCRIPT_MEDEFAIDRIN 146 +#define UCDN_SCRIPT_OLD_SOGDIAN 147 +#define UCDN_SCRIPT_SOGDIAN 148 #define UCDN_GENERAL_CATEGORY_CC 0 #define UCDN_GENERAL_CATEGORY_CF 1 @@ -1984,22 +2086,24 @@ static const unsigned char index0[] = { 66, 67, 68, 69, 70, 71, 65, 66, 67, 68, 69, 70, 71, 65, 72, 73, 73, 73, 73, 73, 73, 73, 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, 52, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 94, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 94, 105, 94, 106, 107, 94, 94, 108, - 108, 108, 109, 110, 111, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 112, - 112, 113, 114, 115, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 116, 117, 118, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 119, 119, 120, 121, 94, 94, 94, 122, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 124, 123, 123, 125, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 126, 127, 128, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 129, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 138, 139, 94, 94, 94, 94, 94, 140, 94, 94, 94, 94, 94, 94, 94, 141, - 142, 94, 94, 94, 94, 143, 94, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 154, 154, 154, 154, 155, 52, 52, 52, 52, 52, 52, 52, 52, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 106, 108, 109, 110, 106, + 111, 111, 111, 112, 113, 114, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 115, 115, 116, 117, 118, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 119, 120, 121, 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, 122, 122, 123, 124, 106, 106, 125, 126, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 128, 127, 127, 129, 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, 130, 131, 132, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 133, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 142, 143, 106, 106, 106, 106, 106, 144, 106, 106, 106, + 106, 106, 106, 106, 145, 146, 106, 106, 147, 106, 148, 106, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 160, 160, 160, 161, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, @@ -2008,187 +2112,232 @@ static const unsigned char index0[] = { 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 156, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 157, 158, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 159, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 160, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 52, 52, 162, 161, 161, 161, 161, 163, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 163, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 164, 165, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 74, 74, 74, 74, 74, + 52, 52, 52, 162, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 163, 164, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 165, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 166, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 52, 52, + 168, 167, 167, 167, 167, 169, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 169, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, + 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, 170, 171, 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, 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, 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, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, @@ -2202,8 +2351,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, 166, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 172, 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, @@ -2217,7 +2366,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, 166, + 74, 74, 74, 74, 172, }; static const unsigned short index1[] = { @@ -2230,391 +2379,405 @@ 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, 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, 120, 154, 155, 156, 156, 156, 157, 158, 159, 160, 160, - 161, 162, 163, 164, 165, 166, 167, 167, 167, 168, 145, 169, 120, 120, - 120, 120, 120, 120, 128, 128, 170, 171, 120, 120, 172, 126, 173, 174, - 175, 176, 177, 178, 178, 178, 178, 178, 178, 179, 180, 181, 182, 178, - 183, 184, 185, 178, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 120, 215, 216, 217, 218, 218, 219, - 220, 221, 222, 223, 224, 120, 225, 226, 227, 228, 229, 230, 231, 232, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 120, 243, 244, - 245, 246, 247, 244, 248, 249, 250, 251, 252, 120, 253, 254, 255, 256, - 257, 258, 259, 260, 260, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 120, 268, 269, 270, 271, 272, 272, 271, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 120, 282, 283, 284, 285, 285, 285, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 296, 296, 299, 300, - 297, 301, 302, 303, 304, 305, 306, 120, 307, 308, 308, 308, 308, 308, - 309, 310, 311, 312, 313, 314, 120, 120, 120, 120, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 120, 120, 120, 120, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 336, 335, 335, 335, 337, 338, 339, - 340, 341, 342, 343, 342, 342, 342, 344, 345, 346, 347, 348, 120, 120, - 120, 120, 349, 349, 349, 349, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 349, 360, 361, 353, 362, 363, 363, 363, 363, 364, 365, - 366, 366, 366, 366, 366, 367, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 371, 371, 371, 371, - 371, 371, 371, 371, 371, 372, 373, 372, 371, 371, 371, 371, 371, 372, - 371, 371, 371, 371, 372, 373, 372, 371, 373, 371, 371, 371, 371, 371, - 371, 371, 372, 371, 371, 371, 371, 371, 371, 371, 371, 374, 375, 376, - 377, 378, 371, 371, 379, 380, 381, 381, 381, 381, 381, 381, 381, 381, - 381, 381, 382, 383, 384, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 385, - 387, 388, 388, 389, 390, 390, 390, 390, 390, 390, 390, 390, 390, 391, - 392, 393, 394, 395, 396, 120, 397, 397, 398, 120, 399, 399, 400, 120, - 401, 402, 403, 120, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 419, 419, 419, - 420, 419, 419, 419, 419, 419, 419, 120, 421, 419, 419, 419, 419, 422, - 385, 385, 385, 385, 385, 385, 385, 385, 423, 120, 424, 424, 424, 425, - 426, 427, 428, 429, 430, 431, 432, 432, 432, 433, 434, 120, 435, 435, + 101, 101, 101, 101, 101, 101, 106, 107, 107, 107, 108, 109, 110, 110, + 110, 110, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 120, + 120, 121, 122, 119, 123, 124, 125, 126, 127, 127, 127, 127, 128, 129, + 130, 131, 132, 133, 134, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 144, + 145, 146, 147, 148, 127, 127, 127, 127, 127, 127, 149, 149, 149, 149, + 150, 151, 152, 119, 153, 154, 155, 155, 155, 156, 157, 158, 159, 159, + 160, 161, 162, 163, 164, 165, 166, 166, 166, 167, 144, 168, 119, 119, + 119, 119, 119, 119, 127, 127, 169, 170, 119, 119, 171, 125, 172, 173, + 174, 175, 176, 177, 177, 177, 177, 177, 177, 178, 179, 180, 181, 177, + 182, 183, 184, 177, 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, 119, 214, 215, 216, 217, 217, 218, + 219, 220, 221, 222, 223, 119, 224, 225, 226, 227, 228, 229, 230, 231, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 119, 242, 243, + 244, 245, 246, 243, 247, 248, 249, 250, 251, 119, 252, 253, 254, 255, + 256, 257, 258, 259, 259, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 119, 267, 268, 269, 270, 271, 271, 270, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 119, 281, 282, 283, 284, 284, 284, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 295, 295, 298, 299, + 296, 300, 301, 302, 303, 304, 305, 119, 306, 307, 307, 307, 307, 307, + 308, 309, 310, 311, 312, 313, 119, 119, 119, 119, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 119, 119, 119, 119, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 334, 334, 334, 336, 337, 338, + 339, 340, 341, 342, 341, 341, 341, 343, 344, 345, 346, 347, 119, 119, + 119, 119, 348, 348, 348, 348, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 348, 359, 360, 352, 361, 362, 362, 362, 362, 363, 364, + 365, 365, 365, 365, 365, 366, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 368, 368, 368, 368, 368, 368, 368, 368, 368, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 371, 372, 371, 370, 370, 370, 370, 370, 371, + 370, 370, 370, 370, 371, 372, 371, 370, 372, 370, 370, 370, 370, 370, + 370, 370, 371, 370, 370, 370, 370, 370, 370, 370, 370, 373, 374, 375, + 376, 377, 370, 370, 378, 379, 380, 380, 380, 380, 380, 380, 380, 380, + 380, 380, 381, 382, 383, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 384, 384, + 386, 387, 387, 388, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, + 391, 392, 393, 394, 395, 119, 396, 396, 397, 119, 398, 398, 399, 119, + 400, 401, 402, 119, 403, 403, 403, 403, 403, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 418, 418, 418, + 419, 418, 418, 418, 418, 418, 418, 420, 421, 418, 418, 418, 418, 422, + 384, 384, 384, 384, 384, 384, 384, 384, 423, 119, 424, 424, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 432, 432, 433, 434, 119, 435, 435, 435, 435, 435, 436, 435, 435, 435, 437, 438, 439, 440, 440, 440, 440, 441, 441, 442, 443, 444, 444, 444, 444, 444, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 451, 452, 453, 454, 455, 456, 120, 120, 120, 120, - 120, 120, 120, 120, 457, 458, 458, 458, 458, 458, 459, 460, 461, 462, + 449, 450, 451, 452, 451, 452, 453, 454, 455, 456, 119, 119, 119, 119, + 119, 119, 119, 119, 457, 458, 458, 458, 458, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 470, 470, 471, 472, 473, 474, 475, 475, 475, 475, 476, 477, 478, 479, 480, 480, 480, 480, 481, 482, - 483, 484, 485, 486, 487, 488, 489, 489, 489, 490, 100, 491, 120, 120, - 120, 120, 120, 120, 492, 120, 493, 494, 495, 496, 497, 498, 54, 54, 54, - 54, 499, 500, 56, 56, 56, 56, 56, 501, 502, 503, 54, 504, 54, 54, 54, - 505, 56, 56, 56, 506, 507, 508, 509, 510, 510, 510, 511, 512, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 513, 514, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 515, 516, 517, 518, 515, 516, - 515, 516, 517, 518, 515, 519, 515, 516, 515, 517, 515, 520, 515, 520, - 515, 520, 521, 522, 523, 524, 525, 526, 515, 527, 528, 529, 530, 531, - 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, - 546, 547, 56, 548, 549, 550, 551, 552, 553, 553, 554, 555, 556, 557, 558, - 120, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, - 572, 571, 573, 574, 575, 576, 577, 578, 579, 580, 581, 580, 582, 583, - 580, 584, 580, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 586, - 595, 596, 586, 597, 598, 586, 586, 598, 586, 599, 600, 599, 586, 586, - 601, 586, 586, 586, 586, 586, 602, 586, 586, 580, 603, 604, 605, 606, - 607, 608, 609, 609, 609, 609, 609, 609, 609, 609, 610, 580, 580, 611, - 612, 586, 586, 613, 580, 580, 580, 580, 585, 606, 614, 615, 580, 580, - 580, 580, 580, 616, 120, 120, 120, 580, 617, 120, 120, 618, 618, 618, - 618, 618, 619, 619, 620, 621, 621, 621, 621, 621, 621, 621, 621, 621, - 622, 618, 623, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625, 624, - 624, 624, 624, 626, 580, 624, 624, 627, 580, 628, 629, 630, 631, 632, - 633, 629, 580, 627, 634, 580, 635, 636, 637, 638, 639, 580, 580, 580, - 640, 641, 642, 643, 580, 644, 645, 580, 646, 580, 580, 647, 648, 649, - 650, 580, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 580, - 580, 580, 662, 580, 663, 580, 664, 665, 666, 667, 668, 669, 618, 670, - 670, 671, 580, 580, 580, 662, 672, 673, 586, 586, 586, 674, 675, 586, - 586, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, - 676, 676, 676, 676, 676, 586, 586, 586, 586, 586, 586, 586, 586, 586, - 586, 586, 586, 586, 586, 586, 586, 677, 678, 678, 679, 586, 586, 586, - 586, 586, 586, 586, 680, 586, 586, 586, 681, 586, 586, 586, 586, 586, - 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, - 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 580, - 580, 580, 682, 580, 580, 586, 586, 683, 684, 685, 629, 580, 580, 686, - 580, 580, 580, 687, 580, 580, 580, 580, 688, 580, 689, 617, 120, 120, - 690, 120, 120, 691, 691, 691, 691, 691, 692, 693, 693, 693, 693, 693, - 694, 695, 696, 697, 698, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 699, 700, 701, 702, 703, 703, 703, 703, 704, 705, 706, 706, 706, 706, - 706, 706, 706, 707, 708, 709, 371, 371, 373, 120, 373, 373, 373, 373, - 373, 373, 373, 373, 710, 710, 710, 710, 711, 712, 713, 714, 715, 716, - 717, 718, 719, 720, 120, 120, 120, 120, 120, 120, 721, 721, 721, 722, - 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 723, 120, 721, 721, - 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, - 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 724, 120, 120, 120, - 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 737, - 738, 737, 737, 737, 739, 740, 741, 742, 743, 744, 745, 745, 746, 745, - 745, 745, 747, 748, 749, 750, 751, 752, 752, 752, 752, 753, 754, 755, - 755, 755, 755, 755, 755, 755, 755, 755, 755, 756, 757, 758, 752, 752, - 752, 759, 725, 725, 725, 725, 726, 120, 760, 760, 761, 761, 761, 762, - 763, 764, 758, 758, 758, 765, 766, 767, 761, 761, 761, 768, 763, 764, - 758, 758, 758, 758, 769, 767, 758, 770, 771, 771, 771, 771, 771, 772, - 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 758, 758, 758, - 773, 774, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 775, - 758, 758, 758, 773, 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, + 483, 484, 485, 486, 487, 488, 489, 489, 489, 490, 100, 491, 362, 362, + 362, 362, 362, 492, 493, 119, 494, 495, 496, 497, 498, 499, 54, 54, 54, + 54, 500, 501, 56, 56, 56, 56, 56, 502, 503, 504, 54, 505, 54, 54, 54, + 506, 56, 56, 56, 507, 508, 509, 510, 511, 511, 511, 512, 513, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 514, 515, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 516, 517, 518, 519, 516, 517, + 516, 517, 518, 519, 516, 520, 516, 517, 516, 518, 516, 521, 516, 521, + 516, 521, 522, 523, 524, 525, 526, 527, 516, 528, 529, 530, 531, 532, + 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, + 547, 548, 56, 549, 550, 551, 552, 553, 554, 554, 555, 556, 557, 558, 559, + 119, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, + 573, 572, 574, 575, 576, 577, 578, 579, 580, 581, 582, 581, 583, 584, + 581, 585, 581, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 587, + 596, 597, 587, 598, 599, 587, 587, 599, 587, 600, 601, 600, 587, 587, + 602, 587, 587, 587, 587, 587, 603, 587, 587, 581, 604, 605, 606, 607, + 608, 609, 610, 610, 610, 610, 610, 610, 610, 610, 611, 581, 581, 612, + 613, 587, 587, 614, 581, 581, 581, 581, 586, 607, 615, 616, 581, 581, + 581, 581, 581, 617, 119, 119, 119, 581, 618, 119, 119, 619, 619, 619, + 619, 619, 620, 620, 621, 622, 622, 622, 622, 622, 622, 622, 622, 622, + 623, 619, 624, 625, 625, 625, 625, 625, 625, 625, 625, 625, 626, 625, + 625, 625, 625, 627, 581, 625, 625, 628, 581, 629, 630, 631, 632, 633, + 634, 630, 581, 628, 635, 581, 636, 637, 638, 639, 640, 581, 581, 581, + 641, 642, 643, 644, 581, 645, 646, 581, 647, 581, 581, 648, 649, 650, + 651, 581, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 581, + 581, 581, 663, 581, 664, 581, 665, 666, 667, 668, 669, 670, 619, 671, + 671, 672, 581, 581, 581, 663, 673, 674, 587, 587, 587, 675, 676, 587, + 587, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 677, 677, 587, 587, 587, 587, 587, 587, 587, 587, 587, + 587, 587, 587, 587, 587, 587, 587, 678, 679, 679, 680, 587, 587, 587, + 587, 587, 587, 587, 681, 587, 587, 587, 682, 587, 587, 587, 587, 587, + 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, + 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 581, + 581, 581, 683, 581, 581, 587, 587, 684, 685, 686, 630, 581, 581, 687, + 581, 581, 581, 688, 581, 581, 581, 581, 581, 581, 689, 581, 581, 581, + 581, 581, 617, 690, 690, 690, 690, 690, 691, 692, 692, 692, 692, 692, + 693, 694, 695, 696, 697, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 698, 699, 700, 701, 365, 365, 365, 365, 702, 703, 704, 704, 704, 704, + 704, 704, 704, 705, 706, 707, 370, 370, 372, 119, 372, 372, 372, 372, + 372, 372, 372, 372, 708, 708, 708, 708, 709, 710, 711, 712, 713, 714, + 715, 716, 717, 718, 119, 119, 119, 119, 119, 119, 719, 719, 719, 720, + 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 721, 119, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 722, 119, 119, 119, + 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 735, + 736, 735, 735, 735, 737, 738, 739, 740, 741, 742, 743, 743, 744, 743, + 743, 743, 745, 746, 747, 748, 749, 750, 750, 750, 750, 750, 751, 752, + 752, 752, 752, 752, 752, 752, 752, 752, 752, 753, 754, 755, 750, 750, + 750, 756, 723, 723, 723, 723, 724, 119, 757, 757, 758, 758, 758, 759, + 760, 761, 755, 755, 755, 762, 763, 764, 758, 758, 758, 765, 760, 761, + 755, 755, 755, 755, 766, 764, 755, 767, 768, 768, 768, 768, 768, 769, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 755, 755, 755, + 770, 771, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 772, + 755, 755, 755, 770, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 774, 775, 581, 581, 581, 581, 581, 581, 581, 581, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 775, 775, 776, 776, 777, 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, 777, 778, 580, 580, 580, 580, 580, 580, 580, 580, 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, 779, - 778, 778, 780, 780, 781, 780, 780, 780, 780, 780, 780, 780, 780, 780, - 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, - 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, - 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, - 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, - 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 782, - 783, 783, 783, 783, 783, 783, 784, 120, 785, 785, 785, 785, 785, 786, - 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 788, 787, 787, 789, 790, 120, 120, 101, 101, - 101, 101, 101, 791, 792, 793, 101, 101, 101, 794, 795, 795, 795, 795, - 795, 795, 795, 795, 796, 797, 798, 120, 64, 64, 799, 800, 801, 27, 802, - 27, 27, 27, 27, 27, 27, 27, 803, 804, 27, 805, 806, 27, 27, 807, 808, - 120, 120, 120, 120, 120, 120, 120, 809, 810, 811, 812, 813, 813, 814, - 815, 816, 817, 818, 818, 818, 818, 818, 818, 819, 120, 820, 821, 821, - 821, 821, 821, 822, 823, 824, 825, 826, 827, 828, 828, 829, 830, 831, - 832, 833, 833, 834, 835, 836, 836, 837, 838, 839, 840, 368, 368, 368, - 841, 842, 843, 843, 843, 843, 843, 844, 845, 846, 847, 848, 849, 850, - 349, 353, 851, 852, 852, 852, 852, 852, 853, 854, 120, 855, 856, 857, - 858, 349, 349, 859, 860, 861, 861, 861, 861, 861, 861, 862, 863, 864, - 120, 120, 865, 866, 867, 868, 120, 869, 869, 869, 120, 373, 373, 54, 54, - 54, 54, 54, 870, 871, 120, 872, 872, 872, 872, 872, 872, 872, 872, 872, - 872, 866, 866, 866, 866, 873, 874, 875, 876, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, - 878, 878, 877, 878, 878, 879, 878, 878, 878, 878, 878, 878, 877, 878, - 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, - 878, 880, 120, 369, 369, 881, 882, 370, 370, 370, 370, 370, 883, 884, - 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, - 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, - 884, 884, 884, 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, 885, 885, 776, 776, 776, 776, 776, 776, 776, - 776, 776, 776, 776, 776, 776, 777, 776, 776, 776, 776, 776, 776, 776, - 776, 776, 776, 776, 776, 776, 886, 778, 778, 778, 778, 887, 120, 888, - 889, 121, 890, 891, 892, 893, 121, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 894, 895, 896, 120, 897, 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, 898, 120, - 120, 128, 128, 128, 128, 128, 128, 128, 128, 899, 128, 128, 128, 128, - 128, 128, 120, 120, 120, 120, 120, 128, 900, 901, 901, 902, 903, 904, - 905, 906, 907, 908, 909, 910, 911, 912, 913, 170, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 914, 915, - 916, 917, 918, 919, 920, 920, 921, 922, 923, 923, 924, 925, 926, 927, - 928, 928, 928, 928, 929, 930, 930, 930, 931, 932, 932, 932, 933, 934, - 935, 120, 936, 937, 938, 937, 937, 939, 937, 937, 940, 937, 941, 937, - 941, 120, 120, 120, 120, 937, 937, 937, 937, 937, 937, 937, 937, 937, - 937, 937, 937, 937, 937, 937, 942, 943, 944, 944, 944, 944, 944, 945, - 609, 946, 946, 946, 946, 946, 946, 947, 948, 949, 950, 580, 951, 952, - 120, 120, 120, 120, 120, 609, 609, 609, 609, 609, 953, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 954, - 954, 954, 955, 956, 956, 956, 956, 956, 956, 957, 120, 958, 959, 959, - 960, 961, 961, 961, 961, 962, 963, 964, 964, 965, 966, 967, 967, 967, - 967, 968, 969, 970, 970, 970, 971, 972, 972, 972, 972, 973, 972, 974, - 120, 120, 120, 120, 120, 975, 975, 975, 975, 975, 976, 976, 976, 976, - 976, 977, 977, 977, 977, 977, 977, 978, 978, 978, 979, 980, 981, 982, - 982, 982, 982, 983, 984, 984, 984, 984, 985, 986, 986, 986, 986, 986, - 120, 987, 987, 987, 987, 987, 987, 988, 989, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 990, - 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, - 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, - 990, 990, 990, 990, 990, 990, 990, 990, 990, 991, 120, 990, 990, 992, - 120, 990, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 993, 994, 995, 995, 995, 995, 996, - 997, 998, 998, 999, 1000, 1001, 1001, 1002, 1003, 1004, 1004, 1004, 1005, - 1006, 1007, 120, 120, 120, 120, 120, 120, 1008, 1008, 1009, 1010, 1011, - 1011, 1012, 1013, 1014, 1014, 1014, 1015, 120, 120, 120, 120, 120, 120, - 120, 120, 1016, 1016, 1016, 1016, 1017, 1017, 1017, 1018, 1019, 1019, - 1020, 1019, 1019, 1019, 1019, 1019, 1021, 1022, 1023, 1024, 1025, 1025, - 1026, 1027, 1028, 120, 1029, 1030, 1031, 1031, 1031, 1032, 1033, 1033, - 1033, 1034, 120, 120, 120, 120, 1035, 1036, 1035, 1035, 1037, 1038, 1039, - 120, 1040, 1040, 1040, 1040, 1040, 1040, 1041, 1042, 1043, 1043, 1044, - 1045, 1046, 1046, 1047, 1048, 1049, 1049, 1050, 1051, 120, 1052, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 1053, 1053, 1053, 1053, - 1053, 1053, 1053, 1053, 1053, 1054, 120, 120, 120, 120, 120, 120, 1055, - 1055, 1055, 1055, 1055, 1055, 1056, 120, 1057, 1057, 1057, 1057, 1057, - 1057, 1058, 1059, 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, 1060, 1060, 1060, 1061, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1062, 1063, 1063, - 1063, 1063, 1063, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 120, - 1071, 1072, 1073, 1073, 1073, 1073, 1073, 1074, 1075, 1076, 120, 1077, - 1077, 1077, 1078, 1079, 1080, 1081, 1082, 1082, 1082, 1083, 1084, 1085, - 1086, 1087, 120, 1088, 1088, 1088, 1088, 1089, 120, 1090, 1091, 1091, - 1091, 1091, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, - 120, 1101, 1101, 1102, 1101, 1101, 1103, 1104, 1105, 120, 120, 120, 120, - 120, 120, 120, 120, 1106, 1107, 1108, 1109, 1108, 1110, 1111, 1111, 1111, - 1111, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1120, - 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1129, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 1130, 1130, 1130, 1130, 1130, 1130, 1131, 1132, 1133, 1134, 1135, - 1136, 120, 120, 120, 120, 1137, 1137, 1137, 1137, 1137, 1137, 1138, 1139, - 1140, 120, 1141, 1142, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1143, 1143, 1143, 1143, - 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 120, 120, 120, 120, 1151, - 1151, 1151, 1151, 1151, 1151, 1152, 1153, 1154, 120, 1155, 1156, 1157, - 1158, 120, 120, 1159, 1159, 1159, 1159, 1159, 1160, 1161, 120, 1162, - 1163, 120, 120, 120, 120, 120, 120, 1164, 1164, 1164, 1165, 1166, 1167, - 1168, 1169, 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, 1170, 1170, 1170, 1170, 1171, 1171, 1171, 1171, 1172, - 1173, 1174, 1175, 1176, 1177, 1178, 1178, 1178, 1178, 1179, 1180, 1181, - 120, 1182, 1183, 1184, 1184, 1184, 1184, 1185, 1186, 1187, 1188, 1189, - 120, 120, 120, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1191, 1192, - 1193, 1192, 1192, 1192, 1194, 1195, 1196, 1197, 120, 1198, 1199, 1200, - 1201, 1202, 1203, 1203, 1203, 1204, 1205, 1205, 1206, 1207, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 1208, 1209, 1210, 1210, 1210, 1210, - 1211, 1212, 1213, 120, 1214, 1215, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1216, - 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, - 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, - 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, - 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, - 1216, 1216, 1217, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, - 1218, 1218, 1219, 1220, 120, 1216, 1216, 1216, 1216, 1216, 1216, 1216, - 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, - 1216, 1216, 1216, 1216, 1216, 1221, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1223, 1222, 1222, - 1222, 1222, 1224, 1225, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1226, 1222, 1222, - 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1227, 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, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1229, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1228, 1230, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, - 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, - 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, - 1231, 1232, 1232, 1232, 1233, 1234, 1235, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 1236, 1236, 1236, 1237, 1238, 120, 1239, - 1239, 1239, 1239, 1239, 1239, 1240, 1241, 1242, 120, 1243, 1244, 1245, - 1239, 1239, 1246, 1239, 1239, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 1247, 1247, 1247, 1247, 1247, 1247, 1247, - 1247, 1248, 120, 1249, 1250, 1250, 1250, 1250, 1251, 120, 1252, 1253, - 1254, 120, 120, 120, 120, 120, 120, 120, 120, 1255, 120, 120, 120, 1256, - 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, - 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, - 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, - 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, - 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, - 1257, 120, 120, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, - 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, - 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1258, 120, 1259, - 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 737, 1260, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 1261, 1261, 1261, 1261, 1262, 1263, 1263, 1263, 1263, 1263, 1263, 1263, - 1263, 1263, 1263, 1263, 1263, 1263, 1264, 1263, 1265, 1263, 1266, 1263, - 1267, 1268, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 609, - 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, - 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, - 609, 1269, 120, 609, 609, 609, 609, 1270, 1271, 609, 609, 609, 609, 609, - 609, 1272, 1273, 1274, 1275, 1276, 1277, 609, 609, 609, 1278, 609, 609, - 609, 609, 609, 609, 609, 1279, 120, 120, 949, 949, 949, 949, 949, 949, - 949, 949, 1280, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 580, 580, - 580, 580, 580, 580, 580, 580, 580, 580, 616, 120, 944, 944, 1281, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 1282, 1282, 1282, 1283, 1284, 1284, 1285, 1282, 1282, 1286, - 1287, 1284, 1284, 1282, 1282, 1282, 1283, 1284, 1284, 1288, 1289, 1290, - 1286, 1291, 1292, 1284, 1282, 1282, 1282, 1283, 1284, 1284, 1293, 1294, - 1295, 1296, 1284, 1284, 1284, 1297, 1298, 1299, 1300, 1284, 1284, 1285, - 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, 1284, 1284, - 1285, 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, 1284, - 1284, 1285, 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, - 1284, 1284, 1301, 1282, 1282, 1282, 1302, 1284, 1284, 1303, 1304, 1282, - 1282, 1305, 1284, 1284, 1306, 1285, 1282, 1282, 1307, 1284, 1284, 1308, - 1309, 1282, 1282, 1310, 1284, 1284, 1284, 1311, 1282, 1282, 1282, 1302, - 1284, 1284, 1303, 1312, 1313, 1313, 1313, 1313, 1313, 1313, 1314, 1314, - 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, - 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, - 1314, 1314, 1314, 1314, 1314, 1314, 1315, 1315, 1315, 1315, 1315, 1315, - 1316, 1317, 1315, 1315, 1315, 1315, 1315, 1318, 1319, 1314, 1320, 1321, - 120, 1322, 1323, 1315, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 1324, 1325, 1325, 1326, 1327, 1328, 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, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, - 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, - 1329, 1329, 1329, 1329, 1330, 1331, 1332, 120, 120, 120, 120, 120, 1333, - 1333, 1333, 1333, 1334, 1335, 1335, 1335, 1336, 1337, 1338, 1339, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 1340, 128, 128, 128, 1341, 1342, 1343, 1344, - 1345, 1346, 1341, 1347, 1341, 1343, 1343, 1348, 128, 1349, 128, 1350, - 1351, 1349, 128, 1350, 120, 120, 120, 120, 120, 120, 1352, 120, 1353, - 1354, 1354, 1354, 1354, 1355, 1354, 1354, 1354, 1354, 1354, 1354, 1354, - 1354, 1354, 1354, 1354, 1354, 1355, 1356, 1354, 1357, 1358, 1354, 1358, - 1359, 1358, 1354, 1354, 1354, 1360, 1356, 619, 1361, 621, 621, 621, 1362, - 621, 621, 621, 621, 621, 621, 621, 1363, 621, 621, 621, 1364, 1365, 1366, - 621, 1367, 1356, 1356, 1356, 1356, 1356, 1356, 1368, 1369, 1369, 1369, - 1370, 1356, 758, 758, 758, 758, 758, 1371, 758, 1372, 1373, 1356, 1374, - 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, - 1356, 1356, 1356, 1356, 1356, 1356, 1356, 725, 725, 725, 725, 1375, 1376, - 1377, 725, 725, 725, 725, 725, 725, 725, 725, 1378, 1379, 725, 1380, - 1381, 725, 725, 1382, 1383, 1384, 1385, 1380, 1354, 725, 725, 1386, 1387, - 725, 725, 725, 725, 725, 725, 725, 1388, 1389, 1390, 1391, 725, 1392, - 1393, 1390, 1394, 1395, 725, 725, 725, 1396, 1397, 1398, 725, 725, 725, - 725, 725, 725, 725, 725, 1399, 1400, 725, 1401, 642, 1402, 725, 1403, - 1404, 580, 1405, 725, 725, 725, 1354, 1406, 1407, 1354, 1354, 1408, 1354, - 1353, 1354, 1354, 1354, 1354, 1354, 1409, 1410, 1354, 1354, 1409, 1411, - 725, 725, 725, 725, 725, 725, 725, 725, 1412, 1413, 580, 580, 580, 580, - 1414, 1415, 725, 725, 725, 725, 1416, 725, 1417, 725, 1418, 1419, 1420, - 1356, 1354, 1421, 1422, 1423, 580, 580, 580, 580, 580, 580, 580, 580, - 580, 580, 580, 580, 580, 580, 1424, 1356, 580, 580, 580, 580, 580, 580, - 580, 580, 580, 580, 1425, 1356, 1356, 1356, 1356, 1356, 580, 1424, 580, - 580, 580, 580, 580, 580, 580, 1356, 580, 1426, 580, 580, 580, 580, 580, - 1356, 580, 580, 580, 1427, 1356, 1356, 1356, 1356, 1356, 1356, 1356, - 1356, 1356, 1356, 580, 1424, 725, 1428, 1429, 725, 1390, 1430, 725, 1431, - 725, 725, 725, 1432, 1356, 1356, 725, 725, 725, 1356, 1356, 1356, 1356, - 1356, 1423, 1356, 1433, 1434, 1435, 1356, 1356, 1356, 1356, 1356, 1356, - 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, - 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, - 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, - 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, - 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, - 1436, 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, 1437, - 778, 778, 778, 778, 778, 776, 776, 776, 776, 776, 776, 1438, 778, 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, 777, 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, 776, 776, 776, 776, - 776, 776, 776, 776, 776, 886, 778, 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, 1439, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 776, 776, 776, - 777, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 778, 778, 778, 1440, 1441, 120, 120, 120, 1442, 1442, 1442, 1442, - 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 901, 901, 901, - 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, - 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 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, 885, 1443, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 778, + 779, 779, 779, 779, 779, 779, 780, 119, 781, 781, 781, 781, 781, 782, + 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, + 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, + 783, 783, 783, 783, 783, 784, 783, 783, 785, 786, 119, 119, 101, 101, + 101, 101, 101, 787, 788, 789, 101, 101, 101, 790, 791, 791, 791, 791, + 791, 791, 791, 791, 792, 793, 794, 119, 64, 64, 795, 796, 797, 27, 798, + 27, 27, 27, 27, 27, 27, 27, 799, 800, 27, 801, 802, 27, 27, 803, 804, + 805, 119, 119, 119, 119, 119, 119, 806, 807, 808, 809, 810, 810, 811, + 812, 813, 814, 815, 815, 815, 815, 815, 815, 816, 119, 817, 818, 818, + 818, 818, 818, 819, 820, 821, 822, 823, 824, 825, 825, 826, 827, 828, + 829, 830, 830, 831, 832, 833, 833, 834, 835, 836, 837, 367, 367, 367, + 838, 839, 840, 840, 840, 840, 840, 841, 842, 843, 844, 845, 846, 847, + 348, 352, 848, 849, 849, 849, 849, 849, 850, 851, 119, 852, 853, 854, + 855, 348, 348, 856, 857, 858, 858, 858, 858, 858, 858, 859, 860, 861, + 119, 119, 862, 863, 864, 865, 119, 866, 866, 866, 119, 372, 372, 54, 54, + 54, 54, 54, 867, 868, 119, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 863, 863, 863, 863, 870, 871, 872, 873, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, + 875, 875, 874, 875, 875, 876, 875, 875, 875, 875, 875, 875, 874, 875, + 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, + 875, 877, 119, 368, 368, 878, 879, 369, 369, 369, 369, 369, 880, 881, + 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, + 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, + 882, 882, 882, 882, 882, 882, 882, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 774, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 883, 775, 775, 775, 775, 884, 119, 885, + 886, 120, 887, 888, 889, 890, 120, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 891, 892, 893, 119, 894, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 895, 119, + 119, 127, 127, 127, 127, 127, 127, 127, 127, 896, 127, 127, 127, 127, + 127, 127, 119, 119, 119, 119, 119, 127, 897, 898, 898, 899, 900, 901, + 902, 903, 904, 905, 906, 907, 908, 909, 910, 169, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 911, 912, + 913, 914, 915, 916, 917, 917, 918, 919, 920, 920, 921, 922, 923, 924, + 925, 925, 925, 925, 926, 927, 927, 927, 928, 929, 929, 929, 930, 931, + 932, 119, 933, 934, 935, 934, 934, 936, 934, 934, 937, 934, 938, 934, + 938, 119, 119, 119, 119, 934, 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 939, 940, 941, 941, 941, 941, 941, 942, + 610, 943, 943, 943, 943, 943, 943, 944, 945, 946, 947, 581, 948, 949, + 119, 119, 119, 119, 119, 610, 610, 610, 610, 610, 950, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 951, + 951, 951, 952, 953, 953, 953, 953, 953, 953, 954, 119, 955, 956, 956, + 957, 958, 958, 958, 958, 959, 960, 961, 961, 962, 963, 964, 964, 964, + 964, 965, 966, 967, 967, 967, 968, 969, 969, 969, 969, 970, 969, 971, + 119, 119, 119, 119, 119, 972, 972, 972, 972, 972, 973, 973, 973, 973, + 973, 974, 974, 974, 974, 974, 974, 975, 975, 975, 976, 977, 978, 979, + 979, 979, 979, 980, 981, 981, 981, 981, 982, 983, 983, 983, 983, 983, + 119, 984, 984, 984, 984, 984, 984, 985, 986, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 987, + 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, + 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, + 987, 987, 987, 987, 987, 987, 987, 987, 987, 988, 119, 987, 987, 989, + 119, 987, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 990, 991, 992, 992, 992, 992, 993, + 994, 995, 995, 996, 997, 998, 998, 999, 1000, 1001, 1001, 1001, 1002, + 1003, 1004, 119, 119, 119, 119, 119, 119, 1005, 1005, 1006, 1007, 1008, + 1008, 1009, 1010, 1011, 1011, 1011, 1012, 119, 119, 119, 119, 119, 119, + 119, 119, 1013, 1013, 1013, 1013, 1014, 1014, 1014, 1015, 1016, 1016, + 1017, 1016, 1016, 1016, 1016, 1016, 1018, 1019, 1020, 1021, 1022, 1022, + 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1029, 1029, 1030, 1031, 1031, + 1031, 1032, 119, 119, 119, 119, 1033, 1034, 1033, 1033, 1035, 1036, 1037, + 119, 1038, 1038, 1038, 1038, 1038, 1038, 1039, 1040, 1041, 1041, 1042, + 1043, 1044, 1044, 1045, 1046, 1047, 1047, 1048, 1049, 119, 1050, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 1051, 1051, 1051, 1051, + 1051, 1051, 1051, 1051, 1051, 1052, 119, 119, 119, 119, 119, 119, 1053, + 1053, 1053, 1053, 1053, 1053, 1054, 119, 1055, 1055, 1055, 1055, 1055, + 1055, 1056, 1057, 1058, 1058, 1058, 1058, 1059, 119, 1060, 1061, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 1062, 1062, 1062, 1063, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1064, + 1064, 1064, 1065, 1066, 119, 1067, 1067, 1068, 1069, 1070, 1071, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 1072, 1073, 1073, 1073, 1073, 1073, 1073, 1074, + 1075, 1076, 1077, 1078, 1079, 1080, 119, 1081, 1082, 1083, 1083, 1083, + 1083, 1083, 1084, 1085, 1086, 1087, 1088, 1088, 1088, 1089, 1090, 1091, + 1092, 1093, 1093, 1093, 1094, 1095, 1096, 1097, 1098, 119, 1099, 1099, + 1099, 1099, 1100, 119, 1101, 1102, 1102, 1102, 1102, 1102, 1103, 1104, + 1105, 1106, 1107, 1108, 1109, 1110, 1111, 119, 1112, 1112, 1113, 1112, + 1112, 1114, 1115, 1116, 119, 119, 119, 119, 119, 119, 119, 119, 1117, + 1118, 1119, 1120, 1119, 1121, 1122, 1122, 1122, 1122, 1122, 1123, 1124, + 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1131, 1132, 1133, 1134, 1135, + 1136, 1137, 1138, 1139, 1140, 1140, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1141, 1141, 1141, 1141, + 1141, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 119, 119, 119, 119, 1148, + 1148, 1148, 1148, 1148, 1148, 1149, 1150, 1151, 119, 1152, 1153, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 1154, 1154, 1154, 1154, 1154, 1155, 1156, 1157, + 1158, 1159, 1160, 1161, 119, 119, 119, 119, 1162, 1162, 1162, 1162, 1162, + 1162, 1163, 1164, 1165, 119, 1166, 1167, 1168, 1169, 119, 119, 1170, + 1170, 1170, 1170, 1170, 1171, 1172, 119, 1173, 1174, 119, 119, 119, 119, + 119, 119, 1175, 1175, 1175, 1176, 1177, 1178, 1179, 1180, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 1181, 1181, 1181, 1181, 1181, 1182, + 1183, 1184, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 1185, 1185, 1185, 1185, 1186, 1186, 1186, 1186, 1187, 1188, 1189, 1190, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 1191, 1192, 1193, 1193, 1193, 1193, 1194, 1195, 1196, + 119, 1197, 1198, 1199, 1199, 1199, 1199, 1200, 1201, 1202, 1203, 1204, + 119, 119, 119, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1206, 1207, + 1208, 1207, 1207, 1207, 1209, 1210, 1211, 1212, 119, 1213, 1214, 1215, + 1216, 1217, 1218, 1218, 1218, 1219, 1220, 1220, 1221, 1222, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 1223, 1224, 1225, 1225, 1225, 1225, + 1226, 1227, 1228, 119, 1229, 1230, 1231, 1232, 1233, 1233, 1233, 1234, + 1235, 1236, 1237, 1238, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 1239, 1239, 1240, 1241, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1243, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 1244, 1244, 1244, 1244, 1244, 1244, + 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1245, 1246, 119, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1247, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1249, 1248, 1248, 1248, 1248, 1250, 1251, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1252, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1253, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1254, + 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1255, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1256, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 791, 791, 791, 791, 791, + 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, + 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, + 791, 791, 791, 791, 791, 791, 1257, 1258, 1258, 1258, 1259, 1260, 1261, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1262, 1262, + 1262, 1263, 1264, 119, 1265, 1265, 1265, 1265, 1265, 1265, 1266, 1267, + 1268, 119, 1269, 1270, 1271, 1265, 1265, 1272, 1265, 1265, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 1273, 1273, 1273, 1273, 1274, 1274, 1274, 1274, + 1275, 1275, 1276, 1277, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1279, 119, + 1280, 1281, 1281, 1281, 1281, 1282, 119, 1283, 1284, 1285, 119, 119, 119, + 119, 119, 119, 119, 119, 1286, 119, 119, 119, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1288, 119, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + 1287, 1287, 1287, 1287, 1287, 1287, 1289, 119, 1290, 735, 735, 735, 735, + 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, + 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, + 735, 735, 1291, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1292, + 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, + 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, + 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, + 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, + 1293, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, + 1294, 1294, 1295, 1294, 1296, 1294, 1297, 1294, 1298, 1299, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 610, 610, 610, 610, 610, + 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, + 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 1300, 119, 610, + 610, 610, 610, 1301, 1302, 610, 610, 610, 610, 610, 610, 1303, 1304, + 1305, 1306, 1307, 1308, 610, 610, 610, 1309, 610, 610, 610, 610, 610, + 610, 610, 1310, 119, 119, 946, 946, 946, 946, 946, 946, 946, 946, 1311, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 941, 941, 1312, 119, 581, 581, 581, 581, 581, + 581, 581, 581, 581, 581, 617, 119, 941, 941, 941, 1313, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1314, + 1314, 1314, 1315, 1316, 1316, 1317, 1314, 1314, 1318, 1319, 1316, 1316, + 1314, 1314, 1314, 1315, 1316, 1316, 1320, 1321, 1322, 1318, 1323, 1324, + 1316, 1314, 1314, 1314, 1315, 1316, 1316, 1325, 1326, 1327, 1328, 1316, + 1316, 1316, 1329, 1330, 1331, 1332, 1316, 1316, 1317, 1314, 1314, 1318, + 1316, 1316, 1316, 1314, 1314, 1314, 1315, 1316, 1316, 1317, 1314, 1314, + 1318, 1316, 1316, 1316, 1314, 1314, 1314, 1315, 1316, 1316, 1317, 1314, + 1314, 1318, 1316, 1316, 1316, 1314, 1314, 1314, 1315, 1316, 1316, 1333, + 1314, 1314, 1314, 1334, 1316, 1316, 1335, 1336, 1314, 1314, 1337, 1316, + 1316, 1338, 1317, 1314, 1314, 1339, 1316, 1316, 1340, 1341, 1314, 1314, + 1342, 1316, 1316, 1316, 1343, 1314, 1314, 1314, 1334, 1316, 1316, 1335, + 1344, 1345, 1345, 1345, 1345, 1345, 1345, 1346, 1346, 1346, 1346, 1346, + 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, + 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, + 1346, 1346, 1346, 1347, 1347, 1347, 1347, 1347, 1347, 1348, 1349, 1347, + 1347, 1347, 1347, 1347, 1350, 1351, 1346, 1352, 1353, 119, 1354, 1355, + 1347, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1356, 1357, 1357, + 1358, 1359, 1360, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, + 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, + 1361, 1362, 1363, 1364, 119, 119, 119, 119, 119, 1365, 1365, 1365, 1365, + 1366, 1367, 1367, 1367, 1368, 1369, 1370, 1371, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 1372, 1373, 1373, 1373, 1373, 1373, 1373, 1374, 1375, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 1376, 127, 127, 127, 1377, 1378, 1379, + 1380, 1381, 1382, 1377, 1383, 1377, 1379, 1379, 1384, 127, 1385, 127, + 1386, 1387, 1385, 127, 1386, 119, 119, 119, 119, 119, 119, 1388, 119, + 1389, 1390, 1390, 1390, 1390, 1391, 1390, 1390, 1390, 1390, 1390, 1390, + 1390, 1390, 1390, 1390, 1390, 1390, 1391, 1392, 1390, 1393, 1394, 1390, + 1394, 1395, 1394, 1390, 1390, 1390, 1396, 1392, 620, 1397, 622, 622, 622, + 1398, 622, 622, 622, 622, 622, 622, 622, 1399, 622, 622, 622, 1400, 1401, + 1402, 622, 1403, 1392, 1392, 1392, 1392, 1392, 1392, 1404, 1405, 1405, + 1405, 1406, 1392, 755, 755, 755, 755, 755, 1407, 755, 1408, 1409, 1392, + 1410, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 723, 723, 723, 723, 1411, + 1412, 1413, 723, 723, 723, 723, 723, 723, 723, 723, 1414, 1415, 723, + 1416, 1417, 723, 723, 1418, 1419, 1420, 1421, 1416, 1390, 723, 723, 1422, + 1423, 723, 723, 723, 723, 723, 723, 723, 1424, 1425, 1426, 1427, 723, + 1428, 1429, 1426, 1430, 1431, 723, 723, 723, 1432, 1433, 1434, 723, 723, + 723, 723, 723, 723, 723, 723, 1435, 1436, 723, 1437, 643, 1438, 723, + 1439, 1440, 581, 1441, 723, 723, 723, 1390, 1442, 1443, 1390, 1390, 1444, + 1390, 1389, 1390, 1390, 1390, 1390, 1390, 1445, 1446, 1390, 1390, 1445, + 1447, 723, 723, 723, 723, 723, 723, 723, 723, 1448, 1449, 581, 581, 581, + 581, 1450, 1451, 723, 723, 723, 723, 1452, 723, 1453, 723, 1454, 1455, + 1456, 1392, 1390, 1457, 1458, 1459, 581, 581, 581, 581, 581, 581, 581, + 581, 581, 581, 581, 581, 581, 581, 1460, 1392, 581, 581, 581, 581, 581, + 581, 581, 581, 581, 581, 1461, 1462, 1392, 1392, 1392, 1392, 581, 1460, + 581, 581, 581, 581, 581, 581, 581, 1392, 581, 1463, 581, 581, 581, 581, + 581, 1392, 581, 581, 581, 1464, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 581, 1460, 723, 1465, 1466, 723, 1426, 1467, 723, 723, + 723, 723, 723, 723, 1468, 1469, 723, 723, 723, 723, 1470, 1392, 1471, + 1472, 1470, 1392, 1473, 1474, 723, 723, 723, 723, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1390, 1396, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, + 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1475, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 1476, 775, 775, 775, 775, 775, 773, + 773, 773, 773, 773, 773, 1477, 775, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 774, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 883, + 775, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 1478, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 773, 773, 773, 774, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 1479, 1480, + 119, 119, 119, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, + 1481, 1481, 1481, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 898, 898, 898, 898, 898, 898, 898, 898, 898, + 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, + 898, 898, 898, 898, 898, 898, 898, 119, 119, 882, 882, 882, 882, 882, + 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, + 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 1482, }; static const unsigned short index2[] = { @@ -2666,716 +2829,743 @@ static const unsigned short index2[] = { 94, 95, 95, 96, 96, 95, 97, 97, 90, 93, 90, 93, 90, 93, 90, 90, 93, 90, 93, 90, 93, 90, 93, 90, 93, 90, 93, 90, 93, 93, 81, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 81, - 81, 99, 100, 100, 100, 100, 100, 100, 81, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 81, 102, 103, 81, 81, 104, - 104, 105, 81, 106, 107, 107, 107, 107, 106, 107, 107, 107, 108, 106, 107, - 107, 107, 107, 107, 107, 106, 106, 106, 106, 106, 106, 107, 107, 106, - 107, 107, 108, 109, 107, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 119, 120, 121, 122, 123, 124, 125, 126, 127, 125, 107, 106, 128, - 118, 81, 81, 81, 81, 81, 81, 81, 81, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 81, 81, 81, 81, 81, 129, 129, 129, 125, 125, 81, 81, - 81, 130, 130, 130, 130, 130, 131, 132, 132, 133, 134, 134, 135, 136, 137, - 138, 138, 139, 139, 139, 139, 139, 139, 139, 139, 140, 141, 142, 143, - 144, 81, 145, 143, 146, 146, 146, 146, 146, 146, 146, 146, 147, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 148, 149, 150, 151, 152, 153, - 154, 155, 96, 96, 156, 157, 139, 139, 139, 139, 139, 157, 139, 139, 157, - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 134, 159, 159, 160, - 146, 146, 161, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 145, 146, 139, 139, 139, 139, 139, 139, 139, 131, 138, 139, 139, 139, - 139, 157, 139, 162, 162, 139, 139, 138, 157, 139, 139, 157, 146, 146, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 146, 146, 146, 164, - 164, 146, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 81, 166, 167, 168, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 169, 170, 169, 169, 170, 169, 169, 170, 170, - 170, 169, 170, 170, 169, 170, 169, 169, 169, 170, 169, 170, 169, 170, - 169, 170, 169, 169, 81, 81, 167, 167, 167, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 171, 81, 81, 81, 81, 81, 81, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, 175, 175, 175, - 175, 175, 176, 175, 177, 177, 178, 179, 180, 181, 177, 81, 81, 81, 81, - 81, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, - 183, 183, 183, 183, 184, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 184, 183, 183, 183, 184, 183, 183, 183, 183, 183, 81, 81, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 81, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 81, 81, 188, 81, 167, - 167, 167, 81, 81, 81, 81, 81, 146, 146, 146, 146, 146, 81, 146, 146, 146, - 146, 146, 146, 146, 146, 81, 81, 81, 81, 81, 81, 139, 139, 139, 139, 139, - 139, 131, 157, 139, 139, 157, 139, 139, 157, 139, 139, 139, 157, 157, - 157, 189, 190, 191, 139, 139, 139, 157, 139, 139, 157, 157, 139, 139, - 139, 139, 139, 192, 192, 192, 193, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 192, 193, 195, 194, 193, 193, 193, - 192, 192, 192, 192, 192, 192, 192, 192, 193, 193, 193, 193, 196, 193, - 193, 194, 96, 156, 197, 197, 192, 192, 192, 194, 194, 192, 192, 198, 198, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 200, 201, 194, 194, - 194, 194, 194, 194, 202, 203, 204, 204, 81, 202, 202, 202, 202, 202, 202, - 202, 202, 81, 81, 202, 202, 81, 81, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 81, 202, 202, 202, 202, 202, 202, 202, - 81, 202, 81, 81, 81, 202, 202, 202, 202, 81, 81, 205, 202, 204, 204, 204, - 203, 203, 203, 203, 81, 81, 204, 204, 81, 81, 204, 204, 206, 202, 81, 81, - 81, 81, 81, 81, 81, 81, 204, 81, 81, 81, 81, 202, 202, 81, 202, 202, 202, - 203, 203, 81, 81, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 202, - 202, 208, 208, 209, 209, 209, 209, 209, 210, 211, 212, 202, 213, 81, 81, - 81, 214, 214, 215, 81, 216, 216, 216, 216, 216, 216, 81, 81, 81, 81, 216, - 216, 81, 81, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, - 216, 216, 81, 216, 216, 216, 216, 216, 216, 216, 81, 216, 216, 81, 216, - 216, 81, 216, 216, 81, 81, 217, 81, 215, 215, 215, 214, 214, 81, 81, 81, - 81, 214, 214, 81, 81, 214, 214, 218, 81, 81, 81, 214, 81, 81, 81, 81, 81, - 81, 81, 216, 216, 216, 216, 81, 216, 81, 81, 81, 81, 81, 81, 81, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 214, 214, 216, 216, 216, - 214, 81, 81, 81, 220, 220, 221, 81, 222, 222, 222, 222, 222, 222, 222, - 222, 222, 81, 222, 222, 222, 81, 222, 222, 222, 222, 222, 222, 222, 222, - 222, 222, 222, 222, 222, 222, 81, 222, 222, 222, 222, 222, 222, 222, 81, - 222, 222, 81, 222, 222, 222, 222, 222, 81, 81, 223, 222, 221, 221, 221, - 220, 220, 220, 220, 220, 81, 220, 220, 221, 81, 221, 221, 224, 81, 81, - 222, 81, 81, 81, 81, 81, 81, 81, 222, 222, 220, 220, 81, 81, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 226, 227, 81, 81, 81, 81, 81, 81, - 81, 222, 220, 220, 220, 220, 220, 220, 81, 228, 229, 229, 81, 230, 230, - 230, 230, 230, 230, 230, 230, 81, 81, 230, 230, 81, 81, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 81, 230, 230, 230, - 230, 230, 230, 230, 81, 230, 230, 81, 230, 230, 230, 230, 230, 81, 81, - 231, 230, 229, 228, 229, 228, 228, 228, 228, 81, 81, 229, 229, 81, 81, - 229, 229, 232, 81, 81, 81, 81, 81, 81, 81, 81, 228, 229, 81, 81, 81, 81, - 230, 230, 81, 230, 230, 230, 228, 228, 81, 81, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 234, 230, 235, 235, 235, 235, 235, 235, 81, 81, - 236, 237, 81, 237, 237, 237, 237, 237, 237, 81, 81, 81, 237, 237, 237, - 81, 237, 237, 237, 237, 81, 81, 81, 237, 237, 81, 237, 81, 237, 237, 81, - 81, 81, 237, 237, 81, 81, 81, 237, 237, 237, 237, 237, 237, 237, 237, - 237, 237, 81, 81, 81, 81, 238, 238, 236, 238, 238, 81, 81, 81, 238, 238, - 238, 81, 238, 238, 238, 239, 81, 81, 237, 81, 81, 81, 81, 81, 81, 238, - 81, 81, 81, 81, 81, 81, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - 241, 241, 241, 242, 242, 242, 242, 242, 242, 243, 242, 81, 81, 81, 81, - 81, 244, 245, 245, 245, 81, 246, 246, 246, 246, 246, 246, 246, 246, 81, - 246, 246, 246, 81, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 246, 246, 246, 81, 81, 81, 246, 244, 244, 244, 245, 245, 245, - 245, 81, 244, 244, 244, 81, 244, 244, 244, 247, 81, 81, 81, 81, 81, 81, - 81, 248, 249, 81, 246, 246, 246, 81, 81, 81, 81, 81, 246, 246, 244, 244, - 81, 81, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, - 251, 251, 251, 251, 252, 253, 254, 255, 255, 81, 253, 253, 253, 253, 253, - 253, 253, 253, 81, 253, 253, 253, 81, 253, 253, 253, 253, 253, 253, 253, - 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 81, 253, 253, 253, - 253, 253, 81, 81, 256, 253, 255, 257, 255, 255, 255, 255, 255, 81, 257, - 255, 255, 81, 255, 255, 254, 258, 81, 81, 81, 81, 81, 81, 81, 255, 255, - 81, 81, 81, 81, 81, 81, 81, 253, 81, 253, 253, 254, 254, 81, 81, 259, - 259, 259, 259, 259, 259, 259, 259, 259, 259, 81, 253, 253, 81, 81, 81, - 81, 81, 260, 260, 261, 261, 81, 262, 262, 262, 262, 262, 262, 262, 262, - 81, 262, 262, 262, 81, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - 262, 262, 262, 262, 262, 262, 262, 263, 263, 262, 261, 261, 261, 260, - 260, 260, 260, 81, 261, 261, 261, 81, 261, 261, 261, 263, 262, 264, 81, - 81, 81, 81, 262, 262, 262, 261, 265, 265, 265, 265, 265, 265, 265, 262, - 262, 262, 260, 260, 81, 81, 266, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 265, 265, 265, 265, 265, 265, 265, 265, 265, 267, 262, 262, 262, - 262, 262, 262, 81, 81, 268, 268, 81, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 81, 81, 81, 269, - 269, 269, 269, 269, 269, 269, 269, 81, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 81, 269, 81, 81, 81, 81, 270, 81, 81, 81, 81, 268, 268, 268, - 271, 271, 271, 81, 271, 81, 268, 268, 268, 268, 268, 268, 268, 268, 81, - 81, 81, 81, 81, 81, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 81, - 81, 268, 268, 273, 81, 81, 81, 81, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 275, 274, 274, 275, 275, - 275, 275, 276, 276, 277, 81, 81, 81, 81, 278, 274, 274, 274, 274, 274, - 274, 279, 275, 280, 280, 280, 280, 275, 275, 275, 281, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 283, 283, 81, 81, 81, 81, 81, 284, - 284, 81, 284, 81, 81, 284, 284, 81, 284, 81, 81, 284, 81, 81, 81, 81, 81, - 81, 284, 284, 284, 284, 81, 284, 284, 284, 284, 284, 284, 284, 81, 284, - 284, 284, 81, 284, 81, 284, 81, 81, 284, 284, 81, 284, 284, 284, 284, - 285, 284, 284, 285, 285, 285, 285, 286, 286, 81, 285, 285, 284, 81, 81, - 284, 284, 284, 284, 284, 81, 287, 81, 288, 288, 288, 288, 285, 285, 81, - 81, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 81, 81, 284, 284, - 284, 284, 290, 291, 291, 291, 292, 293, 292, 292, 294, 292, 292, 295, - 294, 296, 296, 296, 296, 296, 294, 297, 296, 297, 297, 297, 298, 298, - 297, 297, 297, 297, 297, 297, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 299, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 301, 298, - 297, 298, 297, 302, 303, 304, 303, 304, 305, 305, 290, 290, 290, 290, - 290, 290, 290, 290, 81, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 81, 81, 81, 81, 306, 307, 308, 309, 308, 308, 308, 308, 308, - 307, 307, 307, 307, 308, 310, 307, 308, 311, 311, 312, 295, 311, 311, - 290, 290, 290, 290, 290, 308, 308, 308, 308, 308, 308, 308, 308, 308, - 308, 308, 81, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, - 81, 301, 301, 297, 297, 297, 297, 297, 297, 298, 297, 297, 297, 297, 297, - 297, 81, 297, 297, 292, 292, 295, 292, 293, 313, 313, 313, 313, 294, 294, - 81, 81, 81, 81, 81, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 315, 315, 316, 316, 316, 316, 315, 316, 316, 316, 316, 316, 317, - 315, 318, 318, 315, 315, 316, 316, 314, 319, 319, 319, 319, 319, 319, - 319, 319, 319, 319, 320, 320, 321, 321, 321, 321, 314, 314, 314, 314, - 314, 314, 315, 315, 316, 316, 314, 314, 314, 314, 316, 316, 316, 314, - 315, 315, 315, 314, 314, 315, 315, 315, 315, 315, 315, 315, 314, 314, - 314, 316, 316, 316, 316, 314, 314, 314, 314, 314, 316, 315, 315, 316, - 316, 315, 315, 315, 315, 315, 315, 322, 314, 315, 319, 319, 315, 315, - 315, 316, 323, 323, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 81, 324, 81, 81, 81, 81, 81, 324, 81, 81, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 326, 327, 325, 325, 325, - 328, 328, 328, 328, 328, 328, 328, 328, 329, 329, 329, 329, 329, 329, - 329, 329, 330, 330, 330, 330, 330, 330, 330, 330, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 81, 331, 331, 331, 331, 81, 81, 331, 331, 331, - 331, 331, 331, 331, 81, 331, 331, 331, 81, 81, 332, 332, 332, 333, 334, - 333, 333, 333, 333, 333, 333, 333, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 81, 81, - 81, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 81, 81, 81, 81, 81, - 81, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 81, 81, 338, 338, 338, 338, 338, 338, 81, 81, 339, 340, 340, 340, 340, - 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, - 340, 340, 341, 341, 340, 342, 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 344, 345, 81, 81, 81, - 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 198, 198, 198, - 347, 347, 347, 346, 346, 346, 346, 346, 346, 346, 346, 81, 81, 81, 81, - 81, 81, 81, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, - 348, 81, 348, 348, 348, 348, 349, 349, 350, 81, 81, 81, 351, 351, 351, - 351, 351, 351, 351, 351, 351, 351, 352, 352, 353, 198, 198, 81, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 355, 355, 81, 81, 81, 81, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 81, 356, 356, - 356, 81, 357, 357, 81, 81, 81, 81, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 359, 359, 360, 359, 359, 359, 359, 359, 359, - 359, 360, 360, 360, 360, 360, 360, 360, 360, 359, 360, 360, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 361, 359, 362, 362, 363, 364, 362, - 365, 362, 366, 358, 367, 81, 81, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 81, 81, 81, 81, 81, 81, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 81, 81, 81, 81, 81, 81, 370, 370, 371, 371, 372, 373, 374, 370, - 375, 375, 370, 376, 376, 376, 377, 81, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 81, 81, 81, 81, 81, 81, 379, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 380, 379, 379, 379, 379, 379, 379, 379, 379, 379, - 376, 376, 379, 379, 381, 379, 81, 81, 81, 81, 81, 340, 340, 340, 340, - 340, 340, 81, 81, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 81, 383, 383, 383, 384, 384, 384, 384, 383, 383, 384, - 384, 384, 81, 81, 81, 81, 384, 384, 383, 384, 384, 384, 384, 384, 384, - 385, 386, 387, 81, 81, 81, 81, 388, 81, 81, 81, 389, 389, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 81, 81, 391, 391, 391, 391, 391, 81, - 81, 81, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 81, - 81, 81, 81, 392, 392, 81, 81, 81, 81, 81, 81, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 394, 81, 81, 81, 395, 395, 396, 396, 396, 396, - 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 398, 399, 400, 400, 401, 81, 81, 402, 402, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 404, 405, - 404, 405, 405, 405, 405, 405, 405, 405, 81, 406, 404, 405, 404, 404, 405, - 405, 405, 405, 405, 405, 405, 405, 404, 404, 404, 404, 404, 404, 405, - 405, 407, 407, 407, 407, 407, 407, 407, 407, 81, 81, 408, 409, 409, 409, - 409, 409, 409, 409, 409, 409, 409, 81, 81, 81, 81, 81, 81, 410, 410, 410, - 410, 410, 410, 410, 411, 410, 410, 410, 410, 410, 410, 81, 81, 96, 96, - 96, 96, 96, 156, 156, 156, 156, 156, 156, 96, 96, 156, 412, 81, 413, 413, - 413, 413, 414, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, - 415, 415, 415, 415, 416, 414, 413, 413, 413, 413, 413, 414, 413, 414, - 414, 414, 414, 414, 413, 414, 417, 415, 415, 415, 415, 415, 415, 415, 81, - 81, 81, 81, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 419, 419, - 420, 419, 419, 419, 419, 421, 421, 421, 421, 421, 421, 421, 421, 421, - 421, 422, 423, 422, 422, 422, 422, 422, 422, 422, 421, 421, 421, 421, - 421, 421, 421, 421, 421, 81, 81, 81, 424, 424, 425, 426, 426, 426, 426, - 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 425, 424, 424, 424, - 424, 425, 425, 424, 424, 427, 428, 424, 424, 426, 426, 429, 429, 429, - 429, 429, 429, 429, 429, 429, 429, 426, 426, 426, 426, 426, 426, 430, - 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 431, - 432, 433, 433, 432, 432, 432, 433, 432, 433, 433, 433, 434, 434, 81, 81, - 81, 81, 81, 81, 81, 81, 435, 435, 435, 435, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 437, 437, 437, 437, 437, 437, 437, 437, - 438, 438, 438, 438, 438, 438, 438, 438, 437, 437, 438, 439, 81, 81, 81, - 440, 440, 440, 440, 440, 441, 441, 441, 441, 441, 441, 441, 441, 441, - 441, 81, 81, 81, 436, 436, 436, 442, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, - 443, 443, 444, 444, 444, 444, 444, 444, 445, 445, 93, 81, 81, 81, 81, 81, - 81, 81, 446, 446, 446, 446, 446, 446, 446, 446, 96, 96, 96, 326, 447, - 156, 156, 156, 156, 156, 96, 96, 156, 156, 156, 156, 96, 448, 447, 447, - 447, 447, 447, 447, 447, 449, 449, 449, 449, 156, 449, 449, 449, 449, - 448, 448, 96, 449, 449, 448, 96, 96, 81, 81, 81, 81, 81, 81, 56, 56, 56, - 56, 56, 56, 79, 79, 79, 79, 79, 93, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 82, 82, 82, 82, 82, 59, 59, 59, 59, 82, 82, 82, 82, 82, 56, 56, 56, 56, - 56, 450, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 82, 96, 96, 156, 96, 96, 96, 96, 96, 96, 96, 156, - 96, 96, 451, 452, 156, 453, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 454, 455, 455, 156, 81, 96, 456, - 156, 96, 156, 52, 56, 52, 56, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 52, - 56, 79, 79, 79, 79, 79, 79, 79, 79, 78, 78, 78, 78, 78, 78, 78, 78, 79, - 79, 79, 79, 79, 79, 81, 81, 78, 78, 78, 78, 78, 78, 81, 81, 81, 78, 81, - 78, 81, 78, 81, 78, 457, 457, 457, 457, 457, 457, 457, 457, 79, 79, 79, - 79, 79, 81, 79, 79, 78, 78, 78, 78, 457, 80, 79, 80, 80, 80, 79, 79, 79, - 81, 79, 79, 78, 78, 78, 78, 457, 80, 80, 80, 79, 79, 79, 79, 81, 81, 79, - 79, 78, 78, 78, 78, 81, 80, 80, 80, 78, 78, 78, 78, 78, 80, 80, 80, 81, - 81, 79, 79, 79, 81, 79, 79, 78, 78, 78, 78, 457, 458, 80, 81, 459, 459, - 459, 459, 459, 459, 459, 460, 459, 459, 459, 461, 462, 463, 464, 465, - 466, 467, 468, 466, 469, 470, 38, 84, 471, 472, 473, 42, 471, 472, 473, - 42, 38, 38, 474, 84, 475, 475, 475, 476, 477, 478, 479, 480, 481, 482, - 483, 33, 484, 485, 484, 484, 485, 486, 487, 487, 84, 42, 50, 38, 488, - 488, 474, 489, 489, 84, 84, 84, 490, 473, 491, 488, 488, 488, 84, 84, 84, - 84, 84, 84, 84, 84, 492, 84, 489, 84, 373, 84, 373, 373, 373, 373, 84, - 373, 373, 459, 493, 494, 494, 494, 494, 81, 495, 496, 497, 498, 499, 499, - 499, 499, 499, 499, 500, 59, 81, 81, 47, 500, 500, 500, 500, 500, 501, - 501, 492, 473, 491, 502, 500, 47, 47, 47, 47, 500, 500, 500, 500, 500, - 501, 501, 492, 473, 491, 81, 59, 59, 59, 59, 59, 81, 81, 81, 278, 278, - 278, 278, 278, 278, 278, 503, 278, 504, 278, 278, 36, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 503, 278, 278, 278, 278, 503, 278, 278, 503, - 278, 505, 505, 505, 505, 505, 505, 505, 505, 96, 96, 447, 447, 96, 96, - 96, 96, 447, 447, 447, 96, 96, 412, 412, 412, 412, 96, 412, 412, 412, - 447, 447, 96, 156, 96, 447, 447, 156, 156, 156, 156, 96, 81, 81, 81, 81, - 81, 81, 81, 40, 40, 506, 507, 40, 508, 40, 506, 40, 507, 49, 506, 506, - 506, 49, 49, 506, 506, 506, 509, 40, 506, 510, 40, 492, 506, 506, 506, - 506, 506, 40, 40, 40, 508, 508, 40, 506, 40, 85, 40, 506, 40, 52, 511, - 506, 506, 512, 49, 506, 506, 52, 506, 49, 449, 449, 449, 449, 49, 40, 40, - 49, 49, 506, 506, 492, 492, 492, 492, 492, 506, 49, 49, 49, 49, 40, 492, - 40, 40, 56, 313, 513, 513, 513, 514, 51, 515, 513, 513, 513, 513, 513, - 51, 514, 514, 51, 513, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 517, 517, 517, 517, 516, 516, 517, 517, 517, 517, 517, 517, - 517, 517, 517, 52, 56, 517, 517, 517, 517, 51, 40, 40, 81, 81, 81, 81, - 54, 54, 54, 54, 54, 508, 508, 508, 508, 508, 492, 492, 40, 40, 40, 40, - 492, 40, 40, 492, 40, 40, 492, 40, 40, 40, 40, 40, 40, 40, 492, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 44, 44, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 492, 492, 40, 40, 54, 40, 54, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 44, 40, 40, 40, 40, 492, 492, 492, 492, 492, 492, 492, 492, 492, - 492, 492, 492, 54, 492, 54, 54, 492, 492, 492, 54, 54, 492, 492, 54, 492, - 492, 492, 54, 492, 54, 518, 519, 492, 54, 492, 492, 492, 492, 54, 492, - 492, 54, 54, 54, 54, 492, 492, 54, 492, 54, 492, 54, 54, 54, 54, 54, 54, - 492, 54, 492, 492, 492, 492, 492, 54, 54, 54, 54, 492, 492, 492, 492, 54, - 54, 492, 492, 54, 492, 492, 492, 54, 492, 492, 492, 492, 492, 54, 492, - 492, 492, 492, 492, 54, 54, 492, 492, 54, 54, 54, 54, 492, 492, 54, 54, - 492, 492, 54, 54, 492, 492, 492, 492, 492, 54, 492, 492, 492, 54, 492, - 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 54, 492, 492, - 492, 492, 492, 492, 492, 520, 473, 491, 473, 491, 40, 40, 40, 40, 40, 40, - 508, 40, 40, 40, 40, 40, 40, 40, 521, 521, 40, 40, 40, 40, 492, 492, 40, - 40, 40, 40, 40, 40, 40, 522, 523, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 40, - 492, 40, 40, 40, 40, 40, 40, 40, 40, 313, 40, 40, 40, 40, 40, 492, 492, - 492, 492, 492, 492, 492, 492, 492, 40, 40, 40, 40, 40, 524, 524, 524, - 524, 40, 40, 40, 521, 525, 525, 521, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 81, 40, 40, 40, 81, 81, 81, 81, 81, 51, 51, 51, 51, 51, 51, 51, - 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 526, 526, 526, 526, - 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 515, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 514, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 40, 40, 40, 40, 508, 508, 508, 508, 527, 40, 40, - 40, 40, 40, 508, 508, 508, 508, 40, 40, 508, 508, 40, 508, 508, 508, 508, - 508, 508, 508, 40, 40, 40, 40, 40, 40, 40, 40, 508, 508, 40, 40, 508, 54, - 40, 40, 40, 40, 508, 508, 40, 40, 508, 54, 40, 40, 40, 40, 508, 508, 508, - 40, 40, 508, 40, 40, 508, 508, 40, 40, 40, 40, 40, 40, 40, 508, 492, 492, - 492, 492, 492, 528, 528, 492, 525, 525, 525, 525, 40, 508, 508, 40, 40, - 508, 40, 40, 40, 40, 508, 508, 40, 40, 40, 40, 521, 521, 527, 527, 525, - 40, 525, 525, 529, 530, 529, 525, 40, 525, 525, 525, 40, 40, 40, 40, 508, - 40, 508, 40, 40, 40, 40, 40, 524, 524, 524, 524, 524, 524, 524, 524, 524, - 524, 524, 524, 40, 40, 40, 40, 508, 508, 40, 508, 508, 508, 40, 508, 529, - 508, 508, 40, 508, 508, 40, 54, 40, 40, 40, 40, 40, 40, 40, 521, 40, 40, - 40, 524, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 508, 508, 40, 524, 40, - 40, 40, 40, 40, 40, 40, 40, 524, 524, 313, 40, 40, 40, 40, 40, 40, 40, - 40, 521, 521, 529, 525, 525, 525, 525, 521, 521, 529, 529, 529, 508, 508, - 508, 508, 529, 524, 529, 529, 529, 508, 529, 521, 508, 508, 508, 529, - 529, 508, 508, 529, 508, 508, 529, 529, 529, 40, 508, 40, 40, 40, 40, - 508, 508, 521, 508, 508, 508, 508, 508, 508, 529, 521, 521, 529, 521, - 508, 529, 529, 531, 521, 508, 508, 521, 529, 529, 525, 525, 525, 525, - 525, 524, 40, 40, 525, 525, 532, 532, 530, 530, 40, 40, 524, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 40, 40, 40, 40, 40, 40, 524, 40, - 524, 40, 40, 40, 40, 524, 524, 524, 40, 533, 40, 40, 40, 534, 534, 534, - 534, 534, 534, 40, 535, 535, 525, 40, 40, 40, 473, 491, 473, 491, 473, - 491, 473, 491, 473, 491, 473, 491, 473, 491, 51, 51, 515, 515, 515, 515, - 515, 515, 515, 515, 515, 515, 515, 515, 40, 524, 524, 524, 40, 40, 40, - 40, 40, 40, 40, 524, 492, 492, 492, 492, 492, 473, 491, 492, 492, 492, - 492, 492, 492, 492, 16, 31, 16, 31, 16, 31, 16, 31, 473, 491, 536, 536, - 536, 536, 536, 536, 536, 536, 492, 492, 492, 473, 491, 16, 31, 473, 491, - 473, 491, 473, 491, 473, 491, 473, 491, 492, 492, 492, 492, 492, 492, - 492, 473, 491, 473, 491, 492, 492, 492, 492, 492, 492, 492, 492, 473, - 491, 492, 492, 40, 40, 40, 524, 524, 40, 40, 40, 492, 492, 492, 492, 492, - 40, 40, 492, 492, 492, 492, 492, 492, 40, 40, 40, 524, 40, 40, 40, 40, - 533, 508, 508, 40, 40, 40, 40, 81, 81, 40, 40, 40, 40, 40, 40, 40, 40, - 81, 81, 40, 40, 81, 81, 81, 40, 40, 40, 40, 81, 40, 40, 40, 40, 40, 40, - 81, 81, 81, 81, 40, 40, 40, 40, 537, 537, 537, 537, 537, 537, 537, 537, - 537, 537, 537, 537, 537, 537, 537, 81, 538, 538, 538, 538, 538, 538, 538, - 538, 538, 538, 538, 538, 538, 538, 538, 81, 52, 56, 52, 52, 52, 56, 56, - 52, 56, 52, 56, 52, 56, 52, 52, 52, 52, 56, 52, 56, 56, 52, 56, 56, 56, - 56, 56, 56, 59, 59, 52, 52, 87, 88, 87, 88, 88, 539, 539, 539, 539, 539, - 539, 87, 88, 87, 88, 540, 540, 540, 87, 88, 81, 81, 81, 81, 81, 541, 542, - 542, 542, 543, 541, 542, 544, 544, 544, 544, 544, 544, 544, 544, 544, - 544, 544, 544, 544, 544, 81, 544, 81, 81, 81, 81, 81, 544, 81, 81, 545, - 545, 545, 545, 545, 545, 545, 545, 81, 81, 81, 81, 81, 81, 81, 546, 547, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 548, 95, 95, 95, - 95, 95, 95, 95, 95, 549, 549, 42, 50, 42, 50, 549, 549, 549, 42, 50, 549, - 42, 50, 373, 373, 373, 373, 373, 373, 373, 373, 84, 468, 550, 373, 551, - 84, 42, 50, 84, 84, 42, 50, 473, 491, 473, 491, 473, 491, 473, 491, 373, - 373, 373, 373, 371, 60, 373, 373, 84, 373, 373, 84, 84, 84, 84, 84, 552, - 552, 373, 373, 373, 84, 468, 373, 473, 373, 373, 373, 373, 373, 373, 373, - 81, 81, 81, 81, 81, 81, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, - 81, 553, 553, 553, 553, 553, 553, 553, 553, 553, 81, 81, 81, 81, 553, - 553, 553, 553, 553, 553, 81, 81, 521, 521, 521, 521, 521, 521, 521, 521, - 521, 521, 521, 521, 81, 81, 81, 81, 554, 555, 555, 556, 521, 557, 558, - 559, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 521, 521, 522, - 523, 522, 523, 522, 523, 522, 523, 560, 522, 523, 523, 521, 559, 559, - 559, 559, 559, 559, 559, 559, 559, 561, 562, 563, 564, 565, 565, 566, - 567, 567, 567, 567, 568, 521, 521, 559, 559, 559, 557, 569, 556, 521, - 525, 81, 570, 571, 570, 571, 570, 571, 570, 571, 570, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 570, - 571, 571, 571, 571, 571, 571, 571, 570, 571, 570, 571, 570, 571, 571, - 571, 571, 571, 571, 570, 571, 571, 571, 571, 571, 571, 570, 570, 81, 81, - 572, 572, 573, 573, 574, 574, 571, 560, 575, 576, 575, 576, 575, 576, - 575, 576, 575, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, - 576, 576, 576, 576, 576, 576, 575, 576, 576, 576, 576, 576, 576, 576, - 575, 576, 575, 576, 575, 576, 576, 576, 576, 576, 576, 575, 576, 576, - 576, 576, 576, 576, 575, 575, 576, 576, 576, 576, 577, 578, 579, 579, - 576, 81, 81, 81, 81, 81, 580, 580, 580, 580, 580, 580, 580, 580, 580, - 580, 580, 580, 580, 580, 580, 580, 580, 580, 81, 81, 581, 581, 581, 581, - 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, - 581, 581, 581, 581, 81, 582, 582, 583, 583, 583, 583, 582, 582, 582, 582, - 582, 582, 582, 582, 582, 582, 580, 580, 580, 81, 81, 81, 81, 81, 575, - 575, 575, 575, 575, 575, 575, 575, 584, 584, 584, 584, 584, 584, 584, - 584, 584, 584, 584, 584, 584, 585, 585, 81, 583, 583, 583, 583, 583, 583, - 583, 583, 583, 583, 582, 582, 582, 582, 582, 582, 586, 586, 586, 586, - 586, 586, 586, 586, 521, 587, 587, 587, 587, 587, 587, 587, 587, 587, - 587, 587, 587, 587, 587, 587, 584, 584, 584, 584, 585, 585, 585, 582, - 582, 587, 587, 587, 587, 587, 587, 587, 582, 582, 582, 582, 521, 521, - 521, 521, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, - 588, 588, 588, 81, 582, 582, 582, 582, 582, 582, 582, 521, 521, 521, 521, - 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 521, 521, 589, - 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 590, - 590, 590, 590, 590, 590, 590, 590, 590, 590, 589, 589, 589, 590, 590, - 590, 590, 590, 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, - 591, 591, 592, 591, 591, 591, 591, 591, 591, 591, 81, 81, 81, 593, 593, - 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 81, 594, - 594, 594, 594, 594, 594, 594, 594, 595, 595, 595, 595, 595, 595, 596, - 596, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 598, - 599, 600, 599, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 597, - 597, 81, 81, 81, 81, 90, 93, 90, 93, 90, 93, 602, 95, 97, 97, 97, 603, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 603, 604, 90, 93, 90, 93, 450, - 450, 95, 95, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, - 605, 605, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 607, 607, - 608, 609, 609, 609, 609, 609, 62, 62, 62, 62, 62, 62, 62, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 62, 62, 52, 56, 52, 56, 52, 56, 56, 56, 52, 56, 52, - 56, 52, 56, 59, 56, 56, 56, 56, 56, 56, 56, 56, 52, 56, 52, 56, 52, 52, - 56, 60, 610, 610, 52, 56, 52, 56, 57, 52, 56, 52, 56, 56, 56, 52, 56, 52, - 56, 52, 52, 52, 52, 52, 81, 52, 52, 52, 52, 52, 56, 52, 56, 81, 81, 81, - 81, 81, 81, 81, 57, 59, 59, 56, 57, 57, 57, 57, 57, 611, 611, 612, 611, - 611, 611, 613, 611, 611, 611, 611, 612, 611, 611, 611, 611, 611, 611, - 611, 611, 611, 611, 611, 611, 611, 611, 611, 614, 614, 612, 612, 614, - 615, 615, 615, 615, 81, 81, 81, 81, 616, 616, 616, 616, 616, 616, 313, - 313, 503, 512, 81, 81, 81, 81, 81, 81, 617, 617, 617, 617, 617, 617, 617, - 617, 617, 617, 617, 617, 618, 618, 619, 619, 620, 620, 621, 621, 621, - 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, - 621, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, - 620, 620, 620, 622, 623, 81, 81, 81, 81, 81, 81, 81, 81, 624, 624, 625, - 625, 625, 625, 625, 625, 625, 625, 625, 625, 81, 81, 81, 81, 81, 81, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 194, 194, 194, 194, 194, - 194, 200, 200, 200, 194, 626, 194, 81, 81, 627, 627, 627, 627, 627, 627, - 627, 627, 627, 627, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, - 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 629, 629, 629, 629, - 629, 630, 630, 630, 198, 631, 632, 632, 632, 632, 632, 632, 632, 632, - 632, 632, 632, 632, 632, 632, 632, 633, 633, 633, 633, 633, 633, 633, - 633, 633, 633, 633, 634, 635, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 636, 328, 328, 328, 328, 328, 81, 81, 81, 637, 637, 637, 638, 639, 639, - 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 640, - 638, 638, 637, 637, 637, 637, 638, 638, 637, 638, 638, 638, 641, 642, - 642, 642, 642, 642, 642, 643, 643, 643, 642, 642, 642, 642, 81, 61, 644, - 644, 644, 644, 644, 644, 644, 644, 644, 644, 81, 81, 81, 81, 642, 642, - 314, 314, 314, 314, 314, 316, 645, 314, 319, 319, 314, 314, 314, 314, - 314, 81, 646, 646, 646, 646, 646, 646, 646, 646, 646, 647, 647, 647, 647, - 647, 647, 648, 648, 647, 647, 648, 648, 647, 647, 81, 646, 646, 646, 647, - 646, 646, 646, 646, 646, 646, 646, 646, 647, 648, 81, 81, 649, 649, 649, - 649, 649, 649, 649, 649, 649, 649, 81, 81, 650, 651, 651, 651, 645, 314, - 314, 314, 314, 314, 314, 323, 323, 323, 314, 315, 316, 315, 314, 314, - 652, 652, 652, 652, 652, 652, 652, 652, 653, 652, 653, 653, 654, 652, - 652, 653, 653, 652, 652, 652, 652, 652, 653, 653, 652, 653, 652, 81, 81, - 81, 81, 81, 81, 81, 81, 652, 652, 655, 656, 656, 657, 657, 657, 657, 657, - 657, 657, 657, 657, 657, 657, 658, 659, 659, 658, 658, 660, 660, 657, - 661, 661, 658, 662, 81, 81, 331, 331, 331, 331, 331, 331, 81, 56, 56, 56, - 610, 59, 59, 59, 59, 56, 56, 56, 56, 56, 79, 81, 81, 338, 338, 338, 338, - 338, 338, 338, 338, 657, 657, 657, 658, 658, 659, 658, 658, 659, 658, - 658, 660, 658, 662, 81, 81, 663, 663, 663, 663, 663, 663, 663, 663, 663, - 663, 81, 81, 81, 81, 81, 81, 664, 665, 665, 665, 665, 665, 665, 665, 665, - 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, 664, 665, 665, - 665, 665, 665, 665, 665, 81, 81, 81, 81, 329, 329, 329, 329, 329, 329, - 329, 81, 81, 81, 81, 330, 330, 330, 330, 330, 330, 330, 330, 330, 81, 81, - 81, 81, 666, 666, 666, 666, 666, 666, 666, 666, 667, 667, 667, 667, 667, - 667, 667, 667, 589, 589, 590, 590, 590, 590, 590, 590, 56, 56, 56, 56, - 56, 56, 56, 81, 81, 81, 81, 101, 101, 101, 101, 101, 81, 81, 81, 81, 81, - 129, 668, 129, 129, 669, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 81, 129, 129, 129, 129, 129, 81, 129, 81, 129, 129, - 81, 129, 129, 81, 129, 129, 146, 146, 670, 670, 670, 670, 670, 670, 670, - 670, 670, 670, 670, 670, 670, 670, 670, 670, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 491, 473, - 81, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 135, 138, 81, - 81, 671, 671, 671, 671, 671, 671, 671, 671, 672, 555, 555, 672, 672, 673, - 673, 522, 523, 674, 81, 81, 81, 81, 81, 81, 96, 96, 96, 96, 96, 96, 96, - 156, 156, 156, 156, 156, 156, 156, 95, 95, 556, 566, 566, 675, 675, 522, - 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, - 523, 556, 556, 522, 523, 556, 556, 556, 556, 675, 675, 675, 676, 556, - 676, 81, 577, 677, 673, 673, 566, 522, 523, 522, 523, 522, 523, 678, 556, - 556, 679, 680, 681, 681, 681, 81, 556, 682, 683, 556, 81, 81, 81, 81, - 146, 146, 146, 146, 146, 81, 81, 493, 81, 684, 685, 686, 687, 688, 685, - 685, 689, 690, 685, 691, 692, 693, 692, 694, 695, 695, 695, 695, 695, - 695, 695, 695, 695, 695, 696, 697, 698, 698, 698, 684, 685, 699, 699, - 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, - 699, 699, 689, 685, 690, 700, 701, 700, 702, 702, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 689, 698, - 690, 698, 689, 690, 703, 704, 705, 703, 706, 707, 708, 708, 708, 708, - 708, 708, 708, 708, 708, 709, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 710, - 710, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, - 711, 711, 81, 81, 81, 711, 711, 711, 711, 711, 711, 81, 81, 711, 711, - 711, 81, 81, 81, 712, 687, 698, 700, 713, 687, 687, 81, 714, 715, 715, - 715, 715, 714, 714, 81, 81, 716, 716, 716, 717, 508, 81, 81, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 81, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 81, 718, 718, 718, 81, 718, 718, 81, 718, - 718, 718, 718, 718, 718, 718, 81, 81, 718, 718, 718, 81, 81, 81, 81, 81, - 198, 373, 198, 81, 81, 81, 81, 616, 616, 616, 616, 616, 616, 616, 616, - 616, 616, 616, 616, 616, 81, 81, 81, 313, 719, 719, 719, 719, 719, 719, - 719, 719, 719, 719, 719, 719, 719, 720, 720, 720, 720, 721, 721, 721, - 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, - 720, 720, 721, 722, 722, 81, 40, 40, 40, 40, 81, 81, 81, 81, 721, 81, 81, - 81, 81, 81, 81, 81, 313, 313, 313, 313, 313, 156, 81, 81, 723, 723, 723, - 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 81, 81, 81, 724, 724, - 724, 724, 724, 724, 724, 724, 724, 81, 81, 81, 81, 81, 81, 81, 156, 500, - 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, - 500, 500, 500, 500, 81, 81, 81, 81, 725, 725, 725, 725, 725, 725, 725, - 725, 726, 726, 726, 726, 81, 81, 81, 81, 81, 81, 81, 81, 81, 725, 725, - 725, 727, 727, 727, 727, 727, 727, 727, 727, 727, 728, 727, 727, 727, - 727, 727, 727, 727, 727, 728, 81, 81, 81, 81, 81, 729, 729, 729, 729, - 729, 729, 729, 729, 729, 729, 729, 729, 729, 729, 730, 730, 730, 730, - 730, 81, 81, 81, 81, 81, 731, 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 81, 732, 733, 733, 733, 733, 733, 733, 733, 733, - 733, 733, 733, 733, 81, 81, 81, 81, 734, 735, 735, 735, 735, 735, 81, 81, - 736, 736, 736, 736, 736, 736, 736, 736, 737, 737, 737, 737, 737, 737, - 737, 737, 738, 738, 738, 738, 738, 738, 738, 738, 739, 739, 739, 739, - 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 81, 81, 740, 740, 740, - 740, 740, 740, 740, 740, 740, 740, 81, 81, 81, 81, 81, 81, 741, 741, 741, - 741, 741, 741, 741, 741, 741, 741, 741, 741, 81, 81, 81, 81, 742, 742, - 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 81, 81, 81, 81, 743, - 743, 743, 743, 743, 743, 743, 743, 744, 744, 744, 744, 744, 744, 744, - 744, 744, 744, 744, 744, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 745, - 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, - 746, 81, 746, 746, 746, 746, 746, 746, 81, 81, 747, 747, 747, 747, 747, - 747, 81, 81, 747, 81, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, - 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 81, 747, 747, 81, 81, - 81, 747, 81, 81, 747, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, - 748, 748, 748, 748, 81, 749, 750, 750, 750, 750, 750, 750, 750, 750, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, - 752, 752, 753, 753, 753, 753, 753, 753, 753, 754, 754, 754, 754, 754, - 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 81, 81, 81, 81, 81, 81, - 81, 81, 755, 755, 755, 755, 755, 755, 755, 755, 755, 756, 756, 756, 756, - 756, 756, 756, 756, 756, 756, 756, 81, 756, 756, 81, 81, 81, 81, 81, 757, - 757, 757, 757, 757, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, - 758, 758, 758, 758, 759, 759, 759, 759, 759, 759, 81, 81, 81, 760, 761, - 761, 761, 761, 761, 761, 761, 761, 761, 761, 81, 81, 81, 81, 81, 762, - 763, 763, 763, 763, 763, 763, 763, 763, 764, 764, 764, 764, 764, 764, - 764, 764, 81, 81, 81, 81, 765, 765, 764, 764, 765, 765, 765, 765, 765, - 765, 765, 765, 81, 81, 765, 765, 765, 765, 765, 765, 766, 767, 767, 767, - 81, 767, 767, 81, 81, 81, 81, 81, 767, 768, 767, 769, 766, 766, 766, 766, - 81, 766, 766, 766, 81, 766, 766, 766, 766, 766, 766, 766, 766, 766, 766, - 766, 766, 766, 766, 766, 766, 766, 766, 766, 81, 81, 81, 81, 769, 770, - 768, 81, 81, 81, 81, 771, 772, 772, 772, 772, 772, 772, 772, 772, 773, - 773, 773, 773, 773, 773, 773, 773, 774, 81, 81, 81, 81, 81, 81, 81, 775, - 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 776, 776, - 777, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 779, 779, 779, 780, 780, 780, 780, 780, 780, 780, 780, 781, 780, 780, - 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 782, 783, 81, 81, 81, - 81, 784, 784, 784, 784, 784, 785, 785, 785, 785, 785, 785, 786, 81, 787, - 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 81, 81, - 81, 788, 788, 788, 788, 788, 788, 788, 789, 789, 789, 789, 789, 789, 789, - 789, 789, 789, 789, 789, 789, 789, 81, 81, 790, 790, 790, 790, 790, 790, - 790, 790, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 81, 81, - 81, 81, 81, 792, 792, 792, 792, 792, 792, 792, 792, 793, 793, 793, 793, - 793, 793, 793, 793, 793, 793, 81, 81, 81, 81, 81, 81, 81, 794, 794, 794, - 794, 81, 81, 81, 81, 795, 795, 795, 795, 795, 795, 795, 796, 796, 796, + 81, 99, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 102, 103, 81, 81, 104, 104, 105, 81, 106, 107, 107, 107, 107, + 106, 107, 107, 107, 108, 106, 107, 107, 107, 107, 107, 107, 106, 106, + 106, 106, 106, 106, 107, 107, 106, 107, 107, 108, 109, 107, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 125, 107, 106, 128, 118, 81, 81, 81, 81, 81, 81, 81, 81, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 81, 81, 81, 81, + 129, 129, 129, 129, 125, 125, 81, 81, 81, 130, 130, 130, 130, 130, 131, + 132, 132, 133, 134, 134, 135, 136, 137, 138, 138, 139, 139, 139, 139, + 139, 139, 139, 139, 140, 141, 142, 143, 144, 81, 145, 143, 146, 146, 146, + 146, 146, 146, 146, 146, 147, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 148, 149, 150, 151, 152, 153, 154, 155, 96, 96, 156, 157, 139, + 139, 139, 139, 139, 157, 139, 139, 157, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 134, 159, 159, 160, 146, 146, 161, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 145, 146, 139, 139, 139, 139, + 139, 139, 139, 131, 138, 139, 139, 139, 139, 157, 139, 162, 162, 139, + 139, 138, 157, 139, 139, 157, 146, 146, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 146, 146, 146, 164, 164, 146, 165, 165, 165, 165, + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 81, 166, 167, 168, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 169, + 170, 169, 169, 170, 169, 169, 170, 170, 170, 169, 170, 170, 169, 170, + 169, 169, 169, 170, 169, 170, 169, 170, 169, 170, 169, 169, 81, 81, 167, + 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 171, 81, + 81, 81, 81, 81, 81, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 175, 175, 175, 175, 175, 175, 175, 176, 175, 177, 177, + 178, 179, 180, 181, 177, 81, 81, 176, 182, 182, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 184, 184, 184, 185, + 184, 184, 184, 184, 184, 184, 184, 184, 184, 185, 184, 184, 184, 185, + 184, 184, 184, 184, 184, 81, 81, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 81, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 188, 188, 188, 81, 81, 189, 81, 167, 167, 167, 81, 81, 81, 81, + 81, 146, 146, 146, 146, 146, 81, 146, 146, 146, 146, 146, 146, 146, 146, + 81, 81, 81, 81, 81, 157, 139, 139, 139, 139, 139, 139, 131, 157, 139, + 139, 157, 139, 139, 157, 139, 139, 139, 157, 157, 157, 190, 191, 192, + 139, 139, 139, 157, 139, 139, 157, 157, 139, 139, 139, 139, 139, 193, + 193, 193, 194, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 193, 194, 196, 195, 194, 194, 194, 193, 193, 193, 193, + 193, 193, 193, 193, 194, 194, 194, 194, 197, 194, 194, 195, 96, 156, 198, + 198, 193, 193, 193, 195, 195, 193, 193, 199, 199, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 201, 202, 195, 195, 195, 195, 195, 195, + 203, 204, 205, 205, 81, 203, 203, 203, 203, 203, 203, 203, 203, 81, 81, + 203, 203, 81, 81, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 81, 203, 203, 203, 203, 203, 203, 203, 81, 203, 81, 81, + 81, 203, 203, 203, 203, 81, 81, 206, 203, 205, 205, 205, 204, 204, 204, + 204, 81, 81, 205, 205, 81, 81, 205, 205, 207, 203, 81, 81, 81, 81, 81, + 81, 81, 81, 205, 81, 81, 81, 81, 203, 203, 81, 203, 203, 203, 204, 204, + 81, 81, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 203, 203, 209, + 209, 210, 210, 210, 210, 210, 211, 212, 213, 203, 214, 215, 81, 81, 216, + 216, 217, 81, 218, 218, 218, 218, 218, 218, 81, 81, 81, 81, 218, 218, 81, + 81, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 81, 218, 218, 218, 218, 218, 218, 218, 81, 218, 218, 81, 218, 218, 81, + 218, 218, 81, 81, 219, 81, 217, 217, 217, 216, 216, 81, 81, 81, 81, 216, + 216, 81, 81, 216, 216, 220, 81, 81, 81, 216, 81, 81, 81, 81, 81, 81, 81, + 218, 218, 218, 218, 81, 218, 81, 81, 81, 81, 81, 81, 81, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 216, 216, 218, 218, 218, 216, 222, 81, + 81, 223, 223, 224, 81, 225, 225, 225, 225, 225, 225, 225, 225, 225, 81, + 225, 225, 225, 81, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 81, 225, 225, 225, 225, 225, 225, 225, 81, 225, 225, 81, + 225, 225, 225, 225, 225, 81, 81, 226, 225, 224, 224, 224, 223, 223, 223, + 223, 223, 81, 223, 223, 224, 81, 224, 224, 227, 81, 81, 225, 81, 81, 81, + 81, 81, 81, 81, 225, 225, 223, 223, 81, 81, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 229, 230, 81, 81, 81, 81, 81, 81, 81, 225, 223, 223, + 223, 223, 223, 223, 81, 231, 232, 232, 81, 233, 233, 233, 233, 233, 233, + 233, 233, 81, 81, 233, 233, 81, 81, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 81, 233, 233, 233, 233, 233, 233, 233, + 81, 233, 233, 81, 233, 233, 233, 233, 233, 81, 81, 234, 233, 232, 231, + 232, 231, 231, 231, 231, 81, 81, 232, 232, 81, 81, 232, 232, 235, 81, 81, + 81, 81, 81, 81, 81, 81, 231, 232, 81, 81, 81, 81, 233, 233, 81, 233, 233, + 233, 231, 231, 81, 81, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 237, 233, 238, 238, 238, 238, 238, 238, 81, 81, 239, 240, 81, 240, 240, + 240, 240, 240, 240, 81, 81, 81, 240, 240, 240, 81, 240, 240, 240, 240, + 81, 81, 81, 240, 240, 81, 240, 81, 240, 240, 81, 81, 81, 240, 240, 81, + 81, 81, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 81, 81, 81, 81, + 241, 241, 239, 241, 241, 81, 81, 81, 241, 241, 241, 81, 241, 241, 241, + 242, 81, 81, 240, 81, 81, 81, 81, 81, 81, 241, 81, 81, 81, 81, 81, 81, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 244, 244, 244, 245, + 245, 245, 245, 245, 245, 246, 245, 81, 81, 81, 81, 81, 247, 248, 248, + 248, 247, 249, 249, 249, 249, 249, 249, 249, 249, 81, 249, 249, 249, 81, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 81, 81, 81, 249, 247, 247, 247, 248, 248, 248, 248, 81, 247, + 247, 247, 81, 247, 247, 247, 250, 81, 81, 81, 81, 81, 81, 81, 251, 252, + 81, 249, 249, 249, 81, 81, 81, 81, 81, 249, 249, 247, 247, 81, 81, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, + 254, 254, 255, 256, 257, 258, 258, 259, 256, 256, 256, 256, 256, 256, + 256, 256, 81, 256, 256, 256, 81, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 81, 256, 256, 256, 256, + 256, 81, 81, 260, 256, 258, 261, 258, 258, 258, 258, 258, 81, 261, 258, + 258, 81, 258, 258, 257, 262, 81, 81, 81, 81, 81, 81, 81, 258, 258, 81, + 81, 81, 81, 81, 81, 81, 256, 81, 256, 256, 257, 257, 81, 81, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 81, 256, 256, 81, 81, 81, 81, 81, + 264, 264, 265, 265, 81, 266, 266, 266, 266, 266, 266, 266, 266, 81, 266, + 266, 266, 81, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 267, 267, 266, 265, 265, 265, 264, 264, 264, + 264, 81, 265, 265, 265, 81, 265, 265, 265, 267, 266, 268, 81, 81, 81, 81, + 266, 266, 266, 265, 269, 269, 269, 269, 269, 269, 269, 266, 266, 266, + 264, 264, 81, 81, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 271, 266, 266, 266, 266, 266, + 266, 81, 81, 272, 272, 81, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 81, 81, 81, 273, 273, 273, + 273, 273, 273, 273, 273, 81, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 81, 273, 81, 81, 81, 81, 274, 81, 81, 81, 81, 272, 272, 272, 275, 275, + 275, 81, 275, 81, 272, 272, 272, 272, 272, 272, 272, 272, 81, 81, 81, 81, + 81, 81, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 81, 81, 272, + 272, 277, 81, 81, 81, 81, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 279, 278, 278, 279, 279, 279, 279, + 280, 280, 281, 81, 81, 81, 81, 282, 278, 278, 278, 278, 278, 278, 283, + 279, 284, 284, 284, 284, 279, 279, 279, 285, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 287, 287, 81, 81, 81, 81, 81, 288, 288, 81, 288, + 81, 81, 288, 288, 81, 288, 81, 81, 288, 81, 81, 81, 81, 81, 81, 288, 288, + 288, 288, 81, 288, 288, 288, 288, 288, 288, 288, 81, 288, 288, 288, 81, + 288, 81, 288, 81, 81, 288, 288, 81, 288, 288, 288, 288, 289, 288, 288, + 289, 289, 289, 289, 290, 290, 81, 289, 289, 288, 81, 81, 288, 288, 288, + 288, 288, 81, 291, 81, 292, 292, 292, 292, 289, 289, 81, 81, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 81, 81, 288, 288, 288, 288, 294, + 295, 295, 295, 296, 297, 296, 296, 298, 296, 296, 299, 298, 300, 300, + 300, 300, 300, 298, 301, 300, 301, 301, 301, 302, 302, 301, 301, 301, + 301, 301, 301, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 305, 302, 301, 302, 301, + 306, 307, 308, 307, 308, 309, 309, 294, 294, 294, 294, 294, 294, 294, + 294, 81, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 81, + 81, 81, 81, 310, 311, 312, 313, 312, 312, 312, 312, 312, 311, 311, 311, + 311, 312, 314, 311, 312, 315, 315, 316, 299, 315, 315, 294, 294, 294, + 294, 294, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 81, 312, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 81, 305, 305, 301, + 301, 301, 301, 301, 301, 302, 301, 301, 301, 301, 301, 301, 81, 301, 301, + 296, 296, 299, 296, 297, 317, 317, 317, 317, 298, 298, 81, 81, 81, 81, + 81, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 319, 319, 320, + 320, 320, 320, 319, 320, 320, 320, 320, 320, 321, 319, 322, 322, 319, + 319, 320, 320, 318, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, + 324, 324, 325, 325, 325, 325, 318, 318, 318, 318, 318, 318, 319, 319, + 320, 320, 318, 318, 318, 318, 320, 320, 320, 318, 319, 319, 319, 318, + 318, 319, 319, 319, 319, 319, 319, 319, 318, 318, 318, 320, 320, 320, + 320, 318, 318, 318, 318, 318, 320, 319, 319, 320, 320, 319, 319, 319, + 319, 319, 319, 326, 318, 319, 323, 323, 319, 319, 319, 320, 327, 327, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 81, + 328, 81, 81, 81, 81, 81, 328, 81, 81, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 330, 331, 329, 329, 329, 332, 332, 332, 332, 332, + 332, 332, 332, 333, 333, 333, 333, 333, 333, 333, 333, 334, 334, 334, + 334, 334, 334, 334, 334, 335, 335, 335, 335, 335, 335, 335, 335, 335, 81, + 335, 335, 335, 335, 81, 81, 335, 335, 335, 335, 335, 335, 335, 81, 335, + 335, 335, 81, 81, 336, 336, 336, 337, 338, 337, 337, 337, 337, 337, 337, + 337, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 81, 81, 81, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 81, 81, 81, 81, 81, 81, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 341, 81, 81, 342, 342, 342, 342, + 342, 342, 81, 81, 343, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 345, 345, 344, 346, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 348, 349, 81, 81, 81, 350, 350, 350, 350, 350, 350, + 350, 350, 350, 350, 350, 199, 199, 199, 351, 351, 351, 350, 350, 350, + 350, 350, 350, 350, 350, 81, 81, 81, 81, 81, 81, 81, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 81, 352, 352, 352, 352, 353, + 353, 354, 81, 81, 81, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 356, 356, 357, 199, 199, 81, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 359, 359, 81, 81, 81, 81, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 81, 360, 360, 360, 81, 361, 361, 81, 81, 81, 81, + 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 363, 363, + 364, 363, 363, 363, 363, 363, 363, 363, 364, 364, 364, 364, 364, 364, + 364, 364, 363, 364, 364, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 365, 363, 366, 366, 367, 368, 366, 369, 366, 370, 362, 371, 81, 81, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 81, 81, 81, 81, 81, 81, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 81, 81, 81, 81, 81, 81, 374, + 374, 375, 375, 376, 377, 378, 374, 379, 379, 374, 380, 380, 380, 381, 81, + 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 81, 81, 81, 81, 81, 81, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 384, 383, 383, + 383, 383, 383, 81, 81, 81, 81, 81, 81, 81, 383, 383, 383, 383, 383, 380, + 380, 383, 383, 385, 383, 81, 81, 81, 81, 81, 344, 344, 344, 344, 344, + 344, 81, 81, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 81, 387, 387, 387, 388, 388, 388, 388, 387, 387, 388, 388, + 388, 81, 81, 81, 81, 388, 388, 387, 388, 388, 388, 388, 388, 388, 389, + 390, 391, 81, 81, 81, 81, 392, 81, 81, 81, 393, 393, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 81, 81, 395, 395, 395, 395, 395, 81, 81, + 81, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 81, 81, + 81, 81, 396, 396, 81, 81, 81, 81, 81, 81, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 398, 81, 81, 81, 399, 399, 400, 400, 400, 400, 400, + 400, 400, 400, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 402, 403, 404, 404, 405, 81, 81, 406, 406, 407, 407, + 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 408, 409, 408, + 409, 409, 409, 409, 409, 409, 409, 81, 410, 408, 409, 408, 408, 409, 409, + 409, 409, 409, 409, 409, 409, 408, 408, 408, 408, 408, 408, 409, 409, + 411, 411, 411, 411, 411, 411, 411, 411, 81, 81, 412, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 81, 81, 81, 81, 81, 81, 414, 414, 414, 414, + 414, 414, 414, 415, 414, 414, 414, 414, 414, 414, 81, 81, 96, 96, 96, 96, + 96, 156, 156, 156, 156, 156, 156, 96, 96, 156, 416, 81, 417, 417, 417, + 417, 418, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, + 419, 419, 419, 420, 418, 417, 417, 417, 417, 417, 418, 417, 418, 418, + 418, 418, 418, 417, 418, 421, 419, 419, 419, 419, 419, 419, 419, 81, 81, + 81, 81, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 423, 423, 424, + 423, 423, 423, 423, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 426, 427, 426, 426, 426, 426, 426, 426, 426, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 81, 81, 81, 428, 428, 429, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 429, 428, 428, 428, 428, + 429, 429, 428, 428, 431, 432, 428, 428, 430, 430, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 430, 430, 430, 430, 430, 430, 434, 434, + 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 435, 436, + 437, 437, 436, 436, 436, 437, 436, 437, 437, 437, 438, 438, 81, 81, 81, + 81, 81, 81, 81, 81, 439, 439, 439, 439, 440, 440, 440, 440, 440, 440, + 440, 440, 440, 440, 440, 440, 441, 441, 441, 441, 441, 441, 441, 441, + 442, 442, 442, 442, 442, 442, 442, 442, 441, 441, 442, 443, 81, 81, 81, + 444, 444, 444, 444, 444, 445, 445, 445, 445, 445, 445, 445, 445, 445, + 445, 81, 81, 81, 440, 440, 440, 446, 446, 446, 446, 446, 446, 446, 446, + 446, 446, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 448, 448, 448, 448, 448, 448, 449, 449, 93, 81, 81, 81, 81, 81, + 81, 81, 328, 328, 328, 81, 81, 328, 328, 328, 450, 450, 450, 450, 450, + 450, 450, 450, 96, 96, 96, 330, 451, 156, 156, 156, 156, 156, 96, 96, + 156, 156, 156, 156, 96, 452, 451, 451, 451, 451, 451, 451, 451, 453, 453, + 453, 453, 156, 453, 453, 453, 453, 452, 452, 96, 453, 453, 452, 96, 96, + 81, 81, 81, 81, 81, 81, 56, 56, 56, 56, 56, 56, 79, 79, 79, 79, 79, 93, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 82, 82, 82, 82, 82, 59, 59, 59, 59, + 82, 82, 82, 82, 82, 56, 56, 56, 56, 56, 454, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 82, 96, 96, + 156, 96, 96, 96, 96, 96, 96, 96, 156, 96, 96, 455, 456, 156, 457, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 458, 459, 459, 156, 81, 96, 460, 156, 96, 156, 52, 56, 52, 56, 52, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 52, 56, 79, 79, 79, 79, 79, 79, 79, + 79, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 81, 81, 78, + 78, 78, 78, 78, 78, 81, 81, 81, 78, 81, 78, 81, 78, 81, 78, 461, 461, + 461, 461, 461, 461, 461, 461, 79, 79, 79, 79, 79, 81, 79, 79, 78, 78, 78, + 78, 461, 80, 79, 80, 80, 80, 79, 79, 79, 81, 79, 79, 78, 78, 78, 78, 461, + 80, 80, 80, 79, 79, 79, 79, 81, 81, 79, 79, 78, 78, 78, 78, 81, 80, 80, + 80, 78, 78, 78, 78, 78, 80, 80, 80, 81, 81, 79, 79, 79, 81, 79, 79, 78, + 78, 78, 78, 461, 462, 80, 81, 463, 463, 463, 463, 463, 463, 463, 464, + 463, 463, 463, 465, 466, 467, 468, 469, 470, 471, 472, 470, 473, 474, 38, + 84, 475, 476, 477, 42, 475, 476, 477, 42, 38, 38, 478, 84, 479, 479, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 33, 488, 489, 488, 488, 489, 490, + 491, 491, 84, 42, 50, 38, 492, 492, 478, 493, 493, 84, 84, 84, 494, 477, + 495, 492, 492, 492, 84, 84, 84, 84, 84, 84, 84, 84, 496, 84, 493, 84, + 377, 84, 377, 377, 377, 377, 84, 377, 377, 463, 497, 498, 498, 498, 498, + 81, 499, 500, 501, 502, 503, 503, 503, 503, 503, 503, 504, 59, 81, 81, + 47, 504, 504, 504, 504, 504, 505, 505, 496, 477, 495, 506, 504, 47, 47, + 47, 47, 504, 504, 504, 504, 504, 505, 505, 496, 477, 495, 81, 59, 59, 59, + 59, 59, 81, 81, 81, 282, 282, 282, 282, 282, 282, 282, 507, 282, 508, + 282, 282, 36, 282, 282, 282, 282, 282, 282, 282, 282, 282, 507, 282, 282, + 282, 282, 507, 282, 282, 507, 282, 509, 509, 509, 509, 509, 509, 509, + 509, 96, 96, 451, 451, 96, 96, 96, 96, 451, 451, 451, 96, 96, 416, 416, + 416, 416, 96, 416, 416, 416, 451, 451, 96, 156, 96, 451, 451, 156, 156, + 156, 156, 96, 81, 81, 81, 81, 81, 81, 81, 40, 40, 510, 511, 40, 512, 40, + 510, 40, 511, 49, 510, 510, 510, 49, 49, 510, 510, 510, 513, 40, 510, + 514, 40, 496, 510, 510, 510, 510, 510, 40, 40, 40, 512, 512, 40, 510, 40, + 85, 40, 510, 40, 52, 515, 510, 510, 516, 49, 510, 510, 52, 510, 49, 453, + 453, 453, 453, 49, 40, 40, 49, 49, 510, 510, 496, 496, 496, 496, 496, + 510, 49, 49, 49, 49, 40, 496, 40, 40, 56, 317, 517, 517, 517, 518, 51, + 519, 517, 517, 517, 517, 517, 51, 518, 518, 51, 517, 520, 520, 520, 520, + 520, 520, 520, 520, 520, 520, 520, 520, 521, 521, 521, 521, 520, 520, + 521, 521, 521, 521, 521, 521, 521, 521, 521, 52, 56, 521, 521, 521, 521, + 51, 40, 40, 81, 81, 81, 81, 54, 54, 54, 54, 54, 512, 512, 512, 512, 512, + 496, 496, 40, 40, 40, 40, 496, 40, 40, 496, 40, 40, 496, 40, 40, 40, 40, + 40, 40, 40, 496, 40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 44, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 496, 496, 40, 40, 54, 40, 54, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 44, 40, 40, 40, 40, 496, 496, 496, 496, + 496, 496, 496, 496, 496, 496, 496, 496, 54, 496, 54, 54, 496, 496, 496, + 54, 54, 496, 496, 54, 496, 496, 496, 54, 496, 54, 522, 523, 496, 54, 496, + 496, 496, 496, 54, 496, 496, 54, 54, 54, 54, 496, 496, 54, 496, 54, 496, + 54, 54, 54, 54, 54, 54, 496, 54, 496, 496, 496, 496, 496, 54, 54, 54, 54, + 496, 496, 496, 496, 54, 54, 496, 496, 54, 496, 496, 496, 54, 496, 496, + 496, 496, 496, 54, 496, 496, 496, 496, 496, 54, 54, 496, 496, 54, 54, 54, + 54, 496, 496, 54, 54, 496, 496, 54, 54, 496, 496, 496, 496, 496, 54, 496, + 496, 496, 54, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 496, 54, 496, 496, 496, 496, 496, 496, 496, 524, 477, 495, 477, 495, 40, + 40, 40, 40, 40, 40, 512, 40, 40, 40, 40, 40, 40, 40, 525, 525, 40, 40, + 40, 40, 496, 496, 40, 40, 40, 40, 40, 40, 40, 526, 527, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 40, 496, 40, 40, 40, 40, 40, 40, 40, 40, 317, 40, 40, + 40, 40, 40, 496, 496, 496, 496, 496, 496, 496, 496, 496, 40, 40, 40, 40, + 40, 528, 528, 528, 528, 40, 40, 40, 525, 529, 529, 525, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 81, 40, 40, 40, 81, 81, 81, 81, 81, 51, 51, + 51, 51, 51, 51, 51, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, + 519, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 518, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 40, 40, 40, 40, 512, 512, + 512, 512, 531, 40, 40, 40, 40, 40, 512, 512, 512, 512, 40, 40, 512, 512, + 40, 512, 512, 512, 512, 512, 512, 512, 40, 40, 40, 40, 40, 40, 40, 40, + 512, 512, 40, 40, 512, 54, 40, 40, 40, 40, 512, 512, 40, 40, 512, 54, 40, + 40, 40, 40, 512, 512, 512, 40, 40, 512, 40, 40, 512, 512, 40, 40, 40, 40, + 40, 40, 40, 512, 496, 496, 496, 496, 496, 532, 532, 496, 529, 529, 529, + 529, 40, 512, 512, 40, 40, 512, 40, 40, 40, 40, 512, 512, 40, 40, 40, 40, + 525, 525, 531, 531, 529, 40, 529, 529, 533, 534, 533, 529, 40, 529, 529, + 529, 40, 40, 40, 40, 512, 40, 512, 40, 40, 40, 40, 40, 528, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 528, 528, 40, 40, 40, 40, 512, 512, + 40, 512, 512, 512, 40, 512, 533, 512, 512, 40, 512, 512, 40, 54, 40, 40, + 40, 40, 40, 40, 40, 525, 40, 40, 40, 528, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 512, 512, 40, 528, 40, 40, 40, 40, 40, 40, 40, 40, 528, 528, 317, + 40, 40, 40, 40, 40, 40, 40, 40, 525, 525, 533, 529, 529, 529, 529, 525, + 525, 533, 533, 533, 512, 512, 512, 512, 533, 528, 533, 533, 533, 512, + 533, 525, 512, 512, 512, 533, 533, 512, 512, 533, 512, 512, 533, 533, + 533, 40, 512, 40, 40, 40, 40, 512, 512, 525, 512, 512, 512, 512, 512, + 512, 533, 525, 525, 533, 525, 512, 533, 533, 535, 525, 512, 512, 525, + 533, 533, 529, 529, 529, 529, 529, 528, 40, 40, 529, 529, 536, 536, 534, + 534, 40, 40, 528, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 40, + 40, 40, 40, 40, 40, 528, 40, 528, 40, 40, 40, 40, 528, 528, 528, 40, 537, + 40, 40, 40, 538, 538, 538, 538, 538, 538, 40, 539, 539, 529, 40, 40, 40, + 477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 51, + 51, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, 40, 528, + 528, 528, 40, 40, 40, 40, 40, 40, 40, 528, 496, 496, 496, 496, 496, 477, + 495, 496, 496, 496, 496, 496, 496, 496, 16, 31, 16, 31, 16, 31, 16, 31, + 477, 495, 540, 540, 540, 540, 540, 540, 540, 540, 496, 496, 496, 477, + 495, 16, 31, 477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 496, 496, + 496, 496, 496, 496, 496, 477, 495, 477, 495, 496, 496, 496, 496, 496, + 496, 496, 496, 477, 495, 496, 496, 40, 40, 40, 528, 528, 40, 40, 40, 496, + 496, 496, 496, 496, 40, 40, 496, 496, 496, 496, 496, 496, 40, 40, 40, + 528, 40, 40, 40, 40, 537, 512, 512, 40, 40, 40, 40, 81, 81, 40, 40, 40, + 40, 40, 40, 40, 40, 81, 81, 40, 81, 40, 40, 40, 40, 40, 40, 541, 541, + 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 81, 542, + 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 81, + 52, 56, 52, 52, 52, 56, 56, 52, 56, 52, 56, 52, 56, 52, 52, 52, 52, 56, + 52, 56, 56, 52, 56, 56, 56, 56, 56, 56, 59, 59, 52, 52, 87, 88, 87, 88, + 88, 543, 543, 543, 543, 543, 543, 87, 88, 87, 88, 544, 544, 544, 87, 88, + 81, 81, 81, 81, 81, 545, 546, 546, 546, 547, 545, 546, 329, 329, 329, + 329, 329, 329, 81, 329, 81, 81, 81, 81, 81, 329, 81, 81, 548, 548, 548, + 548, 548, 548, 548, 548, 81, 81, 81, 81, 81, 81, 81, 549, 550, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 551, 95, 95, 95, 95, 95, + 95, 95, 95, 552, 552, 42, 50, 42, 50, 552, 552, 552, 42, 50, 552, 42, 50, + 377, 377, 377, 377, 377, 377, 377, 377, 84, 472, 553, 377, 554, 84, 42, + 50, 84, 84, 42, 50, 477, 495, 477, 495, 477, 495, 477, 495, 377, 377, + 377, 377, 375, 60, 377, 377, 84, 377, 377, 84, 84, 84, 84, 84, 555, 555, + 377, 377, 377, 84, 472, 377, 477, 377, 377, 377, 377, 377, 377, 377, 377, + 84, 377, 84, 377, 81, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, + 81, 556, 556, 556, 556, 556, 556, 556, 556, 556, 81, 81, 81, 81, 556, + 556, 556, 556, 556, 556, 81, 81, 525, 525, 525, 525, 525, 525, 525, 525, + 525, 525, 525, 525, 81, 81, 81, 81, 557, 558, 558, 559, 525, 560, 561, + 562, 526, 527, 526, 527, 526, 527, 526, 527, 526, 527, 525, 525, 526, + 527, 526, 527, 526, 527, 526, 527, 563, 526, 527, 527, 525, 562, 562, + 562, 562, 562, 562, 562, 562, 562, 564, 565, 566, 567, 568, 568, 569, + 570, 570, 570, 570, 571, 525, 525, 562, 562, 562, 560, 572, 559, 525, + 529, 81, 573, 574, 573, 574, 573, 574, 573, 574, 573, 574, 574, 574, 574, + 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 573, + 574, 574, 574, 574, 574, 574, 574, 573, 574, 573, 574, 573, 574, 574, + 574, 574, 574, 574, 573, 574, 574, 574, 574, 574, 574, 573, 573, 81, 81, + 575, 575, 576, 576, 577, 577, 574, 563, 578, 579, 578, 579, 578, 579, + 578, 579, 578, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, + 579, 579, 579, 579, 579, 579, 578, 579, 579, 579, 579, 579, 579, 579, + 578, 579, 578, 579, 578, 579, 579, 579, 579, 579, 579, 578, 579, 579, + 579, 579, 579, 579, 578, 578, 579, 579, 579, 579, 580, 581, 582, 582, + 579, 81, 81, 81, 81, 81, 583, 583, 583, 583, 583, 583, 583, 583, 583, + 583, 583, 81, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, + 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 81, 585, 585, 586, 586, + 586, 586, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 583, 583, + 583, 81, 81, 81, 81, 81, 578, 578, 578, 578, 578, 578, 578, 578, 587, + 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 588, 81, + 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 585, 585, 585, 585, + 585, 585, 589, 589, 589, 589, 589, 589, 589, 589, 525, 590, 590, 590, + 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 587, 587, + 587, 587, 588, 588, 588, 585, 585, 590, 590, 590, 590, 590, 590, 590, + 585, 585, 585, 585, 525, 525, 525, 525, 591, 591, 591, 591, 591, 591, + 591, 591, 591, 591, 591, 591, 591, 591, 591, 81, 585, 585, 585, 585, 585, + 585, 585, 525, 525, 525, 525, 585, 585, 585, 585, 585, 585, 585, 585, + 585, 585, 585, 525, 525, 592, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 593, 593, 593, 593, 593, 593, 593, 593, 593, + 593, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + 595, 594, 594, 594, 594, 594, 594, 594, 81, 81, 81, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 81, 597, 597, 597, + 597, 597, 597, 597, 597, 598, 598, 598, 598, 598, 598, 599, 599, 600, + 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 602, 603, + 602, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 600, 600, 81, 81, + 81, 81, 90, 93, 90, 93, 90, 93, 605, 95, 97, 97, 97, 606, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 606, 607, 90, 93, 90, 93, 454, 454, 95, 95, 608, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 610, 611, 612, 612, + 612, 612, 612, 62, 62, 62, 62, 62, 62, 62, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 62, 62, 52, 56, 52, 56, 52, 56, 56, 56, 52, 56, 52, 56, 52, 56, + 59, 56, 56, 56, 56, 56, 56, 56, 56, 52, 56, 52, 56, 52, 52, 56, 60, 613, + 613, 52, 56, 52, 56, 57, 52, 56, 52, 56, 56, 56, 52, 56, 52, 56, 52, 52, + 52, 52, 52, 56, 52, 52, 52, 52, 52, 56, 52, 56, 52, 56, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 57, 59, 59, 56, 57, 57, 57, 57, 57, + 614, 614, 615, 614, 614, 614, 616, 614, 614, 614, 614, 615, 614, 614, + 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 617, + 617, 615, 615, 617, 618, 618, 618, 618, 81, 81, 81, 81, 619, 619, 619, + 619, 619, 619, 317, 317, 507, 516, 81, 81, 81, 81, 81, 81, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 621, 621, 622, 622, 623, + 623, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, + 624, 624, 624, 624, 624, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 625, 626, 81, 81, 81, 81, 81, 81, 81, + 81, 627, 627, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 81, 81, + 81, 81, 81, 81, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 195, + 195, 195, 195, 195, 195, 201, 201, 201, 195, 629, 195, 195, 193, 630, + 630, 630, 630, 630, 630, 630, 630, 630, 630, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 632, 632, 632, 632, 632, 633, 633, 633, 199, 634, 635, 635, 635, + 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 636, 636, + 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 638, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 639, 332, 332, 332, 332, 332, 81, 81, 81, + 640, 640, 640, 641, 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 642, 642, 642, 642, 642, 643, 641, 641, 640, 640, 640, 640, 641, 641, + 640, 641, 641, 641, 644, 645, 645, 645, 645, 645, 645, 646, 646, 646, + 645, 645, 645, 645, 81, 61, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 647, 81, 81, 81, 81, 645, 645, 318, 318, 318, 318, 318, 320, 648, 318, + 323, 323, 318, 318, 318, 318, 318, 81, 649, 649, 649, 649, 649, 649, 649, + 649, 649, 650, 650, 650, 650, 650, 650, 651, 651, 650, 650, 651, 651, + 650, 650, 81, 649, 649, 649, 650, 649, 649, 649, 649, 649, 649, 649, 649, + 650, 651, 81, 81, 652, 652, 652, 652, 652, 652, 652, 652, 652, 652, 81, + 81, 653, 654, 654, 654, 648, 318, 318, 318, 318, 318, 318, 327, 327, 327, + 318, 319, 320, 319, 318, 318, 655, 655, 655, 655, 655, 655, 655, 655, + 656, 655, 656, 656, 657, 655, 655, 656, 656, 655, 655, 655, 655, 655, + 656, 656, 655, 656, 655, 81, 81, 81, 81, 81, 81, 81, 81, 655, 655, 658, + 659, 659, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 661, + 662, 662, 661, 661, 663, 663, 660, 664, 664, 661, 665, 81, 81, 335, 335, + 335, 335, 335, 335, 81, 56, 56, 56, 613, 59, 59, 59, 59, 56, 56, 56, 56, + 56, 79, 81, 81, 342, 342, 342, 342, 342, 342, 342, 342, 660, 660, 660, + 661, 661, 662, 661, 661, 662, 661, 661, 663, 661, 665, 81, 81, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 81, 81, 81, 81, 81, 81, 667, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 667, 668, 668, 668, 668, 668, 668, 668, 81, 81, 81, + 81, 333, 333, 333, 333, 333, 333, 333, 81, 81, 81, 81, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 81, 81, 81, 81, 669, 669, 669, 669, 669, + 669, 669, 669, 670, 670, 670, 670, 670, 670, 670, 670, 592, 592, 593, + 593, 593, 593, 593, 593, 56, 56, 56, 56, 56, 56, 56, 81, 81, 81, 81, 101, + 101, 101, 101, 101, 81, 81, 81, 81, 81, 129, 671, 129, 129, 672, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 81, 129, 129, + 129, 129, 129, 81, 129, 81, 129, 129, 81, 129, 129, 81, 129, 129, 146, + 146, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 81, 81, 81, 81, 81, 81, 81, 81, 81, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 495, 477, 81, 81, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 135, 138, 81, 81, 674, 674, 674, 674, 674, + 674, 674, 674, 675, 558, 558, 675, 675, 676, 676, 526, 527, 677, 81, 81, + 81, 81, 81, 81, 96, 96, 96, 96, 96, 96, 96, 156, 156, 156, 156, 156, 156, + 156, 95, 95, 559, 569, 569, 678, 678, 526, 527, 526, 527, 526, 527, 526, + 527, 526, 527, 526, 527, 526, 527, 526, 527, 559, 559, 526, 527, 559, + 559, 559, 559, 678, 678, 678, 679, 559, 679, 81, 580, 680, 676, 676, 569, + 526, 527, 526, 527, 526, 527, 681, 559, 559, 682, 683, 684, 684, 684, 81, + 559, 685, 686, 559, 81, 81, 81, 81, 146, 146, 146, 146, 146, 81, 81, 497, + 81, 687, 688, 689, 690, 691, 688, 688, 692, 693, 688, 694, 695, 696, 695, + 697, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 699, 700, 701, + 701, 701, 687, 688, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + 702, 702, 702, 702, 702, 702, 702, 702, 692, 688, 693, 703, 704, 703, + 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, + 705, 705, 705, 705, 692, 701, 693, 701, 692, 693, 706, 707, 708, 706, + 709, 710, 711, 711, 711, 711, 711, 711, 711, 711, 711, 712, 710, 710, + 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, + 710, 710, 710, 710, 710, 713, 713, 714, 714, 714, 714, 714, 714, 714, + 714, 714, 714, 714, 714, 714, 714, 714, 81, 81, 81, 714, 714, 714, 714, + 714, 714, 81, 81, 714, 714, 714, 81, 81, 81, 715, 690, 701, 703, 716, + 690, 690, 81, 717, 718, 718, 718, 718, 717, 717, 81, 81, 719, 719, 719, + 720, 512, 81, 81, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, + 721, 81, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 81, 721, 721, + 721, 81, 721, 721, 81, 721, 721, 721, 721, 721, 721, 721, 81, 81, 721, + 721, 721, 81, 81, 81, 81, 81, 199, 377, 199, 81, 81, 81, 81, 619, 619, + 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 81, 81, 81, 317, + 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 723, + 723, 723, 723, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, + 724, 724, 724, 724, 724, 724, 723, 723, 724, 725, 725, 81, 40, 40, 40, + 40, 81, 81, 81, 81, 724, 81, 81, 81, 81, 81, 81, 81, 317, 317, 317, 317, + 317, 156, 81, 81, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + 726, 726, 81, 81, 81, 727, 727, 727, 727, 727, 727, 727, 727, 727, 81, + 81, 81, 81, 81, 81, 81, 156, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 81, 81, 81, 81, 728, + 728, 728, 728, 728, 728, 728, 728, 729, 729, 729, 729, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 728, 728, 728, 730, 730, 730, 730, 730, 730, 730, + 730, 730, 731, 730, 730, 730, 730, 730, 730, 730, 730, 731, 81, 81, 81, + 81, 81, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, + 732, 733, 733, 733, 733, 733, 81, 81, 81, 81, 81, 734, 734, 734, 734, + 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 81, 735, 736, 736, 736, + 736, 736, 736, 736, 736, 736, 736, 736, 736, 81, 81, 81, 81, 737, 738, + 738, 738, 738, 738, 81, 81, 739, 739, 739, 739, 739, 739, 739, 739, 740, + 740, 740, 740, 740, 740, 740, 740, 741, 741, 741, 741, 741, 741, 741, + 741, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, + 742, 81, 81, 743, 743, 743, 743, 743, 743, 743, 743, 743, 743, 81, 81, + 81, 81, 81, 81, 744, 744, 744, 744, 744, 744, 744, 744, 744, 744, 744, + 744, 81, 81, 81, 81, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, + 745, 745, 81, 81, 81, 81, 746, 746, 746, 746, 746, 746, 746, 746, 747, + 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 748, 749, 749, 749, 749, 749, 749, 749, 749, + 749, 749, 749, 749, 749, 749, 749, 81, 749, 749, 749, 749, 749, 749, 81, + 81, 750, 750, 750, 750, 750, 750, 81, 81, 750, 81, 750, 750, 750, 750, + 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, + 750, 750, 81, 750, 750, 81, 81, 81, 750, 81, 81, 750, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 81, 752, 753, 753, 753, + 753, 753, 753, 753, 753, 754, 754, 754, 754, 754, 754, 754, 754, 754, + 754, 754, 754, 754, 754, 754, 755, 755, 756, 756, 756, 756, 756, 756, + 756, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, + 757, 757, 81, 81, 81, 81, 81, 81, 81, 81, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 81, + 759, 759, 81, 81, 81, 81, 81, 760, 760, 760, 760, 760, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 762, 762, 762, + 762, 762, 762, 81, 81, 81, 763, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 81, 81, 81, 81, 81, 765, 766, 766, 766, 766, 766, 766, 766, + 766, 767, 767, 767, 767, 767, 767, 767, 767, 81, 81, 81, 81, 768, 768, + 767, 767, 768, 768, 768, 768, 768, 768, 768, 768, 81, 81, 768, 768, 768, + 768, 768, 768, 769, 770, 770, 770, 81, 770, 770, 81, 81, 81, 81, 81, 770, + 771, 770, 772, 769, 769, 769, 769, 81, 769, 769, 769, 81, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 81, 81, 772, 773, 771, 81, 81, 81, 81, 774, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 81, 81, 81, 81, 81, 81, 81, 776, 776, + 776, 776, 776, 776, 776, 776, 777, 81, 81, 81, 81, 81, 81, 81, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 779, 779, 780, + 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 782, + 782, 782, 783, 783, 783, 783, 783, 783, 783, 783, 784, 783, 783, 783, + 783, 783, 783, 783, 783, 783, 783, 783, 783, 785, 786, 81, 81, 81, 81, + 787, 787, 787, 787, 787, 788, 788, 788, 788, 788, 788, 789, 81, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 81, 81, 81, + 791, 791, 791, 791, 791, 791, 791, 792, 792, 792, 792, 792, 792, 792, + 792, 792, 792, 792, 792, 792, 792, 81, 81, 793, 793, 793, 793, 793, 793, + 793, 793, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 81, 81, + 81, 81, 81, 795, 795, 795, 795, 795, 795, 795, 795, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 81, 81, 81, 81, 81, 81, 81, 797, 797, 797, - 797, 797, 797, 797, 797, 797, 797, 797, 81, 81, 81, 81, 81, 798, 798, - 798, 798, 798, 798, 798, 798, 798, 798, 798, 81, 81, 81, 81, 81, 81, 81, - 799, 799, 799, 799, 799, 799, 800, 800, 800, 800, 800, 800, 800, 800, - 800, 800, 800, 800, 800, 800, 800, 81, 801, 802, 801, 803, 803, 803, 803, - 803, 803, 803, 803, 803, 803, 803, 803, 803, 802, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 802, 802, 802, 802, 804, 805, 805, 806, 806, - 806, 806, 806, 81, 81, 81, 81, 807, 807, 807, 807, 807, 807, 807, 807, - 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 808, 808, - 808, 808, 808, 808, 808, 808, 808, 808, 81, 81, 81, 81, 81, 81, 81, 804, - 809, 809, 810, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, - 811, 811, 810, 810, 810, 809, 809, 809, 809, 810, 810, 812, 813, 814, - 814, 815, 816, 816, 816, 816, 81, 81, 81, 81, 81, 81, 817, 817, 817, 817, - 817, 817, 817, 817, 817, 81, 81, 81, 81, 81, 81, 81, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 81, 81, 81, 81, 81, 81, 819, 819, 819, 820, + 797, 81, 81, 81, 81, 798, 798, 798, 798, 798, 798, 798, 799, 799, 799, + 799, 799, 799, 799, 799, 799, 81, 81, 81, 81, 81, 81, 81, 800, 800, 800, + 800, 800, 800, 800, 800, 800, 800, 800, 81, 81, 81, 81, 81, 801, 801, + 801, 801, 801, 801, 801, 801, 801, 801, 801, 81, 81, 81, 81, 81, 81, 81, + 802, 802, 802, 802, 802, 802, 803, 803, 803, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 804, 804, 804, 804, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 81, 81, 81, 81, 81, 81, 806, 806, 806, 806, 806, 806, + 806, 806, 806, 806, 806, 806, 806, 806, 806, 81, 807, 807, 807, 807, 807, + 807, 807, 807, 807, 807, 807, 807, 807, 808, 808, 808, 808, 808, 808, + 808, 808, 808, 808, 807, 809, 809, 809, 809, 809, 809, 809, 809, 809, + 809, 809, 809, 809, 809, 810, 810, 811, 811, 811, 810, 811, 810, 810, + 810, 810, 812, 812, 812, 812, 813, 813, 813, 813, 813, 81, 81, 81, 81, + 81, 81, 814, 815, 814, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, + 815, 815, 815, 817, 818, 818, 819, 819, 819, 819, 819, 81, 81, 81, 81, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, - 820, 820, 820, 820, 820, 821, 821, 821, 821, 821, 822, 821, 821, 821, - 821, 821, 821, 823, 823, 81, 824, 824, 824, 824, 824, 824, 824, 824, 824, - 824, 825, 825, 825, 825, 81, 81, 81, 81, 826, 826, 826, 826, 826, 826, - 826, 826, 826, 826, 826, 827, 828, 829, 826, 81, 830, 830, 831, 832, 832, - 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, - 831, 831, 831, 830, 830, 830, 830, 830, 830, 830, 830, 830, 831, 833, - 832, 832, 832, 832, 834, 834, 835, 834, 835, 836, 830, 830, 835, 81, 81, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 832, 838, 832, 834, - 834, 834, 81, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 839, 81, 81, 81, 840, 840, 840, 840, - 840, 840, 840, 840, 840, 840, 81, 840, 840, 840, 840, 840, 840, 840, 840, - 840, 841, 841, 841, 842, 842, 842, 841, 841, 842, 843, 844, 842, 845, - 845, 846, 845, 845, 846, 842, 81, 847, 847, 847, 847, 847, 847, 847, 81, - 847, 81, 847, 847, 847, 847, 81, 847, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 847, 847, 847, 81, 847, 847, 848, 81, 81, 81, 81, 81, - 81, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 850, 851, 851, 851, 850, 850, 850, 850, 850, 850, 852, 853, 81, 81, - 81, 81, 81, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 81, 81, 81, - 81, 81, 81, 855, 855, 856, 856, 81, 857, 857, 857, 857, 857, 857, 857, - 857, 81, 81, 857, 857, 81, 81, 857, 857, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 81, 857, 857, 857, 857, 857, 857, 857, 81, - 857, 857, 81, 857, 857, 857, 857, 857, 81, 81, 858, 857, 856, 856, 855, - 856, 856, 856, 856, 81, 81, 856, 856, 81, 81, 856, 856, 859, 81, 81, 857, - 81, 81, 81, 81, 81, 81, 856, 81, 81, 81, 81, 81, 857, 857, 857, 857, 857, - 856, 856, 81, 81, 860, 860, 860, 860, 860, 860, 860, 81, 81, 81, 861, - 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 862, 862, - 862, 863, 863, 863, 863, 863, 863, 863, 863, 862, 862, 864, 863, 863, - 862, 865, 861, 861, 861, 861, 866, 866, 866, 866, 867, 868, 868, 868, - 868, 868, 868, 868, 868, 868, 868, 81, 866, 81, 867, 81, 81, 869, 869, - 869, 869, 869, 869, 869, 869, 870, 870, 870, 871, 871, 871, 871, 871, - 871, 870, 871, 870, 870, 870, 870, 871, 871, 870, 872, 873, 869, 869, - 874, 869, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 81, 81, 81, - 81, 81, 81, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, - 876, 876, 876, 877, 877, 877, 878, 878, 878, 878, 81, 81, 877, 877, 877, - 877, 878, 878, 877, 879, 880, 881, 882, 882, 883, 883, 884, 884, 884, - 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, - 882, 876, 876, 876, 876, 878, 878, 81, 81, 885, 885, 885, 885, 885, 885, - 885, 885, 886, 886, 886, 887, 887, 887, 887, 887, 887, 887, 887, 886, - 886, 887, 886, 888, 887, 889, 889, 890, 885, 81, 81, 81, 891, 891, 891, - 891, 891, 891, 891, 891, 891, 891, 81, 81, 81, 81, 81, 81, 892, 892, 892, - 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 81, 81, 81, 893, 893, - 893, 893, 893, 893, 893, 893, 893, 893, 893, 894, 895, 894, 895, 895, - 894, 894, 894, 894, 894, 894, 896, 897, 898, 898, 898, 898, 898, 898, - 898, 898, 898, 898, 81, 81, 81, 81, 81, 81, 899, 899, 899, 899, 899, 899, - 899, 899, 899, 899, 81, 81, 81, 900, 900, 900, 901, 901, 900, 900, 900, - 900, 901, 900, 900, 900, 900, 902, 81, 81, 81, 81, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 904, 904, 905, 905, 905, 906, 907, 907, - 907, 907, 907, 907, 907, 907, 908, 908, 908, 908, 908, 908, 908, 908, - 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, 910, 910, 910, 910, - 910, 910, 910, 910, 910, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 911, 912, 913, 913, 913, 913, 913, 913, 914, 914, 913, 913, 912, 912, - 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, - 913, 915, 913, 913, 913, 913, 914, 912, 913, 913, 913, 913, 916, 917, - 918, 918, 918, 918, 916, 917, 915, 919, 920, 920, 920, 920, 920, 920, - 921, 921, 920, 920, 920, 919, 919, 919, 919, 919, 919, 919, 919, 919, - 919, 919, 919, 919, 919, 919, 919, 81, 81, 919, 919, 919, 919, 920, 920, - 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, 921, 920, 922, - 923, 923, 923, 81, 924, 924, 924, 923, 923, 81, 81, 81, 81, 81, 925, 925, - 925, 925, 925, 925, 925, 925, 925, 81, 81, 81, 81, 81, 81, 81, 926, 926, - 926, 926, 926, 926, 926, 926, 926, 81, 926, 926, 926, 926, 926, 926, 926, - 926, 926, 926, 926, 926, 926, 927, 928, 928, 928, 928, 928, 928, 928, 81, - 928, 928, 928, 928, 928, 928, 927, 929, 926, 930, 930, 930, 930, 930, 81, - 81, 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, 932, 932, 932, 932, - 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, - 932, 81, 81, 81, 933, 934, 935, 935, 935, 935, 935, 935, 935, 935, 935, - 935, 935, 935, 935, 935, 81, 81, 936, 936, 936, 936, 936, 936, 936, 936, - 936, 936, 936, 936, 936, 936, 81, 937, 936, 936, 936, 936, 936, 936, 936, - 937, 936, 936, 937, 936, 936, 81, 938, 938, 938, 938, 938, 938, 938, 81, - 938, 938, 81, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, - 938, 938, 939, 939, 939, 939, 939, 939, 81, 81, 81, 939, 81, 939, 939, - 81, 939, 939, 939, 940, 939, 941, 941, 938, 939, 942, 942, 942, 942, 942, - 942, 942, 942, 942, 942, 81, 81, 81, 81, 81, 81, 943, 943, 943, 943, 943, - 943, 943, 943, 943, 943, 81, 81, 81, 81, 81, 81, 944, 944, 944, 944, 944, - 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 81, 945, 945, 945, 945, - 945, 81, 81, 81, 943, 943, 943, 943, 81, 81, 81, 81, 946, 946, 946, 946, - 946, 946, 946, 946, 947, 947, 947, 948, 948, 948, 946, 946, 946, 946, - 948, 946, 946, 946, 947, 948, 947, 948, 946, 946, 946, 946, 946, 946, - 946, 947, 948, 948, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, - 946, 81, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, - 949, 950, 951, 949, 949, 949, 949, 949, 949, 949, 81, 605, 81, 81, 81, - 81, 81, 81, 81, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, - 952, 952, 952, 952, 81, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, - 81, 81, 81, 81, 954, 954, 955, 955, 955, 955, 955, 955, 955, 955, 955, - 955, 955, 955, 955, 955, 81, 81, 956, 956, 956, 956, 956, 957, 81, 81, - 958, 958, 958, 958, 958, 958, 958, 958, 959, 959, 959, 959, 959, 959, - 959, 960, 960, 960, 961, 961, 962, 962, 962, 962, 963, 963, 963, 963, - 960, 962, 81, 81, 964, 964, 964, 964, 964, 964, 964, 964, 964, 964, 81, - 965, 965, 965, 965, 965, 965, 965, 81, 958, 958, 958, 958, 958, 81, 81, - 81, 81, 81, 958, 958, 958, 966, 966, 966, 966, 966, 966, 966, 966, 966, - 966, 966, 966, 966, 81, 81, 81, 966, 967, 967, 967, 967, 967, 967, 967, - 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, - 967, 81, 81, 81, 81, 81, 81, 81, 81, 968, 968, 968, 968, 969, 969, 969, - 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 970, 971, 81, 81, 81, - 81, 81, 81, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, - 972, 81, 81, 81, 972, 972, 972, 81, 81, 81, 81, 81, 576, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 81, 973, 973, 973, - 973, 973, 973, 973, 973, 973, 973, 973, 973, 81, 81, 81, 81, 974, 974, - 974, 974, 974, 974, 974, 974, 974, 974, 974, 81, 81, 81, 81, 81, 974, - 974, 974, 974, 974, 81, 81, 81, 974, 81, 81, 81, 81, 81, 81, 81, 974, - 974, 81, 81, 975, 976, 977, 978, 499, 499, 499, 499, 81, 81, 81, 81, 313, - 313, 313, 313, 313, 313, 81, 81, 313, 313, 313, 313, 313, 313, 313, 81, - 81, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 979, 979, - 447, 447, 447, 313, 313, 313, 980, 979, 979, 979, 979, 979, 499, 499, - 499, 499, 499, 499, 499, 499, 156, 156, 156, 156, 156, 156, 156, 156, - 313, 313, 96, 96, 96, 96, 96, 156, 156, 313, 313, 313, 313, 313, 313, 96, - 96, 96, 96, 313, 313, 313, 81, 81, 81, 81, 81, 81, 81, 721, 721, 981, - 981, 981, 721, 81, 81, 616, 616, 81, 81, 81, 81, 81, 81, 506, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, 506, 506, 506, - 506, 506, 506, 49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, 49, 49, - 506, 81, 506, 506, 81, 81, 506, 81, 81, 506, 506, 81, 81, 506, 506, 506, - 506, 81, 506, 506, 49, 49, 81, 49, 81, 49, 49, 49, 49, 49, 49, 49, 81, - 49, 49, 49, 49, 49, 49, 49, 506, 506, 81, 506, 506, 506, 506, 81, 81, - 506, 506, 506, 506, 506, 506, 506, 506, 81, 506, 506, 506, 506, 506, 506, - 506, 81, 49, 49, 506, 506, 81, 506, 506, 506, 506, 81, 506, 506, 506, - 506, 506, 81, 506, 81, 81, 81, 506, 506, 506, 506, 506, 506, 506, 81, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 81, 81, 506, 982, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 492, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, - 506, 506, 506, 506, 506, 982, 49, 49, 49, 49, 49, 49, 49, 49, 49, 492, - 49, 49, 506, 506, 506, 506, 506, 982, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 492, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, 506, 506, 506, 506, 506, - 982, 49, 492, 49, 49, 49, 49, 49, 49, 49, 49, 506, 49, 81, 81, 983, 983, - 983, 983, 983, 983, 983, 983, 983, 983, 984, 984, 984, 984, 984, 984, - 984, 984, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, - 985, 985, 985, 984, 984, 984, 984, 985, 985, 985, 985, 985, 985, 985, - 985, 985, 985, 984, 984, 984, 984, 984, 984, 984, 984, 985, 984, 984, - 984, 984, 984, 984, 985, 984, 984, 986, 986, 986, 986, 987, 81, 81, 81, - 81, 81, 81, 81, 985, 985, 985, 985, 985, 81, 985, 985, 985, 985, 985, - 985, 985, 988, 988, 988, 988, 988, 988, 988, 81, 988, 988, 988, 988, 988, - 988, 988, 988, 988, 81, 81, 988, 988, 988, 988, 988, 988, 988, 81, 988, - 988, 81, 988, 988, 988, 988, 988, 81, 81, 81, 81, 81, 989, 989, 989, 989, - 989, 989, 989, 989, 989, 989, 989, 989, 989, 81, 81, 990, 990, 990, 990, - 990, 990, 990, 990, 990, 991, 991, 991, 991, 991, 991, 991, 81, 992, 992, - 992, 992, 992, 992, 992, 992, 992, 992, 993, 993, 993, 993, 993, 993, - 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 994, 994, - 994, 994, 994, 994, 995, 81, 81, 81, 81, 81, 996, 996, 996, 996, 996, - 996, 996, 996, 996, 996, 81, 81, 81, 81, 997, 997, 146, 146, 146, 146, + 820, 820, 820, 820, 820, 820, 821, 821, 821, 821, 821, 821, 821, 821, + 821, 821, 81, 81, 81, 81, 81, 81, 81, 817, 822, 822, 823, 824, 824, 824, + 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 823, 823, 823, 822, + 822, 822, 822, 823, 823, 825, 826, 827, 827, 828, 829, 829, 829, 829, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 828, 81, 81, 830, 830, 830, 830, + 830, 830, 830, 830, 830, 81, 81, 81, 81, 81, 81, 81, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 81, 81, 81, 81, 81, 81, 832, 832, 832, 833, + 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, + 833, 833, 833, 833, 833, 834, 834, 834, 834, 834, 835, 834, 834, 834, + 834, 834, 834, 836, 836, 81, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 838, 838, 838, 838, 833, 835, 835, 81, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 840, 841, 842, 839, 81, 843, 843, 844, 845, 845, + 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, + 844, 844, 844, 843, 843, 843, 843, 843, 843, 843, 843, 843, 844, 846, + 845, 845, 845, 845, 847, 847, 848, 847, 843, 849, 843, 843, 848, 81, 81, + 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 845, 851, 845, 847, + 847, 847, 81, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, + 852, 852, 852, 852, 852, 852, 852, 852, 81, 81, 81, 853, 853, 853, 853, + 853, 853, 853, 853, 853, 853, 81, 853, 853, 853, 853, 853, 853, 853, 853, + 853, 854, 854, 854, 855, 855, 855, 854, 854, 855, 856, 857, 855, 858, + 858, 859, 858, 858, 859, 855, 81, 860, 860, 860, 860, 860, 860, 860, 81, + 860, 81, 860, 860, 860, 860, 81, 860, 860, 860, 860, 860, 860, 860, 860, + 860, 860, 860, 860, 860, 860, 860, 81, 860, 860, 861, 81, 81, 81, 81, 81, + 81, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, + 862, 863, 864, 864, 864, 863, 863, 863, 863, 863, 863, 865, 866, 81, 81, + 81, 81, 81, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 81, 81, 81, + 81, 81, 81, 868, 868, 869, 869, 81, 870, 870, 870, 870, 870, 870, 870, + 870, 81, 81, 870, 870, 81, 81, 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 81, 870, 870, 870, 870, 870, 870, 870, 81, + 870, 870, 81, 870, 870, 870, 870, 870, 81, 871, 872, 870, 869, 869, 868, + 869, 869, 869, 869, 81, 81, 869, 869, 81, 81, 869, 869, 873, 81, 81, 870, + 81, 81, 81, 81, 81, 81, 869, 81, 81, 81, 81, 81, 870, 870, 870, 870, 870, + 869, 869, 81, 81, 874, 874, 874, 874, 874, 874, 874, 81, 81, 81, 875, + 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 876, 876, + 876, 877, 877, 877, 877, 877, 877, 877, 877, 876, 876, 878, 877, 877, + 876, 879, 875, 875, 875, 875, 880, 880, 880, 880, 881, 882, 882, 882, + 882, 882, 882, 882, 882, 882, 882, 81, 880, 81, 881, 883, 81, 884, 884, + 884, 884, 884, 884, 884, 884, 885, 885, 885, 886, 886, 886, 886, 886, + 886, 885, 886, 885, 885, 885, 885, 886, 886, 885, 887, 888, 884, 884, + 889, 884, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 81, 81, 81, + 81, 81, 81, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 891, 892, 892, 892, 893, 893, 893, 893, 81, 81, 892, 892, 892, + 892, 893, 893, 892, 894, 895, 896, 897, 897, 898, 898, 899, 899, 899, + 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, + 897, 891, 891, 891, 891, 893, 893, 81, 81, 900, 900, 900, 900, 900, 900, + 900, 900, 901, 901, 901, 902, 902, 902, 902, 902, 902, 902, 902, 901, + 901, 902, 901, 903, 902, 904, 904, 905, 900, 81, 81, 81, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 81, 81, 81, 81, 81, 81, 907, 907, 907, + 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 81, 81, 81, 908, 908, + 908, 908, 908, 908, 908, 908, 908, 908, 908, 909, 910, 909, 910, 910, + 909, 909, 909, 909, 909, 909, 911, 912, 913, 913, 913, 913, 913, 913, + 913, 913, 913, 913, 81, 81, 81, 81, 81, 81, 914, 914, 914, 914, 914, 914, + 914, 914, 914, 914, 914, 81, 81, 915, 915, 915, 916, 916, 915, 915, 915, + 915, 916, 915, 915, 915, 915, 917, 81, 81, 81, 81, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 919, 919, 920, 920, 920, 921, 922, 922, + 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 923, 923, 923, 924, + 924, 924, 924, 924, 924, 924, 924, 924, 923, 925, 926, 927, 81, 81, 81, + 81, 928, 928, 928, 928, 928, 928, 928, 928, 929, 929, 929, 929, 929, 929, + 929, 929, 930, 930, 930, 930, 930, 930, 930, 930, 930, 930, 931, 931, + 931, 931, 931, 931, 931, 931, 931, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 932, 933, 934, 934, 934, 934, 934, 934, 935, 935, 934, 934, + 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, + 933, 933, 934, 936, 934, 934, 934, 934, 937, 933, 934, 934, 934, 934, + 938, 939, 940, 940, 940, 940, 938, 939, 936, 941, 942, 942, 942, 942, + 942, 942, 943, 943, 942, 942, 942, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, 941, 81, 81, 941, 941, 941, 941, + 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 943, + 942, 944, 945, 945, 945, 941, 946, 946, 946, 945, 945, 81, 81, 81, 81, + 81, 947, 947, 947, 947, 947, 947, 947, 947, 947, 81, 81, 81, 81, 81, 81, + 81, 948, 948, 948, 948, 948, 948, 948, 948, 948, 81, 948, 948, 948, 948, + 948, 948, 948, 948, 948, 948, 948, 948, 948, 949, 950, 950, 950, 950, + 950, 950, 950, 81, 950, 950, 950, 950, 950, 950, 949, 951, 948, 952, 952, + 952, 952, 952, 81, 81, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, + 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, + 954, 954, 954, 954, 954, 81, 81, 81, 955, 956, 957, 957, 957, 957, 957, + 957, 957, 957, 957, 957, 957, 957, 957, 957, 81, 81, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 81, 959, 958, 958, 958, + 958, 958, 958, 958, 959, 958, 958, 959, 958, 958, 81, 960, 960, 960, 960, + 960, 960, 960, 81, 960, 960, 81, 960, 960, 960, 960, 960, 960, 960, 960, + 960, 960, 960, 960, 960, 960, 961, 961, 961, 961, 961, 961, 81, 81, 81, + 961, 81, 961, 961, 81, 961, 961, 961, 962, 961, 963, 963, 960, 961, 964, + 964, 964, 964, 964, 964, 964, 964, 964, 964, 81, 81, 81, 81, 81, 81, 965, + 965, 965, 965, 965, 965, 81, 965, 965, 81, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 966, 966, 966, 966, + 966, 81, 967, 967, 81, 966, 966, 967, 966, 968, 965, 81, 81, 81, 81, 81, + 81, 81, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 81, 81, 81, 81, + 81, 81, 970, 970, 970, 970, 970, 970, 970, 970, 970, 970, 970, 971, 971, + 972, 972, 973, 973, 81, 81, 81, 81, 81, 81, 81, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 81, 81, 81, 81, 81, 81, 975, 975, 975, 975, 975, + 975, 975, 975, 975, 975, 975, 975, 975, 975, 975, 81, 976, 976, 976, 976, + 976, 81, 81, 81, 974, 974, 974, 974, 81, 81, 81, 81, 977, 977, 977, 977, + 977, 977, 977, 977, 978, 978, 978, 979, 979, 979, 977, 977, 977, 977, + 979, 977, 977, 977, 978, 979, 978, 979, 977, 977, 977, 977, 977, 977, + 977, 978, 979, 979, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, + 977, 81, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, + 980, 981, 982, 980, 980, 980, 980, 980, 980, 980, 81, 608, 81, 81, 81, + 81, 81, 81, 81, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, + 983, 983, 983, 983, 81, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, + 81, 81, 81, 81, 985, 985, 986, 986, 986, 986, 986, 986, 986, 986, 986, + 986, 986, 986, 986, 986, 81, 81, 987, 987, 987, 987, 987, 988, 81, 81, + 989, 989, 989, 989, 989, 989, 989, 989, 990, 990, 990, 990, 990, 990, + 990, 991, 991, 991, 992, 992, 993, 993, 993, 993, 994, 994, 994, 994, + 991, 993, 81, 81, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 81, + 996, 996, 996, 996, 996, 996, 996, 81, 989, 989, 989, 989, 989, 81, 81, + 81, 81, 81, 989, 989, 989, 997, 997, 997, 997, 997, 997, 997, 997, 998, + 998, 998, 998, 998, 998, 998, 998, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 1000, 1000, 1001, 1001, 81, 81, + 81, 81, 81, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, + 1002, 1002, 1002, 81, 81, 81, 1002, 1003, 1003, 1003, 1003, 1003, 1003, + 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, + 1003, 1003, 1003, 1003, 81, 81, 81, 81, 81, 81, 81, 81, 1004, 1004, 1004, + 1004, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, + 1005, 1005, 1006, 1007, 81, 81, 81, 81, 81, 81, 1008, 1008, 1008, 1008, + 1008, 1008, 1008, 1008, 1008, 1008, 81, 81, 81, 81, 81, 81, 1008, 1008, + 1008, 81, 81, 81, 81, 81, 579, 574, 574, 574, 574, 574, 574, 574, 574, + 574, 574, 574, 574, 574, 574, 81, 1009, 1009, 1009, 1009, 1009, 1009, + 1009, 1009, 1009, 1009, 1009, 1009, 81, 81, 81, 81, 1010, 1010, 1010, + 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 81, 81, 81, 81, 81, 1010, + 1010, 1010, 1010, 1010, 81, 81, 81, 1010, 81, 81, 81, 81, 81, 81, 81, + 1010, 1010, 81, 81, 1011, 1012, 1013, 1014, 503, 503, 503, 503, 81, 81, + 81, 81, 317, 317, 317, 317, 317, 317, 81, 81, 317, 317, 317, 317, 317, + 317, 317, 81, 81, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 1015, 1015, 451, 451, 451, 317, 317, 317, 1016, 1015, 1015, 1015, + 1015, 1015, 503, 503, 503, 503, 503, 503, 503, 503, 156, 156, 156, 156, + 156, 156, 156, 156, 317, 317, 96, 96, 96, 96, 96, 156, 156, 317, 317, + 317, 317, 317, 317, 96, 96, 96, 96, 317, 317, 317, 81, 81, 81, 81, 81, + 81, 81, 724, 724, 1017, 1017, 1017, 724, 81, 81, 619, 619, 619, 619, 81, + 81, 81, 81, 619, 81, 81, 81, 81, 81, 81, 81, 510, 510, 510, 510, 510, + 510, 510, 510, 510, 510, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, + 49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, 49, 49, 510, 81, 510, + 510, 81, 81, 510, 81, 81, 510, 510, 81, 81, 510, 510, 510, 510, 81, 510, + 510, 49, 49, 81, 49, 81, 49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, + 49, 49, 49, 510, 510, 81, 510, 510, 510, 510, 81, 81, 510, 510, 510, 510, + 510, 510, 510, 510, 81, 510, 510, 510, 510, 510, 510, 510, 81, 49, 49, + 510, 510, 81, 510, 510, 510, 510, 81, 510, 510, 510, 510, 510, 81, 510, + 81, 81, 81, 510, 510, 510, 510, 510, 510, 510, 81, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 81, 81, 510, 1018, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 496, 49, 49, 49, 49, 49, 49, 510, 510, 510, 510, 510, 510, + 510, 510, 510, 1018, 49, 49, 49, 49, 49, 49, 49, 49, 49, 496, 49, 49, + 510, 510, 510, 510, 510, 1018, 49, 49, 49, 49, 49, 49, 49, 49, 49, 496, + 49, 49, 49, 49, 49, 49, 510, 510, 510, 510, 510, 510, 510, 510, 510, + 1018, 49, 496, 49, 49, 49, 49, 49, 49, 49, 49, 510, 49, 81, 81, 1019, + 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1020, 1020, 1020, + 1020, 1020, 1020, 1020, 1020, 1021, 1021, 1021, 1021, 1021, 1021, 1021, + 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1020, 1020, 1020, 1020, + 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1020, 1020, + 1020, 1020, 1020, 1020, 1020, 1020, 1021, 1020, 1020, 1020, 1020, 1020, + 1020, 1021, 1020, 1020, 1022, 1022, 1022, 1022, 1023, 81, 81, 81, 81, 81, + 81, 81, 1021, 1021, 1021, 1021, 1021, 81, 1021, 1021, 1021, 1021, 1021, + 1021, 1021, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 81, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 81, 81, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 81, 1024, 1024, 81, 1024, 1024, 1024, 1024, 1024, 81, + 81, 81, 81, 81, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, + 1025, 1025, 1025, 1025, 81, 81, 1026, 1026, 1026, 1026, 1026, 1026, 1026, + 1026, 1026, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 81, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, + 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, + 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1030, 1031, 81, 81, 81, 81, 81, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 81, 81, 81, + 81, 1033, 1033, 81, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, + 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1035, 1034, + 1034, 1034, 1036, 1034, 1034, 1034, 1034, 81, 81, 81, 146, 146, 146, 146, 81, 146, 146, 146, 81, 146, 146, 81, 146, 81, 81, 146, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 81, 146, 146, 146, 146, 81, 146, 81, 146, 81, 81, 81, 81, 81, 81, 146, 81, 81, 81, 81, 146, 81, 146, 81, 146, 81, 146, 146, 146, 81, 146, 81, 146, 81, 146, 81, 146, 81, 146, 146, 146, 146, 81, 146, 81, 146, 146, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 81, 81, 81, 81, 81, 146, 146, 146, 81, 146, 146, 146, 132, 132, 81, - 81, 81, 81, 81, 81, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 998, 998, 998, 998, - 998, 998, 998, 998, 998, 998, 998, 998, 525, 525, 525, 525, 525, 525, - 525, 998, 998, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 998, 998, 47, 47, 47, - 515, 515, 998, 998, 998, 526, 526, 526, 526, 526, 526, 313, 998, 526, - 526, 40, 40, 998, 998, 998, 998, 526, 526, 526, 526, 526, 526, 999, 526, - 526, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 526, 526, 526, - 526, 526, 526, 526, 526, 526, 526, 998, 998, 998, 998, 998, 998, 998, - 998, 998, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, - 1001, 582, 582, 998, 998, 998, 998, 998, 582, 582, 582, 582, 998, 998, - 998, 998, 582, 998, 998, 998, 998, 998, 998, 998, 582, 582, 998, 998, - 998, 998, 998, 998, 521, 521, 521, 521, 521, 521, 998, 998, 521, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 521, 521, - 521, 521, 521, 521, 521, 521, 525, 521, 521, 521, 521, 521, 521, 525, - 521, 521, 521, 521, 521, 521, 521, 532, 521, 521, 521, 521, 521, 521, - 525, 525, 525, 525, 525, 525, 525, 525, 40, 40, 525, 525, 521, 521, 521, - 521, 521, 524, 524, 521, 521, 521, 521, 521, 524, 521, 521, 521, 521, - 521, 532, 532, 532, 521, 521, 532, 521, 521, 532, 530, 530, 525, 525, - 521, 521, 525, 525, 525, 521, 525, 525, 525, 521, 521, 521, 1002, 1002, - 1002, 1002, 1002, 521, 521, 521, 521, 521, 521, 521, 525, 521, 525, 532, - 532, 521, 521, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, - 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 532, - 532, 532, 532, 521, 521, 521, 521, 532, 521, 532, 521, 521, 521, 532, - 521, 521, 521, 521, 532, 532, 532, 521, 532, 532, 532, 524, 521, 524, - 521, 524, 521, 521, 521, 521, 521, 532, 521, 521, 521, 521, 524, 521, - 524, 524, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 525, 525, - 521, 524, 524, 524, 524, 524, 524, 524, 521, 521, 521, 521, 521, 521, - 521, 521, 524, 524, 524, 524, 524, 524, 521, 521, 521, 521, 521, 524, - 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 40, 40, 40, 40, - 525, 521, 521, 521, 521, 525, 525, 525, 525, 525, 530, 530, 525, 525, - 525, 525, 532, 525, 525, 525, 525, 525, 530, 525, 525, 525, 525, 532, - 532, 525, 525, 525, 525, 525, 40, 40, 40, 40, 40, 40, 40, 40, 525, 525, - 525, 525, 40, 40, 525, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, - 532, 532, 532, 521, 521, 521, 532, 532, 532, 532, 532, 40, 40, 40, 40, - 40, 40, 534, 534, 534, 1003, 1003, 1003, 40, 40, 40, 40, 521, 521, 521, - 532, 521, 521, 521, 521, 521, 521, 521, 521, 532, 532, 532, 521, 532, - 521, 521, 521, 521, 521, 525, 525, 525, 525, 525, 525, 532, 525, 525, - 525, 521, 521, 521, 525, 525, 998, 998, 998, 525, 525, 525, 521, 521, - 998, 998, 998, 525, 525, 525, 525, 521, 521, 521, 521, 521, 998, 998, - 998, 998, 998, 998, 998, 40, 40, 40, 40, 998, 998, 998, 998, 40, 40, 40, - 40, 40, 998, 998, 998, 40, 40, 998, 998, 998, 998, 998, 998, 40, 40, 40, - 40, 40, 40, 998, 998, 532, 532, 532, 532, 532, 521, 532, 532, 521, 521, - 521, 521, 521, 521, 532, 521, 532, 532, 521, 521, 521, 532, 532, 998, - 521, 521, 521, 521, 521, 998, 998, 998, 521, 521, 521, 521, 998, 998, - 998, 998, 521, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, - 532, 532, 521, 521, 521, 521, 521, 521, 521, 521, 521, 998, 998, 998, - 998, 998, 998, 998, 81, 81, 589, 589, 589, 589, 589, 589, 589, 590, 589, - 589, 589, 589, 589, 590, 590, 590, 589, 590, 590, 590, 590, 590, 590, - 590, 590, 590, 590, 590, 590, 590, 81, 81, 81, 499, 81, 81, 81, 81, 81, - 81, 499, 499, 499, 499, 499, 499, 499, 499, 667, 667, 667, 667, 667, 667, - 81, 81, + 81, 81, 81, 81, 81, 529, 529, 529, 529, 525, 529, 529, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 1037, 1037, 1037, 1037, + 1037, 1037, 1037, 1037, 1037, 1037, 1037, 1037, 529, 529, 529, 529, 529, + 529, 529, 1037, 1037, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, + 529, 529, 529, 529, 525, 529, 529, 529, 529, 529, 529, 1037, 1037, 47, + 47, 47, 519, 519, 1037, 1037, 1037, 530, 530, 530, 530, 530, 530, 317, + 40, 530, 530, 40, 40, 1037, 1037, 1037, 1037, 530, 530, 530, 530, 530, + 530, 1038, 530, 530, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, + 1038, 1038, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 1037, 1037, + 1037, 1037, 1037, 1037, 1037, 1037, 1037, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 1040, 585, 585, 1037, 1037, 1037, 1037, + 1037, 585, 585, 585, 585, 1037, 1037, 1037, 1037, 585, 1037, 1037, 1037, + 1037, 1037, 1037, 1037, 585, 585, 1037, 1037, 1037, 1037, 1037, 1037, + 525, 525, 525, 525, 525, 525, 1037, 1037, 525, 529, 529, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 525, 525, 525, 525, 525, 525, 525, + 525, 525, 529, 525, 525, 525, 525, 525, 525, 529, 525, 525, 525, 525, + 525, 525, 525, 536, 525, 525, 525, 525, 525, 525, 529, 529, 529, 529, + 529, 529, 529, 529, 40, 40, 529, 529, 525, 525, 525, 525, 525, 528, 528, + 525, 525, 525, 525, 525, 528, 525, 525, 525, 525, 525, 536, 536, 536, + 525, 525, 536, 525, 525, 536, 534, 534, 529, 529, 525, 525, 529, 529, + 529, 525, 529, 529, 529, 525, 525, 525, 1041, 1041, 1041, 1041, 1041, + 525, 525, 525, 525, 525, 525, 525, 529, 525, 529, 536, 536, 525, 525, + 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 525, 525, 525, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 536, 536, 536, 536, + 525, 525, 525, 525, 536, 525, 536, 525, 525, 525, 536, 525, 525, 525, + 525, 536, 536, 536, 525, 536, 536, 536, 528, 525, 528, 525, 528, 525, + 525, 525, 525, 525, 536, 525, 525, 525, 525, 528, 525, 528, 528, 525, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 529, 529, 525, 528, 528, + 528, 528, 528, 528, 528, 525, 525, 525, 525, 525, 525, 525, 525, 528, + 528, 528, 528, 528, 528, 525, 525, 525, 525, 525, 528, 528, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 528, 40, 40, 40, 40, 529, 525, 525, + 525, 525, 529, 529, 529, 529, 529, 534, 534, 529, 529, 529, 529, 536, + 529, 529, 529, 529, 529, 534, 529, 529, 529, 529, 536, 536, 529, 529, + 529, 529, 529, 40, 40, 40, 40, 40, 40, 40, 40, 529, 529, 529, 529, 40, + 40, 529, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 536, 536, 536, + 525, 525, 525, 536, 536, 536, 536, 536, 40, 40, 40, 40, 40, 40, 538, 538, + 538, 1042, 1042, 1042, 40, 40, 40, 40, 525, 525, 525, 536, 525, 525, 525, + 525, 525, 525, 525, 525, 536, 536, 536, 525, 536, 525, 525, 525, 525, + 525, 529, 529, 529, 529, 529, 529, 536, 529, 529, 529, 525, 525, 525, + 529, 529, 1037, 1037, 1037, 529, 529, 529, 525, 525, 1037, 1037, 1037, + 529, 529, 529, 529, 525, 525, 525, 525, 525, 525, 1037, 1037, 1037, 1037, + 1037, 1037, 40, 40, 40, 40, 1037, 1037, 1037, 1037, 40, 40, 40, 40, 40, + 529, 529, 529, 529, 1037, 1037, 1037, 1037, 1037, 1037, 1037, 40, 40, + 1037, 1037, 1037, 1037, 1037, 1037, 40, 40, 40, 40, 40, 40, 1037, 1037, + 536, 536, 536, 536, 536, 525, 536, 536, 525, 525, 525, 525, 525, 525, + 536, 525, 536, 536, 525, 525, 525, 536, 536, 1037, 525, 1037, 1037, 525, + 525, 525, 525, 1037, 1037, 1037, 525, 1037, 525, 525, 525, 525, 525, 525, + 525, 1037, 1037, 1037, 1037, 1037, 525, 525, 525, 525, 525, 536, 536, + 525, 536, 536, 1037, 1037, 1037, 1037, 1037, 1037, 525, 536, 536, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 525, 525, 1037, 1037, + 1037, 1037, 1037, 1037, 81, 81, 592, 592, 592, 592, 592, 592, 592, 593, + 592, 592, 592, 592, 592, 593, 593, 593, 592, 593, 593, 593, 593, 593, + 593, 593, 593, 593, 593, 593, 593, 593, 81, 81, 81, 503, 81, 81, 81, 81, + 81, 81, 503, 503, 503, 503, 503, 503, 503, 503, 670, 670, 670, 670, 670, + 670, 81, 81, }; /* decomposition data */ diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh index 82bb9a4..5472ece 100644 --- a/src/hb-unicode-private.hh +++ b/src/hb-unicode-private.hh @@ -202,8 +202,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE } /* Space estimates based on: - * http://www.unicode.org/charts/PDF/U2000.pdf - * https://www.microsoft.com/typography/developers/fdsspec/spaces.aspx + * https://unicode.org/charts/PDF/U2000.pdf + * https://docs.microsoft.com/en-us/typography/develop/character-design-standards/whitespace */ enum space_t { NOT_SPACE = 0, @@ -276,10 +276,10 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; * We permute the "fixed-position" classes 10-26 into the order * described in the SBL Hebrew manual: * - * http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf + * https://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf * * (as recommended by: - * http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html) + * https://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering/msg22823/) * * More details here: * https://bugzilla.mozilla.org/show_bug.cgi?id=662055 @@ -306,8 +306,8 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; * Arabic * * Modify to move Shadda (ccc=33) before other marks. See: - * http://unicode.org/faq/normalization.html#8 - * http://unicode.org/faq/normalization.html#9 + * https://unicode.org/faq/normalization.html#8 + * https://unicode.org/faq/normalization.html#9 */ #define HB_MODIFIED_COMBINING_CLASS_CCC27 28 /* fathatan */ #define HB_MODIFIED_COMBINING_CLASS_CCC28 29 /* dammatan */ @@ -346,9 +346,9 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; #define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */ /* Tibetan - * - * In case of multiple vowel-signs, use u first (but after achung) - * this allows Dzongkha multi-vowel shortcuts to render correctly + * + * In case of multiple vowel-signs, use u first (but after achung) + * this allows Dzongkha multi-vowel shortcuts to render correctly */ #define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */ #define HB_MODIFIED_COMBINING_CLASS_CCC130 132 /* sign i */ diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index 726baeb..2d16c2e 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -64,7 +64,7 @@ hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, static hb_codepoint_t hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t unicode HB_UNUSED, + hb_codepoint_t unicode, void *user_data HB_UNUSED) { return unicode; diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index cd25769..6d6afe8 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -223,11 +223,19 @@ struct hb_uniscribe_shaper_funcs_t { }; static hb_uniscribe_shaper_funcs_t *uniscribe_funcs; +#ifdef HB_USE_ATEXIT static inline void free_uniscribe_funcs (void) { +retry: + hb_uniscribe_shaper_funcs_t *local_uniscribe_funcs = + (hb_uniscribe_shaper_funcs_t *) hb_atomic_ptr_get (&uniscribe_funcs); + if (!hb_atomic_ptr_cmpexch (&uniscribe_funcs, local_uniscribe_funcs, nullptr)) + goto retry; + free (uniscribe_funcs); } +#endif static hb_uniscribe_shaper_funcs_t * hb_uniscribe_shaper_get_funcs (void) @@ -363,9 +371,10 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) 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 padded_name_table_length = ((name_table_length + 3) & ~3); unsigned int name_table_offset = (length + 3) & ~3; - new_length = name_table_offset + ((name_table_length + 3) & ~3); + new_length = name_table_offset + padded_name_table_length; void *new_sfnt_data = calloc (1, new_length); if (!new_sfnt_data) { @@ -410,7 +419,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) 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.checkSum.set_for_data (&name, padded_name_table_length); record.offset.set (name_table_offset); record.length.set (name_table_length); } @@ -621,12 +630,12 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, /* * Set up features. */ - hb_auto_array_t<OPENTYPE_FEATURE_RECORD> feature_records; - hb_auto_array_t<range_record_t> range_records; + hb_auto_t<hb_vector_t<OPENTYPE_FEATURE_RECORD> > feature_records; + hb_auto_t<hb_vector_t<range_record_t> > range_records; if (num_features) { /* Sort features by start/end events. */ - hb_auto_array_t<feature_event_t> feature_events; + hb_auto_t<hb_vector_t<feature_event_t> > feature_events; for (unsigned int i = 0; i < num_features; i++) { active_feature_t feature; @@ -637,15 +646,11 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, 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; @@ -659,15 +664,13 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, 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; + hb_auto_t<hb_vector_t<active_feature_t> > active_features; unsigned int last_index = 0; for (unsigned int i = 0; i < feature_events.len; i++) { @@ -677,8 +680,6 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, { /* 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; @@ -687,10 +688,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, { 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; + feature_records.push (active_features[j].rec); } else { @@ -709,33 +707,28 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, last_index = event->index; } - if (event->start) { - active_feature_t *feature = active_features.push (); - if (unlikely (!feature)) - goto fail_features; - *feature = event->feature; - } else { + if (event->start) + { + active_features.push (event->feature); + } + else + { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.array); + active_features.remove (feature - active_features.arrayZ); } } if (!range_records.len) /* No active feature found. */ - goto fail_features; + num_features = 0; /* 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); + range->props.potfRecords = feature_records.arrayZ + reinterpret_cast<uintptr_t> (range->props.potfRecords); } } - else - { - fail_features: - num_features = 0; - } #define FAIL(...) \ HB_STMT_START { \ @@ -849,8 +842,8 @@ retry: #undef MAX_ITEMS 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; + hb_auto_t<hb_vector_t<TEXTRANGE_PROPERTIES*> > range_properties; + hb_auto_t<hb_vector_t<int> > range_char_counts; unsigned int glyphs_offset = 0; unsigned int glyphs_len; @@ -907,8 +900,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.array, - range_properties.array, + range_char_counts.arrayZ, + range_properties.arrayZ, range_properties.len, pchars + chars_offset, item_chars_len, @@ -948,8 +941,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.array, - range_properties.array, + range_char_counts.arrayZ, + range_properties.arrayZ, range_properties.len, pchars + chars_offset, log_clusters + chars_offset, diff --git a/src/hb-version.h b/src/hb-version.h index 2750932..2180d84 100644 --- a/src/hb-version.h +++ b/src/hb-version.h @@ -37,10 +37,10 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 1 -#define HB_VERSION_MINOR 7 -#define HB_VERSION_MICRO 6 +#define HB_VERSION_MINOR 8 +#define HB_VERSION_MICRO 1 -#define HB_VERSION_STRING "1.7.6" +#define HB_VERSION_STRING "1.8.1" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ @@ -38,6 +38,7 @@ #include "hb-deprecated.h" #include "hb-face.h" #include "hb-font.h" +#include "hb-map.h" #include "hb-set.h" #include "hb-shape.h" #include "hb-shape-plan.h" diff --git a/src/main.cc b/src/main.cc index d221e9d..ca0fcc5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -24,6 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ +#include "hb-static.cc" #include "hb-open-file-private.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsubgpos-private.hh" @@ -37,10 +38,6 @@ using namespace OT; -#ifndef HB_NO_VISIBILITY -const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; -#endif - int main (int argc, char **argv) { @@ -49,25 +46,21 @@ main (int argc, char **argv) exit (1); } - const char *font_data = nullptr; - int len = 0; - -#ifdef HAVE_GLIB - GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr); - font_data = g_mapped_file_get_contents (mf); - len = g_mapped_file_get_length (mf); -#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); - len = fread ((char *) font_data, 1, len, f); -#endif - + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + unsigned int len; + const char *font_data = hb_blob_get_data (blob, &len); printf ("Opened font file %s: %d bytes long\n", argv[1], len); - const OpenTypeFontFile &ot = *CastP<OpenTypeFontFile> (font_data); + Sanitizer<OpenTypeFontFile> sanitizer; + hb_blob_t *font_blob = sanitizer.sanitize (blob); + const OpenTypeFontFile* sanitized = font_blob->as<OpenTypeFontFile> (); + if (sanitized == &Null(OpenTypeFontFile)) + { + printf ("Sanitization of the file wasn't successful. Exit"); + return 1; + } + const OpenTypeFontFile& ot = *sanitized; + switch (ot.get_tag ()) { case OpenTypeFontFile::TrueTypeTag: @@ -101,7 +94,7 @@ main (int argc, char **argv) for (int n_table = 0; n_table < num_tables; n_table++) { const OpenTypeTable &table = font.get_table (n_table); printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables, - (const char *)table.tag, + (const char *) table.tag, (unsigned int) table.offset, (unsigned int) table.length); @@ -197,5 +190,3 @@ main (int argc, char **argv) return 0; } - - diff --git a/src/test-buffer-serialize.cc b/src/test-buffer-serialize.cc index 636b003..39eb13d 100644 --- a/src/test-buffer-serialize.cc +++ b/src/test-buffer-serialize.cc @@ -32,57 +32,17 @@ #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 = nullptr; - 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, nullptr); - 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_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_face_t *face = hb_face_create (blob, 0 /* first face */); hb_blob_destroy (blob); blob = nullptr; diff --git a/src/test-size-params.cc b/src/test-size-params.cc index 9741b87..3c43852 100644 --- a/src/test-size-params.cc +++ b/src/test-size-params.cc @@ -29,58 +29,18 @@ #include "hb.h" #include "hb-ot.h" -#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 = nullptr; - 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, nullptr); - 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); - } - /* Create the face */ + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_face_t *face = hb_face_create (blob, 0 /* first face */); hb_blob_destroy (blob); blob = nullptr; diff --git a/src/test-would-substitute.cc b/src/test-would-substitute.cc index efebf2d..1836d72 100644 --- a/src/test-would-substitute.cc +++ b/src/test-would-substitute.cc @@ -29,13 +29,6 @@ #include "hb.h" #include "hb-ot.h" -#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> #ifdef HAVE_FREETYPE @@ -45,46 +38,13 @@ int main (int argc, char **argv) { - hb_blob_t *blob = nullptr; - if (argc != 4 && argc != 5) { fprintf (stderr, "usage: %s font-file lookup-index first-glyph [second-glyph]\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, nullptr); - 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); - } - /* Create the face */ + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_face_t *face = hb_face_create (blob, 0 /* first face */); hb_blob_destroy (blob); blob = nullptr; diff --git a/src/test.cc b/src/test.cc index 9592b37..cf59e00 100644 --- a/src/test.cc +++ b/src/test.cc @@ -28,13 +28,6 @@ #include "hb.h" -#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> #ifdef HAVE_FREETYPE @@ -44,45 +37,12 @@ int main (int argc, char **argv) { - hb_blob_t *blob = nullptr; - if (argc != 2) { fprintf (stderr, "usage: %s font-file.ttf\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, nullptr); - 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_blob_t *blob = hb_blob_create_from_file (argv[1]); printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob)); /* Create the face */ |