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 <beh...@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 <beh...@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 <beh...@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 <beh...@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 <beh...@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 <beh...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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 <ebra...@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); _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz