[HarfBuzz] harfbuzz: Branch 'master' - 18 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Sat Oct 27 11:47:50 UTC 2018


 docs/harfbuzz-docs.xml        |   21 ++---
 docs/harfbuzz-sections.txt    |   79 ++++++++------------
 src/Makefile.sources          |    1 
 src/dump-emoji.cc             |   86 ++++++++++++++--------
 src/hb-blob.cc                |   13 +++
 src/hb-buffer.cc              |    5 -
 src/hb-common.cc              |   23 ++++++
 src/hb-common.h               |    4 +
 src/hb-coretext.cc            |   10 ++
 src/hb-face.cc                |   13 +++
 src/hb-font.cc                |   13 +++
 src/hb-ft.cc                  |   11 ++
 src/hb-glib.cc                |   10 ++
 src/hb-gobject-structs.cc     |   12 +++
 src/hb-graphite2.cc           |   12 ++-
 src/hb-icu.cc                 |   10 ++
 src/hb-map.cc                 |   11 ++
 src/hb-open-type.hh           |    1 
 src/hb-ot-color-cbdt-table.hh |   73 ++++++++++++++++---
 src/hb-ot-color-sbix-table.hh |  105 +++++++++++++++++++++++----
 src/hb-ot-color-svg-table.hh  |   92 ++++++++++++------------
 src/hb-ot-color.cc            |  161 ++++++++++++++++++++++++++++++++++++------
 src/hb-ot-color.h             |    3 
 src/hb-ot-face.cc             |    2 
 src/hb-ot-face.hh             |    4 -
 src/hb-ot-layout.cc           |    4 -
 src/hb-ot-layout.h            |   42 ++++++++++
 src/hb-ot-tag.h               |   78 --------------------
 src/hb-ot.h                   |    1 
 src/hb-set.cc                 |   11 ++
 src/hb-shape-plan.cc          |   13 +++
 src/hb-shape.cc               |    4 -
 src/hb-unicode.cc             |   14 +++
 src/hb-uniscribe.cc           |   12 ++-
 src/hb.h                      |    4 -
 test/api/test-ot-color.c      |   91 ++++++++++++++++++++++-
 36 files changed, 766 insertions(+), 283 deletions(-)

New commits:
commit 04981ee05d83ed30c9f818106589a4de9c3e9b7f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 27 04:40:43 2018 -0700

    [docs] More

diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc
index 54e3f9cc..8b4f7e6a 100644
--- a/src/hb-coretext.cc
+++ b/src/hb-coretext.cc
@@ -35,6 +35,16 @@
 #include "hb-aat-layout.hh"
 #include <math.h>
 
+
+/**
+ * SECTION:hb-coretext
+ * @title: hb-coretext
+ * @short_description: CoreText integration
+ * @include: hb-coretext.h
+ *
+ * Functions for using HarfBuzz with the CoreText fonts.
+ **/
+
 /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
 #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
 
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index fbf36268..5e051105 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -40,6 +40,17 @@
 #include FT_TRUETYPE_TABLES_H
 
 
+/**
+ * SECTION:hb-ft
+ * @title: hb-ft
+ * @short_description: FreeType integration
+ * @include: hb-ft.h
+ *
+ * Functions for using HarfBuzz with the FreeType library to provide face and
+ * font data.
+ **/
+
+
 /* TODO:
  *
  * In general, this file does a fine job of what it's supposed to do.
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index a34acbba..23a0d89c 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -33,6 +33,16 @@
 #include "hb-machinery.hh"
 
 
+/**
+ * SECTION:hb-glib
+ * @title: hb-glib
+ * @short_description: GLib integration
+ * @include: hb-glib.h
+ *
+ * Functions for using HarfBuzz with the GLib library to provide Unicode data.
+ **/
+
+
 #if !GLIB_CHECK_VERSION(2,29,14)
 static const hb_script_t
 glib_script_to_script[] =
diff --git a/src/hb-gobject-structs.cc b/src/hb-gobject-structs.cc
index 1b875858..23ca4365 100644
--- a/src/hb-gobject-structs.cc
+++ b/src/hb-gobject-structs.cc
@@ -26,6 +26,18 @@
 
 #include "hb.hh"
 
+
+/**
+ * SECTION:hb-gobject
+ * @title: hb-gobject
+ * @short_description: GObject integration
+ * @include: hb-gobject.h
+ *
+ * Functions for using HarfBuzz with the GObject library to provide
+ * type data.
+ **/
+
+
 /* g++ didn't like older gtype.h gcc-only code path. */
 #include <glib.h>
 #if !GLIB_CHECK_VERSION(2,29,16)
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index 022e8814..971241f9 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -36,6 +36,16 @@
 #include "hb-ot-layout.h"
 
 
+/**
+ * SECTION:hb-graphite2
+ * @title: hb-graphite2
+ * @short_description: Graphite2 integration
+ * @include: hb-graphite2.h
+ *
+ * Functions for using HarfBuzz with the Graphite2 fonts.
+ **/
+
+
 HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face)
 HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font)
 
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index e012314b..12864677 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -40,6 +40,16 @@
 #include <unicode/uversion.h>
 
 
+/**
+ * SECTION:hb-icu
+ * @title: hb-icu
+ * @short_description: ICU integration
+ * @include: hb-icu.h
+ *
+ * Functions for using HarfBuzz with the ICU library to provide Unicode data.
+ **/
+
+
 hb_script_t
 hb_icu_script_to_script (UScriptCode script)
 {
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index c6f60b99..b12a0539 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -39,6 +39,16 @@
 #include "hb-ot-layout.h"
 
 
+/**
+ * SECTION:hb-uniscribe
+ * @title: hb-uniscribe
+ * @short_description: Windows integration
+ * @include: hb-uniscribe.h
+ *
+ * Functions for using HarfBuzz with the Windows fonts.
+ **/
+
+
 static inline uint16_t hb_uint16_swap (const uint16_t v)
 { return (v >> 8) | (v << 8); }
 static inline uint32_t hb_uint32_swap (const uint32_t v)
commit 5dd86aa33b4e52a0de4fcd96b2ea7bafcae8dd34
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 27 04:28:40 2018 -0700

    [docs] Rename section titles to object names
    
    More useful.

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 4b741cae..521e8b69 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -42,7 +42,7 @@
 
 /**
  * SECTION: hb-blob
- * @title: Blobs
+ * @title: hb_blob_t
  * @short_description: Binary data containers
  * @include: hb.h
  *
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 7286202a..d773dd84 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -33,7 +33,7 @@
 
 /**
  * SECTION: hb-buffer
- * @title: Buffers
+ * @title: hb_buffer_t
  * @short_description: Input and output buffers
  * @include: hb.h
  *
diff --git a/src/hb-face.cc b/src/hb-face.cc
index 4695267a..2f6ccea3 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -37,8 +37,8 @@
 
 /**
  * SECTION:hb-face
- * @title: Face
- * @short_description: Font face object
+ * @title: hb_face_t
+ * @short_description: Font face objects
  * @include: hb.h
  *
  * Font face is objects represent a single face in a font family.
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 3c7b4a5b..2ef0ff85 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -36,8 +36,8 @@
 
 /**
  * SECTION:hb-font
- * @title: Font
- * @short_description: Font object
+ * @title: hb_font_t
+ * @short_description: Font objects
  * @include: hb.h
  *
  * Font objects represent a font face at a certain size and other
diff --git a/src/hb-map.cc b/src/hb-map.cc
index 57d17ba1..e8339649 100644
--- a/src/hb-map.cc
+++ b/src/hb-map.cc
@@ -29,7 +29,7 @@
 
 /**
  * SECTION:hb-map
- * @title: Map
+ * @title: hb_map_t
  * @short_description: Object representing integer to integer mapping
  * @include: hb.h
  *
diff --git a/src/hb-set.cc b/src/hb-set.cc
index 8b1a359c..2a4b356c 100644
--- a/src/hb-set.cc
+++ b/src/hb-set.cc
@@ -29,7 +29,7 @@
 
 /**
  * SECTION:hb-set
- * @title: Set
+ * @title: hb_set_t
  * @short_description: Object representing a set of integers
  * @include: hb.h
  *
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 3eacd587..abffd40d 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -33,7 +33,7 @@
 
 /**
  * SECTION:hb-shape-plan
- * @title: Shape plan
+ * @title: hb_shape_plan_t
  * @short_description: Object representing a shaping plan
  * @include: hb.h
  *
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index bfa4ca2b..ca555a8d 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -35,7 +35,7 @@
 
 /**
  * SECTION: hb-unicode
- * @title: Unicode functions
+ * @title: hb_unicode_funcs_t
  * @short_description: Unicode character property access
  * @include: hb.h
  *
commit 524fb70216d7fec17f5327237faa4d092ae15a00
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 27 04:27:36 2018 -0700

    [docs] More

diff --git a/src/hb-map.cc b/src/hb-map.cc
index 225f37bc..57d17ba1 100644
--- a/src/hb-map.cc
+++ b/src/hb-map.cc
@@ -27,7 +27,16 @@
 #include "hb-map.hh"
 
 
-/* Public API */
+/**
+ * SECTION:hb-map
+ * @title: Map
+ * @short_description: Object representing integer to integer mapping
+ * @include: hb.h
+ *
+ * Map objects are integer-to-integer hash-maps.  Currently they are
+ * not used in the HarfBuzz public API, but are provided for client's
+ * use if desired.
+ **/
 
 
 /**
diff --git a/src/hb-set.cc b/src/hb-set.cc
index 25c19147..8b1a359c 100644
--- a/src/hb-set.cc
+++ b/src/hb-set.cc
@@ -27,7 +27,16 @@
 #include "hb-set.hh"
 
 
-/* Public API */
+/**
+ * SECTION:hb-set
+ * @title: Set
+ * @short_description: Object representing a set of integers
+ * @include: hb.h
+ *
+ * Set objects represent a mathematical set of integer values.  They are
+ * used in non-shaping API to query certain set of characters or glyphs,
+ * or other integer values.
+ **/
 
 
 /**
commit 46072b7cb55bfeb8c46a78cbdb335dfdcce48298
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 27 04:21:20 2018 -0700

    [ot] Fold hb-ot-tag.h into hb-ot-layout.h

diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml
index 6e3000df..140184af 100644
--- a/docs/harfbuzz-docs.xml
+++ b/docs/harfbuzz-docs.xml
@@ -72,7 +72,6 @@
 
         <xi:include href="xml/hb-ot-font.xml"/>
         <xi:include href="xml/hb-ot-layout.xml"/>
-        <xi:include href="xml/hb-ot-tag.xml"/>
         <xi:include href="xml/hb-ot-color.xml"/>
         <xi:include href="xml/hb-ot-name.xml"/>
         <xi:include href="xml/hb-ot-math.xml"/>
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index f20c7d9f..3ba5b8ce 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -489,6 +489,14 @@ hb_ot_name_get_utf8
 
 <SECTION>
 <FILE>hb-ot-layout</FILE>
+HB_OT_MAX_TAGS_PER_LANGUAGE
+HB_OT_MAX_TAGS_PER_SCRIPT
+HB_OT_TAG_DEFAULT_LANGUAGE
+HB_OT_TAG_DEFAULT_SCRIPT
+hb_ot_tag_to_language
+hb_ot_tag_to_script
+hb_ot_tags_from_script_and_language
+hb_ot_tags_to_script_and_language
 HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX
 HB_OT_LAYOUT_NO_FEATURE_INDEX
 HB_OT_LAYOUT_NO_SCRIPT_INDEX
@@ -564,18 +572,6 @@ hb_ot_shape_glyphs_closure
 </SECTION>
 
 <SECTION>
-<FILE>hb-ot-tag</FILE>
-HB_OT_MAX_TAGS_PER_LANGUAGE
-HB_OT_MAX_TAGS_PER_SCRIPT
-HB_OT_TAG_DEFAULT_LANGUAGE
-HB_OT_TAG_DEFAULT_SCRIPT
-hb_ot_tag_to_language
-hb_ot_tag_to_script
-hb_ot_tags_from_script_and_language
-hb_ot_tags_to_script_and_language
-</SECTION>
-
-<SECTION>
 <FILE>hb-ot-var</FILE>
 HB_OT_TAG_VAR_AXIS_ITALIC
 HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
diff --git a/src/Makefile.sources b/src/Makefile.sources
index fe140b04..561fbed6 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -184,7 +184,6 @@ HB_OT_headers = \
 	hb-ot-math.h \
 	hb-ot-name.h \
 	hb-ot-shape.h \
-	hb-ot-tag.h \
 	hb-ot-var.h \
 	$(NULL)
 
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index 1b73f9f4..022e8814 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -33,7 +33,7 @@
 
 #include <graphite2/Segment.h>
 
-#include "hb-ot-tag.h"
+#include "hb-ot-layout.h"
 
 
 HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face)
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 9bd18c8a..287d0221 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -33,7 +33,6 @@
 
 #include "hb.h"
 
-#include "hb-ot-tag.h"
 #include "hb-ot-name.h"
 
 HB_BEGIN_DECLS
@@ -47,6 +46,47 @@ HB_BEGIN_DECLS
 
 
 /*
+ * Script & Language tags.
+ */
+
+#define HB_OT_TAG_DEFAULT_SCRIPT	HB_TAG ('D', 'F', 'L', 'T')
+#define HB_OT_TAG_DEFAULT_LANGUAGE	HB_TAG ('d', 'f', 'l', 't')
+
+/**
+ * HB_OT_MAX_TAGS_PER_SCRIPT:
+ *
+ * Since: 2.0.0
+ **/
+#define HB_OT_MAX_TAGS_PER_SCRIPT	3u
+/**
+ * HB_OT_MAX_TAGS_PER_LANGUAGE:
+ *
+ * Since: 2.0.0
+ **/
+#define HB_OT_MAX_TAGS_PER_LANGUAGE	3u
+
+HB_EXTERN void
+hb_ot_tags_from_script_and_language (hb_script_t   script,
+				     hb_language_t language,
+				     unsigned int *script_count /* IN/OUT */,
+				     hb_tag_t     *script_tags /* OUT */,
+				     unsigned int *language_count /* IN/OUT */,
+				     hb_tag_t     *language_tags /* OUT */);
+
+HB_EXTERN hb_script_t
+hb_ot_tag_to_script (hb_tag_t tag);
+
+HB_EXTERN hb_language_t
+hb_ot_tag_to_language (hb_tag_t tag);
+
+HB_EXTERN void
+hb_ot_tags_to_script_and_language (hb_tag_t       script_tag,
+				   hb_tag_t       language_tag,
+				   hb_script_t   *script /* OUT */,
+				   hb_language_t *language /* OUT */);
+
+
+/*
  * GDEF
  */
 
diff --git a/src/hb-ot-tag.h b/src/hb-ot-tag.h
deleted file mode 100644
index 33a4dbdb..00000000
--- a/src/hb-ot-tag.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright © 2009  Red Hat, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_H_IN
-#error "Include <hb-ot.h> instead."
-#endif
-
-#ifndef HB_OT_TAG_H
-#define HB_OT_TAG_H
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-
-
-#define HB_OT_TAG_DEFAULT_SCRIPT	HB_TAG ('D', 'F', 'L', 'T')
-#define HB_OT_TAG_DEFAULT_LANGUAGE	HB_TAG ('d', 'f', 'l', 't')
-
-/**
- * HB_OT_MAX_TAGS_PER_SCRIPT:
- *
- * Since: 2.0.0
- **/
-#define HB_OT_MAX_TAGS_PER_SCRIPT	3u
-/**
- * HB_OT_MAX_TAGS_PER_LANGUAGE:
- *
- * Since: 2.0.0
- **/
-#define HB_OT_MAX_TAGS_PER_LANGUAGE	3u
-
-HB_EXTERN void
-hb_ot_tags_from_script_and_language (hb_script_t   script,
-				     hb_language_t language,
-				     unsigned int *script_count /* IN/OUT */,
-				     hb_tag_t     *script_tags /* OUT */,
-				     unsigned int *language_count /* IN/OUT */,
-				     hb_tag_t     *language_tags /* OUT */);
-
-HB_EXTERN hb_script_t
-hb_ot_tag_to_script (hb_tag_t tag);
-
-HB_EXTERN hb_language_t
-hb_ot_tag_to_language (hb_tag_t tag);
-
-HB_EXTERN void
-hb_ot_tags_to_script_and_language (hb_tag_t       script_tag,
-				   hb_tag_t       language_tag,
-				   hb_script_t   *script /* OUT */,
-				   hb_language_t *language /* OUT */);
-
-
-HB_END_DECLS
-
-#endif /* HB_OT_TAG_H */
diff --git a/src/hb-ot.h b/src/hb-ot.h
index 47508d67..c168175a 100644
--- a/src/hb-ot.h
+++ b/src/hb-ot.h
@@ -35,7 +35,6 @@
 #include "hb-ot-layout.h"
 #include "hb-ot-math.h"
 #include "hb-ot-name.h"
-#include "hb-ot-tag.h"
 #include "hb-ot-shape.h"
 #include "hb-ot-var.h"
 
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index c3949c98..c6f60b99 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -36,7 +36,7 @@
 
 #include "hb-open-file.hh"
 #include "hb-ot-name-table.hh"
-#include "hb-ot-tag.h"
+#include "hb-ot-layout.h"
 
 
 static inline uint16_t hb_uint16_swap (const uint16_t v)
commit 00cf4e5eb6dcb04406d5a519712da799277cec2e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 27 04:07:33 2018 -0700

    [docs] Fill in some sections

diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml
index 0057a2a9..6e3000df 100644
--- a/docs/harfbuzz-docs.xml
+++ b/docs/harfbuzz-docs.xml
@@ -61,22 +61,15 @@
     <title>Reference manual</title>
       <chapter>
         <title>HarfBuzz API</title>
-        <xi:include href="xml/hb.xml"/>
         <xi:include href="xml/hb-common.xml"/>
-        <xi:include href="xml/hb-unicode.xml"/>
-        <xi:include href="xml/hb-buffer.xml"/>
         <xi:include href="xml/hb-blob.xml"/>
         <xi:include href="xml/hb-face.xml"/>
         <xi:include href="xml/hb-font.xml"/>
+        <xi:include href="xml/hb-buffer.xml"/>
         <xi:include href="xml/hb-shape.xml"/>
-
+        <xi:include href="xml/hb-unicode.xml"/>
         <xi:include href="xml/hb-version.xml"/>
-        <xi:include href="xml/hb-deprecated.xml"/>
-
-        <xi:include href="xml/hb-set.xml"/>
-        <xi:include href="xml/hb-map.xml"/>
 
-        <xi:include href="xml/hb-ot.xml"/>
         <xi:include href="xml/hb-ot-font.xml"/>
         <xi:include href="xml/hb-ot-layout.xml"/>
         <xi:include href="xml/hb-ot-tag.xml"/>
@@ -87,16 +80,19 @@
 
         <xi:include href="xml/hb-shape-plan.xml"/>
 
-        <xi:include href="xml/hb-glib.xml"/>
-        <xi:include href="xml/hb-icu.xml"/>
+        <xi:include href="xml/hb-set.xml"/>
+        <xi:include href="xml/hb-map.xml"/>
 
         <xi:include href="xml/hb-ft.xml"/>
+        <xi:include href="xml/hb-icu.xml"/>
+        <xi:include href="xml/hb-glib.xml"/>
+        <xi:include href="xml/hb-gobject.xml"/>
 
         <xi:include href="xml/hb-graphite2.xml"/>
         <xi:include href="xml/hb-uniscribe.xml"/>
         <xi:include href="xml/hb-coretext.xml"/>
 
-        <xi:include href="xml/hb-gobject.xml"/>
+        <xi:include href="xml/hb-deprecated.xml"/>
 
       </chapter>
       <chapter id="object-tree">
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 7f2ff2d2..f20c7d9f 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -1,10 +1,6 @@
-<SECTION>
-<FILE>hb</FILE>
 <SUBSECTION Private>
 HB_H_IN
-HB_EXTERN
-HB_DEPRECATED
-HB_DEPRECATED_FOR
+HB_OT_H_IN
 </SECTION>
 
 <SECTION>
@@ -148,6 +144,10 @@ uint16_t
 uint32_t
 uint64_t
 uint8_t
+<SUBSECTION Private>
+HB_EXTERN
+HB_DEPRECATED
+HB_DEPRECATED_FOR
 </SECTION>
 
 <SECTION>
@@ -419,11 +419,6 @@ HB_GOBJECT_H_IN
 </SECTION>
 
 <SECTION>
-<FILE>hb-gobject</FILE>
-
-</SECTION>
-
-<SECTION>
 <FILE>hb-graphite2</FILE>
 HB_GRAPHITE2_TAG_SILF
 hb_graphite2_face_get_gr_face
@@ -458,12 +453,6 @@ hb_map_t
 </SECTION>
 
 <SECTION>
-<FILE>hb-ot</FILE>
-<SUBSECTION Private>
-HB_OT_H_IN
-</SECTION>
-
-<SECTION>
 <FILE>hb-ot-color</FILE>
 hb_color_t
 HB_COLOR
@@ -499,11 +488,6 @@ hb_ot_name_get_utf8
 </SECTION>
 
 <SECTION>
-<FILE>hb-ot-shape</FILE>
-hb_ot_shape_glyphs_closure
-</SECTION>
-
-<SECTION>
 <FILE>hb-ot-layout</FILE>
 HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX
 HB_OT_LAYOUT_NO_FEATURE_INDEX
@@ -555,23 +539,6 @@ Xhb_ot_layout_lookup_substitute
 </SECTION>
 
 <SECTION>
-<FILE>hb-ot-var</FILE>
-HB_OT_TAG_VAR_AXIS_ITALIC
-HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
-HB_OT_TAG_VAR_AXIS_SLANT
-HB_OT_TAG_VAR_AXIS_WEIGHT
-HB_OT_TAG_VAR_AXIS_WIDTH
-HB_OT_VAR_NO_AXIS_INDEX
-hb_ot_var_axis_t
-hb_ot_var_has_data
-hb_ot_var_find_axis
-hb_ot_var_get_axis_count
-hb_ot_var_get_axes
-hb_ot_var_normalize_variations
-hb_ot_var_normalize_coords
-</SECTION>
-
-<SECTION>
 <FILE>hb-ot-math</FILE>
 HB_OT_TAG_MATH
 HB_OT_MATH_SCRIPT
@@ -592,6 +559,11 @@ hb_ot_math_get_glyph_assembly
 </SECTION>
 
 <SECTION>
+<FILE>hb-ot-shape</FILE>
+hb_ot_shape_glyphs_closure
+</SECTION>
+
+<SECTION>
 <FILE>hb-ot-tag</FILE>
 HB_OT_MAX_TAGS_PER_LANGUAGE
 HB_OT_MAX_TAGS_PER_SCRIPT
@@ -604,6 +576,23 @@ hb_ot_tags_to_script_and_language
 </SECTION>
 
 <SECTION>
+<FILE>hb-ot-var</FILE>
+HB_OT_TAG_VAR_AXIS_ITALIC
+HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
+HB_OT_TAG_VAR_AXIS_SLANT
+HB_OT_TAG_VAR_AXIS_WEIGHT
+HB_OT_TAG_VAR_AXIS_WIDTH
+HB_OT_VAR_NO_AXIS_INDEX
+hb_ot_var_axis_t
+hb_ot_var_has_data
+hb_ot_var_find_axis
+hb_ot_var_get_axis_count
+hb_ot_var_get_axes
+hb_ot_var_normalize_variations
+hb_ot_var_normalize_coords
+</SECTION>
+
+<SECTION>
 <FILE>hb-set</FILE>
 HB_SET_VALUE_INVALID
 hb_set_add
diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 368491c0..4b741cae 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -40,6 +40,19 @@
 #include <stdlib.h>
 
 
+/**
+ * SECTION: hb-blob
+ * @title: Blobs
+ * @short_description: Binary data containers
+ * @include: hb.h
+ *
+ * Blobs wrap a chunk of binary data to handle lifecycle management of data
+ * while it is passed between client and HarfBuzz.  Blobs are primarily used
+ * to create font faces, but also to access font face tables, as well as
+ * pass around other binary data.
+ **/
+
+
 DEFINE_NULL_INSTANCE (hb_blob_t) =
 {
   HB_OBJECT_HEADER_STATIC,
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index f905c63a..7286202a 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -38,9 +38,10 @@
  * @include: hb.h
  *
  * Buffers serve dual role in HarfBuzz; they hold the input characters that are
- * passed hb_shape(), and after shaping they hold the output glyphs.
+ * passed to hb_shape(), and after shaping they hold the output glyphs.
  **/
 
+
 /**
  * hb_segment_properties_equal:
  * @a: first #hb_segment_properties_t to compare.
diff --git a/src/hb-common.cc b/src/hb-common.cc
index 86d07cf1..2a61fcc3 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -36,6 +36,16 @@
 #endif
 
 
+/**
+ * SECTION:hb-common
+ * @title: Common types
+ * @short_description: Common data types
+ * @include: hb.h
+ *
+ * Common data types used across HarfBuzz are defined here.
+ **/
+
+
 /* hb_options_t */
 
 hb_atomic_int_t _hb_options;
@@ -615,6 +625,19 @@ hb_user_data_array_t::get (hb_user_data_key_t *key)
 
 /* hb_version */
 
+
+/**
+ * SECTION:hb-version
+ * @title: Version
+ * @short_description: Information about the version of HarfBuzz in use
+ * @include: hb.h
+ *
+ * These functions and macros allow accessing version of the HarfBuzz
+ * library used at compile- as well as run-time, and to direct code
+ * conditionally based on those versions, again, at compile- or run-time.
+ **/
+
+
 /**
  * hb_version:
  * @major: (out): Library major version component.
diff --git a/src/hb-face.cc b/src/hb-face.cc
index 74c77721..4695267a 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -36,6 +36,19 @@
 
 
 /**
+ * SECTION:hb-face
+ * @title: Face
+ * @short_description: Font face object
+ * @include: hb.h
+ *
+ * Font face is objects represent a single face in a font family.
+ * More exactly, a font face represents a single face in a binary font file.
+ * Font faces are typically built from a binary blob and a face index.
+ * Font faces are used to create fonts.
+ **/
+
+
+/**
  * hb_face_count:
  * @blob: a blob.
  *
diff --git a/src/hb-font.cc b/src/hb-font.cc
index e38c2fbd..3c7b4a5b 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -34,6 +34,19 @@
 #include "hb-ot.h"
 
 
+/**
+ * SECTION:hb-font
+ * @title: Font
+ * @short_description: Font object
+ * @include: hb.h
+ *
+ * Font objects represent a font face at a certain size and other
+ * parameters (pixels per EM, points per EM, variation settings.)
+ * Fonts are created from font faces, and are used as input to
+ * hb_shape() among other things.
+ **/
+
+
 /*
  * hb_font_funcs_t
  */
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index dea2c8c7..3eacd587 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -31,6 +31,19 @@
 #include "hb-buffer.hh"
 
 
+/**
+ * SECTION:hb-shape-plan
+ * @title: Shape plan
+ * @short_description: Object representing a shaping plan
+ * @include: hb.h
+ *
+ * Shape plans are not used for shaping directly, but can be access to query
+ * certain information about how shaping will perform given a set of input
+ * parameters (script, language, direction, features, etc.)
+ * Most client would not need to deal with shape plans directly.
+ **/
+
+
 static void
 hb_shape_plan_plan (hb_shape_plan_t    *shape_plan,
 		    const hb_feature_t *user_features,
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index e8eeff5b..00c61397 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -34,6 +34,7 @@
 #include "hb-font.hh"
 #include "hb-machinery.hh"
 
+
 /**
  * SECTION:hb-shape
  * @title: Shaping
@@ -42,10 +43,11 @@
  *
  * Shaping is the central operation of HarfBuzz. Shaping operates on buffers,
  * which are sequences of Unicode characters that use the same font and have
- * the same text direction, script and language. After shaping the buffer
+ * the same text direction, script, and language. After shaping the buffer
  * contains the output glyphs and their positions.
  **/
 
+
 #ifdef HB_USE_ATEXIT
 static void free_static_shaper_list (void);
 #endif
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index a08f8882..bfa4ca2b 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -33,6 +33,20 @@
 #include "hb-unicode.hh"
 
 
+/**
+ * SECTION: hb-unicode
+ * @title: Unicode functions
+ * @short_description: Unicode character property access
+ * @include: hb.h
+ *
+ * Unicode functions are used to access Unicode character properties.
+ * Client can pass its own Unicode functions to HarfBuzz, or access
+ * the built-in Unicode functions that come with HarfBuzz.
+ *
+ * With the Unicode functions, one can query variour Unicode character
+ * properties, such as General Category, Script, Combining Class, etc.
+ **/
+
 
 /*
  * hb_unicode_funcs_t
commit 55a19d73b4d5e7ddd328263d241a442f16f005b2
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 27 04:01:19 2018 -0700

    Move HB_EXTERN

diff --git a/src/hb-common.h b/src/hb-common.h
index 2532d69f..ae23698a 100644
--- a/src/hb-common.h
+++ b/src/hb-common.h
@@ -33,6 +33,10 @@
 #ifndef HB_COMMON_H
 #define HB_COMMON_H
 
+#ifndef HB_EXTERN
+#define HB_EXTERN extern
+#endif
+
 #ifndef HB_BEGIN_DECLS
 # ifdef __cplusplus
 #  define HB_BEGIN_DECLS	extern "C" {
diff --git a/src/hb.h b/src/hb.h
index fc75a691..c5e7072f 100644
--- a/src/hb.h
+++ b/src/hb.h
@@ -28,10 +28,6 @@
 #define HB_H
 #define HB_H_IN
 
-#ifndef HB_EXTERN
-#define HB_EXTERN extern
-#endif
-
 #include "hb-blob.h"
 #include "hb-buffer.h"
 #include "hb-common.h"
commit 524e854c15f9d6c50c5456ae0e188f039dcf153c
Merge: 4ee3c827 8180c37d
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sat Oct 27 15:04:43 2018 +0330

    Merge pull request #1318 from ebraminio/png
    
    Add a non-hooked _png _svg get emoji blob

diff --cc src/hb-ot-color.cc
index 58f5a070,7ffc3d88..78c462f0
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@@ -219,15 -221,16 +221,16 @@@ hb_ot_color_has_layers (hb_face_t *face
  
  /**
   * hb_ot_color_glyph_get_layers:
-  * @face: a font face.
-  * @glyph:
-  * @start_offset:
-  * @count:  (inout) (optional):
-  * @layers: (array length=count) (out) (optional):
+  * @face:         a font face.
+  * @glyph:        a layered color glyph id.
+  * @start_offset: starting offset of layers.
+  * @count:  (inout) (optional): gets number of layers available to be written on buffer
+  * 				and returns number of written layers.
+  * @layers: (array length=count) (out) (optional): layers buffer to buffer.
   *
-  * Returns:
+  * Returns: Total number of layers a layered color glyph have.
   *
 - * Since: REPLACEME
 + * Since: 2.1.0
   */
  unsigned int
  hb_ot_color_glyph_get_layers (hb_face_t           *face,
diff --cc src/hb-ot-face.cc
index dd17faf6,0aba2a69..cbceea9b
--- a/src/hb-ot-face.cc
+++ b/src/hb-ot-face.cc
@@@ -30,9 -30,10 +30,11 @@@
  #include "hb-ot-glyf-table.hh"
  #include "hb-ot-hmtx-table.hh"
  #include "hb-ot-kern-table.hh"
 +#include "hb-ot-name-table.hh"
  #include "hb-ot-post-table.hh"
  #include "hb-ot-color-cbdt-table.hh"
+ #include "hb-ot-color-sbix-table.hh"
+ #include "hb-ot-color-svg-table.hh"
  #include "hb-ot-layout-gdef-table.hh"
  #include "hb-ot-layout-gsub-table.hh"
  #include "hb-ot-layout-gpos-table.hh"
commit 8180c37df0a856dbc3564c0aefd8b2acab8baf8a
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sat Oct 27 14:45:00 2018 +0330

    [ot-color] Remove _png and _svg public APIs

diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 67f9ae2c..7bca7ca2 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -460,12 +460,8 @@ HB_OT_H_IN
 <SECTION>
 <FILE>hb-ot-color</FILE>
 hb_ot_color_glyph_get_layers
-hb_ot_color_glyph_reference_blob_png
-hb_ot_color_glyph_reference_blob_svg
 hb_ot_color_has_layers
 hb_ot_color_has_palettes
-hb_ot_color_has_png
-hb_ot_color_has_svg
 hb_ot_color_layer_t
 hb_ot_color_palette_color_get_name_id
 hb_ot_color_palette_flags_t
diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
index 73305aa7..63fb5885 100644
--- a/src/dump-emoji.cc
+++ b/src/dump-emoji.cc
@@ -89,9 +89,12 @@ 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 = hb_ot_color_glyph_reference_blob_svg (face, glyph_id);
+    hb_blob_t *blob = svg.reference_blob_for_glyph (glyph_id);
 
     if (hb_blob_get_length (blob) == 0) continue;
 
@@ -110,6 +113,8 @@ svg_dump (hb_face_t *face)
 
     hb_blob_destroy (blob);
   }
+
+  svg.fini ();
 }
 
 static void
@@ -290,8 +295,8 @@ main (int argc, char **argv)
 
   sbix_dump (face);
 
-  if (hb_ot_color_has_svg (face))
-    svg_dump (face);
+//   if (hb_ot_color_has_svg (face))
+  svg_dump (face);
 
   cairo_font_face_t *cairo_face;
   {
diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index a2b75383..7ffc3d88 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -47,12 +47,14 @@ _get_colr (hb_face_t *face)
   return *(hb_ot_face_data (face)->COLR.get ());
 }
 
+#if 0
 static inline const OT::CBDT_accelerator_t&
 _get_cbdt (hb_face_t *face)
 {
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t);
   return *(hb_ot_face_data (face)->CBDT.get ());
 }
+#endif
 
 static inline const OT::CPAL&
 _get_cpal (hb_face_t *face)
@@ -61,6 +63,7 @@ _get_cpal (hb_face_t *face)
   return *(hb_ot_face_data (face)->CPAL.get ());
 }
 
+#if 0
 static inline const OT::sbix_accelerator_t&
 _get_sbix (hb_face_t *face)
 {
@@ -74,6 +77,7 @@ _get_svg (hb_face_t *face)
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG_accelerator_t);
   return *(hb_ot_face_data (face)->SVG.get ());
 }
+#endif
 
 
 /*
@@ -239,6 +243,7 @@ hb_ot_color_glyph_get_layers (hb_face_t           *face,
 }
 
 
+#if 0
 /*
  * SVG
  */
@@ -249,7 +254,7 @@ hb_ot_color_glyph_get_layers (hb_face_t           *face,
  *
  * Returns: whether SVG table is available.
  *
- * Since: REPLACEME
+ * Since: DONTREPLACEME
  */
 hb_bool_t
 hb_ot_color_has_svg (hb_face_t *face)
@@ -264,7 +269,7 @@ hb_ot_color_has_svg (hb_face_t *face)
  *
  * Returns: respective svg blob of the glyph, if available.
  *
- * Since: REPLACEME
+ * Since: DONTREPLACEME
  */
 hb_blob_t *
 hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph)
@@ -283,7 +288,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph)
  *
  * Returns: whether either of CBDT or sbix tables is available.
  *
- * Since: REPLACEME
+ * Since: DONTREPLACEME
  */
 hb_bool_t
 hb_ot_color_has_png (hb_face_t *face)
@@ -302,7 +307,7 @@ hb_ot_color_has_png (hb_face_t *face)
  *
  * Returns: respective png blob of the glyph, if available.
  *
- * Since: REPLACEME
+ * Since: DONTREPLACEME
  */
 hb_blob_t *
 hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
@@ -328,3 +333,29 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
 
   return blob;
 }
+
+/* To be moved to public header */
+
+/*
+ * SVG
+ */
+
+HB_EXTERN hb_bool_t
+hb_ot_color_has_svg (hb_face_t *face);
+
+HB_EXTERN hb_blob_t *
+hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph);
+
+/*
+ * PNG: CBDT or sbix
+ */
+
+HB_EXTERN hb_bool_t
+hb_ot_color_has_png (hb_face_t *face);
+
+HB_EXTERN hb_blob_t *
+hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
+				      hb_codepoint_t  glyph,
+				      unsigned int   *strike_x_ppem,
+				      unsigned int   *strike_y_ppem);
+#endif
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index a8eae861..6e4c1777 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -111,30 +111,6 @@ hb_ot_color_glyph_get_layers (hb_face_t           *face,
 			      unsigned int        *count, /* IN/OUT.  May be NULL. */
 			      hb_ot_color_layer_t *layers /* OUT.     May be NULL. */);
 
-/*
- * SVG
- */
-
-HB_EXTERN hb_bool_t
-hb_ot_color_has_svg (hb_face_t *face);
-
-HB_EXTERN hb_blob_t *
-hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph);
-
-/*
- * PNG: CBDT or sbix
- */
-
-HB_EXTERN hb_bool_t
-hb_ot_color_has_png (hb_face_t *face);
-
-HB_EXTERN hb_blob_t *
-hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
-				      hb_codepoint_t  glyph,
-				      unsigned int   *strike_x_ppem,
-				      unsigned int   *strike_y_ppem);
-
-
 HB_END_DECLS
 
 #endif /* HB_OT_COLOR_H */
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index 51b901d2..27409e10 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -363,6 +363,7 @@ test_hb_ot_color_has_data (void)
   g_assert (hb_ot_color_has_palettes (sbix) == FALSE);
   g_assert (hb_ot_color_has_palettes (svg) == FALSE);
 
+#if 0
   g_assert (hb_ot_color_has_svg (empty) == FALSE);
   g_assert (hb_ot_color_has_svg (cpal_v0) == FALSE);
   g_assert (hb_ot_color_has_svg (cpal_v1) == FALSE);
@@ -378,8 +379,10 @@ test_hb_ot_color_has_data (void)
   g_assert (hb_ot_color_has_png (cbdt) == TRUE);
   g_assert (hb_ot_color_has_png (sbix) == TRUE);
   g_assert (hb_ot_color_has_png (svg) == FALSE);
+#endif
 }
 
+#if 0
 static void
 test_hb_ot_color_svg (void)
 {
@@ -441,6 +444,7 @@ test_hb_ot_color_png (void)
   hb_blob_destroy (blob);
   hb_font_destroy (cbdt_font);
 }
+#endif
 
 int
 main (int argc, char **argv)
@@ -468,8 +472,8 @@ main (int argc, char **argv)
   hb_test_add (test_hb_ot_color_palette_color_get_name_id);
   hb_test_add (test_hb_ot_color_glyph_get_layers);
   hb_test_add (test_hb_ot_color_has_data);
-  hb_test_add (test_hb_ot_color_png);
-  hb_test_add (test_hb_ot_color_svg);
+//   hb_test_add (test_hb_ot_color_png);
+//   hb_test_add (test_hb_ot_color_svg);
   status = hb_test_run();
   hb_face_destroy (cpal_v0);
   hb_face_destroy (cpal_v1);
commit 9aa6279a2d64ab8057b0d7acbcc77044442c6d0e
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sat Oct 27 14:24:58 2018 +0330

    [ot-color/png] Try to get image blob from sbix first options.aat is set

diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index 84035069..a2b75383 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -310,15 +310,21 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
 				      unsigned int   *strike_x_ppem /* OUT */,
 				      unsigned int   *strike_y_ppem /* OUT */)
 {
-  if (_get_cbdt (font->face).has_data ())
-    return _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem,
+  hb_blob_t *blob = hb_blob_get_empty ();
+  /* don't run cbdt first if aat is set */
+  if (!hb_options ().aat && _get_cbdt (font->face).has_data ())
+    blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem,
 							    strike_x_ppem, strike_y_ppem);
 
-  if (_get_sbix (font->face).has_data ())
-    return _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem,
+  if (_get_sbix (font->face).has_data () && !hb_blob_get_length (blob))
+    blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem,
 							    MAX (font->x_ppem, font->y_ppem),
 							    HB_TAG('p','n','g',' '),
 							    strike_x_ppem, strike_y_ppem);
 
-  return hb_blob_get_empty ();
+  if (hb_options ().aat && _get_cbdt (font->face).has_data () && !hb_blob_get_length (blob))
+    blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem,
+							    strike_x_ppem, strike_y_ppem);
+
+  return blob;
 }
commit b42661ee91ea92309e827a970f370cacc62c73aa
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sat Oct 27 14:15:38 2018 +0330

    [ot-color] Add some documentation

diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index 9de2f9ac..84035069 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -132,8 +132,8 @@ hb_ot_color_palette_get_name_id (hb_face_t *face,
 
 /**
  * hb_ot_color_palette_color_get_name_id:
- * @face: a font face.
- * @color_index:
+ * @face:        a font face.
+ * @color_index: palette entry index.
  *
  * Returns: Name ID associated with a palette entry, e.g. eye color
  *
@@ -148,7 +148,7 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face,
 
 /**
  * hb_ot_color_palette_get_flags:
- * @face:    a font face
+ * @face:          a font face
  * @palette_index: the index of the color palette whose flags are being requested
  *
  * Returns: the flags for the requested color palette.
@@ -217,13 +217,14 @@ hb_ot_color_has_layers (hb_face_t *face)
 
 /**
  * hb_ot_color_glyph_get_layers:
- * @face: a font face.
- * @glyph:
- * @start_offset:
- * @count:  (inout) (optional):
- * @layers: (array length=count) (out) (optional):
+ * @face:         a font face.
+ * @glyph:        a layered color glyph id.
+ * @start_offset: starting offset of layers.
+ * @count:  (inout) (optional): gets number of layers available to be written on buffer
+ * 				and returns number of written layers.
+ * @layers: (array length=count) (out) (optional): layers buffer to buffer.
  *
- * Returns:
+ * Returns: Total number of layers a layered color glyph have.
  *
  * Since: REPLACEME
  */
@@ -258,10 +259,10 @@ hb_ot_color_has_svg (hb_face_t *face)
 
 /**
  * hb_ot_color_glyph_reference_blob_svg:
- * @face:
- * @glyph:
+ * @face:  a font face.
+ * @glyph: a svg glyph index.
  *
- * Returns:
+ * Returns: respective svg blob of the glyph, if available.
  *
  * Since: REPLACEME
  */
@@ -280,7 +281,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph)
  * hb_ot_color_has_png:
  * @face: a font face.
  *
- * Returns: whether SVG table is available.
+ * Returns: whether either of CBDT or sbix tables is available.
  *
  * Since: REPLACEME
  */
@@ -292,12 +293,14 @@ hb_ot_color_has_png (hb_face_t *face)
 
 /**
  * hb_ot_color_glyph_reference_blob_svg:
- * @font:
- * @glyph:
+ * @font:  a font object, not face. upem should be set on
+ * 	   that font object if one wants to get optimal png blob, otherwise
+ * 	   return the biggest one
+ * @glyph: a glyph index.
  * @strike_x_ppem: (out):
  * @strike_y_ppem: (out):
  *
- * Returns:
+ * Returns: respective png blob of the glyph, if available.
  *
  * Since: REPLACEME
  */
@@ -307,8 +310,6 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
 				      unsigned int   *strike_x_ppem /* OUT */,
 				      unsigned int   *strike_y_ppem /* OUT */)
 {
-  /* TODO: if (hb_options ().aat ()) then call sbix first */
-
   if (_get_cbdt (font->face).has_data ())
     return _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem,
 							    strike_x_ppem, strike_y_ppem);
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index 1810cd63..a8eae861 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -94,7 +94,7 @@ HB_EXTERN hb_bool_t
 hb_ot_color_has_layers (hb_face_t *face);
 
 /**
- * hb_ot_color_layer_t:
+ * hb_ot_color_layer_t: Pairs of glyph and color index.
  *
  * Since: REPLACEME
  **/
commit 9435fb24daadf08add9a701816da01bd54c0cd78
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sat Oct 27 13:32:14 2018 +0330

    [ot-color/png] Implement CBDT part

diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh
index 770fe3eb..a9518b77 100644
--- a/src/hb-ot-color-cbdt-table.hh
+++ b/src/hb-ot-color-cbdt-table.hh
@@ -504,12 +504,58 @@ struct CBDT
       }
     }
 
-    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id HB_UNUSED,
-						unsigned int    requested_x_ppem HB_UNUSED,
-						unsigned int    requested_y_ppem HB_UNUSED,
-						unsigned int   *strike_x_ppem HB_UNUSED,
-						unsigned int   *strike_y_ppem HB_UNUSED) const
+    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id,
+						unsigned int    requested_x_ppem,
+						unsigned int    requested_y_ppem,
+						unsigned int   *strike_x_ppem,
+						unsigned int   *strike_y_ppem) const
     {
+      if (!cblc)
+	return hb_blob_get_empty ();  // Not a color bitmap font.
+
+      if (requested_x_ppem == 0) requested_x_ppem = upem;
+      if (requested_y_ppem == 0) requested_y_ppem = upem;
+      unsigned int x_ppem = requested_x_ppem, y_ppem = requested_y_ppem;
+
+      const void *base;
+      const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph_id, &x_ppem, &y_ppem, &base);
+      if (!subtable_record || !x_ppem || !y_ppem)
+	return hb_blob_get_empty ();
+
+      unsigned int image_offset = 0, image_length = 0, image_format = 0;
+      if (!subtable_record->get_image_data (glyph_id, base, &image_offset, &image_length, &image_format))
+	return hb_blob_get_empty ();
+
+      switch (image_format)
+      {
+      case 17: {
+	if (strike_x_ppem) *strike_x_ppem = x_ppem;
+	if (strike_x_ppem) *strike_y_ppem = y_ppem;
+	const GlyphBitmapDataFormat17& glyphFormat17 =
+          StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt_blob,
+					image_offset + GlyphBitmapDataFormat17::min_size,
+					glyphFormat17.data.len);
+      }
+      case 18: {
+	if (strike_x_ppem) *strike_x_ppem = x_ppem;
+	if (strike_x_ppem) *strike_y_ppem = y_ppem;
+	const GlyphBitmapDataFormat18& glyphFormat18 =
+          StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt_blob,
+					image_offset + GlyphBitmapDataFormat18::min_size,
+					glyphFormat18.data.len);
+      }
+      case 19: {
+	if (strike_x_ppem) *strike_x_ppem = x_ppem;
+	if (strike_x_ppem) *strike_y_ppem = y_ppem;
+	const GlyphBitmapDataFormat19& glyphFormat19 =
+          StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt_blob,
+					image_offset + GlyphBitmapDataFormat19::min_size,
+					glyphFormat19.data.len);
+      }
+      }
       return hb_blob_get_empty ();
     }
 
diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index 8dd3b2a4..9de2f9ac 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -75,22 +75,6 @@ _get_svg (hb_face_t *face)
   return *(hb_ot_face_data (face)->SVG.get ());
 }
 
-#if 0
-static inline const OT::CBDT_accelerator_t&
-_get_cbdt (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t);
-  return *(hb_ot_face_data (face)->CBDT.get ());
-}
-
-static inline const OT::sbix&
-_get_sbix (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix);
-  return *(hb_ot_face_data (face)->sbix.get ());
-}
-#endif
-
 
 /*
  * CPAL
@@ -289,7 +273,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph)
 
 
 /*
- * PNG, CBDT or sbix
+ * PNG: CBDT or sbix
  */
 
 /**
@@ -335,4 +319,5 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
 							    HB_TAG('p','n','g',' '),
 							    strike_x_ppem, strike_y_ppem);
 
+  return hb_blob_get_empty ();
 }
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index 7901a359..1810cd63 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -121,6 +121,10 @@ hb_ot_color_has_svg (hb_face_t *face);
 HB_EXTERN hb_blob_t *
 hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph);
 
+/*
+ * PNG: CBDT or sbix
+ */
+
 HB_EXTERN hb_bool_t
 hb_ot_color_has_png (hb_face_t *face);
 
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index 767a3d61..51b901d2 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -405,22 +405,41 @@ static void
 test_hb_ot_color_png (void)
 {
   hb_blob_t *blob;
+  unsigned int length;
+  const char *data;
+  unsigned int strike_x_ppem, strike_y_ppem;
 
+  /* sbix */
   hb_font_t *sbix_font;
   sbix_font = hb_font_create (sbix);
   blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0, NULL, NULL);
   g_assert (hb_blob_get_length (blob) == 0);
 
-  unsigned int strike_x_ppem, strike_y_ppem;
   blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1,
 					       &strike_x_ppem, &strike_y_ppem);
-  unsigned int length;
-  const char *data = hb_blob_get_data (blob, &length);
+  data = hb_blob_get_data (blob, &length);
   g_assert_cmpuint (length, ==, 224);
   g_assert_cmpuint (strike_x_ppem, ==, 300);
   g_assert_cmpuint (strike_y_ppem, ==, 300);
   g_assert (strncmp (data + 1, "PNG", 3) == 0);
   hb_blob_destroy (blob);
+  hb_font_destroy (sbix_font);
+
+  /* cbdt */
+  hb_font_t *cbdt_font;
+  cbdt_font = hb_font_create (cbdt);
+  blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 0, NULL, NULL);
+  g_assert (hb_blob_get_length (blob) == 0);
+
+  blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 1,
+					       &strike_x_ppem, &strike_y_ppem);
+  data = hb_blob_get_data (blob, &length);
+  g_assert_cmpuint (length, ==, 88);
+  g_assert_cmpuint (strike_x_ppem, ==, 80);
+  g_assert_cmpuint (strike_y_ppem, ==, 80);
+  g_assert (strncmp (data + 1, "PNG", 3) == 0);
+  hb_blob_destroy (blob);
+  hb_font_destroy (cbdt_font);
 }
 
 int
commit 5e2a52f71a8d081441fbc1c57a3550e3a9573e46
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sat Oct 27 12:44:33 2018 +0330

    [sbix] Remove dump method from sbix accelerator

diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
index 7c7392f2..73305aa7 100644
--- a/src/dump-emoji.cc
+++ b/src/dump-emoji.cc
@@ -58,15 +58,30 @@ cbdt_callback (const uint8_t* data, unsigned int length,
 }
 
 static void
-sbix_callback (hb_blob_t *blob, unsigned int group, unsigned int gid)
+sbix_dump (hb_face_t *face)
 {
-  char output_path[255];
-  sprintf (output_path, "out/sbix-%d-%d.png", group, gid);
-  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);
+  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;
+      blob = sbix.reference_blob_for_glyph (glyph_id, 0, available_ppems[group],
+					    HB_TAG('p','n','g',' '), NULL, NULL);
+      if (hb_blob_get_length (blob) == 0) continue;
+
+      char output_path[255];
+      sprintf (output_path, "out/sbix-%d-%d.png", available_ppems[group], 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
@@ -273,10 +288,7 @@ main (int argc, char **argv)
   cbdt.dump (cbdt_callback);
   cbdt.fini ();
 
-  OT::sbix::accelerator_t sbix;
-  sbix.init (face);
-  sbix.dump (sbix_callback);
-  sbix.fini ();
+  sbix_dump (face);
 
   if (hb_ot_color_has_svg (face))
     svg_dump (face);
diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh
index cba62f0c..b48ea171 100644
--- a/src/hb-ot-color-sbix-table.hh
+++ b/src/hb-ot-color-sbix-table.hh
@@ -153,23 +153,17 @@ struct sbix
       hb_blob_destroy (sbix_blob);
     }
 
