[HarfBuzz] harfbuzz: Branch 'master' - 10 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Mon Oct 29 18:42:13 UTC 2018
src/Makefile.am | 15 +
src/gen-def.py | 9 -
src/hb-open-type.hh | 11 +
src/hb-ot-color-svg-table.hh | 7
src/hb-ot-color.h | 4
src/hb-ot-name.cc | 4
src/hb.hh | 6
src/test-ot-color.cc | 347 +++++++++++++++++++++++++++++++++++++++++++
test/api/Makefile.am | 2
9 files changed, 390 insertions(+), 15 deletions(-)
New commits:
commit a256a92b3fbb72487cf073a63e646eab952b42ed
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Oct 29 11:25:35 2018 -0700
Make Array types uncopyable-unassignable
Finally! Catches hard-to-find errors like this:
- const SortedArrayOf<SVGDocumentIndexEntry> docs = this+svgDocEntries;
+ const SortedArrayOf<SVGDocumentIndexEntry> &docs = this+svgDocEntries;
We implement this for our array types. This, in turn, trickles down
into all types that embed the arrays. So, as long as we define all
open-ended structs in terms of Array types (all can be done using
UnsizedArrayOf), this achieves the goal of making uncopyable all
structs that are variable-sized. Yay!
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index 6e545a6d..ee452864 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -335,6 +335,8 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null>
template <typename Type>
struct UnsizedArrayOf
{
+ HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE (UnsizedArrayOf, Type);
+
inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
@@ -424,6 +426,8 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null>
template <typename Type, typename LenType=HBUINT16>
struct ArrayOf
{
+ HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType);
+
inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
{
unsigned int count = len;
@@ -589,6 +593,8 @@ struct OffsetListOf : OffsetArrayOf<Type>
template <typename Type, typename LenType=HBUINT16>
struct HeadlessArrayOf
{
+ HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType);
+
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= lenP1 || !i)) return Null(Type);
@@ -653,6 +659,8 @@ struct HeadlessArrayOf
template <typename Type, typename LenType=HBUINT16>
struct ArrayOfM1
{
+ HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (ArrayOfM1, Type, LenType);
+
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i > lenM1)) return Null(Type);
@@ -757,6 +765,7 @@ struct BinSearchHeader
template <typename Type, typename LenType=HBUINT16>
struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader<LenType> > {};
+
struct VarSizedBinSearchHeader
{
@@ -782,6 +791,8 @@ struct VarSizedBinSearchHeader
template <typename Type>
struct VarSizedBinSearchArrayOf
{
+ HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type);
+
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= header.nUnits)) return Null(Type);
diff --git a/src/hb.hh b/src/hb.hh
index ea474298..e5bec508 100644
--- a/src/hb.hh
+++ b/src/hb.hh
@@ -366,6 +366,12 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
#define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
+#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE(TypeName, T) \
+ TypeName(const TypeName<T>&); \
+ void operator=(const TypeName<T>&)
+#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2(TypeName, T1, T2) \
+ TypeName(const TypeName<T1, T2>&); \
+ void operator=(const TypeName<T1, T2>&)
/*
commit 31cc1f74b7028ef88fa0e93e7f12166c7e06de8e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Oct 29 11:14:37 2018 -0700
[svg] Minor
diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh
index 7c342d01..bb4c4f75 100644
--- a/src/hb-ot-color-svg-table.hh
+++ b/src/hb-ot-color-svg-table.hh
@@ -50,10 +50,11 @@ struct SVGDocumentIndexEntry
svgDocLength);
}
- inline bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
+ return_trace (c->check_struct (this) &&
+ svgDoc.sanitize (c, base, svgDocLength));
}
protected:
commit 1366bb9760d0f171f8f655e5739e74dfd2537652
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Oct 29 11:01:25 2018 -0700
Fix g-i warnings
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index 89935143..1cc04d4f 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -94,7 +94,9 @@ HB_EXTERN hb_bool_t
hb_ot_color_has_layers (hb_face_t *face);
/**
- * hb_ot_color_layer_t: Pairs of glyph and color index.
+ * hb_ot_color_layer_t:
+ *
+ * Pairs of glyph and color index.
*
* Since: REPLACEME
**/
diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc
index 2bf2ae58..e8aa3d8e 100644
--- a/src/hb-ot-name.cc
+++ b/src/hb-ot-name.cc
@@ -52,13 +52,13 @@ _get_name (hb_face_t *face)
/**
* hb_ot_name_list_names:
* @face: font face.
- * @num_entries: (out) number of returned entries.
+ * @num_entries: (out): number of returned entries.
*
* Enumerates all available name IDs and language combinations. Returned
* array is owned by the @face and should not be modified. It can be
* used as long as @face is alive.
*
- * Returns: (out) (transfer none) (array length=num_entries) Array of available name entries.
+ * Returns: (out) (transfer none) (array length=num_entries): Array of available name entries.
* Since: 2.1.0
**/
const hb_ot_name_entry_t *
commit ae802c2c6e001492f8f639e4c24546f0e21d86c7
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Oct 29 13:42:14 2018 +0330
[test-ot-color] Minor
diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc
index 5312554a..2cb9b03b 100644
--- a/src/test-ot-color.cc
+++ b/src/test-ot-color.cc
@@ -74,7 +74,8 @@ png_dump (hb_face_t *face, unsigned int face_index)
strikes_count++;
blob_length = new_blob_length;
}
- strikes[strikes_count - 1] = ppem;
+ if (strikes_count != 0)
+ strikes[strikes_count - 1] = ppem;
hb_blob_destroy (blob);
}
/* can't report the biggest strike correctly, and, we can't do anything about it */
commit 7170e35096f0afd084be1350d080695c70c65d40
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Oct 29 13:11:01 2018 +0330
Rename deprecated symbols list file name and clean it up (#1328)
diff --git a/src/Makefile.am b/src/Makefile.am
index a51048b7..fbd8f602 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -268,7 +268,7 @@ EXTRA_DIST += \
CLEANFILES += $(pkgconfig_DATA)
-DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def harfbuzz-deprecated.def
+DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def harfbuzz-deprecated-symbols.txt
if HAVE_GOBJECT
DEF_FILES += harfbuzz-gobject.def
endif
@@ -282,8 +282,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 "$@" $^
+harfbuzz-deprecated-symbols.txt: $(srcdir)/hb-deprecated.h
+ $(AM_V_GEN) PLAIN_LIST=1 $(srcdir)/gen-def.py "$@" $^
GENERATORS = \
diff --git a/src/gen-def.py b/src/gen-def.py
index ba39eaae..9111c698 100755
--- a/src/gen-def.py
+++ b/src/gen-def.py
@@ -15,11 +15,10 @@ for h in header_paths:
if h.endswith (".h"):
with io.open (h, encoding='utf-8') as f: headers_content.append (f.read ())
-result = """EXPORTS
+symbols = "\n".join (sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M)))
+
+result = symbols if os.environ.get('PLAIN_LIST', '') else """EXPORTS
%s
-LIBRARY lib%s-0.dll""" % (
- "\n".join (sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M))),
- output_file.replace ('.def', '')
-)
+LIBRARY lib%s-0.dll""" % (symbols, output_file.replace ('.def', ''))
with open (output_file, "w") as f: f.write (result)
diff --git a/test/api/Makefile.am b/test/api/Makefile.am
index 45a34e64..c233a90e 100644
--- a/test/api/Makefile.am
+++ b/test/api/Makefile.am
@@ -167,7 +167,7 @@ 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
+symbols-tested-or-deprecated.txt: symbols-tested.txt $(top_builddir)/src/harfbuzz-deprecated-symbols.txt
$(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 $^ \
commit 1dfe964378e97e45eedf9db9b9a7f675fe38c0bf
Merge: f10252b4 9c692e5b
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Oct 29 12:34:33 2018 +0330
Merge pull request #1326 from ebraminio/test-ot-color
Revive and rename dump-emoji to test-ot-color but use public APIs instead
commit 9c692e5b8d195d8e82538594d89865c609d708f3
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Oct 29 11:36:11 2018 +0330
[test-ot-color] Use public APIs on the tool
diff --git a/src/Makefile.am b/src/Makefile.am
index 0b9ae9dc..a51048b7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -377,6 +377,15 @@ test_would_substitute_SOURCES = test-would-substitute.cc
test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
+if HAVE_FREETYPE
+if HAVE_CAIRO_FT
+noinst_PROGRAMS += test-ot-color
+test_ot_color_SOURCES = test-ot-color.cc
+test_ot_color_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS)
+test_ot_color_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS)
+endif # HAVE_CAIRO_FT
+endif # HAVE_FREETYPE
+
dist_check_SCRIPTS = \
check-c-linkage-decls.sh \
check-externs.sh \
diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc
index e3cabc73..5312554a 100644
--- a/src/test-ot-color.cc
+++ b/src/test-ot-color.cc
@@ -23,12 +23,8 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
-#include "hb-static.cc"
-#include "hb-ot-color-cbdt-table.hh"
-#include "hb-ot-color-colr-table.hh"
-#include "hb-ot-color-cpal-table.hh"
-#include "hb-ot-color-sbix-table.hh"
-#include "hb-ot-color-svg-table.hh"
+#include "hb.h"
+#include "hb-ot.h"
#include "hb-ft.h"
@@ -40,71 +36,94 @@
#include <cairo-ft.h>
#include <cairo-svg.h>
-#ifdef HAVE_GLIB
-#include <glib.h>
-#endif
#include <stdlib.h>
#include <stdio.h>
static void
-cbdt_callback (const uint8_t* data, unsigned int length,
- unsigned int group, unsigned int gid)
+png_dump (hb_face_t *face, unsigned int face_index)
{
- char output_path[255];
- sprintf (output_path, "out/cbdt-%d-%d.png", group, gid);
- FILE *f = fopen (output_path, "wb");
- fwrite (data, 1, length, f);
- fclose (f);
-}
+ unsigned glyph_count = hb_face_get_glyph_count (face);
+ hb_font_t *font = hb_font_create (face);
-static void
-sbix_dump (hb_face_t *face)
-{
- OT::sbix::accelerator_t sbix;
- sbix.init (face);
- unsigned int length = 0;
- unsigned int *available_ppems = sbix.get_available_ppems (&length);
- unsigned int num_glyphs = face->num_glyphs;
- for (unsigned int group = 0; group < length; group++)
- for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++)
+ /* ugly hack, scans the font for strikes, not needed for regular clients */
+ #define STRIKES_MAX 20
+ unsigned int strikes_count = 0;
+ unsigned int strikes[STRIKES_MAX] = {0};
+ {
+ /* find a sample glyph */
+ unsigned int sample_glyph_id;
+ /* we don't care much about different strikes for different glyphs */
+ for (sample_glyph_id = 0; sample_glyph_id < glyph_count; sample_glyph_id++)
+ {
+ hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
+ unsigned int blob_length = hb_blob_get_length (blob);
+ hb_blob_destroy (blob);
+ if (blob_length != 0)
+ break;
+ }
+ /* find strikes it has */
+ unsigned int upem = hb_face_get_upem (face);
+ unsigned int blob_length = 0;
+ for (unsigned int ppem = 1; ppem <= upem && strikes_count < STRIKES_MAX; ppem++)
{
- hb_blob_t *blob;
- unsigned int ppem = available_ppems[group];
- blob = sbix.reference_blob_for_glyph (glyph_id, ppem, ppem,
- HB_TAG('p','n','g',' '), nullptr, nullptr);
+ hb_font_set_ppem (font, ppem, ppem);
+ hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
+ unsigned int new_blob_length = hb_blob_get_length (blob);
+ if (blob_length != new_blob_length)
+ {
+ strikes_count++;
+ blob_length = new_blob_length;
+ }
+ strikes[strikes_count - 1] = ppem;
+ hb_blob_destroy (blob);
+ }
+ /* can't report the biggest strike correctly, and, we can't do anything about it */
+ }
+ #undef STRIKES_MAX
+
+ for (unsigned int strike = 0; strike < strikes_count; strike++)
+ for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
+ {
+ unsigned int ppem = strikes[strike];
+ hb_font_set_ppem (font, ppem, ppem);
+ hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id);
+
if (hb_blob_get_length (blob) == 0) continue;
+ unsigned int length;
+ const char *data = hb_blob_get_data (blob, &length);
+
char output_path[255];
- sprintf (output_path, "out/sbix-%d-%d.png", ppem, glyph_id);
+ sprintf (output_path, "out/png-%d-%d-%d.png", glyph_id, strike, face_index);
+
FILE *f = fopen (output_path, "wb");
- unsigned int length;
- const char* data = hb_blob_get_data (blob, &length);
fwrite (data, 1, length, f);
fclose (f);
+
+ hb_blob_destroy (blob);
}
- sbix.fini ();
+
+ hb_font_destroy (font);
}
static void
-svg_dump (hb_face_t *face)
+svg_dump (hb_face_t *face, unsigned int face_index)
{
unsigned glyph_count = hb_face_get_glyph_count (face);
- OT::SVG::accelerator_t svg;
- svg.init (face);
-
for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
{
- hb_blob_t *blob = svg.reference_blob_for_glyph (glyph_id);
+ hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id);
if (hb_blob_get_length (blob) == 0) continue;
unsigned int length;
const char *data = hb_blob_get_data (blob, &length);
- char output_path[256];
- sprintf (output_path, "out/svg-%d.svg%s",
+ char output_path[255];
+ sprintf (output_path, "out/svg-%d-%d.svg%s",
glyph_id,
+ face_index,
// append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
(length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : "");
@@ -114,12 +133,10 @@ svg_dump (hb_face_t *face)
hb_blob_destroy (blob);
}
-
- svg.fini ();
}
static void
-colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face)
+layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int face_index)
{
unsigned int upem = hb_face_get_upem (face);
@@ -171,11 +188,7 @@ colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face)
hb_ot_color_palette_get_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", gid, palette);
+ sprintf (output_path, "out/colr-%d-%d-%d.svg", gid, palette, face_index);
cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
cairo_t *cr = cairo_create (surface);
@@ -213,10 +226,8 @@ colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face)
static void
dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
- unsigned int num_glyphs)
+ unsigned int num_glyphs, unsigned int face_index)
{
- // Dump every glyph available on the font
- return; // disabled for now
for (unsigned int i = 0; i < num_glyphs; ++i)
{
cairo_text_extents_t extents;
@@ -244,7 +255,7 @@ dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
// Render
{
char output_path[255];
- sprintf (output_path, "out/%d.svg", i);
+ sprintf (output_path, "out/%d-%d.svg", face_index, i);
cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
cairo_t *cr = cairo_create (surface);
cairo_set_font_face (cr, cairo_face);
@@ -269,14 +280,14 @@ main (int argc, char **argv)
}
- FILE *font_name_file = fopen ("out/_font_name_file.txt", "r");
+ FILE *font_name_file = fopen ("out/.dumped_font_name", "r");
if (font_name_file != nullptr)
{
fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n");
exit (1);
}
- font_name_file = fopen ("out/_font_name_file.txt", "w");
+ font_name_file = fopen ("out/.dumped_font_name", "w");
if (font_name_file == nullptr)
{
fprintf (stderr, "./out is not accessible as a folder, create it please\n");
@@ -286,36 +297,49 @@ main (int argc, char **argv)
fclose (font_name_file);
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
- hb_face_t *face = hb_face_create (blob, 0);
- hb_font_t *font = hb_font_create (face);
+ unsigned int num_faces = hb_face_count (blob);
+ if (num_faces == 0)
+ {
+ fprintf (stderr, "error: The file (%s) was corrupted, empty or not found", argv[1]);
+ exit (1);
+ }
- OT::CBDT::accelerator_t cbdt;
- cbdt.init (face);
- cbdt.dump (cbdt_callback);
- cbdt.fini ();
+ for (unsigned int face_index = 0; face_index < hb_face_count (blob); face_index++)
+ {
+ hb_face_t *face = hb_face_create (blob, face_index);
+ hb_font_t *font = hb_font_create (face);
- sbix_dump (face);
+ if (hb_ot_color_has_png (face)) printf ("Dumping png (cbdt/sbix)...\n");
+ png_dump (face, face_index);
- if (hb_ot_color_has_svg (face))
- svg_dump (face);
+ if (hb_ot_color_has_svg (face)) printf ("Dumping svg...\n");
+ svg_dump (face, face_index);
- cairo_font_face_t *cairo_face;
- {
- FT_Library library;
- FT_Init_FreeType (&library);
- FT_Face ftface;
- FT_New_Face (library, argv[1], 0, &ftface);
- cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0);
- }
- if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face))
- colr_cpal_dump (face, cairo_face);
+ cairo_font_face_t *cairo_face;
+ {
+ FT_Library library;
+ FT_Init_FreeType (&library);
+ FT_Face ft_face;
+ FT_New_Face (library, argv[1], 0, &ft_face);
+ cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
+ }
+ if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face))
+ printf ("Dumping layered color glyphs...\n");
+ layered_glyph_dump (face, cairo_face, face_index);
- unsigned int num_glyphs = hb_face_get_glyph_count (face);
- unsigned int upem = hb_face_get_upem (face);
- dump_glyphs (cairo_face, upem, num_glyphs);
+ unsigned int num_glyphs = hb_face_get_glyph_count (face);
+ unsigned int upem = hb_face_get_upem (face);
+
+ // disabled when color font as cairo rendering of NotoColorEmoji is soooo slow
+ if (!hb_ot_color_has_layers (face) &&
+ !hb_ot_color_has_png (face) &&
+ !hb_ot_color_has_svg (face))
+ dump_glyphs (cairo_face, upem, num_glyphs, face_index);
+
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+ }
- hb_font_destroy (font);
- hb_face_destroy (face);
hb_blob_destroy (blob);
return 0;
commit fb525f8943b43fe241424c93461bee2b94af28e3
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Oct 29 09:43:17 2018 +0330
Rename dump-emoji to test-ot-color
diff --git a/src/dump-emoji.cc b/src/test-ot-color.cc
similarity index 100%
rename from src/dump-emoji.cc
rename to src/test-ot-color.cc
commit 81bcf47e9ea7eb447ff95ce48ecbc5c4439cb53f
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Oct 29 09:40:39 2018 +0330
Revive dump-emoji
diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
new file mode 100644
index 00000000..e3cabc73
--- /dev/null
+++ b/src/dump-emoji.cc
@@ -0,0 +1,322 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ * Copyright © 2018 Khaled Hosny
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb-static.cc"
+#include "hb-ot-color-cbdt-table.hh"
+#include "hb-ot-color-colr-table.hh"
+#include "hb-ot-color-cpal-table.hh"
+#include "hb-ot-color-sbix-table.hh"
+#include "hb-ot-color-svg-table.hh"
+
+#include "hb-ft.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+#include <cairo.h>
+#include <cairo-ft.h>
+#include <cairo-svg.h>
+
+#ifdef HAVE_GLIB
+#include <glib.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+
+static void
+cbdt_callback (const uint8_t* data, unsigned int length,
+ unsigned int group, unsigned int gid)
+{
+ char output_path[255];
+ sprintf (output_path, "out/cbdt-%d-%d.png", group, gid);
+ FILE *f = fopen (output_path, "wb");
+ fwrite (data, 1, length, f);
+ fclose (f);
+}
+
+static void
+sbix_dump (hb_face_t *face)
+{
+ OT::sbix::accelerator_t sbix;
+ sbix.init (face);
+ unsigned int length = 0;
+ unsigned int *available_ppems = sbix.get_available_ppems (&length);
+ unsigned int num_glyphs = face->num_glyphs;
+ for (unsigned int group = 0; group < length; group++)
+ for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++)
+ {
+ hb_blob_t *blob;
+ unsigned int ppem = available_ppems[group];
+ blob = sbix.reference_blob_for_glyph (glyph_id, ppem, ppem,
+ HB_TAG('p','n','g',' '), nullptr, nullptr);
+ if (hb_blob_get_length (blob) == 0) continue;
+
+ char output_path[255];
+ sprintf (output_path, "out/sbix-%d-%d.png", ppem, glyph_id);
+ FILE *f = fopen (output_path, "wb");
+ unsigned int length;
+ const char* data = hb_blob_get_data (blob, &length);
+ fwrite (data, 1, length, f);
+ fclose (f);
+ }
+ sbix.fini ();
+}
+
+static void
+svg_dump (hb_face_t *face)
+{
+ unsigned glyph_count = hb_face_get_glyph_count (face);
+
+ OT::SVG::accelerator_t svg;
+ svg.init (face);
+
+ for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
+ {
+ hb_blob_t *blob = svg.reference_blob_for_glyph (glyph_id);
+
+ if (hb_blob_get_length (blob) == 0) continue;
+
+ unsigned int length;
+ const char *data = hb_blob_get_data (blob, &length);
+
+ char output_path[256];
+ sprintf (output_path, "out/svg-%d.svg%s",
+ glyph_id,
+ // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
+ (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : "");
+
+ FILE *f = fopen (output_path, "wb");
+ fwrite (data, 1, length, f);
+ fclose (f);
+
+ hb_blob_destroy (blob);
+ }
+
+ svg.fini ();
+}
+
+static void
+colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face)
+{
+ 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 num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr);
+ if (!num_layers)
+ continue;
+
+ hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t));
+
+ hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers);
+ if (num_layers)
+ {
+ // Measure
+ cairo_text_extents_t extents;
+ {
+ cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ cairo_t *cr = cairo_create (surface);
+ cairo_set_font_face (cr, cairo_face);
+ cairo_set_font_size (cr, upem);
+
+ cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t));
+ for (unsigned int j = 0; j < num_layers; ++j)
+ glyphs[j].index = layers[j].glyph;
+ cairo_glyph_extents (cr, glyphs, num_layers, &extents);
+ free (glyphs);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
+
+ // Add a slight margin
+ extents.width += extents.width / 10;
+ extents.height += extents.height / 10;
+ extents.x_bearing -= extents.width / 20;
+ extents.y_bearing -= extents.height / 20;
+
+ // Render
+ unsigned int palette_count = hb_ot_color_palette_get_count (face);
+ for (unsigned int palette = 0; palette < palette_count; palette++) {
+ char output_path[255];
+
+ unsigned int num_colors = hb_ot_color_palette_get_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_palette_get_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", 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 layer = 0; layer < num_layers; ++layer)
+ {
+ hb_color_t color = 0x000000FF;
+ if (layers[layer].color_index != 0xFFFF)
+ color = colors[layers[layer].color_index];
+ 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 = layers[layer].glyph;
+ glyph.x = -extents.x_bearing;
+ glyph.y = -extents.y_bearing;
+ cairo_show_glyphs (cr, &glyph, 1);
+ }
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
+ free (colors);
+ }
+ }
+
+ free (layers);
+ }
+}
+
+static void
+dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
+ unsigned int num_glyphs)
+{
+ // Dump every glyph available on the font
+ return; // disabled for now
+ for (unsigned int i = 0; i < num_glyphs; ++i)
+ {
+ cairo_text_extents_t extents;
+ cairo_glyph_t glyph = {0};
+ glyph.index = i;
+
+ // Measure
+ {
+ cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ cairo_t *cr = cairo_create (surface);
+ cairo_set_font_face (cr, cairo_face);
+ cairo_set_font_size (cr, upem);
+
+ cairo_glyph_extents (cr, &glyph, 1, &extents);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
+
+ // Add a slight margin
+ extents.width += extents.width / 10;
+ extents.height += extents.height / 10;
+ extents.x_bearing -= extents.width / 20;
+ extents.y_bearing -= extents.height / 20;
+
+ // Render
+ {
+ char output_path[255];
+ sprintf (output_path, "out/%d.svg", i);
+ cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
+ cairo_t *cr = cairo_create (surface);
+ cairo_set_font_face (cr, cairo_face);
+ cairo_set_font_size (cr, upem);
+ glyph.x = -extents.x_bearing;
+ glyph.y = -extents.y_bearing;
+ cairo_show_glyphs (cr, &glyph, 1);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf (stderr, "usage: %s font-file.ttf\n"
+ "run it like `rm -rf out && mkdir out && %s font-file.ttf`\n",
+ argv[0], argv[0]);
+ exit (1);
+ }
+
+
+ FILE *font_name_file = fopen ("out/_font_name_file.txt", "r");
+ if (font_name_file != nullptr)
+ {
+ fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n");
+ exit (1);
+ }
+
+ font_name_file = fopen ("out/_font_name_file.txt", "w");
+ if (font_name_file == nullptr)
+ {
+ 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);
+ fclose (font_name_file);
+
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+ hb_face_t *face = hb_face_create (blob, 0);
+ hb_font_t *font = hb_font_create (face);
+
+ OT::CBDT::accelerator_t cbdt;
+ cbdt.init (face);
+ cbdt.dump (cbdt_callback);
+ cbdt.fini ();
+
+ sbix_dump (face);
+
+ if (hb_ot_color_has_svg (face))
+ svg_dump (face);
+
+ cairo_font_face_t *cairo_face;
+ {
+ FT_Library library;
+ FT_Init_FreeType (&library);
+ FT_Face ftface;
+ FT_New_Face (library, argv[1], 0, &ftface);
+ cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0);
+ }
+ if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face))
+ colr_cpal_dump (face, cairo_face);
+
+ unsigned int num_glyphs = hb_face_get_glyph_count (face);
+ unsigned int upem = hb_face_get_upem (face);
+ dump_glyphs (cairo_face, upem, num_glyphs);
+
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+ hb_blob_destroy (blob);
+
+ return 0;
+}
commit f10252b4b637b4aa0b74bb75963ae1e1a41b5b9f
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Oct 29 10:29:58 2018 +0330
[svg] Fix incorrect array referencing
diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh
index 55629769..7c342d01 100644
--- a/src/hb-ot-color-svg-table.hh
+++ b/src/hb-ot-color-svg-table.hh
@@ -106,7 +106,7 @@ struct SVG
inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
{
- const SortedArrayOf<SVGDocumentIndexEntry> docs = this+svgDocEntries;
+ const SortedArrayOf<SVGDocumentIndexEntry> &docs = this+svgDocEntries;
return docs[docs.bsearch (glyph_id)];
}
More information about the HarfBuzz
mailing list