Merge branch 'master' into cff-subset
This commit is contained in:
commit
857c58279e
|
@ -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
|
||||
|
|
2
BUILD.md
2
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:
|
||||
|
|
|
@ -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 ()
|
||||
|
|
21
NEWS
21
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
2
TODO
2
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
|
||||
|
|
15
appveyor.yml
15
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
|
||||
|
|
|
@ -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/])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
* Copyright © 2018 Khaled Hosny
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
|
@ -45,7 +46,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void cbdt_callback (const uint8_t* data, unsigned int length,
|
||||
static void
|
||||
cbdt_callback (const uint8_t* data, unsigned int length,
|
||||
unsigned int group, unsigned int gid)
|
||||
{
|
||||
char output_path[255];
|
||||
|
@ -55,7 +57,8 @@ static void cbdt_callback (const uint8_t* data, unsigned int length,
|
|||
fclose (f);
|
||||
}
|
||||
|
||||
static void sbix_callback (const uint8_t* data, unsigned int length,
|
||||
static void
|
||||
sbix_callback (const uint8_t* data, unsigned int length,
|
||||
unsigned int group, unsigned int gid)
|
||||
{
|
||||
char output_path[255];
|
||||
|
@ -65,7 +68,8 @@ static void sbix_callback (const uint8_t* data, unsigned int length,
|
|||
fclose (f);
|
||||
}
|
||||
|
||||
static void svg_callback (const uint8_t* data, unsigned int length,
|
||||
static void
|
||||
svg_callback (const uint8_t* data, unsigned int length,
|
||||
unsigned int start_glyph, unsigned int end_glyph)
|
||||
{
|
||||
char output_path[255];
|
||||
|
@ -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,36 +129,42 @@ 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);
|
||||
unsigned int num_colors = hb_ot_color_get_palette_colors (face, palette, 0, nullptr, nullptr);
|
||||
if (!num_colors)
|
||||
continue;
|
||||
|
||||
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)
|
||||
{
|
||||
// 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", i, pallet);
|
||||
sprintf (output_path, "out/colr-%d-%d.svg", gid, palette);
|
||||
|
||||
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)
|
||||
for (unsigned int layer = 0; layer < num_layers; ++layer)
|
||||
{
|
||||
hb_codepoint_t glyph_id;
|
||||
unsigned int color_index;
|
||||
colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index);
|
||||
|
||||
uint32_t color = cpal->get_color_record_argb (color_index, pallet);
|
||||
int alpha = color & 0xFF;
|
||||
int r = (color >> 8) & 0xFF;
|
||||
int g = (color >> 16) & 0xFF;
|
||||
int b = (color >> 24) & 0xFF;
|
||||
cairo_set_source_rgba (cr, r / 255., g / 255., b / 255., alpha);
|
||||
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 = glyph_id;
|
||||
glyph.index = layer_gids[layer];
|
||||
glyph.x = -extents.x_bearing;
|
||||
glyph.y = -extents.y_bearing;
|
||||
cairo_show_glyphs (cr, &glyph, 1);
|
||||
|
@ -158,11 +173,17 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe
|
|||
cairo_surface_destroy (surface);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
free (colors);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
|
||||
free (layer_gids);
|
||||
free (color_indices);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
|
||||
unsigned int num_glyphs)
|
||||
{
|
||||
// Dump every glyph available on the font
|
||||
|
@ -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<OT::COLR> (face);
|
||||
const OT::COLR *colr = colr_blob->as<OT::COLR> ();
|
||||
|
||||
hb_blob_t* cpal_blob = hb_sanitize_context_t ().reference_table<OT::CPAL> (face);
|
||||
const OT::CPAL *cpal = cpal_blob->as<OT::CPAL> ();
|
||||
|
||||
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);
|
||||
|
|
|
@ -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<GlyphAnchors> (&(this+anchorData), offset);
|
||||
const Offset<HBUINT16, false> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs);
|
||||
if (!offset)
|
||||
return Null(Anchor);
|
||||
const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), *offset);
|
||||
/* TODO Use sanitizer; to avoid overflows and more. */
|
||||
if (unlikely ((const char *) &anchors + anchors.get_size () > end))
|
||||
return Null(Anchor);
|
||||
|
|
|
@ -246,6 +246,48 @@ struct LookupFormat8
|
|||
DEFINE_SIZE_ARRAY (6, valueArrayZ);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct LookupFormat10
|
||||
{
|
||||
friend struct Lookup<T>;
|
||||
|
||||
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<HBUINT8>
|
||||
valueArrayZ; /* The lookup values (indexed by the glyph index
|
||||
* minus the value of firstGlyph). */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, valueArrayZ);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Lookup
|
||||
{
|
||||
|
@ -261,11 +303,16 @@ 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
|
||||
{
|
||||
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<T> format4;
|
||||
LookupFormat6<T> format6;
|
||||
LookupFormat8<T> format8;
|
||||
LookupFormat10<T> format10;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
|
|
|
@ -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<FWORD> (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<KerxSubTableFormat0> machine (*this);
|
||||
|
||||
accelerator_t accel (*this, c);
|
||||
hb_kern_machine_t<accelerator_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:
|
||||
|
@ -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<EntryData> driver (machine, c->buffer, c->font->face);
|
||||
|
@ -236,7 +272,7 @@ struct KerxSubTableFormat2
|
|||
unsigned int offset = l + r;
|
||||
const FWORD *v = &StructAtOffset<FWORD> (&(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<FWORD32> (&(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<FWORD> (&(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<UnsizedArrayOf<FWORD>, false> array;
|
||||
} s;
|
||||
} u;
|
||||
LOffsetTo<UnsizedArrayOf<FWORD>, 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))
|
||||
|
|
|
@ -136,7 +136,7 @@ struct TrackData
|
|||
/* TODO bfind() */
|
||||
hb_array_t<Fixed> 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;
|
||||
|
||||
|
|
|
@ -487,8 +487,8 @@ hb_blob_t::try_make_writable (void)
|
|||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
#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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <typename Type>
|
|||
struct BEInt<Type, 1>
|
||||
{
|
||||
public:
|
||||
typedef Type type;
|
||||
inline void set (Type V)
|
||||
{
|
||||
v = V;
|
||||
|
@ -666,6 +667,7 @@ template <typename Type>
|
|||
struct BEInt<Type, 2>
|
||||
{
|
||||
public:
|
||||
typedef Type type;
|
||||
inline void set (Type V)
|
||||
{
|
||||
v[0] = (V >> 8) & 0xFF;
|
||||
|
@ -682,6 +684,7 @@ template <typename Type>
|
|||
struct BEInt<Type, 3>
|
||||
{
|
||||
public:
|
||||
typedef Type type;
|
||||
inline void set (Type V)
|
||||
{
|
||||
v[0] = (V >> 16) & 0xFF;
|
||||
|
@ -700,6 +703,7 @@ template <typename Type>
|
|||
struct BEInt<Type, 4>
|
||||
{
|
||||
public:
|
||||
typedef Type type;
|
||||
inline void set (Type V)
|
||||
{
|
||||
v[0] = (V >> 24) & 0xFF;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -49,7 +49,7 @@ static inline Type const & Null (void) {
|
|||
}
|
||||
#define Null(Type) Null<Type>()
|
||||
|
||||
/* 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 <> \
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace OT {
|
|||
template <typename Type, unsigned int Size>
|
||||
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<Type,Size> &o) const { return (Type) v == (Type) o.v; }
|
||||
|
@ -161,6 +162,8 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
|
|||
template <typename Type, bool has_null=true>
|
||||
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)
|
||||
|
|
|
@ -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 */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
static int compare_bgr (const void *pa, const void *pb)
|
||||
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);
|
||||
};
|
||||
|
||||
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<UnsizedArrayOf<BaseGlyphRecord>, false>
|
||||
baseGlyphsZ; /* Offset to Base Glyph records. */
|
||||
LOffsetTo<UnsizedArrayOf<LayerRecord>, 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);
|
||||
};
|
||||
|
|
|
@ -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<UnsizedArrayOf<HBUINT32>, 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<CPALV1Tail> (*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<CPALV1Tail> (*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<CPALV1Tail> (*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<CPALV1Tail> (*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<BGRAColor>& color_records = this+colorRecordsZ;
|
||||
return color_records[colorRecordIndicesZ[palette] + color_index];
|
||||
if (color)
|
||||
*color = color_records[colorRecordIndicesZ[palette] + color_index];
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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,11 +91,9 @@ _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.
|
||||
|
@ -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
|
||||
|
@ -147,35 +162,89 @@ 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 */)
|
||||
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<unsigned int>(*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;
|
||||
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<unsigned int>(*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
|
||||
|
|
|
@ -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 <hb-ot.h> 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 */
|
|
@ -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) \
|
||||
|
|
|
@ -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 <typename TSubTable>
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) && \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) <= \
|
||||
|
|
|
@ -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 .
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -23,16 +23,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <hb.h>
|
||||
#include <hb-ft.h>
|
||||
#include <hb-ot.h>
|
||||
#include <glib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -255,9 +255,9 @@ 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 */
|
||||
|
@ -292,7 +292,71 @@ test_hb_ot_color_get_palette_colors_v1 (void)
|
|||
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);
|
||||
|
|
|
@ -27,12 +27,10 @@
|
|||
|
||||
#include <hb-ot.h>
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[] =
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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:
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue