diff --git a/.circleci/config.yml b/.circleci/config.yml index 1cf4bc885..97a7b1565 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,6 +35,8 @@ jobs: - run: brew update-reset - run: brew install cmake # not needed to be a framework but we like to test that also + # TODO: wrong way of targeting iOS as it doesn't point to iOS headers thus building + # CoreText support is not possible, after the fix feel free HB_IOS from CMake altogether - run: cmake -DBUILD_FRAMEWORK=ON -H. -Bbuild -GXcode -DHB_IOS=ON - run: cd build && xcodebuild -sdk iphoneos12.0 -configuration Release build -arch arm64 @@ -90,6 +92,22 @@ jobs: - run: make -j32 - run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh + gcc-valgrind: + docker: + - image: ubuntu:18.10 + steps: + - checkout + - run: apt update || true + - run: apt install -y gcc binutils libtool autoconf automake make pkg-config gtk-doc-tools ragel libfreetype6-dev libfontconfig1-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip valgrind + - run: pip install fonttools + - run: ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 --with-fontconfig + - run: make -j32 + # run-shape-fuzzer-tests.py automatically runs valgrind if see available + # but test/api runs it by request, we probably should normalize the approaches + - run: RUN_VALGRIND=1 make check && make -Ctest/api check-valgrind || .ci/fail.sh + # informational for now + - run: make -Ctest/api check-symbols || true + clang-everything: docker: - image: ubuntu:18.10 @@ -269,14 +287,14 @@ jobs: - run: cmake -Bbuild -H. -GNinja - run: ninja -Cbuild - crosscompile-cmake-notest-windows-x64: - docker: - - image: dockcross/windows-x64 - steps: - - checkout - - run: apt update && apt install ragel - - run: cmake -Bbuild -H. -GNinja - - run: ninja -Cbuild + #crosscompile-cmake-notest-windows-x64: + # docker: + # - image: dockcross/windows-x64 + # steps: + # - checkout + # - run: apt update && apt install ragel + # - run: cmake -Bbuild -H. -GNinja + # - run: ninja -Cbuild workflows: version: 2 @@ -293,6 +311,7 @@ workflows: # autotools based builds - alpine-O3-NOMMAP - archlinux-debug-O0-py3 + - gcc-valgrind - clang-O3-O0 - clang-everything - clang-asan @@ -317,4 +336,4 @@ workflows: - crosscompile-cmake-notest-browser-asmjs - crosscompile-cmake-notest-linux-arm64 - crosscompile-cmake-notest-linux-mips - - crosscompile-cmake-notest-windows-x64 + #- crosscompile-cmake-notest-windows-x64 diff --git a/BUILD.md b/BUILD.md index 8a6b5695a..4c1c30645 100644 --- a/BUILD.md +++ b/BUILD.md @@ -26,7 +26,7 @@ as with any other standard package. That should leave you with a shared library in `src/`, and a few utility programs including `hb-view` and `hb-shape` under `util/`. -If you are bootstraping from git, you need a few more tools before you can +If you are bootstrapping from git, you need a few more tools before you can run `autogen.sh` for the first time. Namely, `pkg-config` and `ragel`. Again, on Ubuntu / Debian: diff --git a/CMakeLists.txt b/CMakeLists.txt index 760883fda..4eb23af4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,10 +107,10 @@ include (CheckFunctionExists) include (CheckIncludeFile) macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools foreach (func_name ${ARGN}) - string(TOUPPER ${func_name} definiton_to_add) - check_function_exists(${func_name} HAVE_${definiton_to_add}) - if (${HAVE_${definiton_to_add}}) - add_definitions(-DHAVE_${definiton_to_add}) + string(TOUPPER ${func_name} definition_to_add) + check_function_exists(${func_name} HAVE_${definition_to_add}) + if (${HAVE_${definition_to_add}}) + add_definitions(-DHAVE_${definition_to_add}) endif () endforeach () endmacro () diff --git a/NEWS b/NEWS index 58e21a592..b8d364081 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,24 @@ +Overview of changes leading to 2.0.2 +Saturday, October 20, 2018 +==================================== +- Fix two minor memory access issues in AAT tables. + + +Overview of changes leading to 2.0.1 +Friday, October 19, 2018 +==================================== +- Fix hb-version.h reported release version that went wrong (1.8.0) + with previous release. +- Fix extrapolation in 'trak' table. +- Fix hb-font infinite-recursion issue with some font funcs and + subclassed fonts. +- Implement variation-kerning format in kerx table, although without + variation. +- Fix return value of hb_map_is_empty(). + + Overview of changes leading to 2.0.0 -Wednesday, October 17, 2018 +Thursday, October 18, 2018 ==================================== - Added AAT shaping support (morx/kerx/trak). Automatically used if GSUB/GPOS are not available respectively. diff --git a/README.python.md b/README.python.md index 4c0ba9b27..7cf091a09 100644 --- a/README.python.md +++ b/README.python.md @@ -23,7 +23,7 @@ Then make sure you also have GI_TYPELIB_PATH pointing to the resulting $prefix/lib/girepository-* directory. Make sure you have pygobject installed. Then check that the following -import works in your Python interpretter: +import works in your Python interpreter: ```python from gi.repository import HarfBuzz diff --git a/README.wine.md b/README.wine.md index 851d2bf3d..799eb631f 100644 --- a/README.wine.md +++ b/README.wine.md @@ -1,6 +1,6 @@ For the development of HarfBuzz, the Microsoft shaping technology, Uniscribe, as a widely used and tested shaper is used as more-or-less OpenType reference -implemenetation and that specially is important where OpenType specification +implementation and that specially is important where OpenType specification is or wasn't that clear. For having access to Uniscribe on Linux/macOS these steps are recommended: @@ -27,8 +27,8 @@ steps are recommended: Now you can use hb-shape using `wine winbuild/util/hb-shape.exe` but if you like to to use the original Uniscribe, -8. Bring a 32bit version of `usp10.dll` for youself from `C:\Windows\SysWOW64\usp10.dll` of your - Windows installation (asuming you have a 64-bit installation, otherwise `C:\Windows\System32\usp10.dll`) +8. Bring a 32bit version of `usp10.dll` for yourself from `C:\Windows\SysWOW64\usp10.dll` of your + Windows installation (assuming you have a 64-bit installation, otherwise `C:\Windows\System32\usp10.dll`) that it is not a DirectWrite proxy ([for more info](https://en.wikipedia.org/wiki/Uniscribe)). Rule of thumb, your `usp10.dll` should have a size more than 500kb, otherwise it is designed to work with DirectWrite which Wine can't work with its original one. diff --git a/RELEASING.md b/RELEASING.md index d431871c0..4f5705e53 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -27,7 +27,10 @@ HarfBuzz release walk-through checklist: Otherwise, fix things and commit them separately before making release, Note: Check src/hb-version.h and make sure the new version number is there. Sometimes, it does not get updated. If that's the case, - "touch configure.ac" and rebuild. TODO: debug. + "touch configure.ac" and rebuild. Also check that there is no hb-version.h + in your build/src file. Typically it will fail the distcheck if there is. + That's what happened to 2.0.0 going out with 1.8.0 hb-version.h... So, that's + a clue. 7. "make release-files". Enter your GPG password. This creates a sha256 hash and signs it. diff --git a/TODO b/TODO index d2c5812a0..d8e41050e 100644 --- a/TODO +++ b/TODO @@ -15,8 +15,6 @@ API additions - Add sanitize API. -- BCP 47 language handling / API (language_matches?) - - Add query / enumeration API for aalt-like features? - Add segmentation API diff --git a/appveyor.yml b/appveyor.yml index f10078fdd..bf982199b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,9 +28,19 @@ environment: MINGW_CHOST: i686-w64-mingw32 MSYS2_ARCH: i686 + - compiler: cygwin + CYGWIN_PREFIX: C:\Cygwin64 + CYGWIN_ARCH: x86_64 + # Lots of test failures here! + #- compiler: cygwin + # CYGWIN_PREFIX: C:\Cygwin + # CYGWIN_ARCH: x86 + + install: - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --force --noconfirm -Sy && pacman --noconfirm --force -S pacman-mirrors && pacman --force -Syu --noconfirm"' - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-ragel" + - 'if "%compiler%"=="cygwin" %CYGWIN_PREFIX%\setup-%CYGWIN_ARCH%.exe -g -q -P cygwin-devel,libfreetype-devel,libcairo-devel,libicu-devel,gcc,gcc-g++,gobject-introspection,libglib2.0-devel,libgraphite2-devel,pkg-config,python2' build_script: - 'if "%compiler%"=="msvc" if not "%platform%"=="ARM" vcpkg install glib:%triplet% freetype:%triplet% cairo:%triplet%' @@ -49,8 +59,13 @@ build_script: - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://raw.githubusercontent.com/mirror/mingw-w64/023eb04c396d4e8d8fcf604cfababc53dae13398/mingw-w64-headers/include/dwrite_1.h > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"' - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make; make check || .ci/fail.sh"' + - 'if "%compiler%"=="cygwin" set PATH=%PATH%;c:\msys64\mingw64\bin' # msys2 is added just for having "ragel" on PATH + - 'if "%compiler%"=="cygwin" curl https://raw.githubusercontent.com/mirror/mingw-w64/023eb04c396d4e8d8fcf604cfababc53dae13398/mingw-w64-headers/include/dwrite_1.h -o %CYGWIN_PREFIX%\usr\include\dwrite_1.h' + - 'if "%compiler%"=="cygwin" %CYGWIN_PREFIX%\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite; make; make check || .ci/fail.sh"' + cache: - c:\tools\vcpkg\installed\ + - '%CYGWIN_PREFIX%\var\cache\setup' notifications: - provider: Email diff --git a/configure.ac b/configure.ac index a3ce8c1e8..a2d0992a7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [2.0.0], + [2.0.2], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) diff --git a/docs/Makefile.am b/docs/Makefile.am index a9935385b..e48b9ccd8 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -62,7 +62,6 @@ CFILE_GLOB=$(top_srcdir)/src/hb-*.cc # Extra header to include when scanning, which are not under DOC_SOURCE_DIR # e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h -EXTRA_HFILES=$(top_builddir)/src/hb-version.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png diff --git a/src/Makefile.am b/src/Makefile.am index c74bab5d9..e0ea1c5de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -269,7 +269,7 @@ EXTRA_DIST += \ CLEANFILES += $(pkgconfig_DATA) -DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def +DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def harfbuzz-deprecated.def if HAVE_GOBJECT DEF_FILES += harfbuzz-gobject.def endif @@ -283,6 +283,8 @@ harfbuzz-icu.def: $(HB_ICU_headers) $(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^ harfbuzz-gobject.def: $(HB_GOBJECT_headers) $(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^ +harfbuzz-deprecated.def: $(srcdir)/hb-deprecated.h + $(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^ GENERATORS = \ diff --git a/src/Makefile.sources b/src/Makefile.sources index 619715217..575193c08 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -181,6 +181,7 @@ HB_OT_RAGEL_sources = \ HB_OT_headers = \ hb-ot.h \ + hb-ot-color.h \ hb-ot-font.h \ hb-ot-layout.h \ hb-ot-math.h \ diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index f45bc3106..fdd0b097f 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -1,5 +1,6 @@ /* * Copyright © 2018 Ebrahim Byagowi + * Copyright © 2018 Khaled Hosny * * This is part of HarfBuzz, a text shaping library. * @@ -45,8 +46,9 @@ #include #include -static void cbdt_callback (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid) +static 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); @@ -55,8 +57,9 @@ static void cbdt_callback (const uint8_t* data, unsigned int length, fclose (f); } -static void sbix_callback (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid) +static 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); @@ -65,8 +68,9 @@ static void sbix_callback (const uint8_t* data, unsigned int length, fclose (f); } -static void svg_callback (const uint8_t* data, unsigned int length, - unsigned int start_glyph, unsigned int end_glyph) +static 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) @@ -83,13 +87,23 @@ static void svg_callback (const uint8_t* data, unsigned int length, fclose (f); } -static 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) +static void +colr_cpal_rendering (hb_face_t *face, cairo_font_face_t *cairo_face) { - for (unsigned int i = 0; i < num_glyphs; ++i) + unsigned int upem = hb_face_get_upem (face); + + unsigned glyph_count = hb_face_get_glyph_count (face); + for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid) { - unsigned int first_layer_index, num_layers; - if (colr->get_base_glyph_record (i, &first_layer_index, &num_layers)) + unsigned int num_layers = hb_ot_color_get_color_layers (face, gid, 0, nullptr, nullptr, nullptr); + if (!num_layers) + continue; + + hb_codepoint_t *layer_gids = (hb_codepoint_t*) calloc (num_layers, sizeof (hb_codepoint_t)); + unsigned int *color_indices = (unsigned int*) calloc (num_layers, sizeof (unsigned int)); + + hb_ot_color_get_color_layers (face, gid, 0, &num_layers, layer_gids, color_indices); + if (num_layers) { // Measure cairo_text_extents_t extents; @@ -101,12 +115,7 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe 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; - } + glyphs[j].index = layer_gids[j]; cairo_glyph_extents (cr, glyphs, num_layers, &extents); free (glyphs); cairo_surface_destroy (surface); @@ -120,50 +129,62 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe extents.y_bearing -= extents.height / 20; // Render - unsigned int pallet_count = cpal->get_palette_count (); - for (unsigned int pallet = 0; pallet < pallet_count; ++pallet) { + unsigned int palette_count = hb_ot_color_get_palette_count (face); + for (unsigned int palette = 0; palette < palette_count; palette++) { 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); + unsigned int num_colors = hb_ot_color_get_palette_colors (face, palette, 0, nullptr, nullptr); + if (!num_colors) + continue; - 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_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t)); + hb_ot_color_get_palette_colors (face, palette, 0, &num_colors, colors); + if (num_colors) { - hb_codepoint_t glyph_id; - unsigned int color_index; - colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index); + // If we have more than one palette, use a simpler naming + if (palette_count == 1) + sprintf (output_path, "out/colr-%d.svg", gid); + else + sprintf (output_path, "out/colr-%d-%d.svg", gid, palette); - 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., g / 255., b / 255., alpha); + 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); - cairo_glyph_t glyph; - glyph.index = glyph_id; - glyph.x = -extents.x_bearing; - glyph.y = -extents.y_bearing; - cairo_show_glyphs (cr, &glyph, 1); + for (unsigned int layer = 0; layer < num_layers; ++layer) + { + hb_color_t color = 0x000000FF; + if (color_indices[layer] != 0xFFFF) + color = colors[color_indices[layer]]; + cairo_set_source_rgba (cr, + hb_color_get_red (color) / 255., + hb_color_get_green (color) / 255., + hb_color_get_blue (color) / 255., + hb_color_get_alpha (color) / 255.); + + cairo_glyph_t glyph; + glyph.index = layer_gids[layer]; + glyph.x = -extents.x_bearing; + glyph.y = -extents.y_bearing; + cairo_show_glyphs (cr, &glyph, 1); + } + + cairo_surface_destroy (surface); + cairo_destroy (cr); } - - cairo_surface_destroy (surface); - cairo_destroy (cr); + free (colors); } } + + free (layer_gids); + free (color_indices); } } -static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, - unsigned int num_glyphs) +static 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 @@ -208,7 +229,8 @@ static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, } } -int main (int argc, char **argv) +int +main (int argc, char **argv) { if (argc != 2) { fprintf (stderr, "usage: %s font-file.ttf\n" @@ -228,7 +250,7 @@ int main (int argc, char **argv) font_name_file = fopen ("out/_font_name_file.txt", "w"); if (font_name_file == nullptr) { - fprintf (stderr, "./out is not accessible, create it please\n"); + fprintf (stderr, "./out is not accessible as a folder, create it please\n"); exit (1); } fwrite (argv[1], 1, strlen (argv[1]), font_name_file); @@ -253,12 +275,6 @@ int main (int argc, char **argv) svg.dump (svg_callback); svg.fini (); - hb_blob_t* colr_blob = hb_sanitize_context_t ().reference_table (face); - const OT::COLR *colr = colr_blob->as (); - - hb_blob_t* cpal_blob = hb_sanitize_context_t ().reference_table (face); - const OT::CPAL *cpal = cpal_blob->as (); - cairo_font_face_t *cairo_face; { FT_Library library; @@ -267,12 +283,12 @@ int main (int argc, char **argv) FT_New_Face (library, argv[1], 0, &ftface); cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0); } + colr_cpal_rendering (face, cairo_face); + 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); diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh index 2e3ed2758..5f7656d2a 100644 --- a/src/hb-aat-layout-ankr-table.hh +++ b/src/hb-aat-layout-ankr-table.hh @@ -63,8 +63,10 @@ struct ankr unsigned int num_glyphs, const char *end) const { - unsigned int offset = (this+lookupTable).get_value_or_null (glyph_id, num_glyphs); - const GlyphAnchors &anchors = StructAtOffset (&(this+anchorData), offset); + const Offset *offset = (this+lookupTable).get_value (glyph_id, num_glyphs); + if (!offset) + return Null(Anchor); + const GlyphAnchors &anchors = StructAtOffset (&(this+anchorData), *offset); /* TODO Use sanitizer; to avoid overflows and more. */ if (unlikely ((const char *) &anchors + anchors.get_size () > end)) return Null(Anchor); diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 89ed91f28..a99ccaf9f 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -246,6 +246,48 @@ struct LookupFormat8 DEFINE_SIZE_ARRAY (6, valueArrayZ); }; +template +struct LookupFormat10 +{ + friend struct Lookup; + + private: + inline const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const + { + if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount)) + return Null(T); + + const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize]; + + unsigned int v = 0; + unsigned int count = valueSize; + for (unsigned int i = 0; i < count; i++) + v = (v << 8) | *p++; + + return v; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + valueSize <= 4 && + valueArrayZ.sanitize (c, glyphCount * valueSize)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 8 */ + HBUINT16 valueSize; /* Byte size of each value. */ + GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ + HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last + * glyph minus the value of firstGlyph plus 1). */ + UnsizedArrayOf + valueArrayZ; /* The lookup values (indexed by the glyph index + * minus the value of firstGlyph). */ + public: + DEFINE_SIZE_ARRAY (8, valueArrayZ); +}; + template struct Lookup { @@ -261,10 +303,15 @@ struct Lookup } } - inline const T& get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + inline const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { - const T *v = get_value (glyph_id, num_glyphs); - return v ? *v : Null(T); + switch (u.format) { + /* Format 10 cannot return a pointer. */ + case 10: return u.format10.get_value_or_null (glyph_id); + default: + const T *v = get_value (glyph_id, num_glyphs); + return v ? *v : Null(T); + } } inline bool sanitize (hb_sanitize_context_t *c) const @@ -277,6 +324,7 @@ struct Lookup case 4: return_trace (u.format4.sanitize (c)); case 6: return_trace (u.format6.sanitize (c)); case 8: return_trace (u.format8.sanitize (c)); + case 10: return_trace (u.format10.sanitize (c)); default:return_trace (true); } } @@ -289,6 +337,7 @@ struct Lookup LookupFormat4 format4; LookupFormat6 format6; LookupFormat8 format8; + LookupFormat10 format10; } u; public: DEFINE_SIZE_UNION (2, format); diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index c09a6d310..960c37e11 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -45,6 +45,21 @@ namespace AAT { using namespace OT; +static inline int +kerxTupleKern (int value, + unsigned int tupleCount, + const void *base, + hb_aat_apply_context_t *c) +{ + if (likely (!tupleCount)) return value; + + unsigned int offset = value; + const FWORD *pv = &StructAtOffset (base, offset); + if (unlikely (!pv->sanitize (&c->sanitizer))) return 0; + return *pv; +} + + struct KerxSubTableHeader { inline bool sanitize (hb_sanitize_context_t *c) const @@ -63,11 +78,14 @@ struct KerxSubTableHeader struct KerxSubTableFormat0 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, + hb_aat_apply_context_t *c) const { hb_glyph_pair_t pair = {left, right}; int i = pairs.bsearch (pair); - return i == -1 ? 0 : pairs[i].get_kerning (); + if (i == -1) return 0; + int v = pairs[i].get_kerning (); + return kerxTupleKern (v, header.tupleCount, this, c); } inline bool apply (hb_aat_apply_context_t *c) const @@ -77,17 +95,32 @@ struct KerxSubTableFormat0 if (!c->plan->requested_kerning) return false; - hb_kern_machine_t machine (*this); - + accelerator_t accel (*this, c); + hb_kern_machine_t machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); } + struct accelerator_t + { + const KerxSubTableFormat0 &table; + hb_aat_apply_context_t *c; + + inline accelerator_t (const KerxSubTableFormat0 &table_, + hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { return table.get_kerning (left, right, c); } + }; + + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (pairs.sanitize (c))); + return_trace (likely (c->check_struct (this) && + pairs.sanitize (c))); } protected: @@ -143,12 +176,12 @@ struct KerxSubTableFormat1 if (flags & Reset) { - depth = 0; + depth = 0; } if (flags & Push) { - if (likely (depth < ARRAY_LENGTH (stack))) + if (likely (depth < ARRAY_LENGTH (stack))) stack[depth++] = buffer->idx; else depth = 0; /* Probably not what CoreText does, but better? */ @@ -157,14 +190,14 @@ struct KerxSubTableFormat1 if (entry->data.kernActionIndex != 0xFFFF) { const FWORD *actions = &kernAction[entry->data.kernActionIndex]; - if (!c->sanitizer.check_array (actions, depth)) + if (!c->sanitizer.check_array (actions, depth)) { depth = 0; return false; } hb_mask_t kern_mask = c->plan->kern_mask; - for (unsigned int i = 0; i < depth; i++) + for (unsigned int i = 0; i < depth; i++) { /* Apparently, when spec says "Each pops one glyph from the kerning stack * and applies the kerning value to it.", it doesn't mean it in that order. @@ -201,6 +234,9 @@ struct KerxSubTableFormat1 if (!c->plan->requested_kerning) return false; + if (header.tupleCount) + return_trace (false); /* TODO kerxTupleKern */ + driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->font->face); @@ -236,7 +272,7 @@ struct KerxSubTableFormat2 unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+array), offset); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return *v; + return kerxTupleKern (*v, header.tupleCount, this, c); } inline bool apply (hb_aat_apply_context_t *c) const @@ -253,15 +289,6 @@ struct KerxSubTableFormat2 return_trace (true); } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (rowWidth.sanitize (c) && - leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this) && - c->check_range (this, array))); - } - struct accelerator_t { const KerxSubTableFormat2 &table; @@ -275,6 +302,15 @@ struct KerxSubTableFormat2 { return table.get_kerning (left, right, c); } }; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + leftClassTable.sanitize (c, this) && + rightClassTable.sanitize (c, this) && + c->check_range (this, array))); + } + protected: KerxSubTableHeader header; HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ @@ -482,7 +518,7 @@ struct KerxSubTableFormat6 if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return *v; + return kerxTupleKern (*v, header.tupleCount, &(this+vector), c); } else { @@ -492,7 +528,7 @@ struct KerxSubTableFormat6 unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return *v; + return kerxTupleKern (*v, header.tupleCount, &(this+vector), c); } } @@ -523,7 +559,9 @@ struct KerxSubTableFormat6 u.s.rowIndexTable.sanitize (c, this) && u.s.columnIndexTable.sanitize (c, this) && c->check_range (this, u.s.array) - )))); + )) && + (header.tupleCount == 0 || + c->check_range (this, vector)))); } struct accelerator_t @@ -559,8 +597,9 @@ struct KerxSubTableFormat6 LOffsetTo, false> array; } s; } u; + LOffsetTo, false> vector; public: - DEFINE_SIZE_STATIC (32); + DEFINE_SIZE_STATIC (36); }; struct KerxTable @@ -642,9 +681,8 @@ struct kerx { bool reverse; - if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation) || - table->u.header.tupleCount) - goto skip; /* We do NOT handle cross-stream or variation kerning. */ + if (table->u.header.coverage & (KerxTable::CrossStream)) + goto skip; /* We do NOT handle cross-stream. */ if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != bool (table->u.header.coverage & KerxTable::Vertical)) diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index 4b4bc2ffe..16729d16f 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -136,7 +136,7 @@ struct TrackData /* TODO bfind() */ hb_array_t size_table ((base+sizeTable).arrayZ, sizes); unsigned int size_index; - for (size_index = 0; size_index < sizes; size_index++) + for (size_index = 0; size_index < sizes - 1; size_index++) if (size_table[size_index].to_float () >= csspx) break; diff --git a/src/hb-blob.cc b/src/hb-blob.cc index edee67300..368491c05 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -487,8 +487,8 @@ hb_blob_t::try_make_writable (void) #if defined(_WIN32) || defined(__CYGWIN__) # include #else -# ifndef _O_BINARY -# define _O_BINARY 0 +# ifndef O_BINARY +# define O_BINARY 0 # endif #endif @@ -540,7 +540,7 @@ hb_blob_create_from_file (const char *file_name) hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t)); if (unlikely (!file)) return hb_blob_get_empty (); - int fd = open (file_name, O_RDONLY | _O_BINARY, 0); + int fd = open (file_name, O_RDONLY | O_BINARY, 0); if (unlikely (fd == -1)) goto fail_without_close; struct stat st; diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc index c1d82ab8d..1bd603d44 100644 --- a/src/hb-buffer-serialize.cc +++ b/src/hb-buffer-serialize.cc @@ -58,7 +58,7 @@ hb_buffer_serialize_list_formats (void) * @str is a valid buffer serialization format, use * hb_buffer_serialize_list_formats() to get the list of supported formats. * - * Return value: + * Return value: * The parsed #hb_buffer_serialize_format_t. * * Since: 0.9.7 @@ -319,7 +319,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, * ## json * TODO. * - * Return value: + * Return value: * The number of serialized items. * * Since: 0.9.7 @@ -425,14 +425,14 @@ parse_int (const char *pp, const char *end, int32_t *pv) * hb_buffer_deserialize_glyphs: * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): - * @buf_len: + * @buf_len: * @end_ptr: (out): - * @font: - * @format: + * @font: + * @format: * - * * - * Return value: + * + * Return value: * * Since: 0.9.7 **/ diff --git a/src/hb-buffer.h b/src/hb-buffer.h index d0aed02d5..99e01716f 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -89,11 +89,12 @@ typedef struct hb_glyph_info_t * of each line after line-breaking, or limiting * the reshaping to a small piece around the * breaking point only. + * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags. */ typedef enum { /*< flags >*/ HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, - HB_GLYPH_FLAG_DEFINED = 0x00000001 /*< skip >*/ /* OR of all defined flags */ + HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */ } hb_glyph_flags_t; HB_EXTERN hb_glyph_flags_t diff --git a/src/hb-common.cc b/src/hb-common.cc index 4940e7fb5..ba48dd561 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -45,7 +45,7 @@ _hb_options_init (void) { hb_options_union_t u; u.i = 0; - u.opts.initialized = 1; + u.opts.initialized = true; const char *c = getenv ("HB_OPTIONS"); if (c) diff --git a/src/hb-common.h b/src/hb-common.h index 2f09f4318..f9171b41d 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -444,6 +444,18 @@ HB_EXTERN void hb_variation_to_string (hb_variation_t *variation, char *buf, unsigned int size); +/** + * hb_color_t: + * ARGB data type for holding color values. + * + * Since: REPLACEME + */ +typedef uint32_t hb_color_t; + +#define hb_color_get_alpha(color) (color & 0xFF) +#define hb_color_get_red(color) ((color >> 8) & 0xFF) +#define hb_color_get_green(color) ((color >> 16) & 0xFF) +#define hb_color_get_blue(color) ((color >> 24) & 0xFF) HB_END_DECLS diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index aa3921a3f..9f7745dbf 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -643,7 +643,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, CFStringRef string_ref = nullptr; CTLineRef line = nullptr; - if (0) + if (false) { resize_and_retry: DEBUG_MSG (CORETEXT, buffer, "Buffer resize"); @@ -1054,7 +1054,7 @@ resize_and_retry: * * https://crbug.com/419769 */ - if (0) + if (false) { /* Make sure all runs had the expected direction. */ bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h index 5af9bdbd8..369d07361 100644 --- a/src/hb-deprecated.h +++ b/src/hb-deprecated.h @@ -146,12 +146,6 @@ hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose_compatibility_func_t func, void *user_data, hb_destroy_func_t destroy); -/** - * hb_unicode_decompose_compatibility: - * - * - * Deprecated: 2.0.0 - **/ HB_EXTERN HB_DEPRECATED unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_codepoint_t u, diff --git a/src/hb-font.cc b/src/hb-font.cc index 7a430237c..b6b668dd8 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -103,7 +103,7 @@ hb_font_get_nominal_glyph_default (hb_font_t *font, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - if (font->has_nominal_glyphs_func ()) + if (font->has_nominal_glyphs_func_set ()) { return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0); } @@ -121,7 +121,7 @@ hb_font_get_nominal_glyphs_default (hb_font_t *font, unsigned int glyph_stride, void *user_data HB_UNUSED) { - if (font->has_nominal_glyph_func ()) + if (font->has_nominal_glyph_func_set ()) { for (unsigned int i = 0; i < count; i++) { @@ -176,7 +176,7 @@ hb_font_get_glyph_h_advance_default (hb_font_t *font, hb_codepoint_t glyph, void *user_data HB_UNUSED) { - if (font->has_glyph_h_advances_func ()) + if (font->has_glyph_h_advances_func_set ()) { hb_position_t ret; font->get_glyph_h_advances (1, &glyph, 0, &ret, 0); @@ -200,7 +200,7 @@ hb_font_get_glyph_v_advance_default (hb_font_t *font, hb_codepoint_t glyph, void *user_data HB_UNUSED) { - if (font->has_glyph_v_advances_func ()) + if (font->has_glyph_v_advances_func_set ()) { hb_position_t ret; font->get_glyph_v_advances (1, &glyph, 0, &ret, 0); @@ -220,7 +220,7 @@ hb_font_get_glyph_h_advances_default (hb_font_t* font, unsigned int advance_stride, void *user_data HB_UNUSED) { - if (font->has_glyph_h_advance_func ()) + if (font->has_glyph_h_advance_func_set ()) { for (unsigned int i = 0; i < count; i++) { @@ -252,7 +252,7 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font, unsigned int advance_stride, void *user_data HB_UNUSED) { - if (font->has_glyph_v_advance_func ()) + if (font->has_glyph_v_advance_func_set ()) { for (unsigned int i = 0; i < count; i++) { @@ -687,10 +687,16 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT +bool +hb_font_t::has_func_set (unsigned int i) +{ + return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i]; +} + bool hb_font_t::has_func (unsigned int i) { - return (this->klass->get.array[i] != _hb_font_funcs_default.get.array[i]) || + return has_func_set (i) || (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i)); } diff --git a/src/hb-font.hh b/src/hb-font.hh index e10d56745..2df5e42ee 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -171,6 +171,7 @@ struct hb_font_t /* Public getters */ HB_INTERNAL bool has_func (unsigned int i); + HB_INTERNAL bool has_func_set (unsigned int i); /* has_* ... */ #define HB_FONT_FUNC_IMPLEMENT(name) \ @@ -180,6 +181,13 @@ struct hb_font_t hb_font_funcs_t *funcs = this->klass; \ unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \ return has_func (i); \ + } \ + bool \ + has_##name##_func_set (void) \ + { \ + hb_font_funcs_t *funcs = this->klass; \ + unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \ + return has_func_set (i); \ } HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index d836a94d6..ae34c92f4 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -204,7 +204,7 @@ struct hb_dispatch_context_t * The same argument can be made re GSUB/GPOS/GDEF, but there, the table * structure is so complicated that by checking all offsets at sanitize() time, * we make the code much simpler in other methods, as offsets and referenced - * objectes do not need to be validated at each use site. + * objects do not need to be validated at each use site. */ /* This limits sanitizing time on really broken fonts. */ @@ -652,6 +652,7 @@ template struct BEInt { public: + typedef Type type; inline void set (Type V) { v = V; @@ -666,6 +667,7 @@ template struct BEInt { public: + typedef Type type; inline void set (Type V) { v[0] = (V >> 8) & 0xFF; @@ -682,6 +684,7 @@ template struct BEInt { public: + typedef Type type; inline void set (Type V) { v[0] = (V >> 16) & 0xFF; @@ -700,6 +703,7 @@ template struct BEInt { public: + typedef Type type; inline void set (Type V) { v[0] = (V >> 24) & 0xFF; diff --git a/src/hb-map.hh b/src/hb-map.hh index 21898a7a6..b55e3a954 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -172,7 +172,7 @@ struct hb_map_t inline bool is_empty (void) const { - return population != 0; + return population == 0; } inline unsigned int get_population () const diff --git a/src/hb-null.hh b/src/hb-null.hh index ccabf3827..00423e6f7 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -49,7 +49,7 @@ static inline Type const & Null (void) { } #define Null(Type) Null() -/* Specializaitons for arbitrary-content Null objects expressed in bytes. */ +/* Specializations for arbitrary-content Null objects expressed in bytes. */ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ } /* Close namespace. */ \ extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \ @@ -62,7 +62,7 @@ static inline Type const & Null (void) { #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size] -/* Specializaitons for arbitrary-content Null objects expressed as struct initializer. */ +/* Specializations for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ extern HB_INTERNAL const Type _hb_Null_##Type; \ template <> \ diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 8772c79fa..817791ab0 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -160,7 +160,7 @@ typedef struct OffsetTable memcpy (start, hb_blob_get_data (blob, nullptr), rec.length); - /* 4-byte allignment. */ + /* 4-byte alignment. */ c->align (4); const char *end = (const char *) c->head; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 9d2e1fa7c..08e72064a 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -56,6 +56,7 @@ namespace OT { template struct IntType { + typedef Type type; inline void set (Type i) { v.set (i); } inline operator Type(void) const { return v; } inline bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } @@ -161,6 +162,8 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, Index); template struct Offset : Type { + typedef Type type; + inline bool is_null (void) const { return has_null && 0 == *this; } inline void *serialize (hb_serialize_context_t *c, const void *base) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index a59d2bfa9..aef364934 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -39,25 +39,30 @@ namespace OT { struct LayerRecord { - friend struct COLR; - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); } - protected: - GlyphID glyphid; /* Glyph ID of layer glyph */ - HBUINT16 colorIdx; /* Index value to use with a selected color palette */ + public: + GlyphID glyphId; /* Glyph ID of layer glyph */ + HBUINT16 colorIdx; /* Index value to use with a + * selected color palette. + * An index value of 0xFFFF + * is a special case indicating + * that the text foreground + * color (defined by a + * higher-level client) should + * be used and shall not be + * treated as actual index + * into CPAL ColorRecord array. */ public: DEFINE_SIZE_STATIC (4); }; struct BaseGlyphRecord { - friend struct COLR; - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -65,28 +70,64 @@ struct BaseGlyphRecord } inline int cmp (hb_codepoint_t g) const { - return g < glyphid ? -1 : g > glyphid ? 1 : 0; + return g < glyphId ? -1 : g > glyphId ? 1 : 0; } - protected: - GlyphID glyphid; /* Glyph ID of reference glyph */ - HBUINT16 firstLayerIdx; /* Index to the layer record */ - HBUINT16 numLayers; /* Number of color layers associated with this glyph */ + static int cmp (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); + } + + public: + GlyphID glyphId; /* Glyph ID of reference glyph */ + HBUINT16 firstLayerIdx; /* Index (from beginning of + * the Layer Records) to the + * layer record. There will be + * numLayers consecutive entries + * for this base glyph. */ + 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; + inline bool get_base_glyph_record (hb_codepoint_t glyph_id, + unsigned int *first_layer /* OUT */, + unsigned int *num_layers /* OUT */) const + { + const BaseGlyphRecord* record; + record = (BaseGlyphRecord *) bsearch (&glyph_id, &(this+baseGlyphsZ), numBaseGlyphs, + sizeof (BaseGlyphRecord), BaseGlyphRecord::cmp); + if (unlikely (!record)) + return false; + + if (first_layer) *first_layer = record->firstLayerIdx; + if (num_layers) *num_layers = record->numLayers; + return true; + } + + inline bool get_layer_record (unsigned int record, + hb_codepoint_t *glyph_id /* OUT */, + unsigned int *color_index /* OUT */) const + { + if (unlikely (record >= numLayers)) + { + *glyph_id = 0; + *color_index = 0xFFFF; + return false; + } + const LayerRecord &layer = (this+layersZ)[record]; + if (glyph_id) *glyph_id = layer.glyphId; + if (color_index) *color_index = layer.colorIdx; + return true; + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -95,45 +136,14 @@ struct COLR (this+layersZ).sanitize (c, numLayers))); } - inline bool get_base_glyph_record (hb_codepoint_t glyph_id, - unsigned int *first_layer /* OUT */, - unsigned int *num_layers /* OUT */) const - { - 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 bool get_layer_record (unsigned int record, - hb_codepoint_t *glyph_id /* OUT */, - unsigned int *palette_index /* OUT */) const - { - 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 numBaseGlyphs; /* Number of Base Glyph Records */ + HBUINT16 version; /* Table version number (starts at 0). */ + HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ LOffsetTo, false> baseGlyphsZ; /* Offset to Base Glyph records. */ LOffsetTo, false> - layersZ; /* Offset to Layer Records */ - HBUINT16 numLayers; /* Number of Layer Records */ + layersZ; /* Offset to Layer Records. */ + HBUINT16 numLayers; /* Number of Layer Records. */ public: DEFINE_SIZE_STATIC (14); }; diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index e354ced5c..300f2cb44 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -29,53 +29,8 @@ #define HB_OT_COLOR_CPAL_TABLE_HH #include "hb-open-type.hh" - - -/* - * Following parts to be moved to a public header. - */ - -/** - * hb_ot_color_t: - * ARGB data type for holding color values. - * - * Since: REPLACEME - */ -typedef uint32_t hb_ot_color_t; - - -/** - * hb_ot_color_palette_flags_t: - * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special to note about a color palette. - * @HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND: flag indicating that the color palette is suitable for rendering text on light background. - * @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background. - * - * Since: REPLACEME - */ -typedef enum { /*< flags >*/ - HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u, - HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u, - HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u, -} hb_ot_color_palette_flags_t; - -// HB_EXTERN unsigned int -// hb_ot_color_get_palette_count (hb_face_t *face); - -// HB_EXTERN unsigned int -// hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette); - -// HB_EXTERN hb_ot_color_palette_flags_t -// hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette); - -// HB_EXTERN unsigned int -// hb_ot_color_get_palette_colors (hb_face_t *face, -// unsigned int palette, /* default=0 */ -// unsigned int start_offset, -// unsigned int *color_count /* IN/OUT */, -// hb_ot_color_t *colors /* OUT */); - - - +#include "hb-ot-color.h" +#include "hb-ot-name.h" /* @@ -93,30 +48,47 @@ struct CPALV1Tail friend struct CPAL; inline bool - sanitize (hb_sanitize_context_t *c, const void *base, unsigned int palettes) const + sanitize (hb_sanitize_context_t *c, const void *base, + unsigned int palettes, unsigned int paletteEntries) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && (base+paletteFlagsZ).sanitize (c, palettes) && (base+paletteLabelZ).sanitize (c, palettes) && - (base+paletteEntryLabelZ).sanitize (c, palettes)); + (base+paletteEntryLabelZ).sanitize (c, paletteEntries)); } private: inline hb_ot_color_palette_flags_t - get_palette_flags (const void *base, unsigned int palette) const + get_palette_flags (const void *base, unsigned int palette, + unsigned int palettes_count) const { - // range checked at the CPAL caller + if (unlikely (palette >= palettes_count)) + return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; + 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 + get_palette_name_id (const void *base, unsigned int palette, + unsigned int palettes_count) const { - // range checked at the CPAL caller + if (unlikely (palette >= palettes_count)) + return HB_NAME_ID_INVALID; + return (base+paletteLabelZ)[palette]; } + inline unsigned int + get_palette_entry_name_id (const void *base, unsigned int palette_entry, + unsigned int palettes_entries_count) const + { + if (unlikely (palette_entry >= palettes_entries_count)) + return HB_NAME_ID_INVALID; + + return (base+paletteEntryLabelZ)[palette_entry]; + } + protected: LOffsetTo, false> paletteFlagsZ; /* Offset from the beginning of CPAL table to @@ -143,22 +115,22 @@ struct CPAL inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!(c->check_struct (this) && // it checks colorRecordIndices also - // see #get_size + 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 + /* Check for indices sanity so no need for doing it runtime */ for (unsigned int i = 0; i < numPalettes; ++i) 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 is zero, we are done here; otherwise we need to check tail also */ if (version == 0) return_trace (true); const CPALV1Tail &v1 = StructAfter (*this); - return_trace (likely (v1.sanitize (c, this, numPalettes))); + return_trace (likely (v1.sanitize (c, this, numPalettes, numPaletteEntries))); } inline unsigned int get_size (void) const @@ -168,36 +140,48 @@ struct CPAL inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const { - if (unlikely (version == 0 || palette >= numPalettes)) + if (unlikely (version == 0)) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; const CPALV1Tail& cpal1 = StructAfter (*this); - return cpal1.get_palette_flags (this, palette); + return cpal1.get_palette_flags (this, palette, numPalettes); } inline unsigned int get_palette_name_id (unsigned int palette) const { - if (unlikely (version == 0 || palette >= numPalettes)) - return 0xFFFF; + if (unlikely (version == 0)) + return HB_NAME_ID_INVALID; const CPALV1Tail& cpal1 = StructAfter (*this); - return cpal1.get_palette_name_id (this, palette); + return cpal1.get_palette_name_id (this, palette, numPalettes); + } + + inline unsigned int get_palette_entry_name_id (unsigned int palette_entry) const + { + if (unlikely (version == 0)) + return HB_NAME_ID_INVALID; + + const CPALV1Tail& cpal1 = StructAfter (*this); + return cpal1.get_palette_entry_name_id (this, palette_entry, numPaletteEntries); } inline unsigned int get_palette_count () const - { - return numPalettes; - } + { return numPalettes; } - inline hb_ot_color_t - get_color_record_argb (unsigned int color_index, unsigned int palette) const + inline unsigned int get_palette_entries_count () const + { return numPaletteEntries; } + + bool + get_color_record_argb (unsigned int color_index, unsigned int palette, hb_color_t* color) const { if (unlikely (color_index >= numPaletteEntries || palette >= numPalettes)) - return 0; + return false; - // No need for more range check as it is already done on #sanitize + /* No need for more range check as it is already done on #sanitize */ const UnsizedArrayOf& color_records = this+colorRecordsZ; - return color_records[colorRecordIndicesZ[palette] + color_index]; + if (color) + *color = color_records[colorRecordIndicesZ[palette] + color_index]; + return true; } protected: diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 7cdff380e..e47b325d8 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -28,33 +28,56 @@ #include "hb-open-type.hh" #include "hb-ot-color-colr-table.hh" #include "hb-ot-color-cpal-table.hh" +#include "hb-ot-face.hh" #include "hb-ot.h" #include #include #include "hb-ot-layout.hh" -#include "hb-shaper.hh" - -#if 0 -HB_MARK_AS_FLAG_T (hb_ot_color_palette_flags_t) -//HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) Hmm? static inline const OT::COLR& _get_colr (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::COLR); - return *(hb_ot_face_data (face)->colr.get ()); + return *(hb_ot_face_data (face)->COLR.get ()); } static inline const OT::CPAL& _get_cpal (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CPAL); - return *(hb_ot_face_data (face)->cpal.get ()); + return *(hb_ot_face_data (face)->CPAL.get ()); } +/** + * hb_ot_color_has_cpal_data: + * @face: a font face. + * + * Returns: whether CPAL table is available. + * + * Since: REPLACEME + */ +hb_bool_t +hb_ot_color_has_cpal_data (hb_face_t *face) +{ + return &_get_cpal (face) != &Null(OT::CPAL); +} + +/** + * hb_ot_color_has_colr_data: + * @face: a font face. + * + * Returns: whether COLR table is available. + * + * Since: REPLACEME + */ +hb_bool_t +hb_ot_color_has_colr_data (hb_face_t *face) +{ + return &_get_colr (face) != &Null(OT::COLR); +} /** * hb_ot_color_get_palette_count: @@ -68,14 +91,12 @@ _get_cpal (hb_face_t *face) unsigned int hb_ot_color_get_palette_count (hb_face_t *face) { - const OT::CPAL& cpal = _get_cpal (face); - return cpal.get_palette_count (); + return _get_cpal (face).get_palette_count (); } - /** * hb_ot_color_get_palette_name_id: - * @face: a font face. + * @face: a font face. * @palette: the index of the color palette whose name is being requested. * * Retrieves the name id of a color palette. For example, a color font can @@ -89,33 +110,27 @@ hb_ot_color_get_palette_count (hb_face_t *face) * * Since: REPLACEME */ -unsigned int +hb_name_id_t hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette) { - const OT::CPAL& cpal = _get_cpal (face); - return cpal.get_palette_name_id (palette); + return _get_cpal (face).get_palette_name_id (palette); } - /** - * hb_ot_color_get_palette_flags: - * @face: a font face - * @palette: the index of the color palette whose flags are being requested + * hb_ot_color_get_palette_entry_name_id: + * @face: a font face. + * @palette_entry: * - * Returns: the flags for the requested color palette. If @face has no colors, - * or if @palette is not between 0 and hb_ot_color_get_palette_count(), - * the result is #HB_OT_COLOR_PALETTE_FLAG_DEFAULT. + * Returns: Name ID associated with a palette entry, e.g. eye color * * Since: REPLACEME */ -hb_ot_color_palette_flags_t -hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette) +hb_name_id_t +hb_ot_color_get_palette_entry_name_id (hb_face_t *face, unsigned int palette_entry) { - const OT::CPAL& cpal = _get_cpal(face); - return cpal.get_palette_flags (palette); + return _get_cpal (face).get_palette_entry_name_id (palette_entry); } - /** * hb_ot_color_get_palette_colors: * @face: a font face. @@ -125,8 +140,8 @@ hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette) * @color_count: (inout) (optional): on input, how many colors * can be maximally stored into the @colors array; * on output, how many colors were actually stored. - * @colors: (array length=color_count) (optional): - * an array of #hb_ot_color_t records. After calling + * @colors: (array length=color_count) (out) (optional): + * an array of #hb_color_t records. After calling * this function, @colors will be filled with * the palette colors. If @colors is NULL, the function * will just return the number of total colors @@ -144,38 +159,92 @@ hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette) * Since: REPLACEME */ unsigned int -hb_ot_color_get_palette_colors (hb_face_t *face, - unsigned int palette, /* default=0 */ - unsigned int start_offset, - unsigned int *color_count /* IN/OUT */, - hb_ot_color_t *colors /* OUT */) +hb_ot_color_get_palette_colors (hb_face_t *face, + unsigned int palette, /* default=0 */ + unsigned int start_offset, + unsigned int *colors_count /* IN/OUT. May be NULL. */, + hb_color_t *colors /* OUT. May be NULL. */) { const OT::CPAL& cpal = _get_cpal(face); - if (unlikely (palette >= cpal.numPalettes)) + if (unlikely (palette >= cpal.get_palette_count ())) { - if (color_count) *color_count = 0; + if (colors_count) *colors_count = 0; return 0; } - const OT::ColorRecord* crec = &cpal.offsetFirstColorRecord (&cpal); - crec += cpal.colorRecordIndices[palette]; - unsigned int num_results = 0; - if (likely (color_count && colors)) + if (colors_count) { - for (unsigned int i = start_offset; - i < cpal.numPaletteEntries && num_results < *color_count; ++i) + unsigned int platte_count; + platte_count = MIN(*colors_count, + cpal.get_palette_entries_count () - start_offset); + for (unsigned int i = 0; i < platte_count; i++) { - hb_ot_color_t* result = &colors[num_results]; - result->red = crec[i].red; - result->green = crec[i].green; - result->blue = crec[i].blue; - result->alpha = crec[i].alpha; - ++num_results; + if (cpal.get_color_record_argb(start_offset + i, palette, &colors[num_results])) + ++num_results; } } - if (likely (color_count)) *color_count = num_results; - return cpal.numPaletteEntries; + if (likely (colors_count)) *colors_count = num_results; + return cpal.get_palette_entries_count (); +} + +/** + * hb_ot_color_get_color_layers: + * @face: a font face. + * @gid: + * @start_offset: + * @count: (inout) (optional): + * @gids: (array length=count) (out) (optional): + * @color_indices: (array length=count) (out) (optional): + * + * Returns: + * + * Since: REPLACEME + */ +unsigned int +hb_ot_color_get_color_layers (hb_face_t *face, + hb_codepoint_t gid, + unsigned int start_offset, + unsigned int *count /* IN/OUT. May be NULL. */, + hb_codepoint_t *gids /* OUT. May be NULL. */, + unsigned int *color_indices /* OUT. May be NULL. */) +{ + const OT::COLR& colr = _get_colr (face); + unsigned int num_results = 0; + unsigned int start_layer_index, num_layers = 0; + if (colr.get_base_glyph_record (gid, &start_layer_index, &num_layers)) + { + if (count) + { + unsigned int layer_count = MIN(*count, num_layers - start_offset); + for (unsigned int i = 0; i < layer_count; i++) + { + if (colr.get_layer_record (start_layer_index + start_offset + i, + &gids[num_results], &color_indices[num_results])) + ++num_results; + } + } + } + + if (likely (count)) *count = num_results; + return num_layers; +} + +/** + * hb_ot_color_get_palette_flags: + * @face: a font face + * @palette: the index of the color palette whose flags are being requested + * + * Returns: the flags for the requested color palette. If @face has no colors, + * or if @palette is not between 0 and hb_ot_color_get_palette_count(), + * the result is #HB_OT_COLOR_PALETTE_FLAG_DEFAULT. + * + * Since: REPLACEME + */ +hb_ot_color_palette_flags_t +hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette) +{ + const OT::CPAL& cpal = _get_cpal(face); + return cpal.get_palette_flags (palette); } -#endif diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h new file mode 100644 index 000000000..a5f245d69 --- /dev/null +++ b/src/hb-ot-color.h @@ -0,0 +1,90 @@ +/* + * Copyright © 2016 Google, Inc. + * Copyright © 2018 Khaled Hosny + * 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. + * + * Google Author(s): Sascha Brawer + */ + +#ifndef HB_OT_H_IN +#error "Include instead." +#endif + +#ifndef HB_OT_COLOR_H +#define HB_OT_COLOR_H + +#include "hb.h" +#include "hb-ot-name.h" + +HB_BEGIN_DECLS + +HB_EXTERN hb_bool_t +hb_ot_color_has_cpal_data (hb_face_t *face); + +HB_EXTERN hb_bool_t +hb_ot_color_has_colr_data (hb_face_t *face); + +HB_EXTERN unsigned int +hb_ot_color_get_palette_count (hb_face_t *face); + +HB_EXTERN hb_name_id_t +hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette); + +HB_EXTERN hb_name_id_t +hb_ot_color_get_palette_entry_name_id (hb_face_t *face, unsigned int palette_entry); + +HB_EXTERN unsigned int +hb_ot_color_get_palette_colors (hb_face_t *face, + unsigned int palette, /* default=0 */ + unsigned int start_offset, + unsigned int *color_count /* IN/OUT. May be NULL. */, + hb_color_t *colors /* OUT. May be NULL. */); + +HB_EXTERN unsigned int +hb_ot_color_get_color_layers (hb_face_t *face, + hb_codepoint_t gid, + unsigned int start_offset, + unsigned int *count /* IN/OUT. May be NULL. */, + hb_codepoint_t *gids /* OUT. May be NULL. */, + unsigned int *color_indices /* OUT. May be NULL. */); + +/** + * hb_ot_color_palette_flags_t: + * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special to note about a color palette. + * @HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND: flag indicating that the color palette is suitable for rendering text on light background. + * @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background. + * + * Since: REPLACEME + */ +typedef enum { /*< flags >*/ + HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u, + HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u, + HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u, +} hb_ot_color_palette_flags_t; + +HB_EXTERN hb_ot_color_palette_flags_t +hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette); + +HB_END_DECLS + +#endif /* HB_OT_COLOR_H */ diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index dec6d06a3..05aab5775 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -47,6 +47,9 @@ /* OpenType shaping. */ \ HB_OT_TABLE(OT, JSTF) \ HB_OT_TABLE(OT, BASE) \ + /* OpenType color */ \ + HB_OT_TABLE(OT, COLR) \ + HB_OT_TABLE(OT, CPAL) \ /* AAT shaping. */ \ HB_OT_TABLE(AAT, morx) \ HB_OT_TABLE(AAT, kerx) \ diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index cf686a7ee..e4c788658 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -718,7 +718,7 @@ struct Lookup return_trace (true); } - /* Older compileres need this to NOT be locally defined in a function. */ + /* Older compilers need this to NOT be locally defined in a function. */ template struct SubTableSubsetWrapper { @@ -1475,7 +1475,7 @@ struct VarRegionAxis struct VarRegionList { inline float evaluate (unsigned int region_index, - int *coords, unsigned int coord_len) const + const int *coords, unsigned int coord_len) const { if (unlikely (region_index >= regionCount)) return 0.; @@ -1526,7 +1526,7 @@ struct VarData { return itemCount * get_row_size (); } inline float get_delta (unsigned int inner, - int *coords, unsigned int coord_count, + const int *coords, unsigned int coord_count, const VarRegionList ®ions) const { if (unlikely (inner >= itemCount)) @@ -1591,7 +1591,7 @@ struct VarData struct VariationStore { inline float get_delta (unsigned int outer, unsigned int inner, - int *coords, unsigned int coord_count) const + const int *coords, unsigned int coord_count) const { if (unlikely (outer >= dataSets.len)) return 0.; @@ -1602,7 +1602,7 @@ struct VariationStore } inline float get_delta (unsigned int index, - int *coords, unsigned int coord_count) const + const int *coords, unsigned int coord_count) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index cad99a3d6..757090861 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -388,7 +388,7 @@ struct GDEF { return version.to_int () >= 0x00010003u ? this+varStore : Null(VariationStore); } /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing - * glyph class and other bits, and high 8-bit gthe mark attachment type (if any). + * glyph class and other bits, and high 8-bit the mark attachment type (if any). * Not to be confused with lookup_props which is very similar. */ inline unsigned int get_glyph_props (hb_codepoint_t glyph) const { diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 4f81b3278..dad6c4ea9 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1164,7 +1164,7 @@ struct MarkBasePosFormat1 )) break; skippy_iter.reject (); - } while (1); + } while (true); /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); } diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index b664f15a6..2ce52a1b4 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -103,7 +103,7 @@ struct SingleSubstFormat1 TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); - deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */ + deltaGlyphID.set (delta); /* TODO(serialize) overflow? */ return_trace (true); } diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 695a5df99..a4066265c 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -199,8 +199,6 @@ struct hb_collect_glyphs_context_t : after = old_after; recursed_lookups->add (lookup_index); - - return; } hb_face_t *face; @@ -582,7 +580,7 @@ struct hb_ot_apply_context_t : add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED; /* In the only place that the MULTIPLIED bit is used, Uniscribe * seems to only care about the "last" transformation between - * Ligature and Multiple substitions. Ie. if you ligate, expand, + * Ligature and Multiple substitutions. Ie. if you ligate, expand, * and ligate again, it forgives the multiplication and acts as * if only ligation happened. As such, clear MULTIPLIED bit. */ @@ -903,7 +901,7 @@ static inline bool match_input (hb_ot_apply_context_t *c, } static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ + const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_length, hb_codepoint_t lig_glyph, unsigned int total_component_count) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index fb1d9b11f..128253da9 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1115,8 +1115,8 @@ hb_ot_layout_get_size_params (hb_face_t *face, /** * hb_ot_layout_feature_get_name_ids: * @face: #hb_face_t to work upon - * @table_tag: - * @feature_index: + * @table_tag: table tag to query, "GSUB" or "GPOS". + * @feature_index: index of feature to query. * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string * for a user-interface label for this feature. (May be NULL.) * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string @@ -1188,10 +1188,10 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, } /** - * hb_ot_layout_feature_get_characters:: + * hb_ot_layout_feature_get_characters: * @face: #hb_face_t to work upon - * @table_tag: - * @feature_index: + * @table_tag: table tag to query, "GSUB" or "GPOS". + * @feature_index: index of feature to query. * @start_offset: In case the resulting char_count was equal to its input value, there * is a chance there were more characters on the tag so this API can be * called with an offset till resulting char_count gets to a number diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index 3d4e8b066..4dba9c31a 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -201,7 +201,7 @@ subtag_matches (const char *lang_str, if (!ISALNUM (s[strlen (subtag)])) return true; lang_str = s + strlen (subtag); - } while (1); + } while (true); } static hb_bool_t diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index d87285b7f..66e086e1d 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -115,7 +115,7 @@ struct HVARVVAR } inline float get_advance_var (hb_codepoint_t glyph, - int *coords, unsigned int coord_count) const + const int *coords, unsigned int coord_count) const { unsigned int varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, coords, coord_count); diff --git a/src/hb-ot-var-mvar-table.hh b/src/hb-ot-var-mvar-table.hh index d60c6b910..5d6b55954 100644 --- a/src/hb-ot-var-mvar-table.hh +++ b/src/hb-ot-var-mvar-table.hh @@ -72,7 +72,7 @@ struct MVAR } inline float get_var (hb_tag_t tag, - int *coords, unsigned int coord_count) const + const int *coords, unsigned int coord_count) const { const VariationValueRecord *record; record = (VariationValueRecord *) bsearch (&tag, valuesZ.arrayZ, diff --git a/src/hb-ot.h b/src/hb-ot.h index 4b6e3cf74..47508d67c 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -30,6 +30,7 @@ #include "hb.h" +#include "hb-ot-color.h" #include "hb-ot-font.h" #include "hb-ot-layout.h" #include "hb-ot-math.h" diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index b0cf1e92d..b2289f869 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -64,7 +64,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, if (likely (!shaper_list)) { for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) - if (0) + if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ else if (shapers[i].func == _hb_##shaper##_shape) \ @@ -73,7 +73,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, #undef HB_SHAPER_IMPLEMENT } else { for (; *shaper_list; shaper_list++) - if (0) + if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ else if (0 == strcmp (*shaper_list, #shaper)) \ @@ -346,7 +346,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \ } HB_STMT_END - if (0) + if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ else if (shape_plan->shaper_func == _hb_##shaper##_shape) \ @@ -501,7 +501,7 @@ hb_shape_plan_create_cached2 (hb_face_t *face, /* Choose shaper. Adapted from hb_shape_plan_plan(). * Must choose shaper exactly the same way as that function. */ for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++) - if (0) + if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ else if (0 == strcmp (*shaper_item, #shaper) && \ diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index 7b821b46d..596e76d05 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -442,6 +442,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, * Return value: * * Since: 0.9.2 + * Deprecated: 2.0.0 **/ unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, diff --git a/src/hb-version.h b/src/hb-version.h index d10a168a6..a8db51606 100644 --- a/src/hb-version.h +++ b/src/hb-version.h @@ -38,9 +38,9 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 2 #define HB_VERSION_MINOR 0 -#define HB_VERSION_MICRO 0 +#define HB_VERSION_MICRO 2 -#define HB_VERSION_STRING "2.0.0" +#define HB_VERSION_STRING "2.0.2" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 0175c2d4c..26d8eb02d 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -33,6 +33,7 @@ TEST_PROGS = \ test-collect-unicodes \ test-common \ test-font \ + test-map \ test-object \ test-set \ test-shape \ @@ -171,13 +172,18 @@ symbols-tested.txt: $(TEST_PROGS) $(AM_V_GEN)$(top_builddir)/libtool --mode=execute nm $^ \ | grep ' U hb_' | sed 's/.* U hb_/hb_/' \ | sort | uniq > $@.tmp && mv $@.tmp $@ +symbols-tested-or-deprecated.txt: symbols-tested.txt $(top_builddir)/src/harfbuzz-deprecated.def + $(AM_V_GEN)cat $^ | sort | uniq > $@.tmp; mv $@.tmp $@ symbols-exported.txt: $(top_builddir)/src/.libs/libharfbuzz.so $(AM_V_GEN)$(top_builddir)/libtool --mode=execute nm $^ \ | grep ' T ' | sed 's/.* T //' | grep -v '^\(_init\|_fini\)$$' \ | sort | uniq > $@.tmp && mv $@.tmp $@ -symbols-untested.txt: symbols-tested.txt symbols-exported.txt +symbols-untested.txt: symbols-tested-or-deprecated.txt symbols-exported.txt $(AM_V_GEN)diff $^ > $@.tmp; mv $@.tmp $@ -CLEANFILES += symbols-tested.txt symbols-exported.txt symbols-untested.txt +CLEANFILES += symbols-tested.txt \ + symbols-exported.txt \ + symbols-untested.txt \ + symbols-tested-or-deprecated.txt check-symbols: symbols-untested.txt @! cat $^ | grep . diff --git a/test/shaping/data/in-house/fonts/e90374e5e439e00725b4fe7a8d73db57c5a97f82.ttf b/test/api/fonts/cpal-v0.ttf similarity index 100% rename from test/shaping/data/in-house/fonts/e90374e5e439e00725b4fe7a8d73db57c5a97f82.ttf rename to test/api/fonts/cpal-v0.ttf diff --git a/test/shaping/data/in-house/fonts/319f5d7ebffbefc5c5e6569f8cea73444d7a7268.ttf b/test/api/fonts/cpal-v1.ttf similarity index 100% rename from test/shaping/data/in-house/fonts/319f5d7ebffbefc5c5e6569f8cea73444d7a7268.ttf rename to test/api/fonts/cpal-v1.ttf diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h index 5f5cd8d00..6e7888c48 100644 --- a/test/api/hb-subset-test.h +++ b/test/api/hb-subset-test.h @@ -47,27 +47,6 @@ typedef short bool; HB_BEGIN_DECLS -static inline hb_face_t * -hb_subset_test_open_font (const char *font_path) -{ -#if GLIB_CHECK_VERSION(2,37,2) - char *path = g_test_build_filename (G_TEST_DIST, font_path, NULL); -#else - char *path = g_strdup (font_path); -#endif - - hb_blob_t *blob = hb_blob_create_from_file (path); - if (hb_blob_get_length (blob) == 0) - g_error ("Font not found."); - - hb_face_t *face = hb_face_create (blob, 0); - hb_blob_destroy (blob); - - g_free (path); - - return face; -} - static inline hb_subset_input_t * hb_subset_test_create_input(const hb_set_t *codepoints) { diff --git a/test/api/hb-test.h b/test/api/hb-test.h index 39d091b60..5c074c1f6 100644 --- a/test/api/hb-test.h +++ b/test/api/hb-test.h @@ -277,6 +277,27 @@ G_STMT_START { \ } G_STMT_END +static inline hb_face_t * +hb_test_open_font_file (const char *font_path) +{ +#if GLIB_CHECK_VERSION(2,37,2) + char *path = g_test_build_filename (G_TEST_DIST, font_path, NULL); +#else + char *path = g_strdup (font_path); +#endif + + hb_blob_t *blob = hb_blob_create_from_file (path); + if (hb_blob_get_length (blob) == 0) + g_error ("Font not found."); + + hb_face_t *face = hb_face_create (blob, 0); + hb_blob_destroy (blob); + + g_free (path); + + return face; +} + HB_END_DECLS #endif /* HB_TEST_H */ diff --git a/test/api/test-collect-unicodes.c b/test/api/test-collect-unicodes.c index f7a781302..50965a902 100644 --- a/test/api/test-collect-unicodes.c +++ b/test/api/test-collect-unicodes.c @@ -30,7 +30,7 @@ static void test_collect_unicodes_format4 (void) { - hb_face_t *face = hb_subset_test_open_font("fonts/Roboto-Regular.abc.format4.ttf"); + hb_face_t *face = hb_test_open_font_file ("fonts/Roboto-Regular.abc.format4.ttf"); hb_set_t *codepoints = hb_set_create(); hb_codepoint_t cp; @@ -52,7 +52,7 @@ test_collect_unicodes_format4 (void) static void test_collect_unicodes_format12 (void) { - hb_face_t *face = hb_subset_test_open_font("fonts/Roboto-Regular.abc.format12.ttf"); + hb_face_t *face = hb_test_open_font_file ("fonts/Roboto-Regular.abc.format12.ttf"); hb_set_t *codepoints = hb_set_create(); hb_codepoint_t cp; @@ -74,7 +74,7 @@ test_collect_unicodes_format12 (void) static void test_collect_unicodes (void) { - hb_face_t *face = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); hb_set_t *codepoints = hb_set_create(); hb_codepoint_t cp; diff --git a/test/api/test-font.c b/test/api/test-font.c index 4cd8dd8bf..3d81cf961 100644 --- a/test/api/test-font.c +++ b/test/api/test-font.c @@ -364,6 +364,71 @@ test_fontfuncs_subclassing (void) hb_font_destroy (font2); } +static hb_bool_t +nominal_glyph_func (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t unicode HB_UNUSED, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ + *glyph = 0; + return FALSE; +} + +static unsigned int +nominal_glyphs_func (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + unsigned int count HB_UNUSED, + const hb_codepoint_t *first_unicode HB_UNUSED, + unsigned int unicode_stride HB_UNUSED, + hb_codepoint_t *first_glyph HB_UNUSED, + unsigned int glyph_stride HB_UNUSED, + void *user_data HB_UNUSED) +{ + return 0; +} + +static void +test_fontfuncs_parallels (void) +{ + hb_blob_t *blob; + hb_face_t *face; + + hb_font_funcs_t *ffuncs1; + hb_font_funcs_t *ffuncs2; + + hb_font_t *font0; + hb_font_t *font1; + hb_font_t *font2; + + blob = hb_blob_create (test_data, sizeof (test_data), HB_MEMORY_MODE_READONLY, NULL, NULL); + face = hb_face_create (blob, 0); + hb_blob_destroy (blob); + font0 = hb_font_create (face); + hb_face_destroy (face); + + /* setup sub-font1 */ + font1 = hb_font_create_sub_font (font0); + hb_font_destroy (font0); + ffuncs1 = hb_font_funcs_create (); + hb_font_funcs_set_nominal_glyph_func (ffuncs1, nominal_glyph_func, NULL, NULL); + hb_font_set_funcs (font1, ffuncs1, NULL, NULL); + hb_font_funcs_destroy (ffuncs1); + + /* setup sub-font2 */ + font2 = hb_font_create_sub_font (font1); + hb_font_destroy (font1); + ffuncs2 = hb_font_funcs_create (); + hb_font_funcs_set_nominal_glyphs_func (ffuncs1, nominal_glyphs_func, NULL, NULL); + hb_font_set_funcs (font2, ffuncs2, NULL, NULL); + hb_font_funcs_destroy (ffuncs2); + + /* Just test that calling get_nominal_glyph doesn't infinite-loop. */ + hb_codepoint_t glyph; + hb_font_get_nominal_glyph (font2, 0x0020u, &glyph); + + hb_font_destroy (font2); +} static void test_font_empty (void) @@ -543,6 +608,7 @@ main (int argc, char **argv) hb_test_add (test_fontfuncs_empty); hb_test_add (test_fontfuncs_nil); hb_test_add (test_fontfuncs_subclassing); + hb_test_add (test_fontfuncs_parallels); hb_test_add (test_font_empty); hb_test_add (test_font_properties); diff --git a/test/api/test-map.c b/test/api/test-map.c new file mode 100644 index 000000000..0d8be0bbb --- /dev/null +++ b/test/api/test-map.c @@ -0,0 +1,114 @@ +/* + * 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-test.h" + +/* Unit tests for hb-map.h */ + + +static void +test_map_basic (void) +{ + hb_map_t *empty = hb_map_get_empty (); + g_assert (hb_map_is_empty (empty)); + g_assert (!hb_map_allocation_successful (empty)); + hb_map_destroy (empty); + + hb_map_t *m = hb_map_create (); + g_assert (hb_map_allocation_successful (m)); + g_assert (hb_map_is_empty (m)); + + hb_map_set (m, 213, 223); + hb_map_set (m, 643, 675); + g_assert_cmpint (hb_map_get_population (m), ==, 2); + + g_assert_cmpint (hb_map_get (m, 213), ==, 223); + g_assert (!hb_map_has (m, 123)); + g_assert (hb_map_has (m, 213)); + + hb_map_del (m, 213); + g_assert (!hb_map_has (m, 213)); + + g_assert_cmpint (hb_map_get (m, 643), ==, 675); + hb_map_set (m, 237, 673); + g_assert (hb_map_has (m, 237)); + hb_map_clear (m); + g_assert (!hb_map_has (m, 237)); + g_assert (!hb_map_has (m, 643)); + g_assert_cmpint (hb_map_get_population (m), ==, 0); + + hb_map_destroy (m); +} + +static void +test_map_userdata (void) +{ + hb_map_t *m = hb_map_create (); + + hb_user_data_key_t key[2]; + int *data = (int *) malloc (sizeof (int)); + *data = 3123; + hb_map_set_user_data (m, &key[0], data, free, TRUE); + g_assert_cmpint (*((int *) hb_map_get_user_data (m, &key[0])), ==, 3123); + + int *data2 = (int *) malloc (sizeof (int)); + *data2 = 6343; + hb_map_set_user_data (m, &key[0], data2, free, FALSE); + g_assert_cmpint (*((int *) hb_map_get_user_data (m, &key[0])), ==, 3123); + hb_map_set_user_data (m, &key[0], data2, free, TRUE); + g_assert_cmpint (*((int *) hb_map_get_user_data (m, &key[0])), ==, 6343); + + hb_map_destroy (m); +} + +static void +test_map_refcount (void) +{ + hb_map_t *m = hb_map_create (); + hb_map_set (m, 213, 223); + g_assert_cmpint (hb_map_get (m, 213), ==, 223); + + hb_map_t *m2 = hb_map_reference (m); + hb_map_destroy (m); + + /* We copied its reference so it is still usable after one destroy */ + g_assert (hb_map_has (m, 213)); + g_assert (hb_map_has (m2, 213)); + + hb_map_destroy (m2); + + /* Now you can't access them anymore */ +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_map_basic); + hb_test_add (test_map_userdata); + hb_test_add (test_map_refcount); + + return hb_test_run(); +} diff --git a/test/api/test-multithread.c b/test/api/test-multithread.c index 7b62a0298..f9460497e 100644 --- a/test/api/test-multithread.c +++ b/test/api/test-multithread.c @@ -23,16 +23,13 @@ * */ -#include -#include -#include - #include #include #include #include -#include + +#include "hb-test.h" static const char *font_path = "fonts/Inconsolata-Regular.abc.ttf"; static const char *text = "abc"; @@ -127,15 +124,9 @@ test_body (void) int main (int argc, char **argv) { - g_test_init (&argc, &argv, NULL); + hb_test_init (&argc, &argv); -#if GLIB_CHECK_VERSION(2,37,2) - gchar *default_path = g_test_build_filename (G_TEST_DIST, font_path, NULL); -#else - gchar *default_path = g_strdup (font_path); -#endif - - char *path = argc > 1 && *argv[1] ? argv[1] : (char *) default_path; + char *path = argc > 1 && *argv[1] ? argv[1] : (char *) font_path; if (argc > 2) num_threads = atoi (argv[2]); if (argc > 3) @@ -147,11 +138,7 @@ main (int argc, char **argv) * https://github.com/harfbuzz/harfbuzz/issues/1191 */ hb_language_get_default (); - hb_blob_t *blob = hb_blob_create_from_file (path); - if (hb_blob_get_length (blob) == 0) - g_error ("Font not found."); - - hb_face_t *face = hb_face_create (blob, 0); + hb_face_t *face = hb_test_open_font_file (path); font = hb_font_create (face); /* Fill the reference */ @@ -170,9 +157,6 @@ main (int argc, char **argv) hb_font_destroy (font); hb_face_destroy (face); - hb_blob_destroy (blob); - - g_free (default_path); return 0; } diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 254f01556..4e358203d 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -1,5 +1,6 @@ /* * Copyright © 2016 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -98,27 +99,25 @@ static hb_face_t *cpal_v0 = NULL; */ static hb_face_t *cpal_v1 = NULL; - -#if 0 #define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START { \ - const hb_ot_color_t *_colors = (colors); \ + const hb_color_t *_colors = (colors); \ const size_t _i = (i); \ const uint8_t red = (r), green = (g), blue = (b), alpha = (a); \ - if (_colors[_i].red != red) { \ + if (hb_color_get_red (_colors[_i]) != red) { \ g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - "colors[" #i "].red", _colors[_i].red, "==", red, 'x'); \ + "colors[" #i "]", _colors[_i], "==", red, 'x'); \ } \ - if (_colors[_i].green != green) { \ + if (hb_color_get_green (_colors[_i]) != green) { \ g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - "colors[" #i "].green", _colors[_i].green, "==", green, 'x'); \ + "colors[" #i "]", _colors[_i], "==", green, 'x'); \ } \ - if (_colors[_i].blue != blue) { \ + if (hb_color_get_blue (_colors[_i]) != blue) { \ g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - "colors[" #i "].blue", colors[i].blue, "==", blue, 'x'); \ + "colors[" #i "]", colors[_i], "==", blue, 'x'); \ } \ - if (_colors[_i].alpha != alpha) { \ + if (hb_color_get_alpha (_colors[_i]) != alpha) { \ g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - "colors[" #i "].alpha", _colors[_i].alpha, "==", alpha, 'x'); \ + "colors[" #i "]", _colors[_i], "==", alpha, 'x'); \ } \ } G_STMT_END @@ -136,19 +135,19 @@ static void test_hb_ot_color_get_palette_name_id_empty (void) { /* numPalettes=0, so all calls are for out-of-bounds palette indices */ - g_assert_cmpint (hb_ot_color_get_palette_name_id (hb_face_get_empty(), 0), ==, 0xffff); - g_assert_cmpint (hb_ot_color_get_palette_name_id (hb_face_get_empty(), 1), ==, 0xffff); + g_assert_cmpint (hb_ot_color_get_palette_name_id (hb_face_get_empty(), 0), ==, HB_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_get_palette_name_id (hb_face_get_empty(), 1), ==, HB_NAME_ID_INVALID); } static void test_hb_ot_color_get_palette_name_id_v0 (void) { - g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 0), ==, 0xffff); - g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 1), ==, 0xffff); + g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 0), ==, HB_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 1), ==, HB_NAME_ID_INVALID); /* numPalettes=2, so palette #2 is out of bounds */ - g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 2), ==, 0xffff); + g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 2), ==, HB_NAME_ID_INVALID); } @@ -156,13 +155,14 @@ static void test_hb_ot_color_get_palette_name_id_v1 (void) { g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 0), ==, 257); - g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 1), ==, 0xffff); + g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 1), ==, HB_NAME_ID_INVALID); g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 2), ==, 258); /* numPalettes=3, so palette #3 is out of bounds */ - g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 3), ==, 0xffff); + g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 3), ==, HB_NAME_ID_INVALID); } + static void test_hb_ot_color_get_palette_flags_empty (void) { @@ -207,7 +207,7 @@ static void test_hb_ot_color_get_palette_colors_v0 (void) { unsigned int num_colors = hb_ot_color_get_palette_colors (cpal_v0, 0, 0, NULL, NULL); - hb_ot_color_t *colors = (hb_ot_color_t*) alloca (num_colors * sizeof (hb_ot_color_t)); + hb_color_t *colors = (hb_color_t*) alloca (num_colors * sizeof (hb_color_t)); size_t colors_size = num_colors * sizeof(*colors); g_assert_cmpint (num_colors, ==, 2); @@ -243,7 +243,7 @@ test_hb_ot_color_get_palette_colors_v0 (void) assert_color_rgba (colors, 1, 0x44, 0x44, 0x44, 0x44); /* untouched */ /* start_index > numPaletteEntries */ - memset(colors, 0x44, colors_size); + memset (colors, 0x44, colors_size); num_colors = 2; g_assert_cmpint (hb_ot_color_get_palette_colors (cpal_v0, 0, 9876, &num_colors, colors), ==, 2); g_assert_cmpint (num_colors, ==, 0); @@ -255,13 +255,13 @@ test_hb_ot_color_get_palette_colors_v0 (void) static void test_hb_ot_color_get_palette_colors_v1 (void) { - hb_ot_color_t colors[3]; + hb_color_t colors[3]; unsigned int num_colors = hb_ot_color_get_palette_colors (cpal_v1, 0, 0, NULL, NULL); - size_t colors_size = 3 * sizeof(*colors); + size_t colors_size = 3 * sizeof (hb_color_t); g_assert_cmpint (num_colors, ==, 2); /* Palette #0, start_index=0 */ - memset(colors, 0x77, colors_size); + memset (colors, 0x77, colors_size); g_assert_cmpint (hb_ot_color_get_palette_colors (cpal_v1, 0, 0, &num_colors, colors), ==, 2); g_assert_cmpint (num_colors, ==, 2); assert_color_rgba (colors, 0, 0x00, 0x00, 0x00, 0xff); @@ -269,7 +269,7 @@ test_hb_ot_color_get_palette_colors_v1 (void) assert_color_rgba (colors, 2, 0x77, 0x77, 0x77, 0x77); /* untouched */ /* Palette #1, start_index=0 */ - memset(colors, 0x77, colors_size); + memset (colors, 0x77, colors_size); g_assert_cmpint (hb_ot_color_get_palette_colors (cpal_v1, 1, 0, &num_colors, colors), ==, 2); g_assert_cmpint (num_colors, ==, 2); assert_color_rgba (colors, 0, 0x00, 0x00, 0x00, 0xff); @@ -277,7 +277,7 @@ test_hb_ot_color_get_palette_colors_v1 (void) assert_color_rgba (colors, 2, 0x77, 0x77, 0x77, 0x77); /* untouched */ /* Palette #2, start_index=0 */ - memset(colors, 0x77, colors_size); + memset (colors, 0x77, colors_size); g_assert_cmpint (hb_ot_color_get_palette_colors (cpal_v1, 2, 0, &num_colors, colors), ==, 2); g_assert_cmpint (num_colors, ==, 2); assert_color_rgba (colors, 0, 0x00, 0x00, 0x00, 0xff); @@ -285,14 +285,78 @@ test_hb_ot_color_get_palette_colors_v1 (void) assert_color_rgba (colors, 2, 0x77, 0x77, 0x77, 0x77); /* untouched */ /* Palette #3 (out of bounds), start_index=0 */ - memset(colors, 0x77, colors_size); + memset (colors, 0x77, colors_size); g_assert_cmpint (hb_ot_color_get_palette_colors (cpal_v1, 3, 0, &num_colors, colors), ==, 0); g_assert_cmpint (num_colors, ==, 0); assert_color_rgba (colors, 0, 0x77, 0x77, 0x77, 0x77); /* untouched */ assert_color_rgba (colors, 1, 0x77, 0x77, 0x77, 0x77); /* untouched */ assert_color_rgba (colors, 2, 0x77, 0x77, 0x77, 0x77); /* untouched */ } -#endif + + +static void +test_hb_ot_color_get_palette_entry_name_id (void) +{ + hb_face_t *empty = hb_face_get_empty (); + + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (empty, 0), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (empty, 1), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (empty, 2), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v0, 0), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v0, 1), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v0, 2), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v1, 0), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v1, 1), ==, 256); + g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v1, 2), ==, HB_NAME_ID_INVALID); +} + + +static void +test_hb_ot_color_get_color_layers (void) +{ + hb_codepoint_t layer_gids[1]; + unsigned int color_indices[1]; + unsigned int count = 1; + + g_assert_cmpuint (hb_ot_color_get_color_layers (cpal_v1, 0, 0, + NULL, NULL, NULL), ==, 0); + g_assert_cmpuint (hb_ot_color_get_color_layers (cpal_v1, 1, 0, + NULL, NULL, NULL), ==, 0); + g_assert_cmpuint (hb_ot_color_get_color_layers (cpal_v1, 2, 0, + NULL, NULL, NULL), ==, 2); + + unsigned int num_layers; + num_layers = hb_ot_color_get_color_layers (cpal_v1, 2, 0, &count, layer_gids, + color_indices); + + g_assert_cmpuint (num_layers, ==, 2); + g_assert_cmpuint (count, ==, 1); + g_assert_cmpuint (layer_gids[0], ==, 3); + g_assert_cmpuint (color_indices[0], ==, 1); + + count = 1; + hb_ot_color_get_color_layers (cpal_v1, 2, 1, &count, layer_gids, + color_indices); + + g_assert_cmpuint (num_layers, ==, 2); + g_assert_cmpuint (count, ==, 1); + g_assert_cmpuint (layer_gids[0], ==, 4); + g_assert_cmpuint (color_indices[0], ==, 0); +} + +static void +test_hb_ot_color_has_data (void) +{ + hb_face_t *empty = hb_face_get_empty (); + + g_assert (hb_ot_color_has_colr_data (empty) == FALSE); + g_assert (hb_ot_color_has_colr_data (cpal_v0) == TRUE); + g_assert (hb_ot_color_has_colr_data (cpal_v1) == TRUE); + + g_assert (hb_ot_color_has_cpal_data (empty) == FALSE); + g_assert (hb_ot_color_has_cpal_data (cpal_v0) == TRUE); + g_assert (hb_ot_color_has_cpal_data (cpal_v1) == TRUE); +} int main (int argc, char **argv) @@ -300,18 +364,21 @@ main (int argc, char **argv) int status = 0; hb_test_init (&argc, &argv); - // cpal_v0 = hb_test_load_face ("../shaping/data/in-house/fonts/e90374e5e439e00725b4fe7a8d73db57c5a97f82.ttf"); - // cpal_v1 = hb_test_load_face ("../shaping/data/in-house/fonts/319f5d7ebffbefc5c5e6569f8cea73444d7a7268.ttf"); - // hb_test_add (test_hb_ot_color_get_palette_count); - // hb_test_add (test_hb_ot_color_get_palette_name_id_empty); - // hb_test_add (test_hb_ot_color_get_palette_name_id_v0); - // hb_test_add (test_hb_ot_color_get_palette_name_id_v1); - // hb_test_add (test_hb_ot_color_get_palette_flags_empty); - // hb_test_add (test_hb_ot_color_get_palette_flags_v0); - // hb_test_add (test_hb_ot_color_get_palette_flags_v1); - // hb_test_add (test_hb_ot_color_get_palette_colors_empty); - // hb_test_add (test_hb_ot_color_get_palette_colors_v0); - // hb_test_add (test_hb_ot_color_get_palette_colors_v1); + cpal_v0 = hb_test_open_font_file ("fonts/cpal-v0.ttf"); + cpal_v1 = hb_test_open_font_file ("fonts/cpal-v1.ttf"); + hb_test_add (test_hb_ot_color_get_palette_count); + hb_test_add (test_hb_ot_color_get_palette_name_id_empty); + hb_test_add (test_hb_ot_color_get_palette_name_id_v0); + hb_test_add (test_hb_ot_color_get_palette_name_id_v1); + hb_test_add (test_hb_ot_color_get_palette_flags_empty); + hb_test_add (test_hb_ot_color_get_palette_flags_v0); + hb_test_add (test_hb_ot_color_get_palette_flags_v1); + hb_test_add (test_hb_ot_color_get_palette_colors_empty); + hb_test_add (test_hb_ot_color_get_palette_colors_v0); + hb_test_add (test_hb_ot_color_get_palette_colors_v1); + hb_test_add (test_hb_ot_color_get_palette_entry_name_id); + hb_test_add (test_hb_ot_color_get_color_layers); + hb_test_add (test_hb_ot_color_has_data); status = hb_test_run(); hb_face_destroy (cpal_v0); hb_face_destroy (cpal_v1); diff --git a/test/api/test-ot-name.c b/test/api/test-ot-name.c index 477e67f0d..d73339785 100644 --- a/test/api/test-ot-name.c +++ b/test/api/test-ot-name.c @@ -27,12 +27,10 @@ #include -static const char *font_path = "fonts/cv01.otf"; -static hb_face_t *face; - static void -test_ot_layout_feature_get_name_ids_and_characters () +test_ot_layout_feature_get_name_ids_and_characters (void) { + hb_face_t *face = hb_test_open_font_file ("fonts/cv01.otf"); hb_tag_t cv01 = HB_TAG ('c','v','0','1'); unsigned int feature_index; if (!hb_ot_layout_language_find_feature (face, @@ -53,11 +51,11 @@ test_ot_layout_feature_get_name_ids_and_characters () &num_named_parameters, &first_param_id)) g_error ("Failed to get name ids"); - g_assert (label_id == 256); - g_assert (tooltip_id == 257); - g_assert (sample_id == 258); - g_assert (num_named_parameters == 2); - g_assert (first_param_id == 259); + g_assert_cmpint (label_id, ==, 256); + g_assert_cmpint (tooltip_id, ==, 257); + g_assert_cmpint (sample_id, ==, 258); + g_assert_cmpint (num_named_parameters, ==, 2); + g_assert_cmpint (first_param_id, ==, 259); hb_codepoint_t characters[100]; unsigned int char_count = 100; @@ -66,10 +64,12 @@ test_ot_layout_feature_get_name_ids_and_characters () all_chars = hb_ot_layout_feature_get_characters (face, HB_OT_TAG_GSUB, feature_index, 0, &char_count, characters); - g_assert (all_chars == 2); - g_assert (char_count == 2); - g_assert (characters[0] == 10); - g_assert (characters[1] == 24030); + g_assert_cmpint (all_chars, ==, 2); + g_assert_cmpint (char_count, ==, 2); + g_assert_cmpint (characters[0], ==, 10); + g_assert_cmpint (characters[1], ==, 24030); + + hb_face_destroy (face); } int @@ -77,26 +77,7 @@ main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); -#if GLIB_CHECK_VERSION(2,37,2) - gchar *default_path = g_test_build_filename (G_TEST_DIST, font_path, NULL); -#else - gchar *default_path = g_strdup (font_path); -#endif - - hb_blob_t *blob; - - char *path = argc > 1 && *argv[1] ? argv[1] : (char *) default_path; - blob = hb_blob_create_from_file (path); - if (hb_blob_get_length (blob) == 0) - g_error ("Font not found."); - - face = hb_face_create (blob, 0); - hb_test_add (test_ot_layout_feature_get_name_ids_and_characters); - unsigned int result = hb_test_run (); - hb_face_destroy (face); - hb_blob_destroy (blob); - g_free (default_path); - return result; + return hb_test_run (); } diff --git a/test/api/test-set.c b/test/api/test-set.c index 1382adaa9..aa2b388ea 100644 --- a/test/api/test-set.c +++ b/test/api/test-set.c @@ -118,6 +118,9 @@ test_set_basic (void) g_assert (!hb_set_has (s, 801)); g_assert (!hb_set_has (s, 802)); + hb_set_del (s, 800); + g_assert (!hb_set_has (s, 800)); + hb_set_destroy (s); } diff --git a/test/api/test-subset-cmap.c b/test/api/test-subset-cmap.c index 84d34bcd7..74e91ca3a 100644 --- a/test/api/test-subset-cmap.c +++ b/test/api/test-subset-cmap.c @@ -32,8 +32,8 @@ static void test_subset_cmap (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -52,7 +52,7 @@ test_subset_cmap (void) static void test_subset_cmap_non_consecutive_glyphs (void) { - hb_face_t *face = hb_subset_test_open_font ("fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf"); + hb_face_t *face = hb_test_open_font_file ("fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_subset; @@ -74,7 +74,7 @@ test_subset_cmap_non_consecutive_glyphs (void) static void test_subset_cmap_noop (void) { - hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_abc_subset; diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c index 05c7f8cfe..0e5c29311 100644 --- a/test/api/test-subset-glyf.c +++ b/test/api/test-subset-glyf.c @@ -60,8 +60,8 @@ static void check_maxp_num_glyphs (hb_face_t *face, uint16_t expected_num_glyphs static void test_subset_glyf (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_abc_subset; @@ -82,8 +82,8 @@ test_subset_glyf (void) static void test_subset_glyf_with_components (void) { - hb_face_t *face_components = hb_subset_test_open_font ("fonts/Roboto-Regular.components.ttf"); - hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Roboto-Regular.components.subset.ttf"); + hb_face_t *face_components = hb_test_open_font_file ("fonts/Roboto-Regular.components.ttf"); + hb_face_t *face_subset = hb_test_open_font_file ("fonts/Roboto-Regular.components.subset.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_generated_subset; @@ -103,8 +103,8 @@ test_subset_glyf_with_components (void) static void test_subset_glyf_with_gsub (void) { - hb_face_t *face_fil = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fil.ttf"); - hb_face_t *face_fi = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fi.ttf"); + hb_face_t *face_fil = hb_test_open_font_file ("fonts/Roboto-Regular.gsub.fil.ttf"); + hb_face_t *face_fi = hb_test_open_font_file ("fonts/Roboto-Regular.gsub.fi.ttf"); hb_subset_input_t *input; hb_face_t *face_subset; @@ -130,8 +130,8 @@ test_subset_glyf_with_gsub (void) static void test_subset_glyf_without_gsub (void) { - hb_face_t *face_fil = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fil.ttf"); - hb_face_t *face_fi = hb_subset_test_open_font ("fonts/Roboto-Regular.nogsub.fi.ttf"); + hb_face_t *face_fil = hb_test_open_font_file ("fonts/Roboto-Regular.gsub.fil.ttf"); + hb_face_t *face_fi = hb_test_open_font_file ("fonts/Roboto-Regular.nogsub.fi.ttf"); hb_subset_input_t *input; hb_face_t *face_subset; @@ -157,7 +157,7 @@ test_subset_glyf_without_gsub (void) static void test_subset_glyf_noop (void) { - hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_abc_subset; @@ -178,8 +178,8 @@ test_subset_glyf_noop (void) static void test_subset_glyf_strip_hints_simple (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.nohints.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.nohints.ttf"); hb_set_t *codepoints = hb_set_create(); hb_subset_input_t *input; @@ -203,8 +203,8 @@ test_subset_glyf_strip_hints_simple (void) static void test_subset_glyf_strip_hints_composite (void) { - hb_face_t *face_components = hb_subset_test_open_font ("fonts/Roboto-Regular.components.ttf"); - hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Roboto-Regular.components.1fc.nohints.ttf"); + hb_face_t *face_components = hb_test_open_font_file ("fonts/Roboto-Regular.components.ttf"); + hb_face_t *face_subset = hb_test_open_font_file ("fonts/Roboto-Regular.components.1fc.nohints.ttf"); hb_set_t *codepoints = hb_set_create(); hb_subset_input_t *input; @@ -228,7 +228,7 @@ test_subset_glyf_strip_hints_composite (void) static void test_subset_glyf_strip_hints_invalid (void) { - hb_face_t *face = hb_subset_test_open_font ("../fuzzing/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a"); + hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a"); hb_set_t *codepoints = hb_set_create(); const hb_codepoint_t text[] = diff --git a/test/api/test-subset-hdmx.c b/test/api/test-subset-hdmx.c index 8496f9e8f..44e579ace 100644 --- a/test/api/test-subset-hdmx.c +++ b/test/api/test-subset-hdmx.c @@ -33,8 +33,8 @@ static void test_subset_hdmx_simple_subset (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -53,8 +53,8 @@ test_subset_hdmx_simple_subset (void) static void test_subset_hdmx_multiple_device_records (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.multihdmx.abc.ttf"); - hb_face_t *face_a = hb_subset_test_open_font ("fonts/Roboto-Regular.multihdmx.a.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.multihdmx.abc.ttf"); + hb_face_t *face_a = hb_test_open_font_file ("fonts/Roboto-Regular.multihdmx.a.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -72,7 +72,7 @@ test_subset_hdmx_multiple_device_records (void) static void test_subset_hdmx_invalid (void) { - hb_face_t *face = hb_subset_test_open_font("../fuzzing/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a"); + hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a"); hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t *codepoints = hb_subset_input_unicode_set (input); @@ -94,7 +94,7 @@ test_subset_hdmx_invalid (void) static void test_subset_hdmx_fails_sanitize (void) { - hb_face_t *face = hb_subset_test_open_font("../fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016"); + hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016"); hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t *codepoints = hb_subset_input_unicode_set (input); @@ -116,7 +116,7 @@ test_subset_hdmx_fails_sanitize (void) static void test_subset_hdmx_noop (void) { - hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_abc_subset; diff --git a/test/api/test-subset-hmtx.c b/test/api/test-subset-hmtx.c index 1a5a44dc5..1b51dc2f8 100644 --- a/test/api/test-subset-hmtx.c +++ b/test/api/test-subset-hmtx.c @@ -47,8 +47,8 @@ static void check_num_hmetrics(hb_face_t *face, uint16_t expected_num_hmetrics) static void test_subset_hmtx_simple_subset (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -69,8 +69,8 @@ test_subset_hmtx_simple_subset (void) static void test_subset_hmtx_monospace (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Inconsolata-Regular.abc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ac.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Inconsolata-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Inconsolata-Regular.ac.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -91,8 +91,8 @@ test_subset_hmtx_monospace (void) static void test_subset_hmtx_keep_num_metrics (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Inconsolata-Regular.abc.widerc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ac.widerc.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Inconsolata-Regular.abc.widerc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Inconsolata-Regular.ac.widerc.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -112,8 +112,8 @@ test_subset_hmtx_keep_num_metrics (void) static void test_subset_hmtx_decrease_num_metrics (void) { - hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Inconsolata-Regular.abc.widerc.ttf"); - hb_face_t *face_ab = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ab.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Inconsolata-Regular.abc.widerc.ttf"); + hb_face_t *face_ab = hb_test_open_font_file ("fonts/Inconsolata-Regular.ab.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -133,7 +133,7 @@ test_subset_hmtx_decrease_num_metrics (void) static void test_subset_hmtx_noop (void) { - hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_abc_subset; @@ -153,7 +153,7 @@ test_subset_hmtx_noop (void) static void test_subset_invalid_hmtx (void) { - hb_face_t *face = hb_subset_test_open_font("../fuzzing/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480"); + hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480"); hb_face_t *subset; hb_subset_input_t *input = hb_subset_input_create_or_fail (); diff --git a/test/api/test-subset-os2.c b/test/api/test-subset-os2.c index de63a3fd5..dfc946193 100644 --- a/test/api/test-subset-os2.c +++ b/test/api/test-subset-os2.c @@ -31,8 +31,8 @@ static void test_subset_os2 (void) { - hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); - hb_face_t *face_b = hb_subset_test_open_font("fonts/Roboto-Regular.b.ttf"); + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_b = hb_test_open_font_file ("fonts/Roboto-Regular.b.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_abc_subset; diff --git a/test/api/test-subset-post.c b/test/api/test-subset-post.c index c14741e4a..e31b01eec 100644 --- a/test/api/test-subset-post.c +++ b/test/api/test-subset-post.c @@ -32,8 +32,8 @@ static void test_post_drops_glyph_names (void) { - hb_face_t *face_full = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf"); - hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E.ttf"); + hb_face_t *face_full = hb_test_open_font_file ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf"); + hb_face_t *face_subset = hb_test_open_font_file ("fonts/Mplus1p-Regular.660E.ttf"); hb_face_t *face_full_subset; hb_set_t *codepoints = hb_set_create (); diff --git a/test/api/test-subset-vmtx.c b/test/api/test-subset-vmtx.c index 40ea8f872..24a4a760a 100644 --- a/test/api/test-subset-vmtx.c +++ b/test/api/test-subset-vmtx.c @@ -46,8 +46,8 @@ static void check_num_vmetrics(hb_face_t *face, uint16_t expected_num_vmetrics) static void test_subset_vmtx_simple_subset (void) { - hb_face_t *face_full = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf"); - hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E.ttf"); + hb_face_t *face_full = hb_test_open_font_file ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf"); + hb_face_t *face_subset = hb_test_open_font_file ("fonts/Mplus1p-Regular.660E.ttf"); hb_face_t *face_full_subset; hb_set_t *codepoints = hb_set_create (); @@ -67,7 +67,7 @@ test_subset_vmtx_simple_subset (void) static void test_subset_vmtx_noop (void) { - hb_face_t *face_full = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf"); + hb_face_t *face_full = hb_test_open_font_file ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf"); hb_face_t *face_full_subset; hb_set_t *codepoints = hb_set_create(); diff --git a/test/api/test-subset.c b/test/api/test-subset.c index aaed03176..85e4fdf1c 100644 --- a/test/api/test-subset.c +++ b/test/api/test-subset.c @@ -32,7 +32,7 @@ static void test_subset_32_tables (void) { - hb_face_t *face = hb_subset_test_open_font("../fuzzing/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653"); + hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653"); hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t *codepoints = hb_subset_input_unicode_set (input); @@ -54,7 +54,7 @@ test_subset_32_tables (void) static void test_subset_no_inf_loop (void) { - hb_face_t *face = hb_subset_test_open_font("../fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5521982557782016"); + hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5521982557782016"); hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t *codepoints = hb_subset_input_unicode_set (input); @@ -76,7 +76,7 @@ test_subset_no_inf_loop (void) static void test_subset_crash (void) { - hb_face_t *face = hb_subset_test_open_font("../fuzzing/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249"); + hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249"); hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t *codepoints = hb_subset_input_unicode_set (input); diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5097734906839040 b/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5097734906839040 new file mode 100644 index 000000000..8b454526c Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5097734906839040 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5688420752424960 b/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5688420752424960 new file mode 100644 index 000000000..1fe962b85 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5688420752424960 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5728971283496960 b/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5728971283496960 new file mode 100644 index 000000000..25d7bf1de Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-hb-shape-fuzzer-5728971283496960 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-fuzzer-5713868010553344 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-fuzzer-5713868010553344 new file mode 100644 index 000000000..ee0a721b5 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-fuzzer-5713868010553344 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-fuzzer-6278851874258944 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-fuzzer-6278851874258944 new file mode 100644 index 000000000..775c91886 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-fuzzer-6278851874258944 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5649959857160192 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5649959857160192 new file mode 100644 index 000000000..72e702ec6 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5649959857160192 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5664873493561344 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5664873493561344 new file mode 100644 index 000000000..dfc36d897 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5664873493561344 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5688420752424960 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5688420752424960 new file mode 100644 index 000000000..e9f01a232 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5688420752424960 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5706010589659136 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5706010589659136 new file mode 100644 index 000000000..7e15f4b5d Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5706010589659136 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5762953198960640 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5762953198960640 new file mode 100644 index 000000000..9d64eafd9 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5762953198960640 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5764636557705216 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5764636557705216 new file mode 100644 index 000000000..b07416b07 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5764636557705216 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5690658895953920 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5690658895953920 new file mode 100644 index 000000000..abafa4bc4 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5690658895953920 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5695279609675776 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5695279609675776 new file mode 100644 index 000000000..f01626233 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5695279609675776 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5718215406125056 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5718215406125056 new file mode 100644 index 000000000..a6d87dafb Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5718215406125056 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5725847365877760 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5725847365877760 new file mode 100644 index 000000000..3764bed6d Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5725847365877760 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5743250149736448 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5743250149736448 new file mode 100644 index 000000000..b17c94996 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5743250149736448 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5765071062958080 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5765071062958080 new file mode 100644 index 000000000..1f9be049a Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5765071062958080 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-get-codepoints-fuzzer-5930139383758848 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-get-codepoints-fuzzer-5930139383758848 new file mode 100644 index 000000000..940fbd503 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-get-codepoints-fuzzer-5930139383758848 differ diff --git a/test/fuzzing/hb-shape-fuzzer.cc b/test/fuzzing/hb-shape-fuzzer.cc index 79f322297..b5a6c12e0 100644 --- a/test/fuzzing/hb-shape-fuzzer.cc +++ b/test/fuzzing/hb-shape-fuzzer.cc @@ -5,29 +5,29 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - hb_blob_t *blob = hb_blob_create((const char *)data, size, - HB_MEMORY_MODE_READONLY, NULL, NULL); - hb_face_t *face = hb_face_create(blob, 0); - hb_font_t *font = hb_font_create(face); - hb_ot_font_set_funcs(font); - hb_font_set_scale(font, 12, 12); + hb_blob_t *blob = hb_blob_create ((const char *)data, size, + HB_MEMORY_MODE_READONLY, NULL, NULL); + hb_face_t *face = hb_face_create (blob, 0); + hb_font_t *font = hb_font_create (face); + hb_ot_font_set_funcs (font); + hb_font_set_scale (font, 12, 12); { const char text[] = "ABCDEXYZ123@_%&)*$!"; - hb_buffer_t *buffer = hb_buffer_create(); - hb_buffer_add_utf8(buffer, text, -1, 0, -1); - hb_buffer_guess_segment_properties(buffer); - hb_shape(font, buffer, NULL, 0); - hb_buffer_destroy(buffer); + hb_buffer_t *buffer = hb_buffer_create (); + hb_buffer_add_utf8 (buffer, text, -1, 0, -1); + hb_buffer_guess_segment_properties (buffer); + hb_shape (font, buffer, NULL, 0); + hb_buffer_destroy (buffer); } uint32_t text32[16]; - if (size > sizeof(text32)) { - memcpy(text32, data + size - sizeof(text32), sizeof(text32)); - hb_buffer_t *buffer = hb_buffer_create(); - hb_buffer_add_utf32(buffer, text32, sizeof(text32)/sizeof(text32[0]), 0, -1); - hb_buffer_guess_segment_properties(buffer); - hb_shape(font, buffer, NULL, 0); + if (size > sizeof (text32)) { + memcpy(text32, data + size - sizeof (text32), sizeof (text32)); + hb_buffer_t *buffer = hb_buffer_create (); + hb_buffer_add_utf32 (buffer, text32, sizeof (text32) / sizeof (text32[0]), 0, -1); + hb_buffer_guess_segment_properties (buffer); + hb_shape (font, buffer, NULL, 0); unsigned int len = hb_buffer_get_length (buffer); hb_glyph_info_t *infos = hb_buffer_get_glyph_infos (buffer, NULL); @@ -41,12 +41,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) hb_font_get_glyph_extents (font, info.codepoint, &extents); } - hb_buffer_destroy(buffer); + hb_buffer_destroy (buffer); } - hb_font_destroy(font); - hb_face_destroy(face); - hb_blob_destroy(blob); + hb_font_destroy (font); + hb_face_destroy (face); + hb_blob_destroy (blob); return 0; } diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index 8fadd167f..53c4f501a 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -5,6 +5,24 @@ from __future__ import print_function, division, absolute_import import sys, os, subprocess, tempfile, threading +def which(program): + # https://stackoverflow.com/a/377028 + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + fpath, _ = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + + return None + + def cmd(command): # https://stackoverflow.com/a/4408409 # https://stackoverflow.com/a/10012262 @@ -49,6 +67,10 @@ please provide it as the first argument to the tool""") print ('hb_shape_fuzzer:', hb_shape_fuzzer) fails = 0 +valgrind = None +if os.environ.get('RUN_VALGRIND', ''): + valgrind = which ('valgrind') + parent_path = os.path.join (srcdir, "fonts") for file in os.listdir (parent_path): path = os.path.join(parent_path, file) @@ -56,8 +78,19 @@ for file in os.listdir (parent_path): text, returncode = cmd ([hb_shape_fuzzer, path]) print (text) + failed = False if returncode != 0 or 'error' in text: print ('failure on %s' % file) + failed = True + + if valgrind: + text, returncode = cmd ([valgrind, '--error-exitcode=1', hb_shape_fuzzer, path]) + if returncode: + print (text) + print ('failure on %s' % file) + failed = True + + if failed: fails = fails + 1 if fails: diff --git a/test/shaping/data/in-house/tests/aat-trak.tests b/test/shaping/data/in-house/tests/aat-trak.tests index 9e6505585..48b224f33 100644 --- a/test/shaping/data/in-house/tests/aat-trak.tests +++ b/test/shaping/data/in-house/tests/aat-trak.tests @@ -5,4 +5,4 @@ ../fonts/TestTRAK.ttf:--font-ptem=9:U+0041,U+0042,U+0043:[A.alt=0+1000|B=1+1000|C.alt=2+1000] ../fonts/TestTRAK.ttf:--font-ptem=24:U+0041,U+0042,U+0043:[A.alt=0@-12,0+976|B=1@-12,0+976|C.alt=2@-12,0+976] ../fonts/TestTRAK.ttf:--font-ptem=72:U+0041,U+0042,U+0043:[A.alt=0@-50,0+900|B=1@-50,0+900|C.alt=2@-50,0+900] -../fonts/TestTRAK.ttf:--font-ptem=144:U+0041,U+0042,U+0043:[A.alt=0@-100,0+800|B=1@-100,0+800|C.alt=2@-100,0+800] +../fonts/TestTRAK.ttf:--font-ptem=144:U+0041,U+0042,U+0043:[A.alt=0@-107,0+786|B=1@-107,0+786|C.alt=2@-107,0+786] diff --git a/util/options.hh b/util/options.hh index 3749b99be..dd628590e 100644 --- a/util/options.hh +++ b/util/options.hh @@ -586,7 +586,7 @@ struct output_options_t : option_group_t if (output_format) { output_format++; /* skip the dot */ - output_format = strdup (output_format); + output_format = g_strdup (output_format); } }