-    inline void dump (void (*callback) (hb_blob_t *data,
-					unsigned int group, unsigned int gid)) const
+    /* only to support dump-emoji, don't use it anywhere else */
+    inline unsigned int *get_available_ppems (unsigned int *length)
     {
-      for (unsigned group = 0; group < sbix_table->strikes.len; group++)
-      {
-	const SBIXStrike &strike = sbix_table+sbix_table->strikes[group];
-	for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++)
-	{
-	  hb_tag_t tag;
-	  hb_blob_t *blob;
-	  blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len,
-					sbix_table->strikes[group],
-					nullptr, nullptr,
-					HB_TAG('p','n','g',' '), num_glyphs);
-	  if (hb_blob_get_length (blob)) callback (blob, group, glyph_id);
-	}
-      }
+      if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0))
+	return nullptr;
+      *length = sbix_table->strikes.len;
+      unsigned int *result;
+      result = (unsigned int *) malloc (sizeof (unsigned int) * sbix_table->strikes.len);
+      for (unsigned int i = 0; i < sbix_table->strikes.len; i++)
+	result[i] = (sbix_table+sbix_table->strikes[i]).get_ppem ();
+      return result;
     }
 
     inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t  glyph_id,
commit 6a38fd68a8f4e66d9248e0c943ae3a1cf45c521b
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sat Oct 27 10:50:53 2018 +0330

    [ot-color/png] sbix runtime memory check

diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh
index 0f64577d..770fe3eb 100644
--- a/src/hb-ot-color-cbdt-table.hh
+++ b/src/hb-ot-color-cbdt-table.hh
@@ -452,7 +452,7 @@ struct CBDT
     }
 
     inline void dump (void (*callback) (const uint8_t* data, unsigned int length,
-        unsigned int group, unsigned int gid)) const
+					unsigned int group, unsigned int gid)) const
     {
       if (!cblc)
 	return;  // Not a color bitmap font.
@@ -504,15 +504,13 @@ struct CBDT
       }
     }
 
-    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id,
-						unsigned int    requested_x_ppem,
-						unsigned int    requested_y_ppem,
-						unsigned int   *strike_x_ppem,
-						unsigned int   *strike_y_ppem) const
+    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id HB_UNUSED,
+						unsigned int    requested_x_ppem HB_UNUSED,
+						unsigned int    requested_y_ppem HB_UNUSED,
+						unsigned int   *strike_x_ppem HB_UNUSED,
+						unsigned int   *strike_y_ppem HB_UNUSED) const
     {
-//       if (unlikely (cbdt_len == 0))
-        return hb_blob_get_empty ();
-//       return svg->get_glyph_entry (glyph_id).reference_blob (svg_blob, svg->svgDocEntries);
+      return hb_blob_get_empty ();
     }
 
     inline bool has_data () const
diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh
index 97eac9b5..cba62f0c 100644
--- a/src/hb-ot-color-sbix-table.hh
+++ b/src/hb-ot-color-sbix-table.hh
@@ -82,6 +82,7 @@ struct SBIXStrike
 
   inline hb_blob_t *get_glyph_blob (unsigned int  glyph_id,
 				    hb_blob_t    *sbix_blob,
+				    unsigned int  sbix_len,
 				    unsigned int  strike_offset,
 				    unsigned int *x_offset,
 				    unsigned int *y_offset,
@@ -91,6 +92,9 @@ struct SBIXStrike
     if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0)
       return hb_blob_get_empty ();
 
+    if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len)
+      return hb_blob_get_empty ();
+
     const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
     if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') &&
 		  blob_size (glyph_id) >= 2))
@@ -100,6 +104,8 @@ struct SBIXStrike
       {
 	glyph = &(this+imageOffsetsZ[new_glyph_id]);
 	glyph_id = new_glyph_id;
+        if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len)
+          return hb_blob_get_empty ();
       }
     }
     if (unlikely (requested_file_type != glyph->graphicType))
@@ -155,18 +161,18 @@ struct sbix
 	const SBIXStrike &strike = sbix_table+sbix_table->strikes[group];
 	for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++)
 	{
-	  unsigned int x_offset, y_offset;
 	  hb_tag_t tag;
 	  hb_blob_t *blob;
-	  blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group],
-					&x_offset, &x_offset,
+	  blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len,
+					sbix_table->strikes[group],
+					nullptr, nullptr,
 					HB_TAG('p','n','g',' '), num_glyphs);
 	  if (hb_blob_get_length (blob)) callback (blob, group, glyph_id);
 	}
       }
     }
 
-    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id,
+    inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t  glyph_id,
 						unsigned int    ptem HB_UNUSED,
 						unsigned int    requested_ppem,
 						unsigned int    requested_file_type,
@@ -187,7 +193,8 @@ struct sbix
       const SBIXStrike &strike = sbix_table+sbix_table->strikes[group];
       if (available_x_ppem) *available_x_ppem = strike.get_ppem ();
       if (available_y_ppem) *available_y_ppem = strike.get_ppem ();
-      return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group],
+      return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len,
+				    sbix_table->strikes[group],
 				    nullptr, nullptr, requested_file_type, num_glyphs);
     }
 
@@ -200,7 +207,6 @@ struct sbix
 
     unsigned int sbix_len;
     unsigned int num_glyphs;
-    hb_vector_t<hb_vector_t<unsigned int> > data_offsets;
   };
 
   protected:
diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh
index 4ef38074..5238ad45 100644
--- a/src/hb-ot-color-svg-table.hh
+++ b/src/hb-ot-color-svg-table.hh
@@ -50,7 +50,7 @@ struct SVGDocumentIndexEntry
     return b->cmp (*a);
   }
 
-  inline hb_blob_t* reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
+  inline hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
   {
     if (svgDocLength == 0) return hb_blob_get_empty ();
     return hb_blob_create_sub_blob (svg_blob, (unsigned int) svgDoc + index_offset,
@@ -95,7 +95,7 @@ struct SVG
       hb_blob_destroy (svg_blob);
     }
 
-    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id) const
+    inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
     {
       if (unlikely (svg_len == 0))
         return hb_blob_get_empty ();
commit 265ad408ca41e9d0b5a1056a751d834d4eadc911
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Fri Oct 26 23:55:11 2018 +0330

    [ot-color/png] Implement sbix part

diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index c385984a..67f9ae2c 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -460,9 +460,11 @@ HB_OT_H_IN
 <SECTION>
 <FILE>hb-ot-color</FILE>
 hb_ot_color_glyph_get_layers
+hb_ot_color_glyph_reference_blob_png
 hb_ot_color_glyph_reference_blob_svg
 hb_ot_color_has_layers
 hb_ot_color_has_palettes
+hb_ot_color_has_png
 hb_ot_color_has_svg
 hb_ot_color_layer_t
 hb_ot_color_palette_color_get_name_id
diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
index c4710a62..7c7392f2 100644
--- a/src/dump-emoji.cc
+++ b/src/dump-emoji.cc
@@ -58,12 +58,13 @@ cbdt_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)
+sbix_callback (hb_blob_t *blob, unsigned int group, unsigned int gid)
 {
   char output_path[255];
   sprintf (output_path, "out/sbix-%d-%d.png", group, gid);
   FILE *f = fopen (output_path, "wb");
+  unsigned int length;
+  const char* data = hb_blob_get_data (blob, &length);
   fwrite (data, 1, length, f);
   fclose (f);
 }
diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh
index 1e1fe095..0f64577d 100644
--- a/src/hb-ot-color-cbdt-table.hh
+++ b/src/hb-ot-color-cbdt-table.hh
@@ -376,13 +376,6 @@ struct CBDT
 {
   static const hb_tag_t tableTag = HB_OT_TAG_CBDT;
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  likely (version.major == 2 || version.major == 3));
-  }
-
   struct accelerator_t
   {
     inline void init (hb_face_t *face)
@@ -511,6 +504,20 @@ struct CBDT
       }
     }
 
+    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id,
+						unsigned int    requested_x_ppem,
+						unsigned int    requested_y_ppem,
+						unsigned int   *strike_x_ppem,
+						unsigned int   *strike_y_ppem) const
+    {
+//       if (unlikely (cbdt_len == 0))
+        return hb_blob_get_empty ();
+//       return svg->get_glyph_entry (glyph_id).reference_blob (svg_blob, svg->svgDocEntries);
+    }
+
+    inline bool has_data () const
+    { return cbdt_len; }
+
     private:
     hb_blob_t *cblc_blob;
     hb_blob_t *cbdt_blob;
@@ -521,6 +528,12 @@ struct CBDT
     unsigned int upem;
   };
 
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  likely (version.major == 2 || version.major == 3));
+  }
 
   protected:
   FixedVersion<>		version;
diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh
index 1dd0a5c6..97eac9b5 100644
--- a/src/hb-ot-color-sbix-table.hh
+++ b/src/hb-ot-color-sbix-table.hh
@@ -62,8 +62,6 @@ struct SBIXGlyph
 
 struct SBIXStrike
 {
-  friend struct sbix;
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -71,6 +69,48 @@ struct SBIXStrike
 		  imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1));
   }
 
+  inline unsigned int get_ppem () const
+  { return ppem; }
+
+  inline unsigned int get_resolution () const
+  { return resolution; }
+
+  inline unsigned int blob_size (unsigned int glyph_id) const
+  {
+    return imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size;
+  }
+
+  inline hb_blob_t *get_glyph_blob (unsigned int  glyph_id,
+				    hb_blob_t    *sbix_blob,
+				    unsigned int  strike_offset,
+				    unsigned int *x_offset,
+				    unsigned int *y_offset,
+				    hb_tag_t      requested_file_type,
+				    unsigned int  num_glyphs) const
+  {
+    if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0)
+      return hb_blob_get_empty ();
+
+    const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
+    if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') &&
+		  blob_size (glyph_id) >= 2))
+    {
+      unsigned int new_glyph_id = *((HBUINT16 *) &glyph->data);
+      if (new_glyph_id < num_glyphs)
+      {
+	glyph = &(this+imageOffsetsZ[new_glyph_id]);
+	glyph_id = new_glyph_id;
+      }
+    }
+    if (unlikely (requested_file_type != glyph->graphicType))
+      return hb_blob_get_empty ();
+    if (likely (x_offset)) *x_offset = glyph->xOffset;
+    if (likely (y_offset)) *y_offset = glyph->yOffset;
+    unsigned int offset = strike_offset + SBIXGlyph::min_size;
+    offset += imageOffsetsZ[glyph_id];
+    return hb_blob_create_sub_blob (sbix_blob, offset, blob_size (glyph_id));
+  }
+
   protected:
   HBUINT16	ppem;		/* The PPEM size for which this strike was designed. */
   HBUINT16	resolution;	/* The device pixel density (in PPI) for which this
@@ -99,6 +139,7 @@ struct sbix
       sbix_blob = hb_sanitize_context_t().reference_table<sbix> (face);
       sbix_len = hb_blob_get_length (sbix_blob);
       sbix_table = sbix_blob->as<sbix> ();
+      num_glyphs = face->get_num_glyphs ();
     }
 
     inline void fini (void)
@@ -106,29 +147,60 @@ struct sbix
       hb_blob_destroy (sbix_blob);
     }
 
-    inline void dump (void (*callback) (const uint8_t* data, unsigned int length,
+    inline void dump (void (*callback) (hb_blob_t *data,
 					unsigned int group, unsigned int gid)) const
     {
-      for (unsigned group = 0; group < sbix_table->strikes.len; ++group)
+      for (unsigned group = 0; group < sbix_table->strikes.len; group++)
       {
-	const SBIXStrike &strike = sbix_table->strikes[group](sbix_table);
-	for (unsigned int glyph = 0; glyph < num_glyphs; ++glyph)
-	  if (strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] > 0)
-	  {
-	    const SBIXGlyph &sbixGlyph = strike.imageOffsetsZ[glyph]((const void *) &strike);
-	    callback ((const uint8_t*) &sbixGlyph.data,
-		      strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] - 8,
-		      group, glyph);
-	  }
+	const SBIXStrike &strike = sbix_table+sbix_table->strikes[group];
+	for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++)
+	{
+	  unsigned int x_offset, y_offset;
+	  hb_tag_t tag;
+	  hb_blob_t *blob;
+	  blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group],
+					&x_offset, &x_offset,
+					HB_TAG('p','n','g',' '), num_glyphs);
+	  if (hb_blob_get_length (blob)) callback (blob, group, glyph_id);
+	}
       }
     }
 
+    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id,
+						unsigned int    ptem HB_UNUSED,
+						unsigned int    requested_ppem,
+						unsigned int    requested_file_type,
+						unsigned int   *available_x_ppem,
+						unsigned int   *available_y_ppem) const
+    {
+      if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0))
+        return hb_blob_get_empty ();
+
+      /* TODO: Does spec guarantee strikes are ascended sorted? */
+      unsigned int group = sbix_table->strikes.len - 1;
+      if (requested_ppem != 0)
+	/* TODO: Use bsearch maybe or doesn't worth it? */
+        for (group = 0; group < sbix_table->strikes.len; group++)
+	  if ((sbix_table+sbix_table->strikes[group]).get_ppem () >= requested_ppem)
+	    break;
+
+      const SBIXStrike &strike = sbix_table+sbix_table->strikes[group];
+      if (available_x_ppem) *available_x_ppem = strike.get_ppem ();
+      if (available_y_ppem) *available_y_ppem = strike.get_ppem ();
+      return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group],
+				    nullptr, nullptr, requested_file_type, num_glyphs);
+    }
+
+    inline bool has_data () const
+    { return sbix_len; }
+
     private:
     hb_blob_t *sbix_blob;
     const sbix *sbix_table;
 
     unsigned int sbix_len;
     unsigned int num_glyphs;
