diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src')
138 files changed, 6156 insertions, 2966 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am index afa104b83e4..be9cd73ca4e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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) @@ -147,10 +135,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) @@ -163,8 +151,8 @@ EXTRA_DIST += 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 +172,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 +182,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 +199,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 +214,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 +231,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' > "$@" \ @@ -289,16 +286,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 +362,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 +384,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/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources index 787c3c4bb52..299af983157 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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 \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh index bfc93b349ae..d4eca5079cb 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc new file mode 100644 index 00000000000..99e8ef9f393 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc new file mode 100644 index 00000000000..401540940ac --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py index 59bd7601296..ccecb406a0b 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py index 1673537c963..9a997d65a1b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py index 735b9015ec7..6252664caae 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py index 06817255c92..413ce11d648 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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 = {} @@ -145,7 +155,8 @@ globals().update(property_values) def is_BASE(U, UISC, UGC): - return (UISC in [Number, Consonant, Consonant_Head_Letter, + # Consonant_Initial_Postfixed is new in Unicode 11; not in the spec. + return (UISC in [Number, Consonant, Consonant_Initial_Postfixed, Consonant_Head_Letter, #SPEC-DRAFT Consonant_Placeholder, Tone_Letter, Vowel_Independent #SPEC-DRAFT @@ -155,7 +166,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): @@ -325,17 +336,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 +364,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 +386,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 +417,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 +444,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh new file mode 100644 index 00000000000..aa82c88cf95 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh new file mode 100644 index 00000000000..b48a27984bc --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh index d0453bd8807..3b7912b9df6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-bsln-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-bsln-table.hh new file mode 100644 index 00000000000..df2bf5b43f0 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh index 7c0dfa8b0cf..2825b181325 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh new file mode 100644 index 00000000000..3e070d79592 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh index ce7ca105faa..cc03d627862 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh index 4cc2824214e..f25842457db 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh index 5767b116cbf..0617e23d517 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc index 45268e3e7ab..7784fae3331 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh new file mode 100644 index 00000000000..15c4e89cbe5 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh index a7e9b11af8b..12caacaaba7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob-private.hh new file mode 100644 index 00000000000..b72fa721b89 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc index b5291f650cc..c138648ca7b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.h index fd561f73869..d1d9134ac27 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh index be374c77a5b..380f3c5fca3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl index 0f7d48ee298..ec9bc7c9ae9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh index a6ab0bbde67..5bca369f8d2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl index fd9be42df14..1d90979a902 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh index af4767f5114..dd6f1dcd383 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index dc0639f4f29..7b95aea4377 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc index d1fcf799aac..a67fcf85e3d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h index 26200ce125b..5dc1ebcd2c5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc index aba7cf44d3f..61f9c35a110 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc index 69a8aa2081b..187ab3f9da9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h index e743af21411..9bfd1f727c4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh index e41384754e4..9586871947f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index d8af8c1f37e..b8d7e84d7c7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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); } @@ -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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h index 0ce8d0462d5..983ee56b1c1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font-private.hh index 992152f176c..7ba16cdefaf 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index f3534b686bf..4d62b9e9c79 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index fc4b11220a9..69132386470 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -109,7 +109,7 @@ _hb_ft_font_destroy (void *data) * @font: * @load_flags: * - * + * * * Since: 1.0.5 **/ @@ -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 @@ -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 * @@ -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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc index 50c30e9c7b9..246380a7350 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc index 46fe1399913..c20f6bef2d8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h index 82b1e64cd2c..05c55debec9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc index 552eaeca51e..c52e165bac9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map-private.hh new file mode 100644 index 00000000000..76c40877383 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map-private.hh @@ -0,0 +1,204 @@ +/* + * 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 = _hb_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; + } +}; + + +#endif /* HB_MAP_PRIVATE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc new file mode 100644 index 00000000000..e3ddae41336 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h new file mode 100644 index 00000000000..b77843c2baf --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex-private.hh index 49ed10e08a6..14bde3103e1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh index baa1f8f05cc..fc48a91b755 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh index e2644eaf91e..2965b46263a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh index 5d33199e128..8180287d494 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh index 02079898683..c1903f6e303 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh index e7ab917e06e..d1dd9de4771 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh index 2c3b1cccae9..ce6702d2ad3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh index e364c8a44d3..2c312748d3b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh new file mode 100644 index 00000000000..09a9517c48d --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh new file mode 100644 index 00000000000..ed6cf970820 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc index ceebe0b7a02..86171c63353 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index 0e373d30f92..8310230328b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh index d62f24bd916..89c867dfa52 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh index f08fe39d8be..d406e3e21cd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh index 1d458404517..965e30a088f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hhea-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hhea-table.hh index 97952b4ebbb..efb42b61616 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hhea-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh index 3cd48a62e93..2c6266453a7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh index 368f547a693..b0fdea4a7e6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh index 20b8bd76223..33dce89099b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh index c5e7f5217c9..763ea92f935 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh index 2d6c66e6c99..60a8d3adff5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh index 46ffcc66883..bc8a5fd6bf8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh index 5f67aed21ed..6e57195b3f4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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)) { @@ -1287,7 +1287,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh index 90546344d69..3cf9d578205 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh @@ -855,7 +855,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 +990,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 +1713,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 +1727,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 +1741,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 +1754,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 +2072,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 +2093,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 +2112,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 +2139,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh index adbaad64f39..7fabdebb2ac 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh index 870ba73fa88..b2f974b82e8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index 1c9e950b29a..8d1471a332b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -30,22 +30,20 @@ #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" hb_ot_layout_t * @@ -56,24 +54,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 +72,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 +97,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 +169,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 +211,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 +221,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 +229,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 +313,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 +893,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); } /** @@ -973,7 +957,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 +1091,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 +1099,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 +1120,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 +1292,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h index 85938ba123e..d82dc022614 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h @@ -307,7 +307,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map-private.hh index e6bd8ea5ef3..4aaf3283113 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc index 54b0ce377d7..46bf2db0c08 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh index 571ce01b71e..5fef2d28f25 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc index f82a07353c9..1667a7da819 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh index 881dedad54c..390b60d72fd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh index eb013337981..bff85df27fd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh index 6cb8d494958..c52b7eb10bb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh index 2cf168f9c55..9b32cfabbc8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh index 9e4792115ea..5f42751d89d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-table.hh index cd6e4058b56..9459aad3d6c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc index 47961bfd55f..124a67f3271 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc index 7508c223c47..7420c5d181b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh index f3cea227123..73f9d58719f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl index 0ea91c0cfe7..35e7ce9067c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh index 867b936278b..9554994a0f6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-table.cc index 867cfb33bf1..54291bc22d8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-table.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc index 32ad86a5f32..447e36cc4dd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh index 380705a5051..d001021561f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl index 8b00c37f093..54644d8aa6b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc index 304879d8fbb..18e3c941ef8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-private.hh index 04f81bd1227..14d011d67d8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc index 3c57bc1ff66..e4214b87e3c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh index 08b6fe9697d..ed6849bfab2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc index 6ba925c675c..02d78ac04a5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh index 0bf3ad3024a..0ec805afca5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl index 11fb47020ac..7ec8a7fd172 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-private.hh index f7ded133d6b..b4bda8bb778 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc index 6823392f4b4..9cc7d33de57 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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, @@ -281,7 +281,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, FAbv, SUB, SUB, SUB, SUB, O, + /* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, B, SUB, SUB, SUB, SUB, O, /* 1A60 */ H, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, FM, FM, O, O, FBlw, /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, @@ -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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc index ee7653b51ce..66b95711cf5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc index c7b46053d8c..fbf31ab249b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc index 62cbb9de998..358450ee7f0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-private.hh index fe5d2b7f333..d6898263f24 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 263d65c0ccb..c20b110e216 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc index 1338c31732f..991d8e77ab8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh index e305a67c261..ad063d32de8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh index 999b7236f3b..82d299685c3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh index e20131b161a..2b384db71a0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh index e835768521e..dfde782f664 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc index 90ba0bd02c6..f0612a61100 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh index daa496e98cd..429bab0035a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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__) @@ -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! @@ -380,7 +389,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 +423,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--) @@ -453,7 +462,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 +498,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) @@ -521,39 +530,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,28 +682,34 @@ 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; @@ -596,6 +719,7 @@ struct hb_prealloced_array_t inline void pop (void) { + if (!len) return; len--; } @@ -603,54 +727,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 +783,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 +798,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 +809,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 +855,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 +878,7 @@ struct hb_lockable_set_t *item = items[items.len - 1]; items.pop (); l.unlock (); - old.finish (); + old.fini (); } else { l.unlock (); } @@ -773,19 +901,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 +919,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 +949,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 +1098,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 +1138,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 +1195,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 +1209,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 +1219,20 @@ 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 + + +HB_INTERNAL unsigned int _hb_prime_for (unsigned int shift); + + #endif /* HB_PRIVATE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-private.hh index 3615c50e9e2..50be93b84f5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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.finish (); - pages.finish (); + page_map.fini (); + pages.fini (); + } + inline void fini (void) + { + 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; @@ -385,7 +403,9 @@ struct hb_set_t 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; @@ -592,10 +612,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc index 07cf9d09b55..b5753222602 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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; } /** diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h index b0f82f82208..764d4eba832 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc index 39355b337d6..c1e73656c17 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc index 2c44cf26533..d44d8c91212 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc new file mode 100644 index 00000000000..aa0871d5b1e --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc @@ -0,0 +1,83 @@ +/* + * 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 + + +/* 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. + */ +static const unsigned int prime_mod [] = +{ + 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 */ +}; + +unsigned int _hb_prime_for (unsigned int shift) +{ + if (unlikely (shift >= ARRAY_LENGTH (prime_mod))) + return prime_mod[ARRAY_LENGTH (prime_mod) - 1]; + + return prime_mod[shift]; +} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-string-array.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-string-array.hh index ba829b0cf04..679841c87d2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-string-array.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc index 0b84c856c2b..c8fa39be807 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc index f8a09efe4d1..7100efc87c8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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, @@ -121,58 +55,64 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf, 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, + 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; - } - - /* 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); + unicodes_to_retain->add (cp); + codepoint_to_glyph->set (cp, gid); + initial_gids_to_retain->add (gid); } // 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 +130,21 @@ 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->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->unicodes, + plan->codepoint_to_glyph, + &plan->glyphs); + _create_old_gid_to_new_gid_map (plan->glyphs, + plan->glyph_map); return plan; } @@ -216,12 +159,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh index d1b66b44d54..c9904af8e40 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh @@ -30,31 +30,67 @@ #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; - // 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 +100,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index 9ebe5d31da2..6d388e29a26 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -41,10 +41,11 @@ #include "hb-ot-hmtx-table.hh" #include "hb-ot-maxp-table.hh" #include "hb-ot-os2-table.hh" +#include "hb-ot-post-table.hh" -#ifndef HB_NO_VISIBILITY -const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +#if !defined(HB_SUBSET_BUILTIN) +#include "hb-static.cc" #endif @@ -86,14 +87,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 +123,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 +133,8 @@ _hb_subset_face_data_create (void) if (unlikely (!data)) return nullptr; + data->tables.init (); + return data; } @@ -139,7 +146,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 +159,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)) @@ -219,8 +226,6 @@ hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) 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 +257,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 +275,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 +294,40 @@ _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 until subsetting is supported. + case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */ + case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */ + case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */ + // 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 +364,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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h index 55ce25b0a1a..409581c76f6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h @@ -72,12 +72,15 @@ HB_EXTERN hb_bool_t * hb_subset_input_drop_hints (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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc index 9515bda2567..2c08718648a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh index 82bb9a4ddc7..5472ece2f2b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc index 726baeb0f19..2d16c2e3a79 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc index cd25769db1a..6d6afe80a0e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h index 7402034f437..fc75a69187c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h @@ -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/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc index d221e9da221..ca0fcc5b607 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc index 636b0037542..39eb13da7f2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/test-size-params.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-size-params.cc index 9741b87ef88..3c43852b3a0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-size-params.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/test-would-substitute.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-would-substitute.cc index efebf2d069f..1836d720cc2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-would-substitute.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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/Build/source/libs/harfbuzz/harfbuzz-src/src/test.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test.cc index 9592b379e9f..cf59e00ac87 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/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 */ |