+    hb_vector_t<hb_vector_t<unsigned int> > data_offsets;
   };
 
   protected:
diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index 283b3a1e..8dd3b2a4 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -47,6 +47,13 @@ _get_colr (hb_face_t *face)
   return *(hb_ot_face_data (face)->COLR.get ());
 }
 
+static inline const OT::CBDT_accelerator_t&
+_get_cbdt (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t);
+  return *(hb_ot_face_data (face)->CBDT.get ());
+}
+
 static inline const OT::CPAL&
 _get_cpal (hb_face_t *face)
 {
@@ -54,6 +61,13 @@ _get_cpal (hb_face_t *face)
   return *(hb_ot_face_data (face)->CPAL.get ());
 }
 
+static inline const OT::sbix_accelerator_t&
+_get_sbix (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix_accelerator_t);
+  return *(hb_ot_face_data (face)->sbix.get ());
+}
+
 static inline const OT::SVG_accelerator_t&
 _get_svg (hb_face_t *face)
 {
@@ -272,3 +286,53 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph)
 {
   return _get_svg (face).reference_blob_for_glyph (glyph);
 }
+
+
+/*
+ * PNG, CBDT or sbix
+ */
+
+/**
+ * hb_ot_color_has_png:
+ * @face: a font face.
+ *
+ * Returns: whether SVG table is available.
+ *
+ * Since: REPLACEME
+ */
+hb_bool_t
+hb_ot_color_has_png (hb_face_t *face)
+{
+  return _get_cbdt (face).has_data () || _get_sbix (face).has_data ();
+}
+
+/**
+ * hb_ot_color_glyph_reference_blob_svg:
+ * @font:
+ * @glyph:
+ * @strike_x_ppem: (out):
+ * @strike_y_ppem: (out):
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ */
+hb_blob_t *
+hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
+				      hb_codepoint_t  glyph,
+				      unsigned int   *strike_x_ppem /* OUT */,
+				      unsigned int   *strike_y_ppem /* OUT */)
+{
+  /* TODO: if (hb_options ().aat ()) then call sbix first */
+
+  if (_get_cbdt (font->face).has_data ())
+    return _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem,
+							    strike_x_ppem, strike_y_ppem);
+
+  if (_get_sbix (font->face).has_data ())
+    return _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem,
+							    MAX (font->x_ppem, font->y_ppem),
+							    HB_TAG('p','n','g',' '),
+							    strike_x_ppem, strike_y_ppem);
+
+}
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index fb9a9e37..7901a359 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -121,6 +121,15 @@ hb_ot_color_has_svg (hb_face_t *face);
 HB_EXTERN hb_blob_t *
 hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph);
 
+HB_EXTERN hb_bool_t
+hb_ot_color_has_png (hb_face_t *face);
+
+HB_EXTERN hb_blob_t *
+hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
+				      hb_codepoint_t  glyph,
+				      unsigned int   *strike_x_ppem,
+				      unsigned int   *strike_y_ppem);
+
 
 HB_END_DECLS
 
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index 4ffadeec..767a3d61 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -370,6 +370,14 @@ test_hb_ot_color_has_data (void)
   g_assert (hb_ot_color_has_svg (cbdt) == FALSE);
   g_assert (hb_ot_color_has_svg (sbix) == FALSE);
   g_assert (hb_ot_color_has_svg (svg) == TRUE);
+
+  g_assert (hb_ot_color_has_png (empty) == FALSE);
+  g_assert (hb_ot_color_has_png (cpal_v0) == FALSE);
+  g_assert (hb_ot_color_has_png (cpal_v1) == FALSE);
+  g_assert (hb_ot_color_has_png (cpal) == FALSE);
+  g_assert (hb_ot_color_has_png (cbdt) == TRUE);
+  g_assert (hb_ot_color_has_png (sbix) == TRUE);
+  g_assert (hb_ot_color_has_png (svg) == FALSE);
 }
 
 static void
@@ -392,6 +400,29 @@ test_hb_ot_color_svg (void)
   g_assert (hb_blob_get_length (blob) == 0);
 }
 
+
+static void
+test_hb_ot_color_png (void)
+{
+  hb_blob_t *blob;
+
+  hb_font_t *sbix_font;
+  sbix_font = hb_font_create (sbix);
+  blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0, NULL, NULL);
+  g_assert (hb_blob_get_length (blob) == 0);
+
+  unsigned int strike_x_ppem, strike_y_ppem;
+  blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1,
+					       &strike_x_ppem, &strike_y_ppem);
+  unsigned int length;
+  const char *data = hb_blob_get_data (blob, &length);
+  g_assert_cmpuint (length, ==, 224);
+  g_assert_cmpuint (strike_x_ppem, ==, 300);
+  g_assert_cmpuint (strike_y_ppem, ==, 300);
+  g_assert (strncmp (data + 1, "PNG", 3) == 0);
+  hb_blob_destroy (blob);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -418,6 +449,7 @@ main (int argc, char **argv)
   hb_test_add (test_hb_ot_color_palette_color_get_name_id);
   hb_test_add (test_hb_ot_color_glyph_get_layers);
   hb_test_add (test_hb_ot_color_has_data);
+  hb_test_add (test_hb_ot_color_png);
   hb_test_add (test_hb_ot_color_svg);
   status = hb_test_run();
   hb_face_destroy (cpal_v0);
commit 30f18039b3c0e5748101f8934ae82aebfc5a83f7
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Fri Oct 26 09:34:34 2018 +0330

    [svg] Rename _svg_create_blob to _glyph_reference_blob_svg

diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 7bca7ca2..c385984a 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -460,8 +460,10 @@ HB_OT_H_IN
 <SECTION>
 <FILE>hb-ot-color</FILE>
 hb_ot_color_glyph_get_layers
+hb_ot_color_glyph_reference_blob_svg
 hb_ot_color_has_layers
 hb_ot_color_has_palettes
+hb_ot_color_has_svg
 hb_ot_color_layer_t
 hb_ot_color_palette_color_get_name_id
 hb_ot_color_palette_flags_t
diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
index 1603d2d9..c4710a62 100644
--- a/src/dump-emoji.cc
+++ b/src/dump-emoji.cc
@@ -75,7 +75,7 @@ svg_dump (hb_face_t *face)
 
   for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
   {
-    hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id);
+    hb_blob_t *blob = hb_ot_color_glyph_reference_blob_svg (face, glyph_id);
 
     if (hb_blob_get_length (blob) == 0) continue;
 
diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index 3d9f1c1b..283b3a1e 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -259,7 +259,7 @@ hb_ot_color_has_svg (hb_face_t *face)
 }
 
 /**
- * hb_ot_color_glyph_svg_create_blob:
+ * hb_ot_color_glyph_reference_blob_svg:
  * @face:
  * @glyph:
  *
@@ -268,7 +268,7 @@ hb_ot_color_has_svg (hb_face_t *face)
  * Since: REPLACEME
  */
 hb_blob_t *
-hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph)
+hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph)
 {
   return _get_svg (face).reference_blob_for_glyph (glyph);
 }
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index 259c8498..fb9a9e37 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -119,7 +119,7 @@ HB_EXTERN hb_bool_t
 hb_ot_color_has_svg (hb_face_t *face);
 
 HB_EXTERN hb_blob_t *
-hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph);
+hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph);
 
 
 HB_END_DECLS
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index 13a25b0b..4ffadeec 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -377,10 +377,10 @@ test_hb_ot_color_svg (void)
 {
   hb_blob_t *blob;
 
-  blob = hb_ot_color_glyph_svg_create_blob (svg, 0);
+  blob = hb_ot_color_glyph_reference_blob_svg (svg, 0);
   g_assert (hb_blob_get_length (blob) == 0);
 
-  blob = hb_ot_color_glyph_svg_create_blob (svg, 1);
+  blob = hb_ot_color_glyph_reference_blob_svg (svg, 1);
   unsigned int length;
   const char *data = hb_blob_get_data (blob, &length);
   g_assert_cmpuint (length, ==, 146);
@@ -388,7 +388,7 @@ test_hb_ot_color_svg (void)
   g_assert (strncmp (data + 140, "</svg>", 5) == 0);
   hb_blob_destroy (blob);
 
-  blob = hb_ot_color_glyph_svg_create_blob (empty, 0);
+  blob = hb_ot_color_glyph_reference_blob_svg (empty, 0);
   g_assert (hb_blob_get_length (blob) == 0);
 }
 
commit 5cb1ce868138a10c0663a18c3891bc717aa4bc64
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Thu Oct 25 22:39:58 2018 +0330

    [svg] Collapse SVGDocumentIndex into SVG

diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh
index 9e03ef76..4ef38074 100644
--- a/src/hb-ot-color-svg-table.hh
+++ b/src/hb-ot-color-svg-table.hh
@@ -50,7 +50,7 @@ struct SVGDocumentIndexEntry
     return b->cmp (*a);
   }
 
-  inline hb_blob_t* create_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
+  inline hb_blob_t* reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
   {
     if (svgDocLength == 0) return hb_blob_get_empty ();
     return hb_blob_create_sub_blob (svg_blob, (unsigned int) svgDoc + index_offset,
@@ -77,35 +77,6 @@ struct SVGDocumentIndexEntry
   DEFINE_SIZE_STATIC (12);
 };
 
-struct SVGDocumentIndex
-{
-  friend struct SVG;
-
-  inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
-  {
-    const SVGDocumentIndexEntry *rec;
-    rec = (SVGDocumentIndexEntry *) bsearch (&glyph_id,
-					     &entries.arrayZ,
-					     entries.len,
-					     sizeof (SVGDocumentIndexEntry),
-					     SVGDocumentIndexEntry::cmp);
-    return likely (rec) ? *rec : Null(SVGDocumentIndexEntry);
-  }
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  entries.sanitize_shallow (c));
-  }
-
-  protected:
-  ArrayOf<SVGDocumentIndexEntry>
-		entries;	/* Array of SVG Document Index Entries. */
-  public:
-  DEFINE_SIZE_ARRAY (2, entries);
-};
-
 struct SVG
 {
   static const hb_tag_t tableTag = HB_OT_TAG_SVG;
@@ -124,12 +95,11 @@ struct SVG
       hb_blob_destroy (svg_blob);
     }
 
-    inline hb_blob_t* create_blob_for_glyph (hb_codepoint_t glyph_id) const
+    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id) const
     {
       if (unlikely (svg_len == 0))
         return hb_blob_get_empty ();
-      return (svg+svg->svgDocIndex).get_glyph_entry (glyph_id).create_blob (svg_blob,
-									    svg->svgDocIndex);
+      return svg->get_glyph_entry (glyph_id).reference_blob (svg_blob, svg->svgDocEntries);
     }
 
     inline bool has_data () const
@@ -142,18 +112,30 @@ struct SVG
     unsigned int svg_len;
   };
 
+  inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
+  {
+    const SVGDocumentIndexEntry *rec;
+    rec = (SVGDocumentIndexEntry *) bsearch (&glyph_id,
+					     &(this+svgDocEntries).arrayZ,
+					     (this+svgDocEntries).len,
+					     sizeof (SVGDocumentIndexEntry),
+					     SVGDocumentIndexEntry::cmp);
+    return likely (rec) ? *rec : Null(SVGDocumentIndexEntry);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-			  (this+svgDocIndex).sanitize (c)));
+			  (this+svgDocEntries).sanitize_shallow (c)));
   }
 
   protected:
   HBUINT16	version;	/* Table version (starting at 0). */
-  LOffsetTo<SVGDocumentIndex>
-		svgDocIndex;	/* Offset (relative to the start of the SVG table) to the
+  LOffsetTo<ArrayOf<SVGDocumentIndexEntry> >
+		svgDocEntries;	/* Offset (relative to the start of the SVG table) to the
 				 * SVG Documents Index. Must be non-zero. */
+				/* Array of SVG Document Index Entries. */
   HBUINT32	reserved;	/* Set to 0. */
   public:
   DEFINE_SIZE_STATIC (10);
diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index cdfbaade..3d9f1c1b 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -270,5 +270,5 @@ hb_ot_color_has_svg (hb_face_t *face)
 hb_blob_t *
 hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph)
 {
-  return _get_svg (face).create_blob_for_glyph (glyph);
+  return _get_svg (face).reference_blob_for_glyph (glyph);
 }
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index 8e4ec0a0..13a25b0b 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -388,7 +388,7 @@ test_hb_ot_color_svg (void)
   g_assert (strncmp (data + 140, "</svg>", 5) == 0);
   hb_blob_destroy (blob);
 
-  blob = hb_ot_color_glyph_svg_create_blob (empty, 0, &start_glyph, &end_glyph);
+  blob = hb_ot_color_glyph_svg_create_blob (empty, 0);
   g_assert (hb_blob_get_length (blob) == 0);
 }
 
commit 4ceabb8c2126fe365303b8d69e667005276c0241
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Thu Oct 25 21:52:35 2018 +0330

    [svg] Hide start_glyph and end_glyph from API

diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
index 97aab004..1603d2d9 100644
--- a/src/dump-emoji.cc
+++ b/src/dump-emoji.cc
@@ -75,29 +75,24 @@ svg_dump (hb_face_t *face)
 
   for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
   {
-    hb_codepoint_t start_glyph_id, end_glyph_id;
-    hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id,
-							 &start_glyph_id, &end_glyph_id);
+    hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id);
 
     if (hb_blob_get_length (blob) == 0) continue;
 
-    char output_path[255];
-    if (start_glyph_id == end_glyph_id)
-      sprintf (output_path, "out/svg-%d.svg", start_glyph_id);
-    else
-      sprintf (output_path, "out/svg-%d-%d.svg", start_glyph_id, end_glyph_id);
-
     unsigned int length;
     const char *data = hb_blob_get_data (blob, &length);
-    // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
-    if (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B'))
-        strcat (output_path, "z");
+
+    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);
 
-    if (glyph_id < end_glyph_id) glyph_id = end_glyph_id;
+    hb_blob_destroy (blob);
   }
 }
 
diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh
index fc5b8662..9e03ef76 100644
--- a/src/hb-ot-color-svg-table.hh
+++ b/src/hb-ot-color-svg-table.hh
@@ -40,9 +40,6 @@ namespace OT {
 
 struct SVGDocumentIndexEntry
 {
-  friend struct SVG;
-  friend struct SVGDocumentIndex;
-
   inline int cmp (hb_codepoint_t g) const
   { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; }
 
@@ -53,6 +50,13 @@ struct SVGDocumentIndexEntry
     return b->cmp (*a);
   }
 
+  inline hb_blob_t* create_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
+  {
+    if (svgDocLength == 0) return hb_blob_get_empty ();
+    return hb_blob_create_sub_blob (svg_blob, (unsigned int) svgDoc + index_offset,
+				    svgDocLength);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -85,7 +89,7 @@ struct SVGDocumentIndex
 					     entries.len,
 					     sizeof (SVGDocumentIndexEntry),
 					     SVGDocumentIndexEntry::cmp);
-    return likely (rec && glyph_id <= rec->endGlyphID) ? *rec : Null(SVGDocumentIndexEntry);
+    return likely (rec) ? *rec : Null(SVGDocumentIndexEntry);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -120,34 +124,12 @@ struct SVG
       hb_blob_destroy (svg_blob);
     }
 
-    inline hb_blob_t*
-    failed_create_blob (hb_codepoint_t  glyph_id,
-			hb_codepoint_t *start_glyph_id,
-			hb_codepoint_t *end_glyph_id) const
-    {
-      if (start_glyph_id) *start_glyph_id = 0;
-      if (end_glyph_id) *end_glyph_id = 0;
-      return hb_blob_get_empty ();
-    }
-
-    inline hb_blob_t*
-    create_blob (hb_codepoint_t  glyph_id,
-		 hb_codepoint_t *start_glyph_id,
-		 hb_codepoint_t *end_glyph_id) const
+    inline hb_blob_t* create_blob_for_glyph (hb_codepoint_t glyph_id) const
     {
       if (unlikely (svg_len == 0))
-        return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id);
-      const SVGDocumentIndex &index = svg+svg->svgDocIndex;
-      const SVGDocumentIndexEntry &entry = index.get_glyph_entry (glyph_id);
-      if (unlikely (entry.svgDocLength == 0))
-        return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id);
-      unsigned int blob_offset = entry.svgDoc;
-      blob_offset += svg->svgDocIndex;
-      if (unlikely (blob_offset > svg_len || blob_offset + entry.svgDocLength > svg_len))
-        return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id);
-      if (start_glyph_id) *start_glyph_id = entry.startGlyphID;
-      if (end_glyph_id) *end_glyph_id = entry.endGlyphID;
-      return hb_blob_create_sub_blob (svg_blob, blob_offset, entry.svgDocLength);
+        return hb_blob_get_empty ();
+      return (svg+svg->svgDocIndex).get_glyph_entry (glyph_id).create_blob (svg_blob,
+									    svg->svgDocIndex);
     }
 
     inline bool has_data () const
diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index e2f36ca3..cdfbaade 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -262,18 +262,13 @@ hb_ot_color_has_svg (hb_face_t *face)
  * hb_ot_color_glyph_svg_create_blob:
  * @face:
  * @glyph:
- * @start_glyph: (out) (optional): Start of range this SVG supports
- * @end_glyph:   (out) (optional): End of range this SVG supports
  *
  * Returns:
  *
  * Since: REPLACEME
  */
 hb_blob_t *
-hb_ot_color_glyph_svg_create_blob (hb_face_t      *face,
-				   hb_codepoint_t  glyph,
-				   hb_codepoint_t *start_glyph, /* OUT.  May be NULL. */
-				   hb_codepoint_t *end_glyph    /* OUT.  May be NULL. */)
+hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph)
 {
-  return _get_svg (face).create_blob (glyph, start_glyph, end_glyph);
+  return _get_svg (face).create_blob_for_glyph (glyph);
 }
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index 8b31b687..259c8498 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -119,10 +119,7 @@ HB_EXTERN hb_bool_t
 hb_ot_color_has_svg (hb_face_t *face);
 
 HB_EXTERN hb_blob_t *
-hb_ot_color_glyph_svg_create_blob (hb_face_t      *face,
-				   hb_codepoint_t  glyph,
-				   hb_codepoint_t *start_glyph, /* OUT.  May be NULL. */
-				   hb_codepoint_t *end_glyph    /* OUT.  May be NULL. */);
+hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph);
 
 
 HB_END_DECLS
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index f145a4ce..8e4ec0a0 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -375,28 +375,21 @@ test_hb_ot_color_has_data (void)
 static void
 test_hb_ot_color_svg (void)
 {
-  hb_codepoint_t start_glyph, end_glyph;
   hb_blob_t *blob;
 
-  blob = hb_ot_color_glyph_svg_create_blob (svg, 0, &start_glyph, &end_glyph);
+  blob = hb_ot_color_glyph_svg_create_blob (svg, 0);
   g_assert (hb_blob_get_length (blob) == 0);
-  g_assert (start_glyph == 0);
-  g_assert (end_glyph == 0);
 
-  blob = hb_ot_color_glyph_svg_create_blob (svg, 1, &start_glyph, &end_glyph);
+  blob = hb_ot_color_glyph_svg_create_blob (svg, 1);
   unsigned int length;
   const char *data = hb_blob_get_data (blob, &length);
   g_assert_cmpuint (length, ==, 146);
-  g_assert_cmpuint (start_glyph, ==, 1);
-  g_assert_cmpuint (end_glyph, ==, 1);
   g_assert (strncmp (data, "<?xml", 4) == 0);
   g_assert (strncmp (data + 140, "</svg>", 5) == 0);
   hb_blob_destroy (blob);
 
   blob = hb_ot_color_glyph_svg_create_blob (empty, 0, &start_glyph, &end_glyph);
   g_assert (hb_blob_get_length (blob) == 0);
-  g_assert (start_glyph == 0);
-  g_assert (end_glyph == 0);
 }
 
 int
commit c7a4e3dfb5c8dd4f8faf08e327bb1900c0096cf6
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Tue Oct 23 18:00:48 2018 +0330

    [svg] Add public API
    
    * hb_ot_color_has_svg
    * hb_ot_color_glyph_svg_create_blob

diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
index 2f79fc69..97aab004 100644
--- a/src/dump-emoji.cc
+++ b/src/dump-emoji.cc
@@ -69,26 +69,40 @@ sbix_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)
+svg_dump (hb_face_t *face)
 {
-  char output_path[255];
-  if (start_glyph == end_glyph)
-    sprintf (output_path, "out/svg-%d.svg", start_glyph);
-  else
-    sprintf (output_path, "out/svg-%d-%d.svg", start_glyph, end_glyph);
+  unsigned glyph_count = hb_face_get_glyph_count (face);
 
-  // append "z" if the content is gzipped
-  if ((data[0] == 0x1F) && (data[1] == 0x8B))
-    strcat (output_path, "z");
+  for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
+  {
+    hb_codepoint_t start_glyph_id, end_glyph_id;
+    hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id,
+							 &start_glyph_id, &end_glyph_id);
 
-  FILE *f = fopen (output_path, "wb");
-  fwrite (data, 1, length, f);
-  fclose (f);
+    if (hb_blob_get_length (blob) == 0) continue;
+
+    char output_path[255];
+    if (start_glyph_id == end_glyph_id)
+      sprintf (output_path, "out/svg-%d.svg", start_glyph_id);
+    else
+      sprintf (output_path, "out/svg-%d-%d.svg", start_glyph_id, end_glyph_id);
+
+    unsigned int length;
+    const char *data = hb_blob_get_data (blob, &length);
+    // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
+    if (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B'))
+        strcat (output_path, "z");
+
+    FILE *f = fopen (output_path, "wb");
+    fwrite (data, 1, length, f);
+    fclose (f);
+
+    if (glyph_id < end_glyph_id) glyph_id = end_glyph_id;
+  }
 }
 
 static void
-colr_cpal_rendering (hb_face_t *face, cairo_font_face_t *cairo_face)
+colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face)
 {
   unsigned int upem = hb_face_get_upem (face);
 
@@ -268,10 +282,8 @@ main (int argc, char **argv)
   sbix.dump (sbix_callback);
   sbix.fini ();
 
-  OT::SVG::accelerator_t svg;
-  svg.init (face);
-  svg.dump (svg_callback);
-  svg.fini ();
+  if (hb_ot_color_has_svg (face))
+    svg_dump (face);
 
   cairo_font_face_t *cairo_face;
   {
@@ -281,7 +293,8 @@ 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);
+  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);
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index 8b7ea093..8d17f3ed 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -523,7 +523,6 @@ struct ArrayOf
     ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
   }
 
-  private:
   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh
index 1b643c77..1dd0a5c6 100644
--- a/src/hb-ot-color-sbix-table.hh
+++ b/src/hb-ot-color-sbix-table.hh
@@ -142,6 +142,8 @@ struct sbix
   DEFINE_SIZE_ARRAY (8, strikes);
 };
 
+struct sbix_accelerator_t : sbix::accelerator_t {};
+
 } /* namespace OT */
 
 #endif /* HB_OT_COLOR_SBIX_TABLE_HH */
diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh
index 53d46684..fc5b8662 100644
--- a/src/hb-ot-color-svg-table.hh
+++ b/src/hb-ot-color-svg-table.hh
@@ -41,12 +41,22 @@ namespace OT {
 struct SVGDocumentIndexEntry
 {
   friend struct SVG;
+  friend struct SVGDocumentIndex;
 
-  inline bool sanitize (hb_sanitize_context_t *c, const void* base) const
+  inline int cmp (hb_codepoint_t g) const
+  { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; }
+
+  static int cmp (const void *pa, const void *pb)
+  {
+    const hb_codepoint_t *a = (const hb_codepoint_t *) pa;
+    const SVGDocumentIndexEntry *b = (const SVGDocumentIndexEntry *) pb;
+    return b->cmp (*a);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  (base+svgDoc).sanitize (c, svgDocLength));
+    return_trace (c->check_struct (this));
   }
 
   protected:
@@ -57,7 +67,7 @@ struct SVGDocumentIndexEntry
   LOffsetTo<UnsizedArrayOf<HBUINT8>, false>
 		svgDoc;		/* Offset from the beginning of the SVG Document Index
 				 * to an SVG document. Must be non-zero. */
-  HBUINT32 svgDocLength;	/* Length of the SVG document.
+  HBUINT32	svgDocLength;	/* Length of the SVG document.
 				 * Must be non-zero. */
   public:
   DEFINE_SIZE_STATIC (12);
@@ -67,11 +77,22 @@ struct SVGDocumentIndex
 {
   friend struct SVG;
 
+  inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
+  {
+    const SVGDocumentIndexEntry *rec;
+    rec = (SVGDocumentIndexEntry *) bsearch (&glyph_id,
+					     &entries.arrayZ,
+					     entries.len,
+					     sizeof (SVGDocumentIndexEntry),
+					     SVGDocumentIndexEntry::cmp);
+    return likely (rec && glyph_id <= rec->endGlyphID) ? *rec : Null(SVGDocumentIndexEntry);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  entries.sanitize (c, this));
+		  entries.sanitize_shallow (c));
   }
 
   protected:
@@ -85,13 +106,6 @@ struct SVG
 {
   static const hb_tag_t tableTag = HB_OT_TAG_SVG;
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  (this+svgDocIndex).sanitize (c)));
-  }
-
   struct accelerator_t
   {
     inline void init (hb_face_t *face)
@@ -106,20 +120,39 @@ struct SVG
       hb_blob_destroy (svg_blob);
     }
 
-    inline void
-    dump (void (*callback) (const uint8_t* data, unsigned int length,
-			    unsigned int start_glyph, unsigned int end_glyph)) const
+    inline hb_blob_t*
+    failed_create_blob (hb_codepoint_t  glyph_id,
+			hb_codepoint_t *start_glyph_id,
+			hb_codepoint_t *end_glyph_id) const
     {
+      if (start_glyph_id) *start_glyph_id = 0;
+      if (end_glyph_id) *end_glyph_id = 0;
+      return hb_blob_get_empty ();
+    }
+
+    inline hb_blob_t*
+    create_blob (hb_codepoint_t  glyph_id,
+		 hb_codepoint_t *start_glyph_id,
+		 hb_codepoint_t *end_glyph_id) const
+    {
+      if (unlikely (svg_len == 0))
+        return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id);
       const SVGDocumentIndex &index = svg+svg->svgDocIndex;
-      const ArrayOf<SVGDocumentIndexEntry> &entries = index.entries;
-      for (unsigned int i = 0; i < entries.len; ++i)
-      {
-	const SVGDocumentIndexEntry &entry = entries[i];
-	callback ((const uint8_t*) &entry.svgDoc (&index), entry.svgDocLength,
-						  entry.startGlyphID, entry.endGlyphID);
-      }
+      const SVGDocumentIndexEntry &entry = index.get_glyph_entry (glyph_id);
+      if (unlikely (entry.svgDocLength == 0))
+        return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id);
+      unsigned int blob_offset = entry.svgDoc;
+      blob_offset += svg->svgDocIndex;
+      if (unlikely (blob_offset > svg_len || blob_offset + entry.svgDocLength > svg_len))
+        return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id);
+      if (start_glyph_id) *start_glyph_id = entry.startGlyphID;
+      if (end_glyph_id) *end_glyph_id = entry.endGlyphID;
+      return hb_blob_create_sub_blob (svg_blob, blob_offset, entry.svgDocLength);
     }
 
+    inline bool has_data () const
+    { return svg_len; }
+
     private:
     hb_blob_t *svg_blob;
     const SVG *svg;
@@ -127,6 +160,13 @@ struct SVG
     unsigned int svg_len;
   };
 
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  (this+svgDocIndex).sanitize (c)));
+  }
+
   protected:
   HBUINT16	version;	/* Table version (starting at 0). */
   LOffsetTo<SVGDocumentIndex>
@@ -137,6 +177,8 @@ struct SVG
   DEFINE_SIZE_STATIC (10);
 };
 
+struct SVG_accelerator_t : SVG::accelerator_t {};
+
 } /* namespace OT */
 
 
diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc
index 229b6e66..e2f36ca3 100644
--- a/src/hb-ot-color.cc
+++ b/src/hb-ot-color.cc
@@ -54,6 +54,13 @@ _get_cpal (hb_face_t *face)
   return *(hb_ot_face_data (face)->CPAL.get ());
 }
 
+static inline const OT::SVG_accelerator_t&
+_get_svg (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG_accelerator_t);
+  return *(hb_ot_face_data (face)->SVG.get ());
+}
+
 #if 0
 static inline const OT::CBDT_accelerator_t&
 _get_cbdt (hb_face_t *face)
@@ -68,13 +75,6 @@ _get_sbix (hb_face_t *face)
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix);
   return *(hb_ot_face_data (face)->sbix.get ());
 }
-
-static inline const OT::SVG&
-_get_svg (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG);
-  return *(hb_ot_face_data (face)->SVG.get ());
-}
 #endif
 
 
@@ -238,3 +238,42 @@ hb_ot_color_glyph_get_layers (hb_face_t           *face,
 {
   return _get_colr (face).get_glyph_layers (glyph, start_offset, count, layers);
 }
+
+
+/*
+ * SVG
+ */
+
+/**
+ * hb_ot_color_has_svg:
+ * @face: a font face.
+ *
+ * Returns: whether SVG table is available.
+ *
+ * Since: REPLACEME
+ */
+hb_bool_t
+hb_ot_color_has_svg (hb_face_t *face)
+{
+  return _get_svg (face).has_data ();
+}
+
+/**
+ * hb_ot_color_glyph_svg_create_blob:
+ * @face:
+ * @glyph:
+ * @start_glyph: (out) (optional): Start of range this SVG supports
+ * @end_glyph:   (out) (optional): End of range this SVG supports
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ */
+hb_blob_t *
+hb_ot_color_glyph_svg_create_blob (hb_face_t      *face,
+				   hb_codepoint_t  glyph,
+				   hb_codepoint_t *start_glyph, /* OUT.  May be NULL. */
+				   hb_codepoint_t *end_glyph    /* OUT.  May be NULL. */)
+{
+  return _get_svg (face).create_blob (glyph, start_glyph, end_glyph);
+}
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
index 02b76bff..8b31b687 100644
--- a/src/hb-ot-color.h
+++ b/src/hb-ot-color.h
@@ -111,6 +111,19 @@ hb_ot_color_glyph_get_layers (hb_face_t           *face,
 			      unsigned int        *count, /* IN/OUT.  May be NULL. */
 			      hb_ot_color_layer_t *layers /* OUT.     May be NULL. */);
 
+/*
+ * SVG
+ */
+
+HB_EXTERN hb_bool_t
+hb_ot_color_has_svg (hb_face_t *face);
+
+HB_EXTERN hb_blob_t *
+hb_ot_color_glyph_svg_create_blob (hb_face_t      *face,
+				   hb_codepoint_t  glyph,
+				   hb_codepoint_t *start_glyph, /* OUT.  May be NULL. */
+				   hb_codepoint_t *end_glyph    /* OUT.  May be NULL. */);
+
 
 HB_END_DECLS
 
diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc
index 1bc68d36..0aba2a69 100644
--- a/src/hb-ot-face.cc
+++ b/src/hb-ot-face.cc
@@ -32,6 +32,8 @@
 #include "hb-ot-kern-table.hh"
 #include "hb-ot-post-table.hh"
 #include "hb-ot-color-cbdt-table.hh"
+#include "hb-ot-color-sbix-table.hh"
+#include "hb-ot-color-svg-table.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh
index a45a4936..cce2f1d8 100644
--- a/src/hb-ot-face.hh
+++ b/src/hb-ot-face.hh
@@ -73,8 +73,8 @@
     HB_OT_TABLE(OT, COLR) \
     HB_OT_TABLE(OT, CPAL) \
     HB_OT_ACCELERATOR(OT, CBDT) \
-    HB_OT_TABLE(OT, sbix) \
-    HB_OT_TABLE(OT, SVG) \
+    HB_OT_ACCELERATOR(OT, sbix) \
+    HB_OT_ACCELERATOR(OT, SVG) \
     /* */
 
 /* Declare tables. */
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 096fda20..7f3e6c73 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -41,10 +41,6 @@
 // Just so we compile them; unused otherwise:
 #include "hb-ot-layout-base-table.hh"
 #include "hb-ot-layout-jstf-table.hh"
-#include "hb-ot-color-colr-table.hh"
-#include "hb-ot-color-cpal-table.hh"
-#include "hb-ot-color-sbix-table.hh"
-#include "hb-ot-color-svg-table.hh"
 #include "hb-ot-kern-table.hh"
 #include "hb-ot-name-table.hh"
 
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index a514c6aa..f145a4ce 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -103,6 +103,7 @@ static hb_face_t *cpal = NULL;
 static hb_face_t *cbdt = NULL;
 static hb_face_t *sbix = NULL;
 static hb_face_t *svg = NULL;
+static hb_face_t *empty = NULL;
 
 #define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START {	\
   const hb_color_t *_colors = (colors); \
@@ -203,7 +204,6 @@ test_hb_ot_color_palette_get_flags_v1 (void)
 static void
 test_hb_ot_color_palette_get_colors_empty (void)
 {
-  hb_face_t *empty = hb_face_get_empty ();
   g_assert_cmpint (hb_ot_color_palette_get_colors (empty, 0, 0, NULL, NULL), ==, 0);
 }
 
@@ -302,8 +302,6 @@ test_hb_ot_color_palette_get_colors_v1 (void)
 static void
 test_hb_ot_color_palette_color_get_name_id (void)
 {
-  hb_face_t *empty = hb_face_get_empty ();
-
   g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 0), ==, HB_NAME_ID_INVALID);
   g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 1), ==, HB_NAME_ID_INVALID);
   g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 2), ==, HB_NAME_ID_INVALID);
@@ -349,8 +347,6 @@ test_hb_ot_color_glyph_get_layers (void)
 static void
 test_hb_ot_color_has_data (void)
 {
-  hb_face_t *empty = hb_face_get_empty ();
-
   g_assert (hb_ot_color_has_layers (empty) == FALSE);
   g_assert (hb_ot_color_has_layers (cpal_v0) == TRUE);
   g_assert (hb_ot_color_has_layers (cpal_v1) == TRUE);
@@ -366,6 +362,41 @@ test_hb_ot_color_has_data (void)
   g_assert (hb_ot_color_has_palettes (cbdt) == FALSE);
   g_assert (hb_ot_color_has_palettes (sbix) == FALSE);
   g_assert (hb_ot_color_has_palettes (svg) == FALSE);
+
+  g_assert (hb_ot_color_has_svg (empty) == FALSE);
+  g_assert (hb_ot_color_has_svg (cpal_v0) == FALSE);
+  g_assert (hb_ot_color_has_svg (cpal_v1) == FALSE);
+  g_assert (hb_ot_color_has_svg (cpal) == FALSE);
+  g_assert (hb_ot_color_has_svg (cbdt) == FALSE);
+  g_assert (hb_ot_color_has_svg (sbix) == FALSE);
+  g_assert (hb_ot_color_has_svg (svg) == TRUE);
+}
+
+static void
+test_hb_ot_color_svg (void)
+{
+  hb_codepoint_t start_glyph, end_glyph;
+  hb_blob_t *blob;
+
+  blob = hb_ot_color_glyph_svg_create_blob (svg, 0, &start_glyph, &end_glyph);
+  g_assert (hb_blob_get_length (blob) == 0);
+  g_assert (start_glyph == 0);
+  g_assert (end_glyph == 0);
+
+  blob = hb_ot_color_glyph_svg_create_blob (svg, 1, &start_glyph, &end_glyph);
+  unsigned int length;
+  const char *data = hb_blob_get_data (blob, &length);
+  g_assert_cmpuint (length, ==, 146);
+  g_assert_cmpuint (start_glyph, ==, 1);
+  g_assert_cmpuint (end_glyph, ==, 1);
+  g_assert (strncmp (data, "<?xml", 4) == 0);
+  g_assert (strncmp (data + 140, "</svg>", 5) == 0);
+  hb_blob_destroy (blob);
+
+  blob = hb_ot_color_glyph_svg_create_blob (empty, 0, &start_glyph, &end_glyph);
+  g_assert (hb_blob_get_length (blob) == 0);
+  g_assert (start_glyph == 0);
+  g_assert (end_glyph == 0);
 }
 
 int
@@ -380,6 +411,7 @@ main (int argc, char **argv)
   cbdt = hb_test_open_font_file ("fonts/chromacheck-cbdt.ttf");
   sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf");
   svg = hb_test_open_font_file ("fonts/chromacheck-svg.ttf");
+  empty = hb_face_get_empty ();
   hb_test_add (test_hb_ot_color_palette_get_count);
   hb_test_add (test_hb_ot_color_palette_get_name_id_empty);
   hb_test_add (test_hb_ot_color_palette_get_name_id_v0);
@@ -393,6 +425,7 @@ main (int argc, char **argv)
   hb_test_add (test_hb_ot_color_palette_color_get_name_id);
   hb_test_add (test_hb_ot_color_glyph_get_layers);
   hb_test_add (test_hb_ot_color_has_data);
+  hb_test_add (test_hb_ot_color_svg);
   status = hb_test_run();
   hb_face_destroy (cpal_v0);
   hb_face_destroy (cpal_v1);


More information about the HarfBuzz mailing list