From 83d0a49f7100008937fcf7e69e31fe9625365259 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 13 Dec 2022 21:14:25 -0500 Subject: [PATCH 001/219] wip: hb-paint --- src/harfbuzz-subset.cc | 1 + src/harfbuzz.cc | 1 + src/hb-ot-color-colr-table.hh | 5 + src/hb-paint.cc | 311 ++++++++++++++++++++++++++++++++++ src/hb-paint.h | 276 ++++++++++++++++++++++++++++++ src/hb-paint.hh | 125 ++++++++++++++ src/hb.h | 1 + src/meson.build | 3 + 8 files changed, 723 insertions(+) create mode 100644 src/hb-paint.cc create mode 100644 src/hb-paint.h create mode 100644 src/hb-paint.hh diff --git a/src/harfbuzz-subset.cc b/src/harfbuzz-subset.cc index a43485e6f..4eeb99fe7 100644 --- a/src/harfbuzz-subset.cc +++ b/src/harfbuzz-subset.cc @@ -40,6 +40,7 @@ #include "hb-ot-shaper-vowel-constraints.cc" #include "hb-ot-tag.cc" #include "hb-ot-var.cc" +#include "hb-paint.cc" #include "hb-set.cc" #include "hb-shape-plan.cc" #include "hb-shape.cc" diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc index fe4e21db0..d5bb3880e 100644 --- a/src/harfbuzz.cc +++ b/src/harfbuzz.cc @@ -45,6 +45,7 @@ #include "hb-ot-shaper-vowel-constraints.cc" #include "hb-ot-tag.cc" #include "hb-ot-var.cc" +#include "hb-paint.cc" #include "hb-set.cc" #include "hb-shape-plan.cc" #include "hb-shape.cc" diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 79b0b476c..2636a8c87 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -979,6 +979,11 @@ struct ClipBox return true; } + void paint_glyph (hb_font_t *font, hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *paint_data) const + { + } + protected: union { HBUINT8 format; /* Format identifier */ diff --git a/src/hb-paint.cc b/src/hb-paint.cc new file mode 100644 index 000000000..1d8004f0f --- /dev/null +++ b/src/hb-paint.cc @@ -0,0 +1,311 @@ +/* + * Copyright © 2022 Matthias Clasen + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb.hh" + +#ifndef HB_NO_PAINT + +#include "hb-paint.hh" + +static void +hb_paint_push_transform_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + float xx HB_UNUSED, float xy HB_UNUSED, + float yx HB_UNUSED, float yy HB_UNUSED, + float x0 HB_UNUSED, float y0 HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_push_clip_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_solid_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + unsigned int color_index HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + hb_color_line_t *color_line HB_UNUSED, + hb_position_t x0, hb_position_t y0 HB_UNUSED, + hb_position_t x1, hb_position_t y1 HB_UNUSED, + hb_position_t x2, hb_position_t y2 HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + hb_color_line_t *color_line HB_UNUSED, + hb_position_t x0, hb_position_t y0 HB_UNUSED, + float r0 HB_UNUSED, + hb_position_t x1 HB_UNUSED, hb_position_t y1 HB_UNUSED, + float r1 HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + hb_color_line_t *color_line HB_UNUSED, + hb_position_t x0, hb_position_t y0 HB_UNUSED, + float start_angle HB_UNUSED, + float end_angle HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_push_group_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_paint_pop_group_and_composite_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, + hb_paint_composite_mode_t mode, + void *user_data HB_UNUSED) {} + +static bool +_hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs, + bool func_is_null, + void **user_data, + hb_destroy_func_t *destroy) +{ + if (hb_object_is_immutable (funcs)) + { + if (*destroy) + (*destroy) (*user_data); + return false; + } + + if (func_is_null) + { + if (*destroy) + (*destroy) (*user_data); + *destroy = nullptr; + *user_data = nullptr; + } + + return true; +} + +static bool +_hb_paint_funcs_set_middle (hb_paint_funcs_t *funcs, + void *user_data, + hb_destroy_func_t destroy) +{ + if (user_data && !funcs->user_data) + { + funcs->user_data = (decltype (funcs->user_data)) hb_calloc (1, sizeof (*funcs->user_data)); + if (unlikely (!funcs->user_data)) + goto fail; + } + if (destroy && !funcs->destroy) + { + funcs->destroy = (decltype (funcs->destroy)) hb_calloc (1, sizeof (*funcs->destroy)); + if (unlikely (!funcs->destroy)) + goto fail; + } + + return true; + +fail: + if (destroy) + (destroy) (user_data); + return false; +} + +#define HB_PAINT_FUNC_IMPLEMENT(name) \ + \ +void \ +hb_paint_funcs_set_##name##_func (hb_paint_funcs_t *funcs, \ + hb_paint_##name##_func_t func, \ + void *user_data, \ + hb_destroy_func_t destroy) \ +{ \ + if (!_hb_paint_funcs_set_preamble (funcs, !func, &user_data, &destroy)) \ + return; \ + \ + if (funcs->destroy && funcs->destroy->name) \ + funcs->destroy->name (!funcs->user_data ? nullptr : funcs->user_data->name);\ + \ + if (!_hb_paint_funcs_set_middle (funcs, user_data, destroy)) \ + return; \ + \ + if (func) \ + funcs->func.name = func; \ + else \ + funcs->func.name = hb_paint_##name##_nil; \ + \ + if (funcs->user_data) \ + funcs->user_data->name = user_data; \ + if (funcs->destroy) \ + funcs->destroy->name = destroy; \ +} + +HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_PAINT_FUNC_IMPLEMENT + +hb_paint_funcs_t * +hb_paint_funcs_create () +{ + hb_paint_funcs_t *funcs; + if (unlikely (!(funcs = hb_object_create ()))) + return const_cast (&Null (hb_paint_funcs_t)); + + funcs->func = Null (hb_paint_funcs_t).func; + + return funcs; +} + +DEFINE_NULL_INSTANCE (hb_paint_funcs_t) = +{ + HB_OBJECT_HEADER_STATIC, + + { +#define HB_PAINT_FUNC_IMPLEMENT(name) hb_paint_##name##_nil, + HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_PAINT_FUNC_IMPLEMENT + } +}; + +hb_paint_funcs_t * +hb_paint_funcs_reference (hb_paint_funcs_t *funcs) +{ + return hb_object_reference (funcs); +} + +void +hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) +{ + if (!hb_object_destroy (funcs)) return; + + if (funcs->destroy) + { +#define HB_PAINT_FUNC_IMPLEMENT(name) \ + if (funcs->destroy->name) funcs->destroy->name (!funcs->user_data ? nullptr : funcs->user_data->name); + HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_PAINT_FUNC_IMPLEMENT + } + + hb_free (funcs->destroy); + hb_free (funcs->user_data); + hb_free (funcs); +} + +void +hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs) +{ + if (hb_object_is_immutable (funcs)) + return; + + hb_object_make_immutable (funcs); +} + +hb_bool_t +hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) +{ + return hb_object_is_immutable (funcs); +} + +void +hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, + float xx, float xy, + float yx, float yy, + float x0, float y0) +{ + funcs->push_transform (paint_data, xx, xy, yx, yy, x0, y0); +} + +void +hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) +{ + funcs->pop_transform (paint_data); +} + +void +hb_paint_push_clip (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph) +{ + funcs->push_clip (paint_data, glyph); +} + +void +hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) +{ + funcs->pop_clip (paint_data); +} + +void +hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, + unsigned int color_index) +{ + funcs->solid (paint_data, color_index); +} + +void +hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + hb_position_t x1, hb_position_t y1, + hb_position_t x2, hb_position_t y2) +{ + funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); +} + +void +hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float r0, + hb_position_t x1, hb_position_t y1, + float r1) +{ + funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); +} + +void +hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float start_angle, float end_angle) +{ + funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); +} + +void +hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) +{ + funcs->push_group (paint_data); +} + +void +hb_paint_pop_group_and_composite (hb_paint_funcs_t *funcs, void *paint_data, + hb_paint_composite_mode_t mode) +{ + funcs->pop_group_and_composite (paint_data, mode); +} + +#endif diff --git a/src/hb-paint.h b/src/hb-paint.h new file mode 100644 index 000000000..b00f8df02 --- /dev/null +++ b/src/hb-paint.h @@ -0,0 +1,276 @@ +/* + * Copyright © 2022 Matthias Clasen + * + * 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. + */ + +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) +#error "Include instead." +#endif + +#ifndef HB_PAINT_H +#define HB_PAINT_H + +#include "hb.h" + +HB_BEGIN_DECLS + +typedef struct hb_paint_funcs_t hb_paint_funcs_t; + +HB_EXTERN hb_paint_funcs_t * +hb_paint_funcs_create (); + +HB_EXTERN hb_paint_funcs_t * +hb_paint_funcs_reference (hb_paint_funcs_t *funcs); + +HB_EXTERN void +hb_paint_funcs_destroy (hb_paint_funcs_t *funcs); + +HB_EXTERN void +hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs); + +HB_EXTERN hb_bool_t +hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); + +typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + float xx, float xy, + float yx, float yy, + float x0, float y0, + void *user_data); + +typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data); + +typedef void (*hb_paint_push_clip_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data); + +typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data); + +typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + unsigned int color_index, + void *user_data); + + +typedef struct hb_color_line_t hb_color_line_t; + +typedef struct { + float offset; + unsigned int color_index; +} hb_color_stop_t; + +HB_EXTERN unsigned int +hb_color_line_get_color_stops (hb_color_line_t color_line, + unsigned int start, + unsigned int count, + hb_color_stop_t *color_stops); + +typedef enum { + HB_PAINT_EXTEND_PAD, + HB_PAINT_EXTEND_REPEAT, + HB_PAINT_EXTEND_REFLECT +} hb_paint_extend_t; + +HB_EXTERN hb_paint_extend_t +hb_color_line_get_extend (hb_color_line_t *color_line); + +typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + hb_position_t x1, hb_position_t y1, + hb_position_t x2, hb_position_t y2, + void *user_data); + +typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float r0, + hb_position_t x1, hb_position_t y1, + float r1, + void *user_data); + +typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float start_angle, + float end_angle, + void *user_data); + +typedef enum { + HB_PAINT_COMPOSITE_MODE_CLEAR, + HB_PAINT_COMPOSITE_MODE_SRC, + HB_PAINT_COMPOSITE_MODE_DEST, + HB_PAINT_COMPOSITE_MODE_SRC_OVER, + HB_PAINT_COMPOSITE_MODE_DEST_OVER, + HB_PAINT_COMPOSITE_MODE_SRC_IN, + HB_PAINT_COMPOSITE_MODE_DEST_IN, + HB_PAINT_COMPOSITE_MODE_SRC_OUT, + HB_PAINT_COMPOSITE_MODE_DEST_OUT, + HB_PAINT_COMPOSITE_MODE_SRC_ATOP, + HB_PAINT_COMPOSITE_MODE_DEST_ATOP, + HB_PAINT_COMPOSITE_MODE_XOR, + HB_PAINT_COMPOSITE_MODE_PLUS, + HB_PAINT_COMPOSITE_MODE_SCREEN, + HB_PAINT_COMPOSITE_MODE_OVERLAY, + HB_PAINT_COMPOSITE_MODE_DARKEN, + HB_PAINT_COMPOSITE_MODE_LIGHTEN, + HB_PAINT_COMPOSITE_MODE_COLOR_DODGE, + HB_PAINT_COMPOSITE_MODE_COLOR_BURN, + HB_PAINT_COMPOSITE_MODE_HARD_LIGHT, + HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT, + HB_PAINT_COMPOSITE_MODE_DIFFERENCE, + HB_PAINT_COMPOSITE_MODE_EXCLUSION, + HB_PAINT_COMPOSITE_MODE_MULTIPLY, + HB_PAINT_COMPOSITE_MODE_HSL_HUE, + HB_PAINT_COMPOSITE_MODE_HSL_SATURATION, + HB_PAINT_COMPOSITE_MODE_HSL_COLOR, + HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY, +} hb_paint_composite_mode_t; + +typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data); + +typedef void (*hb_paint_pop_group_and_composite_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data); + +HB_EXTERN void +hb_paint_funcs_set_push_transform_func (hb_paint_funcs_t *funcs, + hb_paint_push_transform_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, + hb_paint_pop_transform_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_push_clip_func (hb_paint_funcs_t *funcs, + hb_paint_push_clip_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_pop_clip_func (hb_paint_funcs_t *funcs, + hb_paint_pop_clip_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_solid_func (hb_paint_funcs_t *funcs, + hb_paint_solid_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_linear_gradient_func (hb_paint_funcs_t *funcs, + hb_paint_linear_gradient_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_radial_gradient_func (hb_paint_funcs_t *funcs, + hb_paint_radial_gradient_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_sweep_gradient_func (hb_paint_funcs_t *funcs, + hb_paint_sweep_gradient_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_push_group_func (hb_paint_funcs_t *funcs, + hb_paint_push_group_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_funcs_set_pop_group_and_composite_func (hb_paint_funcs_t *funcs, + hb_paint_pop_group_and_composite_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN void +hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, + float xx, float xy, + float yx, float yy, + float x0, float y0); + +HB_EXTERN void +hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); + +HB_EXTERN void +hb_paint_push_clip (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph); + +HB_EXTERN void +hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); + +HB_EXTERN void +hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, + unsigned int color_index); + +HB_EXTERN void +hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + hb_position_t x1, hb_position_t y1, + hb_position_t x2, hb_position_t y2); + +HB_EXTERN void +hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float r0, + hb_position_t x1, hb_position_t y1, + float r1); + +HB_EXTERN void +hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float start_angle, float end_angle); + +HB_EXTERN void +hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data); + +HB_EXTERN void +hb_paint_pop_group_and_composite (hb_paint_funcs_t *funcs, void *paint_data, + hb_paint_composite_mode_t mode); + +HB_END_DECLS + +#endif /* HB_PAINT_H */ diff --git a/src/hb-paint.hh b/src/hb-paint.hh new file mode 100644 index 000000000..6f7f1e157 --- /dev/null +++ b/src/hb-paint.hh @@ -0,0 +1,125 @@ +/* + * Copyright © 2022 Matthias Clasen + * + * 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. + */ + +#ifndef HB_PAINT_HH +#define HB_PAINT_HH + +#include "hb.hh" + +#define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ + HB_PAINT_FUNC_IMPLEMENT (push_transform) \ + HB_PAINT_FUNC_IMPLEMENT (pop_transform) \ + HB_PAINT_FUNC_IMPLEMENT (push_clip) \ + HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ + HB_PAINT_FUNC_IMPLEMENT (solid) \ + HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \ + HB_PAINT_FUNC_IMPLEMENT (radial_gradient) \ + HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \ + HB_PAINT_FUNC_IMPLEMENT (push_group) \ + HB_PAINT_FUNC_IMPLEMENT (pop_group_and_composite) \ + /* ^--- Add new callbacks here */ + +struct hb_paint_funcs_t +{ + hb_object_header_t header; + + struct { +#define HB_PAINT_FUNC_IMPLEMENT(name) hb_paint_##name##_func_t name; + HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_PAINT_FUNC_IMPLEMENT + } func; + + struct { +#define HB_PAINT_FUNC_IMPLEMENT(name) void *name; + HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_PAINT_FUNC_IMPLEMENT + } *user_data; + + struct { +#define HB_PAINT_FUNC_IMPLEMENT(name) hb_destroy_func_t name; + HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_PAINT_FUNC_IMPLEMENT + } *destroy; + + void push_transform (void *paint_data, + float xx, float xy, + float yx, float yy, + float x0, float y0) + { func.push_transform (this, paint_data, + xx, xy, yx, yy, x0, y0, + !user_data ? nullptr : user_data->push_transform); } + void pop_transform (void *paint_data) + { func.pop_transform (this, paint_data, + !user_data ? nullptr : user_data->pop_transform); } + void push_clip (void *paint_data, + hb_codepoint_t glyph) + { func.push_clip (this, paint_data, + glyph, + !user_data ? nullptr : user_data->push_clip); } + void pop_clip (void *paint_data) + { func.pop_clip (this, paint_data, + !user_data ? nullptr : user_data->pop_clip); } + void solid (void *paint_data, + unsigned int color_index) + { func.solid (this, paint_data, + color_index, + !user_data ? nullptr : user_data->solid); } + void linear_gradient (void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + hb_position_t x1, hb_position_t y1, + hb_position_t x2, hb_position_t y2) + { func.linear_gradient (this, paint_data, + color_line, x0, y0, x1, y1, x2, y2, + !user_data ? nullptr : user_data->linear_gradient); } + void radial_gradient (void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float r0, + hb_position_t x1, hb_position_t y1, + float r1) + { func.radial_gradient (this, paint_data, + color_line, x0, y0, r0, x1, y1, r1, + !user_data ? nullptr : user_data->radial_gradient); } + void sweep_gradient (void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float start_angle, + float end_angle) + { func.sweep_gradient (this, paint_data, + color_line, x0, y0, start_angle, end_angle, + !user_data ? nullptr : user_data->sweep_gradient); } + void push_group (void *paint_data) + { func.push_group (this, paint_data, + !user_data ? nullptr : user_data->push_group); } + void pop_group_and_composite (void *paint_data, + hb_paint_composite_mode_t mode) + { func.pop_group_and_composite (this, paint_data, + mode, + !user_data ? nullptr : user_data->pop_group_and_composite); } + +}; +DECLARE_NULL_INSTANCE (hb_paint_funcs_t); + +#endif /* HB_PAINT_HH */ diff --git a/src/hb.h b/src/hb.h index 360686ca6..d4c241c7f 100644 --- a/src/hb.h +++ b/src/hb.h @@ -33,6 +33,7 @@ #include "hb-common.h" #include "hb-deprecated.h" #include "hb-draw.h" +#include "hb-paint.h" #include "hb-face.h" #include "hb-font.h" #include "hb-map.h" diff --git a/src/meson.build b/src/meson.build index 64753cb10..463a3b349 100644 --- a/src/meson.build +++ b/src/meson.build @@ -44,6 +44,8 @@ hb_base_sources = files( 'hb-dispatch.hh', 'hb-draw.cc', 'hb-draw.hh', + 'hb-paint.cc', + 'hb-paint.hh', 'hb-face.cc', 'hb-face.hh', 'hb-fallback-shape.cc', @@ -276,6 +278,7 @@ hb_base_headers = files( 'hb-cplusplus.hh', 'hb-deprecated.h', 'hb-draw.h', + 'hb-paint.h', 'hb-face.h', 'hb-font.h', 'hb-map.h', From 71efa0dcf12eb3924697f96d3a4ed203bb71962b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 06:22:00 -0500 Subject: [PATCH 002/219] wip: hb_font_paint_glyph --- src/hb-font.cc | 30 ++++++++++++++++++++++++++++++ src/hb-font.h | 16 ++++++++++++++++ src/hb-font.hh | 9 +++++++++ 3 files changed, 55 insertions(+) diff --git a/src/hb-font.cc b/src/hb-font.cc index 0ce3e2608..59512b049 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -30,6 +30,7 @@ #include "hb-font.hh" #include "hb-draw.hh" +#include "hb-paint.hh" #include "hb-machinery.hh" #include "hb-ot.h" @@ -512,6 +513,15 @@ hb_font_get_glyph_shape_nil (hb_font_t *font HB_UNUSED, { } +static void +hb_font_get_glyph_paint_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_paint_funcs_t *paint_funcs HB_UNUSED, + void *paint_data HB_UNUSED, + void *user_data HB_UNUSED) +{ +} typedef struct hb_font_get_glyph_shape_default_adaptor_t { hb_draw_funcs_t *draw_funcs; @@ -639,6 +649,18 @@ hb_font_get_glyph_shape_default (hb_font_t *font, &adaptor); } +static void +hb_font_get_glyph_paint_default (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, + void *paint_data, + void *user_data) +{ + // FIXME adaptor like for draw funcs + font->parent->get_glyph_paint (glyph, paint_funcs, paint_data); +} + DEFINE_NULL_INSTANCE (hb_font_funcs_t) = { HB_OBJECT_HEADER_STATIC, @@ -1366,6 +1388,14 @@ hb_font_get_glyph_shape (hb_font_t *font, font->get_glyph_shape (glyph, dfuncs, draw_data); } +void +hb_font_paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *paint_data) +{ + font->get_glyph_paint (glyph, funcs, paint_data); +} + /* A bit higher-level, and with fallback */ /** diff --git a/src/hb-font.h b/src/hb-font.h index e2c3df4a5..99c73a217 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -34,6 +34,7 @@ #include "hb-common.h" #include "hb-face.h" #include "hb-draw.h" +#include "hb-paint.h" HB_BEGIN_DECLS @@ -531,6 +532,11 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data void *user_data); +typedef void (*hb_font_get_glyph_paint_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + void *user_data); + /* func setters */ /** @@ -805,6 +811,11 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, void *user_data, hb_destroy_func_t destroy); +HB_EXTERN void +hb_font_funcs_set_glyph_paint_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_paint_func_t func, + void *user_data, hb_destroy_func_t destroy); + /* func dispatch */ HB_EXTERN hb_bool_t @@ -890,6 +901,11 @@ hb_font_get_glyph_shape (hb_font_t *font, hb_codepoint_t glyph, hb_draw_funcs_t *dfuncs, void *draw_data); +HB_EXTERN void +hb_font_paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *paint_data); + /* high-level funcs, with fallback */ diff --git a/src/hb-font.hh b/src/hb-font.hh index a8b3ee5c4..d45c6a8f7 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -58,6 +58,7 @@ HB_FONT_FUNC_IMPLEMENT (glyph_name) \ HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ HB_FONT_FUNC_IMPLEMENT (glyph_shape) \ + HB_FONT_FUNC_IMPLEMENT (glyph_paint) \ /* ^--- Add new callbacks here */ struct hb_font_funcs_t @@ -401,6 +402,14 @@ struct hb_font_t !klass->user_data ? nullptr : klass->user_data->glyph_shape); } + void get_glyph_paint (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data) + { + klass->get.f.glyph_paint (this, user_data, + glyph, + paint_funcs, paint_data, + !klass->user_data ? nullptr : klass->user_data->glyph_paint); + } /* A bit higher-level, and with fallback */ From 6a48ac42f4f8404ecf64fda876141a0d1c48a56c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 06:55:01 -0500 Subject: [PATCH 003/219] COLR implementation --- src/hb-ot-color-colr-table.hh | 5 +++++ src/hb-ot-font.cc | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 2636a8c87..1fe3ee420 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1615,6 +1615,11 @@ struct COLR return false; } + void + paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const + { + } + protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 840510342..0975d5ac6 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -439,6 +439,20 @@ hb_ot_get_glyph_shape (hb_font_t *font, } #endif +#ifndef HB_NO_PAINT +static void +hb_ot_get_glyph_paint (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + void *user_data) +{ +#ifndef HB_NO_COLOR + font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data); +#endif +} +#endif + static inline void free_static_ot_funcs (); static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t @@ -465,6 +479,10 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t Date: Wed, 14 Dec 2022 09:50:52 -0500 Subject: [PATCH 004/219] fix introspection --- src/hb-font.h | 8 ++++- src/hb-gobject-structs.cc | 1 + src/hb-gobject-structs.h | 4 +++ src/hb-paint.cc | 5 +++ src/hb-paint.h | 70 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/hb-font.h b/src/hb-font.h index 99c73a217..69f011d68 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -531,7 +531,6 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data); - typedef void (*hb_font_get_glyph_paint_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_paint_funcs_t *paint_funcs, void *paint_data, @@ -811,6 +810,13 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_font_funcs_set_glyph_paint_func: + * @ffuncs: + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: (nullable): + */ HB_EXTERN void hb_font_funcs_set_glyph_paint_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_paint_func_t func, diff --git a/src/hb-gobject-structs.cc b/src/hb-gobject-structs.cc index ef13f1e96..7383169fd 100644 --- a/src/hb-gobject-structs.cc +++ b/src/hb-gobject-structs.cc @@ -91,6 +91,7 @@ hb_gobject_##name##_get_type () \ HB_DEFINE_OBJECT_TYPE (buffer) HB_DEFINE_OBJECT_TYPE (blob) HB_DEFINE_OBJECT_TYPE (draw_funcs) +HB_DEFINE_OBJECT_TYPE (paint_funcs) HB_DEFINE_OBJECT_TYPE (face) HB_DEFINE_OBJECT_TYPE (font) HB_DEFINE_OBJECT_TYPE (font_funcs) diff --git a/src/hb-gobject-structs.h b/src/hb-gobject-structs.h index 3914a2431..e76ac1e54 100644 --- a/src/hb-gobject-structs.h +++ b/src/hb-gobject-structs.h @@ -52,6 +52,10 @@ HB_EXTERN GType hb_gobject_draw_funcs_get_type (void); #define HB_GOBJECT_TYPE_DRAW_FUNCS (hb_gobject_draw_funcs_get_type ()) +HB_EXTERN GType +hb_gobject_paint_funcs_get_type (void); +#define HB_GOBJECT_TYPE_PAINT_FUNCS (hb_gobject_paint_funcs_get_type ()) + HB_EXTERN GType hb_gobject_face_get_type (void); #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 1d8004f0f..d1eefbb80 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -168,6 +168,11 @@ hb_paint_funcs_set_##name##_func (hb_paint_funcs_t *funcs, HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_PAINT_FUNC_IMPLEMENT +/** + * hb_paint_funcs_create: + * + * Returns value: (transfer full): + */ hb_paint_funcs_t * hb_paint_funcs_create () { diff --git a/src/hb-paint.h b/src/hb-paint.h index b00f8df02..32decd090 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -163,60 +163,130 @@ typedef void (*hb_paint_pop_group_and_composite_func_t) (hb_paint_funcs_t *funcs hb_paint_composite_mode_t mode, void *user_data); +/** + * hb_paint_funcs_set_push_transform_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_push_transform_func (hb_paint_funcs_t *funcs, hb_paint_push_transform_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_pop_transform_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, hb_paint_pop_transform_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_push_clip_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_push_clip_func (hb_paint_funcs_t *funcs, hb_paint_push_clip_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_pop_clip_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_pop_clip_func (hb_paint_funcs_t *funcs, hb_paint_pop_clip_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_solid_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_solid_func (hb_paint_funcs_t *funcs, hb_paint_solid_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_linear_gradient_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_linear_gradient_func (hb_paint_funcs_t *funcs, hb_paint_linear_gradient_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_radial_gradient_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_radial_gradient_func (hb_paint_funcs_t *funcs, hb_paint_radial_gradient_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_sweep_gradient_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_sweep_gradient_func (hb_paint_funcs_t *funcs, hb_paint_sweep_gradient_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_push_group_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_push_group_func (hb_paint_funcs_t *funcs, hb_paint_push_group_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_pop_group_and_composite_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scop notified): + * @user_data: + * @destroy: (nullable) + */ HB_EXTERN void hb_paint_funcs_set_pop_group_and_composite_func (hb_paint_funcs_t *funcs, hb_paint_pop_group_and_composite_func_t func, From 8377341b289f47a8e63d448b5a3376dfdd464734 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 22:03:52 -0500 Subject: [PATCH 005/219] wip: implement paint_glyph --- src/harfbuzz-subset.cc | 1 + src/harfbuzz.cc | 1 + src/hb-ot-color-colr-table.hh | 204 ++++++++++++++++++++++++++++++++-- src/meson.build | 1 + 4 files changed, 199 insertions(+), 8 deletions(-) diff --git a/src/harfbuzz-subset.cc b/src/harfbuzz-subset.cc index 4eeb99fe7..c5c66747a 100644 --- a/src/harfbuzz-subset.cc +++ b/src/harfbuzz-subset.cc @@ -14,6 +14,7 @@ #include "hb-number.cc" #include "hb-ot-cff1-table.cc" #include "hb-ot-cff2-table.cc" +#include "hb-ot-color-colr-table.cc" #include "hb-ot-color.cc" #include "hb-ot-face.cc" #include "hb-ot-font.cc" diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc index d5bb3880e..03196eaa6 100644 --- a/src/harfbuzz.cc +++ b/src/harfbuzz.cc @@ -19,6 +19,7 @@ #include "hb-number.cc" #include "hb-ot-cff1-table.cc" #include "hb-ot-cff2-table.cc" +#include "hb-ot-color-colr-table.cc" #include "hb-ot-color.cc" #include "hb-ot-face.cc" #include "hb-ot-font.cc" diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 1fe3ee420..1ec48dc00 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -31,6 +31,7 @@ #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-var-common.hh" +#include "hb-paint.hh" /* * COLR -- Color @@ -45,6 +46,31 @@ namespace OT { struct COLR; + +struct hb_paint_context_t; + +struct Paint; + +static void paint_dispatch (const Paint *paint, hb_paint_context_t *c); + +struct hb_paint_context_t { + + const COLR* get_colr_table () const + { return reinterpret_cast (base); } + +public: + const void *base; + hb_paint_funcs_t *funcs; + void *data; + + hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, void *data_) : + base(base_), + funcs(funcs_), + data(data_) + {} + +}; + struct hb_colrv1_closure_context_t : hb_dispatch_context_t { @@ -182,6 +208,11 @@ struct Variable return_trace (c->check_struct (this) && value.sanitize (c)); } + void paint_glyph (hb_paint_context_t *c) const + { + value.paint_glyph (c); + } + protected: T value; public: @@ -216,6 +247,11 @@ struct NoVariable return_trace (c->check_struct (this) && value.sanitize (c)); } + void paint_glyph (hb_paint_context_t *c) const + { + value.paint_glyph (c); + } + T value; public: DEFINE_SIZE_STATIC (T::static_size); @@ -357,6 +393,14 @@ struct Affine2x3 return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, + xx.to_float (), yx.to_float (), + xy.to_float (), yy.to_float (), + dx.to_float (), dy.to_float ()); + } + F16DOT16 xx; F16DOT16 yx; F16DOT16 xy; @@ -388,6 +432,8 @@ struct PaintColrLayers return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const; + HBUINT8 format; /* format = 1 */ HBUINT8 numLayers; HBUINT32 firstLayerIndex; /* index into COLRv1::layerList */ @@ -415,6 +461,11 @@ struct PaintSolid return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->solid (c->data, paletteIndex); + } + HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ HBUINT16 paletteIndex; F2DOT14 alpha; @@ -443,6 +494,11 @@ struct PaintLinearGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->linear_gradient (c->data, nullptr, x0, y0, x1, y1, x2, y2); + } + HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintLinearGradient * table) to ColorLine subtable. */ @@ -477,6 +533,11 @@ struct PaintRadialGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->radial_gradient (c->data, nullptr, x0, y0, radius0, x1, y1, radius1); + } + HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintRadialGradient * table) to ColorLine subtable. */ @@ -511,6 +572,11 @@ struct PaintSweepGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->sweep_gradient (c->data, nullptr, centerX, centerY, startAngle, endAngle); + } + HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintSweepGradient * table) to ColorLine subtable. */ @@ -522,8 +588,6 @@ struct PaintSweepGradient DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size); }; -struct Paint; - // Paint a non-COLR glyph, filled as indicated by paint. struct PaintGlyph { @@ -548,6 +612,13 @@ struct PaintGlyph return_trace (c->check_struct (this) && paint.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_clip (c->data, gid); + paint_dispatch (&(this+paint), c); + c->funcs->pop_clip (c->data); + } + HBUINT8 format; /* format = 10 */ Offset24To paint; /* Offset (from beginning of PaintGlyph table) to Paint subtable. */ HBUINT16 gid; @@ -575,6 +646,12 @@ struct PaintColrGlyph return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const + { + // FIXME clipbox + //paint_glyph (c->data, gid); + } + HBUINT8 format; /* format = 11 */ HBUINT16 gid; public: @@ -603,6 +680,13 @@ struct PaintTransform transform.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + (this+transform).paint_glyph (c); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ Offset24To src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */ Offset24To> transform; @@ -629,6 +713,13 @@ struct PaintTranslate return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, 0, 0, 0, 0, 0, 0); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ Offset24To src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */ FWORD dx; @@ -656,6 +747,13 @@ struct PaintScale return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, scaleX, 0, 0, scaleY, 0, 0); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ Offset24To src; /* Offset (from beginning of PaintScale table) to Paint subtable. */ F2DOT14 scaleX; @@ -683,6 +781,17 @@ struct PaintScaleAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); + c->funcs->push_transform (c->data, scaleX, 0, 0, scaleY, 0, 0); + c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ Offset24To src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */ F2DOT14 scaleX; @@ -712,6 +821,10 @@ struct PaintScaleUniform return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ Offset24To src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */ F2DOT14 scale; @@ -738,6 +851,10 @@ struct PaintScaleUniformAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ Offset24To src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */ F2DOT14 scale; @@ -766,6 +883,10 @@ struct PaintRotate return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ Offset24To src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */ F2DOT14 angle; @@ -792,6 +913,10 @@ struct PaintRotateAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ Offset24To src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */ F2DOT14 angle; @@ -820,6 +945,10 @@ struct PaintSkew return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ Offset24To src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */ F2DOT14 xSkewAngle; @@ -847,6 +976,10 @@ struct PaintSkewAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ Offset24To src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */ F2DOT14 xSkewAngle; @@ -879,6 +1012,16 @@ struct PaintComposite backdrop.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_group (c->data); + paint_dispatch (&(this+backdrop), c); + c->funcs->push_group (c->data); + paint_dispatch (&(this+src), c); + c->funcs->pop_group_and_composite (c->data, (hb_paint_composite_mode_t) (int)mode); + c->funcs->pop_group_and_composite (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + } + HBUINT8 format; /* format = 32 */ Offset24To src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */ CompositeMode mode; /* If mode is unrecognized use COMPOSITE_CLEAR */ @@ -979,11 +1122,6 @@ struct ClipBox return true; } - void paint_glyph (hb_font_t *font, hb_codepoint_t glyph, - hb_paint_funcs_t *funcs, void *paint_data) const - { - } - protected: union { HBUINT8 format; /* Format identifier */ @@ -1195,6 +1333,45 @@ struct Paint } } + void paint_glyph (hb_paint_context_t *c) const + { + switch (u.format) { + case 1: u.paintformat1.paint_glyph (c); break; + case 2: u.paintformat2.paint_glyph (c); break; + case 3: u.paintformat3.paint_glyph (c); break; + case 4: u.paintformat4.paint_glyph (c); break; + case 5: u.paintformat5.paint_glyph (c); break; + case 6: u.paintformat6.paint_glyph (c); break; + case 7: u.paintformat7.paint_glyph (c); break; + case 8: u.paintformat8.paint_glyph (c); break; + case 9: u.paintformat9.paint_glyph (c); break; + case 10: u.paintformat10.paint_glyph (c); break; + case 11: u.paintformat11.paint_glyph (c); break; + case 12: u.paintformat12.paint_glyph (c); break; + case 13: u.paintformat13.paint_glyph (c); break; + case 14: u.paintformat14.paint_glyph (c); break; + case 15: u.paintformat15.paint_glyph (c); break; + case 16: u.paintformat16.paint_glyph (c); break; + case 17: u.paintformat17.paint_glyph (c); break; + case 18: u.paintformat18.paint_glyph (c); break; + case 19: u.paintformat19.paint_glyph (c); break; + case 20: u.paintformat20.paint_glyph (c); break; + case 21: u.paintformat21.paint_glyph (c); break; + case 22: u.paintformat22.paint_glyph (c); break; + case 23: u.paintformat23.paint_glyph (c); break; + case 24: u.paintformat24.paint_glyph (c); break; + case 25: u.paintformat25.paint_glyph (c); break; + case 26: u.paintformat26.paint_glyph (c); break; + case 27: u.paintformat27.paint_glyph (c); break; + case 28: u.paintformat28.paint_glyph (c); break; + case 29: u.paintformat29.paint_glyph (c); break; + case 30: u.paintformat30.paint_glyph (c); break; + case 31: u.paintformat31.paint_glyph (c); break; + case 32: u.paintformat32.paint_glyph (c); break; + default: assert (0); + } + } + protected: union { HBUINT8 format; @@ -1618,6 +1795,12 @@ struct COLR void paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + hb_paint_context_t c (this, funcs, data); + const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; + const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph); + const Paint &paint = &baseglyph_paintrecords+record->paint; + + paint.paint_glyph (&c); } protected: @@ -1642,7 +1825,12 @@ struct COLR_accelerator_t : COLR::accelerator_t { COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {} }; +static void +paint_dispatch (const Paint *paint, hb_paint_context_t *c) +{ + paint->paint_glyph (c); +} + } /* namespace OT */ - #endif /* HB_OT_COLOR_COLR_TABLE_HH */ diff --git a/src/meson.build b/src/meson.build index 463a3b349..164bb17f0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -75,6 +75,7 @@ hb_base_sources = files( 'hb-ot-cmap-table.hh', 'hb-ot-color-cbdt-table.hh', 'hb-ot-color-colr-table.hh', + 'hb-ot-color-colr-table.cc', 'hb-ot-color-cpal-table.hh', 'hb-ot-color-sbix-table.hh', 'hb-ot-color-svg-table.hh', From 42324aef2b18728d6318ffd4de08a21b54126c92 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 22:04:46 -0500 Subject: [PATCH 006/219] hb-paint: annotation fix --- src/hb-paint.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index 32decd090..d76956b77 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -166,7 +166,7 @@ typedef void (*hb_paint_pop_group_and_composite_func_t) (hb_paint_funcs_t *funcs /** * hb_paint_funcs_set_push_transform_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -179,7 +179,7 @@ hb_paint_funcs_set_push_transform_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_pop_transform_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -192,7 +192,7 @@ hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_push_clip_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -205,7 +205,7 @@ hb_paint_funcs_set_push_clip_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_pop_clip_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -218,7 +218,7 @@ hb_paint_funcs_set_pop_clip_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_solid_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -231,7 +231,7 @@ hb_paint_funcs_set_solid_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_linear_gradient_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -244,7 +244,7 @@ hb_paint_funcs_set_linear_gradient_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_radial_gradient_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -257,7 +257,7 @@ hb_paint_funcs_set_radial_gradient_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_sweep_gradient_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -270,7 +270,7 @@ hb_paint_funcs_set_sweep_gradient_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_push_group_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ @@ -283,7 +283,7 @@ hb_paint_funcs_set_push_group_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_pop_group_and_composite_func: * @funcs: - * @func: (closure user_data) (destroy destroy) (scop notified): + * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ From 5a123e8691ae839e6409fdcd51edab0c62c0e9a4 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 22:05:02 -0500 Subject: [PATCH 007/219] quick testcase --- util/hb-test.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++ util/meson.build | 7 ++ 2 files changed, 175 insertions(+) create mode 100644 util/hb-test.c diff --git a/util/hb-test.c b/util/hb-test.c new file mode 100644 index 000000000..ebd6c20d1 --- /dev/null +++ b/util/hb-test.c @@ -0,0 +1,168 @@ +#include +#include +#include +#include + +typedef struct { + int level; +} paint_data_t; + +#define INDENT 2 + +static void +print (paint_data_t *data, + const char *format, + ...) +{ + va_list args; + + printf ("%*s", 2 * data->level, ""); + + va_start (args, format); + vprintf (format, args); + va_end (args); + + printf ("\n"); +} + +static void +push_transform (hb_paint_funcs_t *funcs, + void *paint_data, + float xx, float xy, + float yx, float yy, + float x0, float y0, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "start transform %f %f %f %f %f %f", xx, xy, yx, yy, x0, y0); + data->level++; +} + +static void +pop_transform (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + data->level--; + print (data, "end transform"); +} + +static void +push_clip (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "start clip %u", glyph); + data->level++; +} + +static void +pop_clip (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + data->level--; + print (data, "end clip"); +} + +static void +solid (hb_paint_funcs_t *funcs, + void *paint_data, + unsigned int color_index, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "solid %u", color_index); +} + +static void +linear_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + hb_position_t x1, hb_position_t y1, + hb_position_t x2, hb_position_t y2, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "linear gradient"); +} + +static void +radial_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float r0, + hb_position_t x1, hb_position_t y1, + float r1, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "radial gradient"); +} + +static void +sweep_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + hb_position_t x0, hb_position_t y0, + float start_angle, + float end_angle, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "sweep gradient"); +} + +static void +push_group (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "push group"); + data->level++; +} + +static void +pop_group_and_composite (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data) +{ + paint_data_t *data = user_data; + data->level--; + print (data, "pop group mode %d", mode); +} + +int main (int argc, char *argv[]) +{ + paint_data_t data = { 0 }; + hb_paint_funcs_t *funcs; + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + hb_face_t *face = hb_face_create (blob, 0); + hb_font_t *font = hb_font_create (face); + hb_font_set_scale (font, 20, 20); + hb_codepoint_t gid = atoi (argv[2]); + + funcs = hb_paint_funcs_create (); + hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); + hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); + hb_paint_funcs_set_push_clip_func (funcs, push_clip, &data, NULL); + hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); + hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); + hb_paint_funcs_set_pop_group_and_composite_func (funcs, pop_group_and_composite, &data, NULL); + hb_paint_funcs_set_solid_func (funcs, solid, &data, NULL); + hb_paint_funcs_set_linear_gradient_func (funcs, linear_gradient, &data, NULL); + hb_paint_funcs_set_radial_gradient_func (funcs, radial_gradient, &data, NULL); + hb_paint_funcs_set_sweep_gradient_func (funcs, sweep_gradient, &data, NULL); + + hb_font_paint_glyph (font, gid, funcs, NULL); + + return 0; +} diff --git a/util/meson.build b/util/meson.build index 41965994c..2e57cf1e4 100644 --- a/util/meson.build +++ b/util/meson.build @@ -16,6 +16,13 @@ hb_subset_cli_sources = [ util_deps = [freetype_dep, cairo_dep, cairo_ft_dep, glib_dep] +hb_test = executable('hb-test', [ 'hb-test.c' ], + cpp_args: cpp_args, + include_directories: [incconfig, incsrc], + dependencies: [util_deps, chafa_dep], + link_with: [libharfbuzz], + ) + if conf.get('HAVE_GLIB', 0) == 1 if conf.get('HAVE_CAIRO', 0) == 1 hb_view = executable('hb-view', hb_view_sources, From c9350838c7a039b87408ff2686759d0bd0c05377 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 22:32:40 -0500 Subject: [PATCH 008/219] assorted fixes and changes --- src/hb-ot-color-colr-table.hh | 4 +- src/hb-paint.cc | 112 ++++++++++++++++++---------------- src/hb-paint.h | 73 ++++++++++++++-------- src/hb-paint.hh | 37 ++++++----- util/hb-test.c | 43 ++++++++----- 5 files changed, 158 insertions(+), 111 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 1ec48dc00..c88583b92 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -463,7 +463,7 @@ struct PaintSolid void paint_glyph (hb_paint_context_t *c) const { - c->funcs->solid (c->data, paletteIndex); + c->funcs->solid (c->data, paletteIndex, alpha.to_float ()); } HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ @@ -614,7 +614,7 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_clip (c->data, gid); + c->funcs->push_clip_glyph (c->data, gid); paint_dispatch (&(this+paint), c); c->funcs->pop_clip (c->data); } diff --git a/src/hb-paint.cc b/src/hb-paint.cc index d1eefbb80..06d70acf8 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -29,63 +29,67 @@ #include "hb-paint.hh" static void -hb_paint_push_transform_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - float xx HB_UNUSED, float xy HB_UNUSED, - float yx HB_UNUSED, float yy HB_UNUSED, - float x0 HB_UNUSED, float y0 HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, + float xx, float xy, + float yx, float yy, + float x0, float y0, + void *user_data) {} static void -hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, + void *user_data) {} static void -hb_paint_push_clip_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + void *user_data) {} static void -hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_push_clip_rect_nil (hb_paint_funcs_t *funcs, void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) {} static void -hb_paint_solid_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - unsigned int color_index HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, + void *user_data) {} static void -hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - hb_color_line_t *color_line HB_UNUSED, - hb_position_t x0, hb_position_t y0 HB_UNUSED, - hb_position_t x1, hb_position_t y1 HB_UNUSED, - hb_position_t x2, hb_position_t y2 HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_solid_nil (hb_paint_funcs_t *funcs, void *paint_data, + unsigned int color_index, + float alpha, + void *user_data) {} static void -hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - hb_color_line_t *color_line HB_UNUSED, - hb_position_t x0, hb_position_t y0 HB_UNUSED, - float r0 HB_UNUSED, - hb_position_t x1 HB_UNUSED, hb_position_t y1 HB_UNUSED, - float r1 HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *user_data) {} static void -hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - hb_color_line_t *color_line HB_UNUSED, - hb_position_t x0, hb_position_t y0 HB_UNUSED, - float start_angle HB_UNUSED, - float end_angle HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1, + void *user_data) {} static void -hb_paint_push_group_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, - void *user_data HB_UNUSED) {} +hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float start_angle, + float end_angle, + void *user_data) {} static void -hb_paint_pop_group_and_composite_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, +hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data, + void *user_data) {} + +static void +hb_paint_pop_group_and_composite_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - void *user_data HB_UNUSED) {} + void *user_data) {} static bool _hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs, @@ -251,10 +255,17 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) } void -hb_paint_push_clip (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph) +hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph) { - funcs->push_clip (paint_data, glyph); + funcs->push_clip_glyph (paint_data, glyph); +} + +void +hb_paint_push_clip_rect (hb_paint_funcs_t *funcs, void *paint_data, + float xmin, float ymin, float xmax, float ymax) +{ + funcs->push_clip_rect (paint_data, xmin, ymin, xmax, ymax); } void @@ -265,17 +276,18 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) void hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index) + unsigned int color_index, + float alpha) { - funcs->solid (paint_data, color_index); + funcs->solid (paint_data, color_index, alpha); } void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - hb_position_t x1, hb_position_t y1, - hb_position_t x2, hb_position_t y2) + float x0, float y0, + float x1, float y1, + float x2, float y2) { funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); } @@ -283,10 +295,8 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - float r0, - hb_position_t x1, hb_position_t y1, - float r1) + float x0, float y0, float r0, + float x1, float y1, float r1) { funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); } @@ -294,7 +304,7 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, + float x0, float y0, float start_angle, float end_angle) { funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); diff --git a/src/hb-paint.h b/src/hb-paint.h index d76956b77..5e0c3e3eb 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -61,9 +61,15 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, void *user_data); -typedef void (*hb_paint_push_clip_func_t) (hb_paint_funcs_t *funcs, +typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data); + +typedef void (*hb_paint_push_clip_rect_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph, + float xmin, float ymin, + float xmax, float ymax, void *user_data); typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, @@ -73,6 +79,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, + float alpha, void *user_data); @@ -101,24 +108,22 @@ hb_color_line_get_extend (hb_color_line_t *color_line); typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - hb_position_t x1, hb_position_t y1, - hb_position_t x2, hb_position_t y2, + float x0, float y0, + float x1, float y1, + float x2, float y2, void *user_data); typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - float r0, - hb_position_t x1, hb_position_t y1, - float r1, + float x0, float y0, float r0, + float x1, float y1, float r1, void *user_data); typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, + float x0, float y0, float start_angle, float end_angle, void *user_data); @@ -190,17 +195,30 @@ hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, hb_destroy_func_t destroy); /** - * hb_paint_funcs_set_push_clip_func: + * hb_paint_funcs_set_push_clip_glyph_func: * @funcs: * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ HB_EXTERN void -hb_paint_funcs_set_push_clip_func (hb_paint_funcs_t *funcs, - hb_paint_push_clip_func_t func, - void *user_data, - hb_destroy_func_t destroy); +hb_paint_funcs_set_push_clip_glyph_func (hb_paint_funcs_t *funcs, + hb_paint_push_clip_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +/** + * hb_paint_funcs_set_push_clip_rect_func: + * @funcs: + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: (nullable) + */ +HB_EXTERN void +hb_paint_funcs_set_push_clip_rect_func (hb_paint_funcs_t *funcs, + hb_paint_push_clip_rect_func_t func, + void *user_data, + hb_destroy_func_t destroy); /** * hb_paint_funcs_set_pop_clip_func: @@ -303,35 +321,38 @@ HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); HB_EXTERN void -hb_paint_push_clip (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph); +hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph); + +HB_EXTERN void +hb_paint_push_clip_rect (hb_paint_funcs_t *funcs, void *paint_data, + float xmin, float ymin, float xmax, float ymax); HB_EXTERN void hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); HB_EXTERN void hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index); + unsigned int color_index, + float alpha); HB_EXTERN void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - hb_position_t x1, hb_position_t y1, - hb_position_t x2, hb_position_t y2); + float x0, float y0, + float x1, float y1, + float x2, float y2); HB_EXTERN void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - float r0, - hb_position_t x1, hb_position_t y1, - float r1); + float x0, float y0, float r0, + float x1, float y1, float r1); HB_EXTERN void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, + float x0, float y0, float start_angle, float end_angle); HB_EXTERN void diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 6f7f1e157..6cb116b52 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -30,7 +30,8 @@ #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ HB_PAINT_FUNC_IMPLEMENT (pop_transform) \ - HB_PAINT_FUNC_IMPLEMENT (push_clip) \ + HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \ + HB_PAINT_FUNC_IMPLEMENT (push_clip_rect) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ HB_PAINT_FUNC_IMPLEMENT (solid) \ HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \ @@ -72,39 +73,43 @@ struct hb_paint_funcs_t void pop_transform (void *paint_data) { func.pop_transform (this, paint_data, !user_data ? nullptr : user_data->pop_transform); } - void push_clip (void *paint_data, - hb_codepoint_t glyph) - { func.push_clip (this, paint_data, - glyph, - !user_data ? nullptr : user_data->push_clip); } + void push_clip_glyph (void *paint_data, + hb_codepoint_t glyph) + { func.push_clip_glyph (this, paint_data, + glyph, + !user_data ? nullptr : user_data->push_clip_glyph); } + void push_clip_rect (void *paint_data, + float xmin, float ymin, float xmax, float ymax) + { func.push_clip_rect (this, paint_data, + xmin, ymin, xmax, ymax, + !user_data ? nullptr : user_data->push_clip_rect); } void pop_clip (void *paint_data) { func.pop_clip (this, paint_data, !user_data ? nullptr : user_data->pop_clip); } void solid (void *paint_data, - unsigned int color_index) + unsigned int color_index, + float alpha) { func.solid (this, paint_data, - color_index, + color_index, alpha, !user_data ? nullptr : user_data->solid); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - hb_position_t x1, hb_position_t y1, - hb_position_t x2, hb_position_t y2) + float x0, float y0, + float x1, float y1, + float x2, float y2) { func.linear_gradient (this, paint_data, color_line, x0, y0, x1, y1, x2, y2, !user_data ? nullptr : user_data->linear_gradient); } void radial_gradient (void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - float r0, - hb_position_t x1, hb_position_t y1, - float r1) + float x0, float y0, float r0, + float x1, float y1, float r1) { func.radial_gradient (this, paint_data, color_line, x0, y0, r0, x1, y1, r1, !user_data ? nullptr : user_data->radial_gradient); } void sweep_gradient (void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, + float x0, float y0, float start_angle, float end_angle) { func.sweep_gradient (this, paint_data, diff --git a/util/hb-test.c b/util/hb-test.c index ebd6c20d1..079fd5749 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -49,13 +49,24 @@ pop_transform (hb_paint_funcs_t *funcs, } static void -push_clip (hb_paint_funcs_t *funcs, - void *paint_data, - hb_codepoint_t glyph, - void *user_data) +push_clip_glyph (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data) { paint_data_t *data = user_data; - print (data, "start clip %u", glyph); + print (data, "start clip glyph %u", glyph); + data->level++; +} + +static void +push_clip_rect (hb_paint_funcs_t *funcs, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "start clip rect %f %f %f %f", xmin, ymin, xmax, ymax); data->level++; } @@ -73,33 +84,32 @@ static void solid (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, + float alpha, void *user_data) { paint_data_t *data = user_data; - print (data, "solid %u", color_index); + print (data, "solid %u %f", color_index, alpha); } static void linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - hb_position_t x1, hb_position_t y1, - hb_position_t x2, hb_position_t y2, + float x0, float y0, + float x1, float y1, + float x2, float y2, void *user_data) { paint_data_t *data = user_data; - print (data, "linear gradient"); + print (data, "linear gradient "); } static void radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, - float r0, - hb_position_t x1, hb_position_t y1, - float r1, + float x0, float y0, float r0, + float x1, float y1, float r1, void *user_data) { paint_data_t *data = user_data; @@ -110,7 +120,7 @@ static void sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - hb_position_t x0, hb_position_t y0, + float x0, float y0, float start_angle, float end_angle, void *user_data) @@ -153,7 +163,8 @@ int main (int argc, char *argv[]) funcs = hb_paint_funcs_create (); hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); - hb_paint_funcs_set_push_clip_func (funcs, push_clip, &data, NULL); + hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, &data, NULL); + hb_paint_funcs_set_push_clip_rect_func (funcs, push_clip_rect, &data, NULL); hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); hb_paint_funcs_set_pop_group_and_composite_func (funcs, pop_group_and_composite, &data, NULL); From 627c857f8b8ea5c5efab1525daef2d7e5ec04401 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 22:36:54 -0500 Subject: [PATCH 009/219] rename pop_group_and_composite --- src/hb-ot-color-colr-table.hh | 4 ++-- src/hb-paint.cc | 12 ++++++------ src/hb-paint.h | 28 ++++++++++++++-------------- src/hb-paint.hh | 12 ++++++------ util/hb-test.c | 10 +++++----- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index c88583b92..cdec4fe6c 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1018,8 +1018,8 @@ struct PaintComposite paint_dispatch (&(this+backdrop), c); c->funcs->push_group (c->data); paint_dispatch (&(this+src), c); - c->funcs->pop_group_and_composite (c->data, (hb_paint_composite_mode_t) (int)mode); - c->funcs->pop_group_and_composite (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int)mode); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } HBUINT8 format; /* format = 32 */ diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 06d70acf8..270a11eee 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -87,9 +87,9 @@ hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) {} static void -hb_paint_pop_group_and_composite_nil (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode, - void *user_data) {} +hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data) {} static bool _hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs, @@ -317,10 +317,10 @@ hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) } void -hb_paint_pop_group_and_composite (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode) +hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, + hb_paint_composite_mode_t mode) { - funcs->pop_group_and_composite (paint_data, mode); + funcs->pop_group (paint_data, mode); } #endif diff --git a/src/hb-paint.h b/src/hb-paint.h index 5e0c3e3eb..38d6fc396 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -159,14 +159,14 @@ typedef enum { HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY, } hb_paint_composite_mode_t; -typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data); +typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data); -typedef void (*hb_paint_pop_group_and_composite_func_t) (hb_paint_funcs_t *funcs, - void *paint_data, - hb_paint_composite_mode_t mode, - void *user_data); +typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data); /** * hb_paint_funcs_set_push_transform_func: @@ -299,17 +299,17 @@ hb_paint_funcs_set_push_group_func (hb_paint_funcs_t *funcs, hb_destroy_func_t destroy); /** - * hb_paint_funcs_set_pop_group_and_composite_func: + * hb_paint_funcs_set_pop_group_func: * @funcs: * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable) */ HB_EXTERN void -hb_paint_funcs_set_pop_group_and_composite_func (hb_paint_funcs_t *funcs, - hb_paint_pop_group_and_composite_func_t func, - void *user_data, - hb_destroy_func_t destroy); +hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs, + hb_paint_pop_group_func_t func, + void *user_data, + hb_destroy_func_t destroy); HB_EXTERN void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, @@ -359,8 +359,8 @@ HB_EXTERN void hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data); HB_EXTERN void -hb_paint_pop_group_and_composite (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode); +hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, + hb_paint_composite_mode_t mode); HB_END_DECLS diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 6cb116b52..0c848d67a 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -38,7 +38,7 @@ HB_PAINT_FUNC_IMPLEMENT (radial_gradient) \ HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \ HB_PAINT_FUNC_IMPLEMENT (push_group) \ - HB_PAINT_FUNC_IMPLEMENT (pop_group_and_composite) \ + HB_PAINT_FUNC_IMPLEMENT (pop_group) \ /* ^--- Add new callbacks here */ struct hb_paint_funcs_t @@ -118,11 +118,11 @@ struct hb_paint_funcs_t void push_group (void *paint_data) { func.push_group (this, paint_data, !user_data ? nullptr : user_data->push_group); } - void pop_group_and_composite (void *paint_data, - hb_paint_composite_mode_t mode) - { func.pop_group_and_composite (this, paint_data, - mode, - !user_data ? nullptr : user_data->pop_group_and_composite); } + void pop_group (void *paint_data, + hb_paint_composite_mode_t mode) + { func.pop_group (this, paint_data, + mode, + !user_data ? nullptr : user_data->pop_group); } }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); diff --git a/util/hb-test.c b/util/hb-test.c index 079fd5749..e4facb2c8 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -140,10 +140,10 @@ push_group (hb_paint_funcs_t *funcs, } static void -pop_group_and_composite (hb_paint_funcs_t *funcs, - void *paint_data, - hb_paint_composite_mode_t mode, - void *user_data) +pop_group (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data) { paint_data_t *data = user_data; data->level--; @@ -167,7 +167,7 @@ int main (int argc, char *argv[]) hb_paint_funcs_set_push_clip_rect_func (funcs, push_clip_rect, &data, NULL); hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); - hb_paint_funcs_set_pop_group_and_composite_func (funcs, pop_group_and_composite, &data, NULL); + hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); hb_paint_funcs_set_solid_func (funcs, solid, &data, NULL); hb_paint_funcs_set_linear_gradient_func (funcs, linear_gradient, &data, NULL); hb_paint_funcs_set_radial_gradient_func (funcs, radial_gradient, &data, NULL); From 64f1b55d01afa0a8424b0336fcaad626d9814126 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 23:58:25 -0500 Subject: [PATCH 010/219] api fixes: use floats consistently --- src/hb-paint.cc | 14 +++++++------- src/hb-paint.h | 11 ++++++----- src/hb-paint.hh | 8 ++++---- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 270a11eee..ceb95c197 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -30,9 +30,9 @@ static void hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, - float xx, float xy, - float yx, float yy, - float x0, float y0, + float xx, float yx, + float xy, float yy, + float dx, float dy, void *user_data) {} static void @@ -241,11 +241,11 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, - float xx, float xy, - float yx, float yy, - float x0, float y0) + float xx, float yx, + float xy, float yy, + float dx, float dy) { - funcs->push_transform (paint_data, xx, xy, yx, yy, x0, y0); + funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); } void diff --git a/src/hb-paint.h b/src/hb-paint.h index 38d6fc396..af15ecc2b 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -88,12 +88,13 @@ typedef struct hb_color_line_t hb_color_line_t; typedef struct { float offset; unsigned int color_index; + float alpha; } hb_color_stop_t; HB_EXTERN unsigned int -hb_color_line_get_color_stops (hb_color_line_t color_line, +hb_color_line_get_color_stops (hb_color_line_t *color_line, unsigned int start, - unsigned int count, + unsigned int *count, hb_color_stop_t *color_stops); typedef enum { @@ -313,9 +314,9 @@ hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs, HB_EXTERN void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, - float xx, float xy, - float yx, float yy, - float x0, float y0); + float xx, float yx, + float xy, float yy, + float dx, float dy); HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 0c848d67a..05cff5354 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -64,11 +64,11 @@ struct hb_paint_funcs_t } *destroy; void push_transform (void *paint_data, - float xx, float xy, - float yx, float yy, - float x0, float y0) + float xx, float yx, + float xy, float yy, + float dx, float dy) { func.push_transform (this, paint_data, - xx, xy, yx, yy, x0, y0, + xx, yx, xy, yy, dx, dy, !user_data ? nullptr : user_data->push_transform); } void pop_transform (void *paint_data) { func.pop_transform (this, paint_data, From 3937d6b0aaff5b5937bb513430e7df30f3517315 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 23:58:47 -0500 Subject: [PATCH 011/219] Implement hb_color_line_t --- src/hb-ot-color-colr-table.hh | 139 ++++++++++++++++++++++++++++++---- 1 file changed, 123 insertions(+), 16 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index cdec4fe6c..9b9637ab2 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -32,6 +32,7 @@ #include "hb-ot-layout-common.hh" #include "hb-ot-var-common.hh" #include "hb-paint.hh" +#include /* * COLR -- Color @@ -43,6 +44,11 @@ #define HB_COLRV1_MAX_NESTING_LEVEL 128 #endif +struct hb_color_line_t { + const void *base; + OT::HBUINT8 format; +}; + namespace OT { struct COLR; @@ -51,7 +57,7 @@ struct hb_paint_context_t; struct Paint; -static void paint_dispatch (const Paint *paint, hb_paint_context_t *c); +static void paint_glyph_dispatch (const Paint *paint, hb_paint_context_t *c); struct hb_paint_context_t { @@ -213,6 +219,11 @@ struct Variable value.paint_glyph (c); } + void get_color_stop (hb_color_stop_t *c) const + { + value.get_color_stop (c); + } + protected: T value; public: @@ -252,6 +263,11 @@ struct NoVariable value.paint_glyph (c); } + void get_color_stop (hb_color_stop_t *c) const + { + value.get_color_stop (c); + } + T value; public: DEFINE_SIZE_STATIC (T::static_size); @@ -279,6 +295,13 @@ struct ColorStop return_trace (c->check_struct (this)); } + void get_color_stop (hb_color_stop_t *out) const + { + out->offset = stopOffset.to_float(); + out->color_index = paletteIndex; + out->alpha = alpha.to_float(); + } + F2DOT14 stopOffset; HBUINT16 paletteIndex; F2DOT14 alpha; @@ -330,6 +353,25 @@ struct ColorLine stops.sanitize (c)); } + /* get up to count stops from start */ + unsigned int + get_color_stops (unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops) const + { + unsigned int len = stops.len; + + if (count && color_stops) + { + unsigned int i; + for (i = 0; i < *count && start + i < len; i++) + stops[start + i].get_color_stop (&color_stops[i]); + *count = i; + } + + return len; + } + Extend extend; Array16Of> stops; public: @@ -496,7 +538,16 @@ struct PaintLinearGradient void paint_glyph (hb_paint_context_t *c) const { - c->funcs->linear_gradient (c->data, nullptr, x0, y0, x1, y1, x2, y2); + hb_color_line_t cl = { this, format }; + + c->funcs->linear_gradient (c->data, &cl, x0, y0, x1, y1, x2, y2); + } + + unsigned int get_color_stops (unsigned int start, + unsigned int *count, + hb_color_stop_t *stops) const + { + return (this+colorLine).get_color_stops (start, count, stops); } HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ @@ -535,7 +586,16 @@ struct PaintRadialGradient void paint_glyph (hb_paint_context_t *c) const { - c->funcs->radial_gradient (c->data, nullptr, x0, y0, radius0, x1, y1, radius1); + hb_color_line_t cl = { this, format }; + + c->funcs->radial_gradient (c->data, &cl, x0, y0, radius0, x1, y1, radius1); + } + + unsigned int get_color_stops (unsigned int start, + unsigned int *count, + hb_color_stop_t *stops) const + { + return (this+colorLine).get_color_stops (start, count, stops); } HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ @@ -574,7 +634,16 @@ struct PaintSweepGradient void paint_glyph (hb_paint_context_t *c) const { - c->funcs->sweep_gradient (c->data, nullptr, centerX, centerY, startAngle, endAngle); + hb_color_line_t cl = { this, format }; + + c->funcs->sweep_gradient (c->data, &cl, centerX, centerY, startAngle, endAngle); + } + + unsigned int get_color_stops (unsigned int start, + unsigned int *count, + hb_color_stop_t *stops) const + { + return (this+colorLine).get_color_stops (start, count, stops); } HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ @@ -615,7 +684,7 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { c->funcs->push_clip_glyph (c->data, gid); - paint_dispatch (&(this+paint), c); + paint_glyph_dispatch (&(this+paint), c); c->funcs->pop_clip (c->data); } @@ -683,7 +752,7 @@ struct PaintTransform void paint_glyph (hb_paint_context_t *c) const { (this+transform).paint_glyph (c); - paint_dispatch (&(this+src), c); + paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -715,8 +784,8 @@ struct PaintTranslate void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_transform (c->data, 0, 0, 0, 0, 0, 0); - paint_dispatch (&(this+src), c); + c->funcs->push_transform (c->data, 0, 0, 0, 0, dx, dy); + paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -749,8 +818,8 @@ struct PaintScale void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_transform (c->data, scaleX, 0, 0, scaleY, 0, 0); - paint_dispatch (&(this+src), c); + c->funcs->push_transform (c->data, scaleX.to_float (), 0, 0, scaleY.to_float (), 0, 0); + paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -784,9 +853,9 @@ struct PaintScaleAroundCenter void paint_glyph (hb_paint_context_t *c) const { c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); - c->funcs->push_transform (c->data, scaleX, 0, 0, scaleY, 0, 0); + c->funcs->push_transform (c->data, scaleX.to_float (), 0, 0, scaleY.to_float (), 0, 0); c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); - paint_dispatch (&(this+src), c); + paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -823,6 +892,9 @@ struct PaintScaleUniform void paint_glyph (hb_paint_context_t *c) const { + c->funcs->push_transform (c->data, scale.to_float (), 0, 0, scale.to_float (), 0, 0); + paint_glyph_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ @@ -853,6 +925,13 @@ struct PaintScaleUniformAroundCenter void paint_glyph (hb_paint_context_t *c) const { + c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); + c->funcs->push_transform (c->data, scale.to_float (), 0, 0, scale.to_float (), 0, 0); + c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + paint_glyph_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ @@ -885,6 +964,11 @@ struct PaintRotate void paint_glyph (hb_paint_context_t *c) const { + float cc = cosf (angle.to_float() * (float)M_PI); + float ss = sinf (angle.to_float() * (float)M_PI); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0, 0); + paint_glyph_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ @@ -915,6 +999,15 @@ struct PaintRotateAroundCenter void paint_glyph (hb_paint_context_t *c) const { + float cc = cosf (angle.to_float() * (float)M_PI); + float ss = sinf (angle.to_float() * (float)M_PI); + c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0, 0); + c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + paint_glyph_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ @@ -947,6 +1040,11 @@ struct PaintSkew void paint_glyph (hb_paint_context_t *c) const { + float x = tanf (xSkewAngle.to_float() * (float)M_PI); + float y = - tanf (ySkewAngle.to_float() * (float)M_PI); + c->funcs->push_transform (c->data, 1, y, x, 1, 0, 0); + paint_glyph_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ @@ -978,6 +1076,15 @@ struct PaintSkewAroundCenter void paint_glyph (hb_paint_context_t *c) const { + float x = tanf (xSkewAngle.to_float() * (float)M_PI); + float y = - tanf (ySkewAngle.to_float() * (float)M_PI); + c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); + c->funcs->push_transform (c->data, 1, y, x, 1, 0, 0); + c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + paint_glyph_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ @@ -1015,10 +1122,10 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { c->funcs->push_group (c->data); - paint_dispatch (&(this+backdrop), c); + paint_glyph_dispatch (&(this+backdrop), c); c->funcs->push_group (c->data); - paint_dispatch (&(this+src), c); - c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int)mode); + paint_glyph_dispatch (&(this+src), c); + c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } @@ -1826,7 +1933,7 @@ struct COLR_accelerator_t : COLR::accelerator_t { }; static void -paint_dispatch (const Paint *paint, hb_paint_context_t *c) +paint_glyph_dispatch (const Paint *paint, hb_paint_context_t *c) { paint->paint_glyph (c); } From d07fdc69dd66ad520f9ce24438fbef5c7c41f28e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 23:58:59 -0500 Subject: [PATCH 012/219] test: dump color lines --- util/hb-test.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/util/hb-test.c b/util/hb-test.c index e4facb2c8..b03c08389 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -28,13 +28,13 @@ print (paint_data_t *data, static void push_transform (hb_paint_funcs_t *funcs, void *paint_data, - float xx, float xy, - float yx, float yy, - float x0, float y0, + float xx, float yx, + float xy, float yy, + float dx, float dy, void *user_data) { paint_data_t *data = user_data; - print (data, "start transform %f %f %f %f %f %f", xx, xy, yx, yy, x0, y0); + print (data, "start transform %f %f %f %f %f %f", xx, yx, xy, yy, dx, dy); data->level++; } @@ -101,7 +101,23 @@ linear_gradient (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; - print (data, "linear gradient "); + unsigned int len; + hb_color_stop_t *stops; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + + print (data, "linear gradient"); + data->level += 1; + print (data, "p0 %f %f", x0, y0); + print (data, "p1 %f %f", x1, y1); + print (data, "p2 %f %f", x2, y2); + print (data, "colors"); + data->level += 1; + for (unsigned int i = 0; i < len; i++) + print (data, "%f %u %f", stops[i].offset, stops[i].color_index, stops[i].alpha); + data->level -= 2; } static void From a6f813b68009325f9b5cc478ed83b312b06ad996 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 15 Dec 2022 00:05:27 -0500 Subject: [PATCH 013/219] Implement hb_color_line_get_extend --- src/hb-ot-color-colr-table.hh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 9b9637ab2..e71158774 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -224,6 +224,11 @@ struct Variable value.get_color_stop (c); } + hb_paint_extend_t get_extend () const + { + return value.get_extend (); + } + protected: T value; public: @@ -268,6 +273,11 @@ struct NoVariable value.get_color_stop (c); } + hb_paint_extend_t get_extend () const + { + return value.get_extend (); + } + T value; public: DEFINE_SIZE_STATIC (T::static_size); @@ -372,6 +382,11 @@ struct ColorLine return len; } + hb_paint_extend_t get_extend () const + { + return (hb_paint_extend_t) (unsigned int) extend; + } + Extend extend; Array16Of> stops; public: @@ -550,6 +565,11 @@ struct PaintLinearGradient return (this+colorLine).get_color_stops (start, count, stops); } + hb_paint_extend_t get_extend () const + { + return (this+colorLine).get_extend (); + } + HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintLinearGradient * table) to ColorLine subtable. */ @@ -598,6 +618,11 @@ struct PaintRadialGradient return (this+colorLine).get_color_stops (start, count, stops); } + hb_paint_extend_t get_extend () const + { + return (this+colorLine).get_extend (); + } + HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintRadialGradient * table) to ColorLine subtable. */ @@ -646,6 +671,11 @@ struct PaintSweepGradient return (this+colorLine).get_color_stops (start, count, stops); } + hb_paint_extend_t get_extend () const + { + return (this+colorLine).get_extend (); + } + HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintSweepGradient * table) to ColorLine subtable. */ From 684df8a82a81e01412dc951c251abab77165ae66 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 15 Dec 2022 00:32:48 -0500 Subject: [PATCH 014/219] add some todos --- src/hb-font.cc | 1 + src/hb-ot-color-colr-table.hh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/hb-font.cc b/src/hb-font.cc index 59512b049..078a84354 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1393,6 +1393,7 @@ hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *paint_data) { + // TODO add an adapter for child fonts like get_glyph_shape does font->get_glyph_paint (glyph, funcs, paint_data); } diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index e71158774..41960bfcb 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1937,6 +1937,8 @@ struct COLR const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph); const Paint &paint = &baseglyph_paintrecords+record->paint; + // TODO handle v0 layers + // TODO apply clipbox clip paint.paint_glyph (&c); } From 1880e547531a8f137564e9c5bf7421005e8cffbd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 15 Dec 2022 01:06:00 -0500 Subject: [PATCH 015/219] Assorted fixes --- src/hb-ot-color-colr-table.hh | 62 +++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 41960bfcb..47d484c7d 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -555,7 +555,10 @@ struct PaintLinearGradient { hb_color_line_t cl = { this, format }; - c->funcs->linear_gradient (c->data, &cl, x0, y0, x1, y1, x2, y2); + c->funcs->linear_gradient (c->data, &cl, + (float)x0, (float)y0, + (float)x1, (float)y1, + (float)x2, (float)y2); } unsigned int get_color_stops (unsigned int start, @@ -608,7 +611,9 @@ struct PaintRadialGradient { hb_color_line_t cl = { this, format }; - c->funcs->radial_gradient (c->data, &cl, x0, y0, radius0, x1, y1, radius1); + c->funcs->radial_gradient (c->data, &cl, + (float)x0, (float)y0, (float)radius0, + (float)x1, (float)y1, (float)radius1); } unsigned int get_color_stops (unsigned int start, @@ -661,7 +666,10 @@ struct PaintSweepGradient { hb_color_line_t cl = { this, format }; - c->funcs->sweep_gradient (c->data, &cl, centerX, centerY, startAngle, endAngle); + c->funcs->sweep_gradient (c->data, &cl, + (float)centerX, (float)centerY, + (startAngle.to_float () + 1) * (float)M_PI, + (endAngle.to_float () + 1) * (float)M_PI); } unsigned int get_color_stops (unsigned int start, @@ -745,11 +753,7 @@ struct PaintColrGlyph return_trace (c->check_struct (this)); } - void paint_glyph (hb_paint_context_t *c) const - { - // FIXME clipbox - //paint_glyph (c->data, gid); - } + void paint_glyph (hb_paint_context_t *c) const; HBUINT8 format; /* format = 11 */ HBUINT16 gid; @@ -814,7 +818,7 @@ struct PaintTranslate void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_transform (c->data, 0, 0, 0, 0, dx, dy); + c->funcs->push_transform (c->data, 1., 0., 0., 1., (float)dx, (float)dy); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -848,7 +852,7 @@ struct PaintScale void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_transform (c->data, scaleX.to_float (), 0, 0, scaleY.to_float (), 0, 0); + c->funcs->push_transform (c->data, scaleX.to_float (), 0., 0., scaleY.to_float (), 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -882,9 +886,9 @@ struct PaintScaleAroundCenter void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); - c->funcs->push_transform (c->data, scaleX.to_float (), 0, 0, scaleY.to_float (), 0, 0); - c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); + c->funcs->push_transform (c->data, scaleX.to_float (), 0., 0., scaleY.to_float (), 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -922,7 +926,7 @@ struct PaintScaleUniform void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_transform (c->data, scale.to_float (), 0, 0, scale.to_float (), 0, 0); + c->funcs->push_transform (c->data, scale.to_float (), 0., 0., scale.to_float (), 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -955,9 +959,9 @@ struct PaintScaleUniformAroundCenter void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); - c->funcs->push_transform (c->data, scale.to_float (), 0, 0, scale.to_float (), 0, 0); - c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); + c->funcs->push_transform (c->data, scale.to_float (), 0., 0., scale.to_float (), 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -996,7 +1000,7 @@ struct PaintRotate { float cc = cosf (angle.to_float() * (float)M_PI); float ss = sinf (angle.to_float() * (float)M_PI); - c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0, 0); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -1031,9 +1035,9 @@ struct PaintRotateAroundCenter { float cc = cosf (angle.to_float() * (float)M_PI); float ss = sinf (angle.to_float() * (float)M_PI); - c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); - c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0, 0); - c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -1072,7 +1076,7 @@ struct PaintSkew { float x = tanf (xSkewAngle.to_float() * (float)M_PI); float y = - tanf (ySkewAngle.to_float() * (float)M_PI); - c->funcs->push_transform (c->data, 1, y, x, 1, 0, 0); + c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -1108,9 +1112,9 @@ struct PaintSkewAroundCenter { float x = tanf (xSkewAngle.to_float() * (float)M_PI); float y = - tanf (ySkewAngle.to_float() * (float)M_PI); - c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); - c->funcs->push_transform (c->data, 1, y, x, 1, 0, 0); - c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); + c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -1908,6 +1912,14 @@ struct COLR return_trace (true); } + const Paint *get_base_glyph_paint (hb_codepoint_t glyph) const + { + const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; + const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph); + const Paint &paint = &baseglyph_paintrecords+record->paint; + return &paint; + } + bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { From 794fa4c3c1d6564477a0885b95f80409f9272090 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 15 Dec 2022 22:22:31 -0500 Subject: [PATCH 016/219] sweep gradients etc --- util/hb-test.c | 819 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 817 insertions(+), 2 deletions(-) diff --git a/util/hb-test.c b/util/hb-test.c index b03c08389..b6024d215 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -1,10 +1,33 @@ #include +#include #include #include #include +#include +#include +#include +#include + +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif typedef struct { int level; + cairo_t *cr; + hb_font_t *font; + hb_color_t *colors; + unsigned int num_colors; + hb_color_t foreground_color; } paint_data_t; #define INDENT 2 @@ -25,6 +48,82 @@ print (paint_data_t *data, printf ("\n"); } +typedef struct { + float r, g, b, a; +} color_t; + +static void +get_color (paint_data_t *data, + unsigned int color_index, + float alpha, + color_t *c) +{ + hb_color_t color; + + if (color_index == 0xffff) + color = data->foreground_color; + else + color = data->colors[color_index]; + + c->r = hb_color_get_red (color) / 255.; + c->g = hb_color_get_green (color) / 255.; + c->b = hb_color_get_blue (color) / 255.; + c->a = (hb_color_get_alpha (color) / 255.) * alpha; +} + +static cairo_operator_t +to_operator (hb_paint_composite_mode_t mode) +{ + switch (mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: return CAIRO_OPERATOR_CLEAR; + case HB_PAINT_COMPOSITE_MODE_SRC: return CAIRO_OPERATOR_SOURCE; + case HB_PAINT_COMPOSITE_MODE_DEST: return CAIRO_OPERATOR_DEST; + case HB_PAINT_COMPOSITE_MODE_SRC_OVER: return CAIRO_OPERATOR_OVER; + case HB_PAINT_COMPOSITE_MODE_DEST_OVER: return CAIRO_OPERATOR_DEST_OVER; + case HB_PAINT_COMPOSITE_MODE_SRC_IN: return CAIRO_OPERATOR_IN; + case HB_PAINT_COMPOSITE_MODE_DEST_IN: return CAIRO_OPERATOR_DEST_IN; + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: return CAIRO_OPERATOR_OUT; + case HB_PAINT_COMPOSITE_MODE_DEST_OUT: return CAIRO_OPERATOR_DEST_OUT; + case HB_PAINT_COMPOSITE_MODE_SRC_ATOP: return CAIRO_OPERATOR_ATOP; + case HB_PAINT_COMPOSITE_MODE_DEST_ATOP: return CAIRO_OPERATOR_DEST_ATOP; + case HB_PAINT_COMPOSITE_MODE_XOR: return CAIRO_OPERATOR_XOR; + case HB_PAINT_COMPOSITE_MODE_PLUS: return CAIRO_OPERATOR_ADD; + case HB_PAINT_COMPOSITE_MODE_SCREEN: return CAIRO_OPERATOR_SCREEN; + case HB_PAINT_COMPOSITE_MODE_OVERLAY: return CAIRO_OPERATOR_OVERLAY; + case HB_PAINT_COMPOSITE_MODE_DARKEN: return CAIRO_OPERATOR_DARKEN; + case HB_PAINT_COMPOSITE_MODE_LIGHTEN: return CAIRO_OPERATOR_LIGHTEN; + case HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: return CAIRO_OPERATOR_COLOR_DODGE; + case HB_PAINT_COMPOSITE_MODE_COLOR_BURN: return CAIRO_OPERATOR_COLOR_BURN; + case HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: return CAIRO_OPERATOR_HARD_LIGHT; + case HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: return CAIRO_OPERATOR_SOFT_LIGHT; + case HB_PAINT_COMPOSITE_MODE_DIFFERENCE: return CAIRO_OPERATOR_DIFFERENCE; + case HB_PAINT_COMPOSITE_MODE_EXCLUSION: return CAIRO_OPERATOR_EXCLUSION; + case HB_PAINT_COMPOSITE_MODE_MULTIPLY: return CAIRO_OPERATOR_MULTIPLY; + case HB_PAINT_COMPOSITE_MODE_HSL_HUE: return CAIRO_OPERATOR_HSL_HUE; + case HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: return CAIRO_OPERATOR_HSL_SATURATION; + case HB_PAINT_COMPOSITE_MODE_HSL_COLOR: return CAIRO_OPERATOR_HSL_COLOR; + case HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: return CAIRO_OPERATOR_HSL_LUMINOSITY; + default:; + } + + return CAIRO_OPERATOR_SOURCE; +} + +static cairo_extend_t +cairo_extend (hb_paint_extend_t extend) +{ + switch (extend) + { + case HB_PAINT_EXTEND_PAD: return CAIRO_EXTEND_PAD; + case HB_PAINT_EXTEND_REPEAT: return CAIRO_EXTEND_REPEAT; + case HB_PAINT_EXTEND_REFLECT: return CAIRO_EXTEND_REFLECT; + default:; + } + + return CAIRO_EXTEND_PAD; +} + static void push_transform (hb_paint_funcs_t *funcs, void *paint_data, @@ -34,7 +133,14 @@ push_transform (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + cairo_matrix_t m; + print (data, "start transform %f %f %f %f %f %f", xx, yx, xy, yy, dx, dy); + + cairo_save (data->cr); + cairo_matrix_init (&m, xx, yx, xy, yy, dx, dy); + cairo_transform (data->cr, &m); + data->level++; } @@ -44,10 +150,59 @@ pop_transform (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + data->level--; + + cairo_restore (data->cr); + print (data, "end transform"); } +static void +move_to (hb_draw_funcs_t *funcs, void *draw_data, + hb_draw_state_t *st, + float x, float y, + void *user_data) +{ + paint_data_t *data = user_data; + + cairo_move_to (data->cr, x, y); +} + +static void +line_to (hb_draw_funcs_t *funcs, void *draw_data, + hb_draw_state_t *st, + float x, float y, + void *user_data) +{ + paint_data_t *data = user_data; + + cairo_line_to (data->cr, x, y); +} + +static void +cubic_to (hb_draw_funcs_t *funcs, void *draw_data, + hb_draw_state_t *st, + float c1x, float c1y, + float c2x, float c2y, + float x, float y, + void *user_data) +{ + paint_data_t *data = user_data; + + cairo_curve_to (data->cr, c1x, c1y, c2x, c2y, x, y); +} + +static void +close_path (hb_draw_funcs_t *funcs, void *draw_data, + hb_draw_state_t *st, + void *user_data) +{ + paint_data_t *data = user_data; + + cairo_close_path (data->cr); +} + static void push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, @@ -55,8 +210,26 @@ push_clip_glyph (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + hb_draw_funcs_t *dfuncs; print (data, "start clip glyph %u", glyph); data->level++; + + cairo_save (data->cr); + + dfuncs = hb_draw_funcs_create (); + hb_draw_funcs_set_move_to_func (dfuncs, move_to, data, NULL); + hb_draw_funcs_set_line_to_func (dfuncs, line_to, data, NULL); + hb_draw_funcs_set_cubic_to_func (dfuncs, cubic_to, data, NULL); + hb_draw_funcs_set_close_path_func (dfuncs, close_path, data, NULL); + + cairo_new_path (data->cr); + + hb_font_get_glyph_shape (data->font, glyph, dfuncs, data); + cairo_close_path (data->cr); + + cairo_clip (data->cr); + + hb_draw_funcs_destroy (dfuncs); } static void @@ -66,8 +239,15 @@ push_clip_rect (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + print (data, "start clip rect %f %f %f %f", xmin, ymin, xmax, ymax); data->level++; + + cairo_save (data->cr); + + cairo_rectangle (data->cr, xmin, ymin, xmax - xmin, ymax - ymin); + + cairo_clip (data->cr); } static void @@ -76,6 +256,9 @@ pop_clip (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + + cairo_restore (data->cr); + data->level--; print (data, "end clip"); } @@ -88,7 +271,86 @@ solid (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + color_t c; + print (data, "solid %u %f", color_index, alpha); + + get_color (data, color_index, alpha, &c); + cairo_set_source_rgba (data->cr, c.r, c.g, c.b, c.a); + cairo_paint (data->cr); +} + +static void +reduce_anchors (float x0, float y0, + float x1, float y1, + float x2, float y2, + float *xx0, float *yy0, + float *xx1, float *yy1) +{ + float q1x, q1y, q2x, q2y; + float s; + float k; + + q2x = x2 - x0; + q2y = y2 - y0; + q1x = y1 - x0; + q1y = y1 - y0; + + s = q2x * q2x + q2y * q2y; + if (s < 0.000001) + { + *xx0 = x0; *yy0 = y0; + *xx1 = x1; *yy1 = y1; + return; + } + + k = (q2x * q1x + q2y * q1y) / s; + *xx0 = x0; + *yy0 = y0; + *xx1 = x1 - k * q2x; + *yy1 = y1 - k * q2y; +} + +static int +cmp_color_stop (const void *p1, + const void *p2) +{ + const hb_color_stop_t *c1 = p1; + const hb_color_stop_t *c2 = p2; + + if (c1->offset < c2->offset) + return -1; + else if (c1->offset > c2->offset) + return 1; + else + return 0; +} + +static void +normalize_color_line (hb_color_stop_t *stops, + unsigned int len, + float *omin, + float *omax) +{ + float min, max; + + qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); + + min = max = stops[0].offset; + for (unsigned int i = 0; i < len; i++) + { + min = MIN (min, stops[i].offset); + max = MAX (max, stops[i].offset); + } + + if (min != max) + { + for (unsigned int i = 0; i < len; i++) + stops[i].offset = (stops[i].offset - min) / (max - min); + } + + *omin = min; + *omax = max; } static void @@ -103,6 +365,10 @@ linear_gradient (hb_paint_funcs_t *funcs, paint_data_t *data = user_data; unsigned int len; hb_color_stop_t *stops; + float xx0, yy0, xx1, yy1; + float xxx0, yyy0, xxx1, yyy1; + float min, max; + cairo_pattern_t *pattern; len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); stops = alloca (len * sizeof (hb_color_stop_t)); @@ -118,6 +384,28 @@ linear_gradient (hb_paint_funcs_t *funcs, for (unsigned int i = 0; i < len; i++) print (data, "%f %u %f", stops[i].offset, stops[i].color_index, stops[i].alpha); data->level -= 2; + + reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1); + normalize_color_line (stops, len, &min, &max); + + xxx0 = xx0 + min * (xx1 - xx0); + yyy0 = yy0 + min * (yy1 - yy0); + xxx1 = xx0 + max * (xx1 - xx0); + yyy1 = yy0 + max * (yy1 - yy0); + + pattern = cairo_pattern_create_linear (xxx0, yyy0, xxx1, yyy1); + cairo_pattern_set_extend (pattern, cairo_extend (hb_color_line_get_extend (color_line))); + for (unsigned int i = 0; i < len; i++) + { + color_t c; + get_color (data, stops[i].color_index, stops[i].alpha, &c); + cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, c.r, c.g, c.b, c.a); + } + + cairo_set_source (data->cr, pattern); + cairo_paint (data->cr); + + cairo_pattern_destroy (pattern); } static void @@ -129,20 +417,478 @@ radial_gradient (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + unsigned int len; + hb_color_stop_t *stops; + cairo_extend_t extend; + float min, max; + float xx0, yy0, xx1, yy1; + float rr0, rr1; + cairo_pattern_t *pattern; + print (data, "radial gradient"); + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + + extend = cairo_extend (hb_color_line_get_extend (color_line)); + + normalize_color_line (stops, len, &min, &max); + xx0 = x0 + min * (x1 - x0); + yy0 = y0 + min * (y1 - y0); + xx1 = x0 + max * (x1 - x0); + yy1 = y0 + max * (y1 - y0); + rr0 = r0 + min * (r1 - r0); + rr1 = r0 + max * (r1 - r0); + + pattern = cairo_pattern_create_radial (xx0, yy0, rr0, xx1, yy1, rr1); + cairo_pattern_set_extend (pattern, extend); + + for (unsigned int i = 0; i < len; i++) + { + color_t c; + + get_color (data, stops[i].color_index, stops[i].alpha, &c); + cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, c.r, c.g, c.b, c.a); + } + + cairo_set_source (data->cr, pattern); + cairo_paint (data->cr); + + cairo_pattern_destroy (pattern); +} + +typedef struct { + float x, y; +} Point; + +static inline float +interpolate (float f0, float f1, float f) +{ + return f0 + f * (f1 - f0); +} + +static inline void +interpolate_points (Point *p0, Point *p1, float f, Point *out) +{ + out->x = interpolate (p0->x, p1->x, f); + out->y = interpolate (p0->y, p1->y, f); +} + +void +interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) +{ + c->r = c0->r + k * (c1->r - c0->r); + c->g = c0->g + k * (c1->g - c0->g); + c->b = c0->b + k * (c1->b - c0->b); + c->a = c0->a + k * (c1->a - c0->a); +} + +static inline float +dot (Point p, Point q) +{ + return p.x * q.x + p.y * q.y; +} + +static inline Point +normalize (Point p) +{ + float len = sqrt (dot (p, p)); + + return (Point) { p.x / len, p.y / len }; +} + +static inline Point +sum (Point p, Point q) +{ + return (Point) { p.x + q.x, p.y + q.y }; +} + +static inline Point +difference (Point p, Point q) +{ + return (Point) { p.x - q.x, p.y - q.y }; +} + +static inline Point +scale (Point p, float f) +{ + return (Point) { p.x * f, p.y * f }; +} + +typedef struct { + Point center, p0, c0, c1, p1; + color_t color0, color1; +} Patch; + +static void +add_patch (cairo_pattern_t *pattern, Point *center, Patch *p) +{ + cairo_mesh_pattern_begin_patch (pattern); + cairo_mesh_pattern_move_to (pattern, center->x, center->y); + cairo_mesh_pattern_line_to (pattern, p->p0.x, p->p0.y); + cairo_mesh_pattern_curve_to (pattern, + p->c0.x, p->c0.y, + p->c1.x, p->c1.y, + p->p1.x, p->p1.y); + cairo_mesh_pattern_line_to (pattern, center->x, center->y); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, + p->color0.r, + p->color0.g, + p->color0.b, + p->color0.a); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, + p->color0.r, + p->color0.g, + p->color0.b, + p->color0.a); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, + p->color1.r, + p->color1.g, + p->color1.b, + p->color1.a); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, + p->color1.r, + p->color1.g, + p->color1.b, + p->color1.a); + cairo_mesh_pattern_end_patch (pattern); +} + +#define MAX_ANGLE (M_PI / 8.) + +static void +add_sweep_gradient_patches1 (float cx, float cy, float radius, + float a0, color_t *c0, + float a1, color_t *c1, + cairo_pattern_t *pattern) +{ + Point center = (Point) { cx, cy }; + int num_splits; + Point p0; + color_t color0, color1; + + num_splits = ceilf (fabs (a1 - a0) / MAX_ANGLE); + p0 = (Point) { cosf (a0), sinf (a0) }; + color0 = *c0; + + for (int a = 0; a < num_splits; a++) + { + float k = (a + 1.) / num_splits; + float angle1; + Point p1; + Point A, U; + Point C0, C1; + Patch patch; + + angle1 = interpolate (a0, a1, k); + interpolate_colors (c0, c1, k, &color1); + + patch.color0 = color0; + patch.color1 = color1; + + p1 = (Point) { cosf (angle1), sinf (angle1) }; + patch.p0 = sum (center, scale (p0, radius)); + patch.p1 = sum (center, scale (p1, radius)); + + A = normalize (sum (p0, p1)); + U = (Point) { -A.y, A.x }; + C0 = sum (A, scale (U, dot (difference (p0, A), p0) / dot (U, p0))); + C1 = sum (A, scale (U, dot (difference (p1, A), p1) / dot (U, p1))); + + patch.c0 = sum (center, scale (sum (C0, scale (difference (C0, p0), 0.33333)), radius)); + patch.c1 = sum (center, scale (sum (C1, scale (difference (C1, p1), 0.33333)), radius)); + + add_patch (pattern, ¢er, &patch); + + p0 = p1; + color0 = color1; + } +} + +static void +add_sweep_gradient_patches (paint_data_t *data, + hb_color_stop_t *stops, + unsigned int n_stops, + cairo_extend_t extend, + float cx, float cy, + float radius, + float start_angle, + float end_angle, + cairo_pattern_t *pattern) +{ + float *angles; + color_t *colors; + color_t color0, color1; + + if (start_angle == end_angle) + { + if (extend == CAIRO_EXTEND_PAD) + { + color_t c; + if (start_angle > 0) + { + get_color (data, stops[0].color_index, stops[0].alpha, &c); + add_sweep_gradient_patches1 (cx, cy, radius, + 0., &c, + start_angle, &c, + pattern); + } + if (end_angle < 2 * M_PI) + { + get_color (data, stops[n_stops - 1].color_index, stops[n_stops - 1].alpha, &c); + add_sweep_gradient_patches1 (cx, cy, radius, + end_angle, &c, + 2 * M_PI, &c, + pattern); + } + } + return; + } + + assert (start_angle != end_angle); + + /* handle directions */ + if (end_angle < start_angle) + { + float angle = end_angle; + end_angle = start_angle; + start_angle = angle; + + for (int i = 0; i < n_stops - 1 - i; i++) + { + hb_color_stop_t stop = stops[i]; + stops[i] = stops[n_stops - 1 - i]; + stops[n_stops - 1 - i] = stop; + } + } + + angles = alloca (sizeof (float) * n_stops); + colors = alloca (sizeof (color_t) * n_stops); + + for (int i = 0; i < n_stops; i++) + { + angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); + get_color (data, stops[i].color_index, stops[i].alpha, &colors[i]); + } + + if (extend == CAIRO_EXTEND_PAD) + { + int pos; + + color0 = colors[0]; + for (pos = 0; pos < n_stops; pos++) + { + if (angles[pos] >= 0) + { + if (pos > 0) + { + float k = (0 - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); + interpolate_colors (&colors[pos-1], &colors[pos], k, &color0); + } + break; + } + } + if (pos == n_stops) + { + /* everything is below 0 */ + color0 = colors[n_stops-1]; + add_sweep_gradient_patches1 (cx, cy, radius, + 0., &color0, + 2 * M_PI, &color0, + pattern); + return; + } + + add_sweep_gradient_patches1 (cx, cy, radius, + 0., &color0, + angles[pos], &colors[pos], + pattern); + + for (pos++; pos < n_stops; pos++) + { + if (angles[pos] <= 2 * M_PI) + { + add_sweep_gradient_patches1 (cx, cy, radius, + angles[pos - 1], &colors[pos-1], + angles[pos], &colors[pos], + pattern); + } + else + { + float k = (2 * M_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); + interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1); + add_sweep_gradient_patches1 (cx, cy, radius, + angles[pos - 1], &colors[pos - 1], + 2 * M_PI, &color1, + pattern); + break; + } + } + + if (pos == n_stops) + { + /* everything is below 2*M_PI */ + color0 = colors[n_stops - 1]; + add_sweep_gradient_patches1 (cx, cy, radius, + angles[n_stops - 1], &color0, + 2 * M_PI, &color0, + pattern); + return; + } + } + else + { + int k; + float span; + + span = angles[n_stops - 1] - angles[0]; + k = 0; + if (angles[0] >= 0) + { + float ss = angles[0]; + while (ss > 0) + { + if (span > 0) + { + ss -= span; + k--; + } + else + { + ss += span; + k++; + } + } + } + else if (angles[0] < 0) + { + float ee = angles[n_stops - 1]; + while (ee < 0) + { + if (span > 0) + { + ee += span; + k++; + } + else + { + ee -= span; + k--; + } + } + } + + //assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span); + + for (int l = k; TRUE; l++) + { + for (int i = 1; i < n_stops; i++) + { + float a0, a1; + color_t *c0, *c1; + + if ((l % 2 != 0) && (extend == CAIRO_EXTEND_REFLECT)) + { + a0 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - (i-1)] + l * span; + a1 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - i] + l * span; + c0 = &colors[n_stops - 1 - (i - 1)]; + c1 = &colors[n_stops - 1 - i]; + } + else + { + a0 = angles[i-1] + l * span; + a1 = angles[i] + l * span; + c0 = &colors[i-1]; + c1 = &colors[i]; + } + + if (a1 < 0) + continue; + if (a0 < 0) + { + color_t color; + float f = (0 - a0)/(a1 - a0); + interpolate_colors (c0, c1, f, &color); + add_sweep_gradient_patches1 (cx, cy, radius, + 0, &color, + a1, c1, + pattern); + } + else if (a1 >= 2 * M_PI) + { + color_t color; + float f = (2 * M_PI - a0)/(a1 - a0); + interpolate_colors (c0, c1, f, &color); + add_sweep_gradient_patches1 (cx, cy, radius, + a0, c0, + 2 * M_PI, &color, + pattern); + goto done; + } + else + { + add_sweep_gradient_patches1 (cx, cy, radius, + a0, c0, + a1, c1, + pattern); + } + } + } +done: + } } static void sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - float x0, float y0, + float cx, float cy, float start_angle, float end_angle, void *user_data) { paint_data_t *data = user_data; + unsigned int len; + hb_color_stop_t *stops; + cairo_extend_t extend; + double x1, y1, x2, y2; + float max_x, max_y, radius; + cairo_pattern_t *pattern; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); + print (data, "sweep gradient"); + data->level++; + print (data, "center %f %f", cx, cy); + print (data, "angles %f %f", start_angle, end_angle); + + data->level += 1; + for (unsigned int i = 0; i < len; i++) + print (data, "%f %u %f", stops[i].offset, stops[i].color_index, stops[i].alpha); + data->level -= 2; + + cairo_clip_extents (data->cr, &x1, &y1, &x2, &y2); + max_x = MAX ((x1 - cx) * (x1 - cx), (x2 - cx) * (x2 - cx)); + max_y = MAX ((y1 - cy) * (y1 - cy), (y2 - cy) * (y2 - cy)); + radius = sqrt (max_x + max_y); + + extend = cairo_extend (hb_color_line_get_extend (color_line)); + + pattern = cairo_pattern_create_mesh (); + + add_sweep_gradient_patches (data, stops, len, extend, cx, cy, + radius, start_angle, end_angle, pattern); + + cairo_set_source (data->cr, pattern); + cairo_paint (data->cr); + + cairo_pattern_destroy (pattern); + + data->level--; } static void @@ -153,6 +899,9 @@ push_group (hb_paint_funcs_t *funcs, paint_data_t *data = user_data; print (data, "push group"); data->level++; + + cairo_save (data->cr); + cairo_push_group (data->cr); } static void @@ -162,19 +911,64 @@ pop_group (hb_paint_funcs_t *funcs, void *user_data) { paint_data_t *data = user_data; + + cairo_pop_group_to_source (data->cr); + cairo_set_operator (data->cr, to_operator (mode)); + cairo_paint (data->cr); + + cairo_restore (data->cr); + data->level--; print (data, "pop group mode %d", mode); } int main (int argc, char *argv[]) { - paint_data_t data = { 0 }; + paint_data_t data; hb_paint_funcs_t *funcs; hb_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_face_t *face = hb_face_create (blob, 0); hb_font_t *font = hb_font_create (face); hb_font_set_scale (font, 20, 20); hb_codepoint_t gid = atoi (argv[2]); + hb_glyph_extents_t extents; + cairo_surface_t *surface; + cairo_pattern_t *pattern; + cairo_matrix_t m; + float xmin, ymin, xmax, ymax; + + float size = 120.; + int upem = hb_face_get_upem (hb_font_get_face (font)); + + hb_font_set_scale (font, size, size); + hb_font_get_glyph_extents (font, gid, &extents); + hb_font_set_scale (font, upem, upem); + + xmin = extents.x_bearing; + xmax = xmin + extents.width; + ymin = - extents.y_bearing; + ymax = - extents.y_bearing - extents.height; + + printf ("surface %f %f, offset %f %f\n", ceil (xmax - xmin), ceil (ymax - ymin), - xmin, - ymin); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + (int) ceil (xmax - xmin), + (int) ceil (ymax - ymin)); + + cairo_surface_set_device_offset (surface, - xmin, ymax); + + data.level = 0; + data.cr = cairo_create (surface); + cairo_push_group (data.cr); + + data.font = font; + data.foreground_color = HB_COLOR (0, 0, 0, 255); + + data.num_colors = hb_ot_color_palette_get_colors (hb_font_get_face (font), + 0, 0, NULL, NULL); + data.colors = alloca (data.num_colors * sizeof (hb_color_t)); + hb_ot_color_palette_get_colors (hb_font_get_face (font), + 0, 0, &data.num_colors, data.colors); funcs = hb_paint_funcs_create (); hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); @@ -189,7 +983,28 @@ int main (int argc, char *argv[]) hb_paint_funcs_set_radial_gradient_func (funcs, radial_gradient, &data, NULL); hb_paint_funcs_set_sweep_gradient_func (funcs, sweep_gradient, &data, NULL); + cairo_save (data.cr); + cairo_scale (data.cr, size/upem, size/upem); // root transform + hb_font_paint_glyph (font, gid, funcs, NULL); + cairo_restore (data.cr); + + pattern = cairo_pop_group (data.cr); + + cairo_matrix_init_scale (&m, 1, -1); + cairo_matrix_translate (&m, 0, (ymax - ymin) + 2 * ymin); + cairo_pattern_set_matrix (pattern, &m); + cairo_set_source (data.cr, pattern); + + cairo_paint (data.cr); + + cairo_surface_set_device_offset (surface, - xmin, - ymin); + + printf ("writing glyph.png\n"); + cairo_surface_write_to_png (surface, "glyph.png"); + + execvp ("eog", (char *const[]) { "eog", "glyph.png", NULL }); + return 0; } From 55ca6ed230b74f84345258217e51d4865e763f2c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 15 Dec 2022 23:16:54 -0500 Subject: [PATCH 017/219] minor fixes --- src/hb-ot-color-colr-table.cc | 73 +++++++++++++++++++++++++++++++++++ src/hb-ot-color-colr-table.hh | 9 ++++- 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/hb-ot-color-colr-table.cc diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc new file mode 100644 index 000000000..45884d4b3 --- /dev/null +++ b/src/hb-ot-color-colr-table.cc @@ -0,0 +1,73 @@ +#include "hb-ot-color-colr-table.hh" + +namespace OT { + +void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const +{ + const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); + for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) + { + const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i]; + c->funcs->push_group (c->data); + paint_glyph_dispatch (&paint, c); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + } +} + +void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const +{ + const COLR *colr_table = c->get_colr_table (); + const Paint *paint = colr_table->get_base_glyph_paint (gid); + + if (paint) + paint_glyph_dispatch (paint, c); +} + +} + +unsigned int +hb_color_line_get_color_stops (hb_color_line_t *cl, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops) +{ + switch (cl->format) + { + case 4: + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + case 5: + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + case 6: + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + case 7: + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + case 8: + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + case 9: + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + default: assert (0); + } + return 0; +} + +hb_paint_extend_t +hb_color_line_get_extend (hb_color_line_t *cl) +{ + switch (cl->format) + { + case 4: + return reinterpret_cast *>(cl->base)->get_extend (); + case 5: + return reinterpret_cast *>(cl->base)->get_extend (); + case 6: + return reinterpret_cast *>(cl->base)->get_extend (); + case 7: + return reinterpret_cast *>(cl->base)->get_extend (); + case 8: + return reinterpret_cast *>(cl->base)->get_extend (); + case 9: + return reinterpret_cast *>(cl->base)->get_extend (); + default: assert (0); + } + return HB_PAINT_EXTEND_PAD; +} diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 47d484c7d..786cfe767 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1916,8 +1916,13 @@ struct COLR { const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph); - const Paint &paint = &baseglyph_paintrecords+record->paint; - return &paint; + if (record) + { + const Paint &paint = &baseglyph_paintrecords+record->paint; + return &paint; + } + else + return nullptr; } bool From d7c2eacf454e1345c15978bae9fff791d23effde Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 15 Dec 2022 23:42:40 -0500 Subject: [PATCH 018/219] Handle COLRv0 layers in paint_glyph --- src/hb-ot-color-colr-table.hh | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 786cfe767..d1bf5c4c5 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1950,13 +1950,27 @@ struct COLR paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { hb_paint_context_t c (this, funcs, data); - const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; - const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph); - const Paint &paint = &baseglyph_paintrecords+record->paint; + const Paint *paint = get_base_glyph_paint (glyph); - // TODO handle v0 layers - // TODO apply clipbox clip - paint.paint_glyph (&c); + if (paint) + { + // TODO root transform + // TODO apply clipbox clip + paint_glyph_dispatch (paint, &c); + } + else + { + const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph); + hb_array_t all_layers = (this+layersZ).as_array (numLayers); + for (unsigned int i = 0; i < record.numLayers; i++) + { + const LayerRecord *r = &all_layers[record.firstLayerIdx + i]; + + c.funcs->push_clip_glyph (c.data, r->glyphId); + c.funcs->solid (c.data, r->colorIdx, 1.); + c.funcs->pop_clip (c.data); + } + } } protected: From 44c68594f197f325fd9c50c3ca3d8ca1dca0be01 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 00:48:28 -0500 Subject: [PATCH 019/219] Some docs --- src/hb-paint.cc | 9 ++ src/hb-paint.h | 230 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index ceb95c197..ce8e07bc2 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -28,6 +28,15 @@ #include "hb-paint.hh" +/** + * SECTION: hb-paint + * @title: hb-paint + * @short_description: Glyph painting + * @include: hb.h + * + * Functions for painting (extracting) glyph color layers. + **/ + static void hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, diff --git a/src/hb-paint.h b/src/hb-paint.h index af15ecc2b..e1dfa62bd 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -33,6 +33,25 @@ HB_BEGIN_DECLS +/** + * hb_paint_funcs_t: + * + * Glyph paint callbacks. + * + * All the callbacks are necessary. + * + * The callbacks assume that the caller maintains a stack + * of current transforms, clips and intermediate surfaces, + * as evidenced by the pairs of push/pop callbacks. The + * push/pop calls will be properly nested, so it is fine + * to store the different kinds of object on a single stack. + * + * The callbacks also assume that the caller uses + * hb_ot_color_palette_get_colors() to obtain colors + * from one of the fonts color palettes. + * + * Since: REPLACEME + **/ typedef struct hb_paint_funcs_t hb_paint_funcs_t; HB_EXTERN hb_paint_funcs_t * @@ -50,6 +69,27 @@ hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs); HB_EXTERN hb_bool_t hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); +/** + * hb_paint_push_transform_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @xx: xx component of the transform matrix + * @yx: yx component of the transform matrix + * @xy: xy component of the transform matrix + * @yy: yy component of the transform matrix + * @dx: dx component of the transform matrix + * @dy: dy component of the transform matrix + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to apply + * a transform to subsequent paint calls. + * + * This transform is applied after the current transform, + * and remains in effect until a matching call to the + * #hb_paint_funcs_pop_transform_func_t vfunc. + * + * Since: REPLACEME + */ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, float xx, float xy, @@ -57,25 +97,110 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, float x0, float y0, void *user_data); +/** + * hb_paint_pop_transform_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to undo + * the effect of a prior call to the #hb_paint_funcs_push_transform_func_t + * vfunc. + * + * Since: REPLACEME + */ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, void *user_data); +/** + * hb_paint_push_clip_glyph_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @glyph: the glyph ID + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to clip + * subsequent paint calls to the outline of a glyph. + * + * The coordinates of the glyph outline are interpreted according + * to the current transform. + * + * This clip is applied in addition to the current clip, + * and remains in effect until a matching call to the + * #hb_paint_funcs_pop_clip_func_t vfunc. + * + * Since: REPLACEME + */ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, void *user_data); +/** + * hb_paint_push_clip_rect_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @xmin: min X for the rectangle + * @ymin: min Y for the rectangle + * @xmax: max X for the rectangle + * @ymax: max Y for the rectangle + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to clip + * subsequent paint calls to a rectangle. + * + * The coordinates of the rectangle are interpreted according + * to the current transform. + * + * This clip is applied in addition to the current clip, + * and remains in effect until a matching call to the + * #hb_paint_funcs_pop_clip_func_t vfunc. + * + * Since: REPLACEME + */ typedef void (*hb_paint_push_clip_rect_func_t) (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, void *user_data); +/** + * hb_paint_pop_clip_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to undo + * the effect of a prior call to the #hb_paint_funcs_push_clip_glyph_func_t + * or #hb_paint_funcs_push_clip_rect_func_t vfuncs. + * + * Since: REPLACEME + */ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, void *paint_data, void *user_data); +/** + * hb_paint_solid_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @color_index: Index of a color in the fonts selected color palette + * @alpha: alpha to apply in addition + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to paint a solid + * color everywhere within the current clip. + * + * The @color_index can be either an index into one of the fonts + * color palettes, or the special value #FFFF, which indicates that + * the foreground color should be used. + * + * In either case, the @alpha value should be applied in addition + * (i.e. multiplied with) the alpha value found in the color. + * + * Since: REPLACEME + */ typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, @@ -106,6 +231,31 @@ typedef enum { HB_EXTERN hb_paint_extend_t hb_color_line_get_extend (hb_color_line_t *color_line); +/** + * hb_paint_linear_gradient_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @color_line: Color information for the gradient + * @x0: X coordinate of the first point + * @y0: Y coordinate of the first point + * @x1: X coordinate of the second point + * @y1: Y coordinate of the second point + * @x2: X coordinate of the third point + * @y2: Y coordinate of the third point + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to paint a linear + * gradient everywhere within the current clip. + * + * The coordinates of the points are interpreted according + * to the current transform. + * + * See the OpenType spec COLR section (FIXME link) for details on how the + * points define the direction of the gradient, and how + * to interpret the @color_line. + * + * Since: REPLACEME + */ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, @@ -114,6 +264,31 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, float x2, float y2, void *user_data); +/** + * hb_paint_radial_gradient_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @color_line: Color information for the gradient + * @x0: X coordinate of the first circle's center + * @y0: Y coordinate of the first circle's center + * @r0: radius of the first circle + * @x1: X coordinate of the second circle's center + * @y1: Y coordinate of the second circle's center + * @r1: radius of the second circle + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to paint a radial + * gradient everywhere within the current clip. + * + * The coordinates of the points are interpreted according + * to the current transform. + * + * See the OpenType spec COLR section (FIXME link) for details on how the + * points define the direction of the gradient, and how + * to interpret the @color_line. + * + * Since: REPLACEME + */ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, @@ -121,6 +296,29 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, float x1, float y1, float r1, void *user_data); +/** + * hb_paint_sweep_gradient_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @color_line: Color information for the gradient + * @x0: X coordinate of the circle's center + * @y0: Y coordinate of the circle's center + * @start_angle: the start angle + * @end_angle: the end angle + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to paint a sweep + * gradient everywhere within the current clip. + * + * The coordinates of the points are interpreted according + * to the current transform. + * + * See the OpenType spec COLR section (FIXME link) for details on how the + * points define the direction of the gradient, and how + * to interpret the @color_line. + * + * Since: REPLACEME + */ typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, @@ -160,10 +358,42 @@ typedef enum { HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY, } hb_paint_composite_mode_t; +/** + * hb_paint_push_group_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to use + * an intermediate surface for subsequent paint calls. + * + * The drawing will be redirected to an intermediate surface + * until a matching call to the #hb_paint_funcs_pop_group_func_t + * vfunc. + * + * Since: REPLACEME + */ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, void *user_data); +/** + * hb_paint_pop_group_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @mode: the compositing mode to use + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to undo + * the effect of a prior call to the #hb_paint_funcs_push_group_func_t + * vfunc. + * + * This call stops the redirection to the intermediate surface, + * and then composites it on the previous surface, using the + * compositing mode passed to this call. + * + * Since: REPLACEME + */ typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, From 5afca91ff22c76fbe65da1f2084b5029a66bee14 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 06:43:43 -0500 Subject: [PATCH 020/219] Add some docs --- src/hb-paint.cc | 48 +++++++++- src/hb-paint.h | 226 +++++++++++++++++++++++++++++++----------------- 2 files changed, 196 insertions(+), 78 deletions(-) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index ce8e07bc2..e94ffb2d4 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -184,7 +184,11 @@ HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS /** * hb_paint_funcs_create: * - * Returns value: (transfer full): + * Creates a new #hb_paint_funcs_t structure of paint functions. + + * Returns value: (transfer full): the paint-functions structure + * + * Since: REPLACEME */ hb_paint_funcs_t * hb_paint_funcs_create () @@ -209,12 +213,33 @@ DEFINE_NULL_INSTANCE (hb_paint_funcs_t) = } }; +/** + * hb_paint_funcs_reference: (skip) + * @funcs: The paint-functions structure + * + * Increases the reference count on a paint-functions structure. + * + * Return value: The paint-functions structure + * + * Since: REPLACEME + */ hb_paint_funcs_t * hb_paint_funcs_reference (hb_paint_funcs_t *funcs) { return hb_object_reference (funcs); } +/** + * hb_paint_funcs_destroy: (skip) + * @funcs: The paint-functions structure + * + * Decreases the reference count on a paint-functions structure. + * + * When the reference count reaches zero, the structure + * is destroyed, freeing all memory. + * + * Since: REPLACEME + */ void hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) { @@ -233,6 +258,17 @@ hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) hb_free (funcs); } +/** + * hb_paint_funcs_make_immutable: + * @funcs: The paint-functions structure + * + * Makes a paint-functions structure immutable. + * + * After this call, all attempts to set one of the callbacks + * on @funcs will fail. + * + * Since: REPLACEME + */ void hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs) { @@ -242,6 +278,16 @@ hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs) hb_object_make_immutable (funcs); } +/** + * hb_paint_funcs_is_immutable: + * @funcs: The paint-functions structure + * + * Tests whether a paint-functions structure is immutable. + * + * Return value: `true` if @funcs is immutable, `false` otherwise + * + * Since: REPLACEME + */ hb_bool_t hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) { diff --git a/src/hb-paint.h b/src/hb-paint.h index e1dfa62bd..6be3b8478 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -85,16 +85,16 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); * a transform to subsequent paint calls. * * This transform is applied after the current transform, - * and remains in effect until a matching call to the - * #hb_paint_funcs_pop_transform_func_t vfunc. + * and remains in effect until a matching call to + * the #hb_paint_funcs_pop_transform_func_t vfunc. * * Since: REPLACEME */ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - float xx, float xy, - float yx, float yy, - float x0, float y0, + float xx, float yx, + float xy, float yy, + float dx, float dy, void *user_data); /** @@ -109,9 +109,9 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, * * Since: REPLACEME */ -typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data); +typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data); /** * hb_paint_push_clip_glyph_func_t: @@ -126,9 +126,14 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * The coordinates of the glyph outline are interpreted according * to the current transform. * + * Note that hb_font_paint_glyph() applies the scale and slant of + * the font as a transform, so you need to pass an unscaled, unslanted + * copy of the font to hb_font_get_glyph_shape() when obtaining outlines, + * to avoid double scaling. + * * This clip is applied in addition to the current clip, - * and remains in effect until a matching call to the - * #hb_paint_funcs_pop_clip_func_t vfunc. + * and remains in effect until a matching call to + * the #hb_paint_funcs_pop_clip_func_t vfunc. * * Since: REPLACEME */ @@ -154,8 +159,8 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, * to the current transform. * * This clip is applied in addition to the current clip, - * and remains in effect until a matching call to the - * #hb_paint_funcs_pop_clip_func_t vfunc. + * and remains in effect until a matching call to + * the #hb_paint_funcs_pop_clip_func_t vfunc. * * Since: REPLACEME */ @@ -177,9 +182,9 @@ typedef void (*hb_paint_push_clip_rect_func_t) (hb_paint_funcs_t *funcs, * * Since: REPLACEME */ -typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data); +typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data); /** * hb_paint_solid_func_t: @@ -193,7 +198,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * color everywhere within the current clip. * * The @color_index can be either an index into one of the fonts - * color palettes, or the special value #FFFF, which indicates that + * color palettes, or the special value 0xFFFF, which indicates that * the foreground color should be used. * * In either case, the @alpha value should be applied in addition @@ -201,15 +206,35 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * * Since: REPLACEME */ -typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs, - void *paint_data, - unsigned int color_index, - float alpha, - void *user_data); +typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + unsigned int color_index, + float alpha, + void *user_data); +/** + * hb_color_line_t: + * + * An opaque struct containing color information for a gradient. + * + * Since: REPLACEME + */ typedef struct hb_color_line_t hb_color_line_t; +/** + * hb_color_stop_t: + * @offset: the offset of the color stop + * @color_index: either a color palette index or the special value 0xFFFF + * @alpha: alpha to apply + * + * Information about a color stop on a color line. + * + * Color lines typically have offsets ranging between 0 and 1, + * but that is not required. + * + * Since: REPLACEME + */ typedef struct { float offset; unsigned int color_index; @@ -250,9 +275,9 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * The coordinates of the points are interpreted according * to the current transform. * - * See the OpenType spec COLR section (FIXME link) for details on how the - * points define the direction of the gradient, and how - * to interpret the @color_line. + * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * for details on how the points define the direction of the + * gradient, and how to interpret the @color_line. * * Since: REPLACEME */ @@ -283,9 +308,9 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * The coordinates of the points are interpreted according * to the current transform. * - * See the OpenType spec COLR section (FIXME link) for details on how the - * points define the direction of the gradient, and how - * to interpret the @color_line. + * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * for details on how the points define the direction of the + * gradient, and how to interpret the @color_line. * * Since: REPLACEME */ @@ -313,9 +338,9 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * The coordinates of the points are interpreted according * to the current transform. * - * See the OpenType spec COLR section (FIXME link) for details on how the - * points define the direction of the gradient, and how - * to interpret the @color_line. + * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * for details on how the points define the direction of the + * gradient, and how to interpret the @color_line. * * Since: REPLACEME */ @@ -401,10 +426,14 @@ typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_push_transform_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The push-transform callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the push-transform callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_push_transform_func (hb_paint_funcs_t *funcs, @@ -414,10 +443,14 @@ hb_paint_funcs_set_push_transform_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_pop_transform_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The pop-transform callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the pop-transform callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, @@ -427,10 +460,14 @@ hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_push_clip_glyph_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-glyph callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the push-clip-glyph callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_push_clip_glyph_func (hb_paint_funcs_t *funcs, @@ -440,10 +477,14 @@ hb_paint_funcs_set_push_clip_glyph_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_push_clip_rect_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-rect callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the push-clip-rect callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_push_clip_rect_func (hb_paint_funcs_t *funcs, @@ -453,10 +494,14 @@ hb_paint_funcs_set_push_clip_rect_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_pop_clip_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The pop-clip callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the pop-clip callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_pop_clip_func (hb_paint_funcs_t *funcs, @@ -466,10 +511,14 @@ hb_paint_funcs_set_pop_clip_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_solid_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The paint-solid callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the paint-solid callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_solid_func (hb_paint_funcs_t *funcs, @@ -479,10 +528,14 @@ hb_paint_funcs_set_solid_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_linear_gradient_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The linear-gradient callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the linear-gradient callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_linear_gradient_func (hb_paint_funcs_t *funcs, @@ -492,10 +545,14 @@ hb_paint_funcs_set_linear_gradient_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_radial_gradient_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The radial-gradient callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the radial-gradient callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_radial_gradient_func (hb_paint_funcs_t *funcs, @@ -505,10 +562,14 @@ hb_paint_funcs_set_radial_gradient_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_sweep_gradient_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The sweep-gradient callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the sweep-gradient callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_sweep_gradient_func (hb_paint_funcs_t *funcs, @@ -518,10 +579,14 @@ hb_paint_funcs_set_sweep_gradient_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_push_group_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The push-group callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the push-group callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_push_group_func (hb_paint_funcs_t *funcs, @@ -531,10 +596,14 @@ hb_paint_funcs_set_push_group_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_pop_group_func: - * @funcs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable) + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The pop-group callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the pop-group callback on the paint functions struct. + * + * Since: REPLACEME */ HB_EXTERN void hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs, @@ -557,7 +626,8 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_push_clip_rect (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, float xmax, float ymax); + float xmin, float ymin, + float xmax, float ymax); HB_EXTERN void hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); @@ -577,8 +647,10 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - float x0, float y0, float r0, - float x1, float y1, float r1); + float x0, float y0, + float r0, + float x1, float y1, + float r1); HB_EXTERN void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, From 5c6329555e6171e82cdf151a119166666a08426b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 12:04:17 -0500 Subject: [PATCH 021/219] Apply root transform This commit applies scale, slant is still missing. --- src/hb-ot-color-colr-table.hh | 15 +++++++++++++-- util/hb-test.c | 22 +++++++++++++--------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index d1bf5c4c5..d826c4f04 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1954,9 +1954,20 @@ struct COLR if (paint) { - // TODO root transform - // TODO apply clipbox clip + int xscale, yscale; + unsigned int upem; + + hb_font_get_scale (font, &xscale, &yscale); + upem = hb_face_get_upem (hb_font_get_face (font)); + + // FIXME handle slant + funcs->push_transform (data, xscale/(float)upem, 0, + 0, yscale/(float)upem, + 0, 0); + paint_glyph_dispatch (paint, &c); + + funcs->pop_transform (data); } else { diff --git a/util/hb-test.c b/util/hb-test.c index b6024d215..b2d0ed74d 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -25,6 +25,7 @@ typedef struct { int level; cairo_t *cr; hb_font_t *font; + hb_font_t *unscaled_font; hb_color_t *colors; unsigned int num_colors; hb_color_t foreground_color; @@ -223,8 +224,10 @@ push_clip_glyph (hb_paint_funcs_t *funcs, hb_draw_funcs_set_close_path_func (dfuncs, close_path, data, NULL); cairo_new_path (data->cr); - - hb_font_get_glyph_shape (data->font, glyph, dfuncs, data); + /* Note: we need to use a upem-scaled, unslanted copy of the font here, + * since hb has already applied the root transform. + */ + hb_font_get_glyph_shape (data->unscaled_font, glyph, dfuncs, data); cairo_close_path (data->cr); cairo_clip (data->cr); @@ -929,6 +932,7 @@ int main (int argc, char *argv[]) hb_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_face_t *face = hb_face_create (blob, 0); hb_font_t *font = hb_font_create (face); + hb_font_t *unscaled_font; hb_font_set_scale (font, 20, 20); hb_codepoint_t gid = atoi (argv[2]); hb_glyph_extents_t extents; @@ -936,13 +940,17 @@ int main (int argc, char *argv[]) cairo_pattern_t *pattern; cairo_matrix_t m; float xmin, ymin, xmax, ymax; + unsigned int upem; float size = 120.; - int upem = hb_face_get_upem (hb_font_get_face (font)); hb_font_set_scale (font, size, size); hb_font_get_glyph_extents (font, gid, &extents); - hb_font_set_scale (font, upem, upem); + + unscaled_font = hb_font_create (face); + upem = hb_face_get_upem (face); + hb_font_set_scale (unscaled_font, upem, upem); + hb_font_set_synthetic_slant (unscaled_font, 0.); xmin = extents.x_bearing; xmax = xmin + extents.width; @@ -962,6 +970,7 @@ int main (int argc, char *argv[]) cairo_push_group (data.cr); data.font = font; + data.unscaled_font = unscaled_font; data.foreground_color = HB_COLOR (0, 0, 0, 255); data.num_colors = hb_ot_color_palette_get_colors (hb_font_get_face (font), @@ -983,13 +992,8 @@ int main (int argc, char *argv[]) hb_paint_funcs_set_radial_gradient_func (funcs, radial_gradient, &data, NULL); hb_paint_funcs_set_sweep_gradient_func (funcs, sweep_gradient, &data, NULL); - cairo_save (data.cr); - cairo_scale (data.cr, size/upem, size/upem); // root transform - hb_font_paint_glyph (font, gid, funcs, NULL); - cairo_restore (data.cr); - pattern = cairo_pop_group (data.cr); cairo_matrix_init_scale (&m, 1, -1); From 9d3440b74299da8beb59c55e88aaf61fec39c507 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 12:12:21 -0700 Subject: [PATCH 022/219] [colr] Add variation infrastructure to paint_glyph No paint applies variations yet. --- src/hb-ot-color-colr-table.hh | 78 ++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index d826c4f04..930182643 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -68,11 +68,16 @@ public: const void *base; hb_paint_funcs_t *funcs; void *data; + VarStoreInstancer &instancer; - hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, void *data_) : - base(base_), - funcs(funcs_), - data(data_) + hb_paint_context_t (const void *base_, + hb_paint_funcs_t *funcs_, + void *data_, + VarStoreInstancer &instancer_) : + base (base_), + funcs (funcs_), + data (data_), + instancer (instancer_) {} }; @@ -216,7 +221,7 @@ struct Variable void paint_glyph (hb_paint_context_t *c) const { - value.paint_glyph (c); + value.paint_glyph (c, varIdxBase); } void get_color_stop (hb_color_stop_t *c) const @@ -265,7 +270,7 @@ struct NoVariable void paint_glyph (hb_paint_context_t *c) const { - value.paint_glyph (c); + value.paint_glyph (c, varIdxBase); } void get_color_stop (hb_color_stop_t *c) const @@ -450,7 +455,7 @@ struct Affine2x3 return_trace (c->check_struct (this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, xx.to_float (), yx.to_float (), @@ -518,7 +523,7 @@ struct PaintSolid return_trace (c->check_struct (this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->solid (c->data, paletteIndex, alpha.to_float ()); } @@ -551,7 +556,7 @@ struct PaintLinearGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { this, format }; @@ -607,7 +612,7 @@ struct PaintRadialGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { this, format }; @@ -662,7 +667,7 @@ struct PaintSweepGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { this, format }; @@ -816,7 +821,7 @@ struct PaintTranslate return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, 1., 0., 0., 1., (float)dx, (float)dy); paint_glyph_dispatch (&(this+src), c); @@ -850,7 +855,7 @@ struct PaintScale return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, scaleX.to_float (), 0., 0., scaleY.to_float (), 0., 0.); paint_glyph_dispatch (&(this+src), c); @@ -884,7 +889,7 @@ struct PaintScaleAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); c->funcs->push_transform (c->data, scaleX.to_float (), 0., 0., scaleY.to_float (), 0., 0.); @@ -924,7 +929,7 @@ struct PaintScaleUniform return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, scale.to_float (), 0., 0., scale.to_float (), 0., 0.); paint_glyph_dispatch (&(this+src), c); @@ -957,7 +962,7 @@ struct PaintScaleUniformAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); c->funcs->push_transform (c->data, scale.to_float (), 0., 0., scale.to_float (), 0., 0.); @@ -996,7 +1001,7 @@ struct PaintRotate return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float cc = cosf (angle.to_float() * (float)M_PI); float ss = sinf (angle.to_float() * (float)M_PI); @@ -1031,7 +1036,7 @@ struct PaintRotateAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float cc = cosf (angle.to_float() * (float)M_PI); float ss = sinf (angle.to_float() * (float)M_PI); @@ -1072,7 +1077,7 @@ struct PaintSkew return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float x = tanf (xSkewAngle.to_float() * (float)M_PI); float y = - tanf (ySkewAngle.to_float() * (float)M_PI); @@ -1108,7 +1113,7 @@ struct PaintSkewAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float x = tanf (xSkewAngle.to_float() * (float)M_PI); float y = - tanf (ySkewAngle.to_float() * (float)M_PI); @@ -1517,35 +1522,35 @@ struct Paint union { HBUINT8 format; PaintColrLayers paintformat1; - PaintSolid paintformat2; + NoVariable paintformat2; Variable paintformat3; - PaintLinearGradient paintformat4; + NoVariable> paintformat4; Variable> paintformat5; - PaintRadialGradient paintformat6; + NoVariable> paintformat6; Variable> paintformat7; - PaintSweepGradient paintformat8; + NoVariable> paintformat8; Variable> paintformat9; PaintGlyph paintformat10; PaintColrGlyph paintformat11; PaintTransform paintformat12; PaintTransform paintformat13; - PaintTranslate paintformat14; + NoVariable paintformat14; Variable paintformat15; - PaintScale paintformat16; + NoVariable paintformat16; Variable paintformat17; - PaintScaleAroundCenter paintformat18; + NoVariable paintformat18; Variable paintformat19; - PaintScaleUniform paintformat20; + NoVariable paintformat20; Variable paintformat21; - PaintScaleUniformAroundCenter paintformat22; + NoVariable paintformat22; Variable paintformat23; - PaintRotate paintformat24; + NoVariable paintformat24; Variable paintformat25; - PaintRotateAroundCenter paintformat26; + NoVariable paintformat26; Variable paintformat27; - PaintSkew paintformat28; + NoVariable paintformat28; Variable paintformat29; - PaintSkewAroundCenter paintformat30; + NoVariable paintformat30; Variable paintformat31; PaintComposite paintformat32; } u; @@ -1949,7 +1954,12 @@ struct COLR void paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { - hb_paint_context_t c (this, funcs, data); + VarStoreInstancer instancer (this+varStore, + this+varIdxMap, + hb_array (font->coords, font->num_coords)); + + hb_paint_context_t c (this, funcs, data, instancer); + const Paint *paint = get_base_glyph_paint (glyph); if (paint) From 5bce0053463ff29386f1442f3720fd847d972263 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 12:31:08 -0700 Subject: [PATCH 023/219] [colr] Flesh out variations for a few paints --- src/hb-ot-color-colr-table.hh | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 930182643..d55e687ad 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -458,9 +458,12 @@ struct Affine2x3 void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, - xx.to_float (), yx.to_float (), - xy.to_float (), yy.to_float (), - dx.to_float (), dy.to_float ()); + xx.to_float (c->instancer (varIdxBase, 0)), + yx.to_float (c->instancer (varIdxBase, 1)), + xy.to_float (c->instancer (varIdxBase, 2)), + yy.to_float (c->instancer (varIdxBase, 3)), + dx.to_float (c->instancer (varIdxBase, 4)), + dy.to_float (c->instancer (varIdxBase, 5))); } F16DOT16 xx; @@ -525,7 +528,9 @@ struct PaintSolid void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->solid (c->data, paletteIndex, alpha.to_float ()); + c->funcs->solid (c->data, + paletteIndex, + alpha.to_float (c->instancer (varIdxBase, 0))); } HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ @@ -561,9 +566,12 @@ struct PaintLinearGradient hb_color_line_t cl = { this, format }; c->funcs->linear_gradient (c->data, &cl, - (float)x0, (float)y0, - (float)x1, (float)y1, - (float)x2, (float)y2); + x0 + c->instancer (varIdxBase, 0), + y0 + c->instancer (varIdxBase, 1), + x1 + c->instancer (varIdxBase, 2), + y1 + c->instancer (varIdxBase, 3), + x2 + c->instancer (varIdxBase, 4), + y2 + c->instancer (varIdxBase, 5)); } unsigned int get_color_stops (unsigned int start, From 07575190928ff7bcb72885943d9b7073a27e4e3c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 12:45:02 -0700 Subject: [PATCH 024/219] [colr] Add variation to rest of the paints --- src/hb-ot-color-colr-table.hh | 80 +++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index d55e687ad..7194b23fb 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -625,8 +625,12 @@ struct PaintRadialGradient hb_color_line_t cl = { this, format }; c->funcs->radial_gradient (c->data, &cl, - (float)x0, (float)y0, (float)radius0, - (float)x1, (float)y1, (float)radius1); + x0 + c->instancer (varIdxBase, 0), + y0 + c->instancer (varIdxBase, 1), + x1 + c->instancer (varIdxBase, 3), + y1 + c->instancer (varIdxBase, 4), + radius0 + c->instancer (varIdxBase, 2), + radius1 + c->instancer (varIdxBase, 5)); } unsigned int get_color_stops (unsigned int start, @@ -680,9 +684,10 @@ struct PaintSweepGradient hb_color_line_t cl = { this, format }; c->funcs->sweep_gradient (c->data, &cl, - (float)centerX, (float)centerY, - (startAngle.to_float () + 1) * (float)M_PI, - (endAngle.to_float () + 1) * (float)M_PI); + centerX + c->instancer (varIdxBase, 0), + centerY + c->instancer (varIdxBase, 1), + (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI, + (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI); } unsigned int get_color_stops (unsigned int start, @@ -831,7 +836,10 @@ struct PaintTranslate void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->push_transform (c->data, 1., 0., 0., 1., (float)dx, (float)dy); + c->funcs->push_transform (c->data, + 1., 0., 0., 1., + dx + c->instancer (varIdxBase, 0), + dy + c->instancer (varIdxBase, 0)); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -865,7 +873,11 @@ struct PaintScale void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->push_transform (c->data, scaleX.to_float (), 0., 0., scaleY.to_float (), 0., 0.); + c->funcs->push_transform (c->data, + scaleX.to_float (c->instancer (varIdxBase, 0)), + 0., 0., + scaleY.to_float (c->instancer (varIdxBase, 1)), + 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -899,9 +911,15 @@ struct PaintScaleAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); - c->funcs->push_transform (c->data, scaleX.to_float (), 0., 0., scaleY.to_float (), 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); + float tCenterX = centerX + c->instancer (varIdxBase, 2); + float tCenterY = centerY + c->instancer (varIdxBase, 3); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); + c->funcs->push_transform (c->data, + scaleX.to_float (c->instancer (varIdxBase, 0)), + 0., 0., + scaleY.to_float (c->instancer (varIdxBase, 1)), + 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -939,7 +957,8 @@ struct PaintScaleUniform void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->push_transform (c->data, scale.to_float (), 0., 0., scale.to_float (), 0., 0.); + float s = scale + c->instancer (varIdxBase, 0); + c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); } @@ -972,9 +991,12 @@ struct PaintScaleUniformAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); - c->funcs->push_transform (c->data, scale.to_float (), 0., 0., scale.to_float (), 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); + float s = scale + c->instancer (varIdxBase, 0); + float tCenterX = centerX + c->instancer (varIdxBase, 1); + float tCenterY = centerY + c->instancer (varIdxBase, 2); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); + c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -1011,8 +1033,9 @@ struct PaintRotate void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - float cc = cosf (angle.to_float() * (float)M_PI); - float ss = sinf (angle.to_float() * (float)M_PI); + float a = angle.to_float (c->instancer (varIdxBase, 0)); + float cc = cosf (a * (float) M_PI); + float ss = sinf (a * (float) M_PI); c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); @@ -1046,11 +1069,14 @@ struct PaintRotateAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - float cc = cosf (angle.to_float() * (float)M_PI); - float ss = sinf (angle.to_float() * (float)M_PI); - c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); + float a = angle.to_float (c->instancer (varIdxBase, 0)); + float cc = cosf (a * (float) M_PI); + float ss = sinf (a * (float) M_PI); + float tCenterX = centerX + c->instancer (varIdxBase, 1); + float tCenterY = centerY + c->instancer (varIdxBase, 2); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -1087,8 +1113,8 @@ struct PaintSkew void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - float x = tanf (xSkewAngle.to_float() * (float)M_PI); - float y = - tanf (ySkewAngle.to_float() * (float)M_PI); + float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); + float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); @@ -1123,11 +1149,13 @@ struct PaintSkewAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - float x = tanf (xSkewAngle.to_float() * (float)M_PI); - float y = - tanf (ySkewAngle.to_float() * (float)M_PI); - c->funcs->push_transform (c->data, 0., 0., 0., 0., (float)centerX, (float)centerY); + float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); + float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); + float tCenterX = centerX + c->instancer (varIdxBase, 2); + float tCenterY = centerY + c->instancer (varIdxBase, 3); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., - (float)centerX, - (float)centerY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); paint_glyph_dispatch (&(this+src), c); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); From b4cab86d94affa5b610154623a393afffac9728c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 14:58:39 -0700 Subject: [PATCH 025/219] Fix autotools build --- src/Makefile.sources | 1 + src/harfbuzz-subset.cc | 1 - src/harfbuzz.cc | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Makefile.sources b/src/Makefile.sources index 6c4fc5de7..4253426f3 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -69,6 +69,7 @@ HB_BASE_sources = \ hb-ot-cmap-table.hh \ hb-ot-color-cbdt-table.hh \ hb-ot-color-colr-table.hh \ + hb-ot-color-colr-table.cc \ hb-ot-color-cpal-table.hh \ hb-ot-color-sbix-table.hh \ hb-ot-color-svg-table.hh \ diff --git a/src/harfbuzz-subset.cc b/src/harfbuzz-subset.cc index c5c66747a..b3a0666dc 100644 --- a/src/harfbuzz-subset.cc +++ b/src/harfbuzz-subset.cc @@ -41,7 +41,6 @@ #include "hb-ot-shaper-vowel-constraints.cc" #include "hb-ot-tag.cc" #include "hb-ot-var.cc" -#include "hb-paint.cc" #include "hb-set.cc" #include "hb-shape-plan.cc" #include "hb-shape.cc" diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc index 03196eaa6..b5faf722b 100644 --- a/src/harfbuzz.cc +++ b/src/harfbuzz.cc @@ -46,7 +46,6 @@ #include "hb-ot-shaper-vowel-constraints.cc" #include "hb-ot-tag.cc" #include "hb-ot-var.cc" -#include "hb-paint.cc" #include "hb-set.cc" #include "hb-shape-plan.cc" #include "hb-shape.cc" From fdf17dbf34666918979cb53c89e85b0c92fcf12b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 15:00:06 -0700 Subject: [PATCH 026/219] Try fixing bots --- util/hb-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/hb-test.c b/util/hb-test.c index b2d0ed74d..2b9cf8b15 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -838,7 +838,7 @@ add_sweep_gradient_patches (paint_data_t *data, } } } -done: +done: ; } } From a96300d42cf0a85ba6fa84eacfe583d8faf9c906 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 15:11:35 -0700 Subject: [PATCH 027/219] [colr] Hide internal symbols --- src/harfbuzz-subset.cc | 1 + src/harfbuzz.cc | 1 + src/hb-ot-color-colr-table.hh | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/harfbuzz-subset.cc b/src/harfbuzz-subset.cc index b3a0666dc..c5c66747a 100644 --- a/src/harfbuzz-subset.cc +++ b/src/harfbuzz-subset.cc @@ -41,6 +41,7 @@ #include "hb-ot-shaper-vowel-constraints.cc" #include "hb-ot-tag.cc" #include "hb-ot-var.cc" +#include "hb-paint.cc" #include "hb-set.cc" #include "hb-shape-plan.cc" #include "hb-shape.cc" diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc index b5faf722b..03196eaa6 100644 --- a/src/harfbuzz.cc +++ b/src/harfbuzz.cc @@ -46,6 +46,7 @@ #include "hb-ot-shaper-vowel-constraints.cc" #include "hb-ot-tag.cc" #include "hb-ot-var.cc" +#include "hb-paint.cc" #include "hb-set.cc" #include "hb-shape-plan.cc" #include "hb-shape.cc" diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 7194b23fb..6bb28a5bb 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -497,7 +497,7 @@ struct PaintColrLayers return_trace (c->check_struct (this)); } - void paint_glyph (hb_paint_context_t *c) const; + HB_INTERNAL void paint_glyph (hb_paint_context_t *c) const; HBUINT8 format; /* format = 1 */ HBUINT8 numLayers; @@ -771,7 +771,7 @@ struct PaintColrGlyph return_trace (c->check_struct (this)); } - void paint_glyph (hb_paint_context_t *c) const; + HB_INTERNAL void paint_glyph (hb_paint_context_t *c) const; HBUINT8 format; /* format = 11 */ HBUINT16 gid; From 81f232afb509bf94d8d909236c5bc1f507b08b5e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 15:17:35 -0700 Subject: [PATCH 028/219] [colr] Use dispatch machinery for paint_glyph context --- src/hb-ot-color-colr-table.hh | 48 +++++------------------------------ 1 file changed, 7 insertions(+), 41 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 6bb28a5bb..5d32924ce 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -59,7 +59,12 @@ struct Paint; static void paint_glyph_dispatch (const Paint *paint, hb_paint_context_t *c); -struct hb_paint_context_t { +struct hb_paint_context_t : + hb_dispatch_context_t +{ + template + return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); } + static return_t default_return_value () { return hb_empty_t (); } const COLR* get_colr_table () const { return reinterpret_cast (base); } @@ -1515,45 +1520,6 @@ struct Paint } } - void paint_glyph (hb_paint_context_t *c) const - { - switch (u.format) { - case 1: u.paintformat1.paint_glyph (c); break; - case 2: u.paintformat2.paint_glyph (c); break; - case 3: u.paintformat3.paint_glyph (c); break; - case 4: u.paintformat4.paint_glyph (c); break; - case 5: u.paintformat5.paint_glyph (c); break; - case 6: u.paintformat6.paint_glyph (c); break; - case 7: u.paintformat7.paint_glyph (c); break; - case 8: u.paintformat8.paint_glyph (c); break; - case 9: u.paintformat9.paint_glyph (c); break; - case 10: u.paintformat10.paint_glyph (c); break; - case 11: u.paintformat11.paint_glyph (c); break; - case 12: u.paintformat12.paint_glyph (c); break; - case 13: u.paintformat13.paint_glyph (c); break; - case 14: u.paintformat14.paint_glyph (c); break; - case 15: u.paintformat15.paint_glyph (c); break; - case 16: u.paintformat16.paint_glyph (c); break; - case 17: u.paintformat17.paint_glyph (c); break; - case 18: u.paintformat18.paint_glyph (c); break; - case 19: u.paintformat19.paint_glyph (c); break; - case 20: u.paintformat20.paint_glyph (c); break; - case 21: u.paintformat21.paint_glyph (c); break; - case 22: u.paintformat22.paint_glyph (c); break; - case 23: u.paintformat23.paint_glyph (c); break; - case 24: u.paintformat24.paint_glyph (c); break; - case 25: u.paintformat25.paint_glyph (c); break; - case 26: u.paintformat26.paint_glyph (c); break; - case 27: u.paintformat27.paint_glyph (c); break; - case 28: u.paintformat28.paint_glyph (c); break; - case 29: u.paintformat29.paint_glyph (c); break; - case 30: u.paintformat30.paint_glyph (c); break; - case 31: u.paintformat31.paint_glyph (c); break; - case 32: u.paintformat32.paint_glyph (c); break; - default: assert (0); - } - } - protected: union { HBUINT8 format; @@ -2055,7 +2021,7 @@ struct COLR_accelerator_t : COLR::accelerator_t { static void paint_glyph_dispatch (const Paint *paint, hb_paint_context_t *c) { - paint->paint_glyph (c); + paint->dispatch (c); } } /* namespace OT */ From 46286275f7f49149ef9e1db45d703880f094c1ee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 16 Dec 2022 15:27:18 -0700 Subject: [PATCH 029/219] [colr] More dispatch functionality --- src/hb-ot-color-colr-table.cc | 4 ++-- src/hb-ot-color-colr-table.hh | 39 ++++++++++++++++------------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 45884d4b3..62f1319fb 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -9,7 +9,7 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i]; c->funcs->push_group (c->data); - paint_glyph_dispatch (&paint, c); + c->recurse (paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } } @@ -20,7 +20,7 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const const Paint *paint = colr_table->get_base_glyph_paint (gid); if (paint) - paint_glyph_dispatch (paint, c); + c->recurse (*paint); } } diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 5d32924ce..86e114190 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -53,12 +53,8 @@ namespace OT { struct COLR; -struct hb_paint_context_t; - struct Paint; -static void paint_glyph_dispatch (const Paint *paint, hb_paint_context_t *c); - struct hb_paint_context_t : hb_dispatch_context_t { @@ -85,6 +81,7 @@ public: instancer (instancer_) {} + inline void recurse (const Paint &paint); }; struct hb_colrv1_closure_context_t : @@ -745,7 +742,7 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { c->funcs->push_clip_glyph (c->data, gid); - paint_glyph_dispatch (&(this+paint), c); + c->recurse (this+paint); c->funcs->pop_clip (c->data); } @@ -809,7 +806,7 @@ struct PaintTransform void paint_glyph (hb_paint_context_t *c) const { (this+transform).paint_glyph (c); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -845,7 +842,7 @@ struct PaintTranslate 1., 0., 0., 1., dx + c->instancer (varIdxBase, 0), dy + c->instancer (varIdxBase, 0)); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -883,7 +880,7 @@ struct PaintScale 0., 0., scaleY.to_float (c->instancer (varIdxBase, 1)), 0., 0.); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -925,7 +922,7 @@ struct PaintScaleAroundCenter scaleY.to_float (c->instancer (varIdxBase, 1)), 0., 0.); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -964,7 +961,7 @@ struct PaintScaleUniform { float s = scale + c->instancer (varIdxBase, 0); c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -1002,7 +999,7 @@ struct PaintScaleUniformAroundCenter c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -1042,7 +1039,7 @@ struct PaintRotate float cc = cosf (a * (float) M_PI); float ss = sinf (a * (float) M_PI); c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -1082,7 +1079,7 @@ struct PaintRotateAroundCenter c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -1121,7 +1118,7 @@ struct PaintSkew float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -1161,7 +1158,7 @@ struct PaintSkewAroundCenter c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data); @@ -1202,9 +1199,9 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { c->funcs->push_group (c->data); - paint_glyph_dispatch (&(this+backdrop), c); + c->recurse (this+backdrop); c->funcs->push_group (c->data); - paint_glyph_dispatch (&(this+src), c); + c->recurse (this+src); c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } @@ -1977,7 +1974,7 @@ struct COLR 0, yscale/(float)upem, 0, 0); - paint_glyph_dispatch (paint, &c); + c.recurse (*paint); funcs->pop_transform (data); } @@ -2018,10 +2015,10 @@ struct COLR_accelerator_t : COLR::accelerator_t { COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {} }; -static void -paint_glyph_dispatch (const Paint *paint, hb_paint_context_t *c) +void +hb_paint_context_t::recurse (const Paint &paint) { - paint->dispatch (c); + paint.dispatch (this); } } /* namespace OT */ From 2c07828603847892fe2759d2397530910f3f42e2 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 23:23:51 -0500 Subject: [PATCH 030/219] test: More debug spew --- util/hb-test.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/util/hb-test.c b/util/hb-test.c index 2b9cf8b15..ed91d2568 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -167,6 +167,8 @@ move_to (hb_draw_funcs_t *funcs, void *draw_data, { paint_data_t *data = user_data; + print (data, "move to %f %f", x, y); + cairo_move_to (data->cr, x, y); } @@ -178,6 +180,8 @@ line_to (hb_draw_funcs_t *funcs, void *draw_data, { paint_data_t *data = user_data; + print (data, "line to %f %f", x, y); + cairo_line_to (data->cr, x, y); } @@ -191,6 +195,8 @@ cubic_to (hb_draw_funcs_t *funcs, void *draw_data, { paint_data_t *data = user_data; + print (data, "curve to %f %f %f %f %f %f", c1x, c1y, c2x, c2y, x, y); + cairo_curve_to (data->cr, c1x, c1y, c2x, c2y, x, y); } @@ -201,6 +207,8 @@ close_path (hb_draw_funcs_t *funcs, void *draw_data, { paint_data_t *data = user_data; + print (data, "close path\n"); + cairo_close_path (data->cr); } @@ -279,6 +287,9 @@ solid (hb_paint_funcs_t *funcs, print (data, "solid %u %f", color_index, alpha); get_color (data, color_index, alpha, &c); + data->level++; + print (data, "color %f %f %f %f", c.r, c.g, c.b, c.a); + data->level--; cairo_set_source_rgba (data->cr, c.r, c.g, c.b, c.a); cairo_paint (data->cr); } @@ -952,6 +963,8 @@ int main (int argc, char *argv[]) hb_font_set_scale (unscaled_font, upem, upem); hb_font_set_synthetic_slant (unscaled_font, 0.); + printf ("size %f upem %u\n", size, upem); + xmin = extents.x_bearing; xmax = xmin + extents.width; ymin = - extents.y_bearing; @@ -959,6 +972,13 @@ int main (int argc, char *argv[]) printf ("surface %f %f, offset %f %f\n", ceil (xmax - xmin), ceil (ymax - ymin), - xmin, - ymin); + if ((int) ceil (xmax - xmin) == 0 || + (int) ceil (ymax - ymin) == 0) + { + printf ("ERROR: empty surface\n"); + return 1; + } + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (int) ceil (xmax - xmin), (int) ceil (ymax - ymin)); From 0d890061d139a9a8b59d8aef7e73a02bec1489ee Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 00:07:30 -0500 Subject: [PATCH 031/219] Rename 'solid' to 'color' 'solid' does not really describe well what the function does, and there is no strong reason to stick 1:1 to the terminology used in the spec. --- src/hb-ot-color-colr-table.hh | 4 +- src/hb-ot-color-colrv1-paint.hh | 286 ++++++++++++++++++++++++++++++++ src/hb-paint.cc | 6 +- src/hb-paint.h | 18 +- src/hb-paint.hh | 8 +- util/hb-test.c | 58 +++---- 6 files changed, 333 insertions(+), 47 deletions(-) create mode 100644 src/hb-ot-color-colrv1-paint.hh diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 86e114190..146ba9e34 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -530,7 +530,7 @@ struct PaintSolid void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->solid (c->data, + c->funcs->color (c->data, paletteIndex, alpha.to_float (c->instancer (varIdxBase, 0))); } @@ -1987,7 +1987,7 @@ struct COLR const LayerRecord *r = &all_layers[record.firstLayerIdx + i]; c.funcs->push_clip_glyph (c.data, r->glyphId); - c.funcs->solid (c.data, r->colorIdx, 1.); + c.funcs->color (c.data, r->colorIdx, 1.); c.funcs->pop_clip (c.data); } } diff --git a/src/hb-ot-color-colrv1-paint.hh b/src/hb-ot-color-colrv1-paint.hh new file mode 100644 index 000000000..75a8539ac --- /dev/null +++ b/src/hb-ot-color-colrv1-paint.hh @@ -0,0 +1,286 @@ +/* + * Copyright © 2022 Matthias Clasen + * + * 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. + * + */ + +#ifndef HB_OT_COLR_COLRV1_PAINT_HH +#define HB_OT_COLR_COLRV1_PAINT_HH + +#include "hb-open-type.hh" +#include "hb-ot-layout-common.hh" +#include "hb-ot-color-colr-table.hh" + +/* + * COLR -- Color + * https://docs.microsoft.com/en-us/typography/opentype/spec/colr + */ +namespace OT { + +struct hb_colrv1_paint_context_t : + hb_dispatch_context_t +{ + template + return_t dispatch (const T &obj) + { + obj.paint (this); + return hb_empty_t (); + } + + const COLR* get_colr_table () const + { return reinterpret_cast (base); } + + public: + const void *base; + hb_paint_funcs_t *funcs; + void *paint_data; + + hb_colrv1_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, void *paint_data_) + base (base_), funcs (funcs_), paint_data (paint_data_) + {} + + void push_transform (float xx, float yx, + float xy, float yy, + float x0, float y0) + { + funcs->push_transform (paint_data, xx, yx, xy, yy, x0, y0); + } + + void pop_transform () + { + funcs->pop_transform (paint_data); + } + + void push_clip (hb_codepoint_t gid) + { + funcs->push_clip (paint_data, gid); + } + + void pop_clip () + { + funcs->pop_clip (paint_data); + } + + void solid (unsigned int color_index) + { + funcs->solid (paint_data, color_index); + } + + void linear_gradient (hb_color_line *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2) + { + funcs->linear_gradient (paint_data, + color_line, x0, y0, x1, y1, x2, y2); + } + + void radial_gradient (hb_color_line *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1) + { + funcs->radial_gradient (paint_data, + color_line, x0, y0, r0, x1, y1, r1); + } + + void sweep_gradient (hb_color_line *color_line, + float x0, float y0, + float start_angle, float end_angle)' + { + funcs->sweep_gradient (paint_data, + color_line, x0, y0, start_angle, end_angle); + } + + void push_group () + { + funcs->push_group (paint_data); + } + + void pop_group_and_composite (hb_paint_composite_mode_t mode) + { + funcs->pop_group_and_composite (paint_data, mode); + } +} + +HB_INTERNAL void PaintColrLayers::paint (hb_colrv1_paint_context_t *c) const +{ + const COLR *colr_table = c->get_colr_table (); + const LayerList &paint_offset_lists = colr_table->get_layerList (); + for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) + { + const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i]; + c->push_group (); + paint.dispatch (c); + c->pop_group_and_composite (HB_PAINT_COMPOSITE_MODE_OVER); + } +} + +HB_INTERNAL void PaintGlyph::paint (hb_colrv1_paint_context_t *c) const +{ + c->push_clip (gid); + (this+paint).dispatch (c); + c->pop_clip (); +} + +HB_INTERNAL void PaintColrGlyph::paint (hb_colrv1_paint_context_t *c) const +{ + const COLR *colr_table = c->get_colr_table (); + const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid); + if (!baseglyph_paintrecord) return; + + c->push_clip (gid); + const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList (); + (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c); + c->pop_clip (); +} + +template class Var> +HB_INTERNAL void PaintTransform::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (transform.xx, transform.yx, + transform.xy, transform.yy, + transform.dx, transform.dy); + (this+src).dispatch (c); + c->pop_transform (); +} + +HB_INTERNAL void PaintTranslate::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (0, 0, 0, 0, dx, dy); + (this+src).dispatch (c); + c->pop_transform (); +} + +HB_INTERNAL void PaintScale::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (scaleX, 0, 0, scaleY, 0, 0); + (this+src).dispatch (c); + c->pop_transform (); +} + +HB_INTERNAL void PaintScaleAroundCenter::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (0, 0, 0, 0, - centerX, - centerY); + c->push_transform (scaleX, 0, 0, scaleY, 0, 0); + c->push_transform (0, 0, 0, 0, centerX, centerY); + (this+src).dispatch (c); + c->pop_transform (); + c->pop_transform (); + c->pop_transform (); +} + +HB_INTERNAL void PaintScaleUniform::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (scale, 0, 0, scale, 0, 0); + (this+src).dispatch (c); + c->pop_transform (); +} + +HB_INTERNAL void PaintScaleUniformAroundCenter::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (0, 0, 0, 0, - centerX, - centerY); + c->push_transform (scale, 0, 0, scale, 0, 0); + c->push_transform (0, 0, 0, 0, centerX, centerY); + (this+src).dispatch (c); + c->pop_transform (); + c->pop_transform (); + c->pop_transform (); +} + +HB_INTERNAL void PaintRotate::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (cos (angle), sin (angle), + - sin (angle), cos (angle), + 0, 0); + (this+src).dispatch (c); + c->pop_transform (); +} + +HB_INTERNAL void PaintRotateAroundCenter::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (0, 0, 0, 0, - centerX, - centerY); + c->push_transform (cos (angle), sin (angle), + - sin (angle), cos (angle), + 0, 0); + c->push_transform (0, 0, 0, 0, centerX, centerY); + (this+src).dispatch (c); + c->pop_transform (); + c->pop_transform (); + c->pop_transform (); +} + +HB_INTERNAL void PaintSkew::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (1, tan (ySkewAngle), + - tan (xSkewAngle), 1, + 0, 0); + (this+src).dispatch (c); + c->pop_transform (); +} + +HB_INTERNAL void PaintSkewAroundCenter::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_transform (0, 0, 0, 0, - centerX, - centerY); + c->push_transform (1, tan (ySkewAngle), + - tan (xSkewAngle), 1, + 0, 0); + c->push_transform (0, 0, 0, 0, centerX, centerY); + (this+src).dispatch (c); + c->pop_transform (); + c->pop_transform (); + c->pop_transform (); +} + +HB_INTERNAL void PaintComposite::paint (hb_colrv1_paint_context_t* c) const +{ + c->push_group (); + (this+src).dispatch (c); + c->push_group (); + (this+backdrop).dispatch (c); + c->pop_group_and_composite (mode); + c->pop_group_and_composite (HB_PAINT_COMPOSITE_MODE_OVER); +} + +HB_INTERNAL void PaintSolid::paint (hb_colrv1_paint_context_t *c) const +{ + c->solid (paletteIndex); +} + +HB_INTERNAL void PaintLinearGradient::paint (hb_colrv1_paint_context_t *c) const +{ + c->linear_gradient (color_line, x0, y0, x1, y1, x2, y2); +} + +HB_INTERNAL void PaintRadialGradient::paint (hb_colrv1_paint_context_t *c) const +{ + c->radial_gradient (color_line, x0, y0, radius0, x1, y1, radius1); +} + +HB_INTERNAL void PaintSweepGradient::paint (hb_colrv1_paint_context_t *c) const +{ + c->sweep_gradient (color_line, centerX, centerY, startAngle, endAngle); +} + +} /* namespace OT */ + + +#endif /* HB_OT_COLR_COLRV1_CLOSURE_HH */ diff --git a/src/hb-paint.cc b/src/hb-paint.cc index e94ffb2d4..5b8ab2c4f 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -63,7 +63,7 @@ hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) {} static void -hb_paint_solid_nil (hb_paint_funcs_t *funcs, void *paint_data, +hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, void *user_data) {} @@ -330,11 +330,11 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) } void -hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, +hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha) { - funcs->solid (paint_data, color_index, alpha); + funcs->color (paint_data, color_index, alpha); } void diff --git a/src/hb-paint.h b/src/hb-paint.h index 6be3b8478..a65eb9505 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -187,14 +187,14 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, void *user_data); /** - * hb_paint_solid_func_t: + * hb_paint_color_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions * @color_index: Index of a color in the fonts selected color palette * @alpha: alpha to apply in addition * @user_data: user data passed to the hb_font_paint_glyph() call * - * A virtual method for the #hb_paint_funcs_t to paint a solid + * A virtual method for the #hb_paint_funcs_t to paint a * color everywhere within the current clip. * * The @color_index can be either an index into one of the fonts @@ -206,7 +206,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * * Since: REPLACEME */ -typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs, +typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, @@ -510,19 +510,19 @@ hb_paint_funcs_set_pop_clip_func (hb_paint_funcs_t *funcs, hb_destroy_func_t destroy); /** - * hb_paint_funcs_set_solid_func: + * hb_paint_funcs_set_color_func: * @funcs: A paint functions struct - * @func: (closure user_data) (destroy destroy) (scope notified): The paint-solid callback + * @func: (closure user_data) (destroy destroy) (scope notified): The paint-color callback * @user_data: Data to pass to @func * @destroy: (nullable): Function to call when @user_data is no longer needed * - * Sets the paint-solid callback on the paint functions struct. + * Sets the paint-color callback on the paint functions struct. * * Since: REPLACEME */ HB_EXTERN void -hb_paint_funcs_set_solid_func (hb_paint_funcs_t *funcs, - hb_paint_solid_func_t func, +hb_paint_funcs_set_color_func (hb_paint_funcs_t *funcs, + hb_paint_color_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -633,7 +633,7 @@ HB_EXTERN void hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); HB_EXTERN void -hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, +hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha); diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 05cff5354..58d0da7fd 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -33,7 +33,7 @@ HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_rect) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ - HB_PAINT_FUNC_IMPLEMENT (solid) \ + HB_PAINT_FUNC_IMPLEMENT (color) \ HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \ HB_PAINT_FUNC_IMPLEMENT (radial_gradient) \ HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \ @@ -86,12 +86,12 @@ struct hb_paint_funcs_t void pop_clip (void *paint_data) { func.pop_clip (this, paint_data, !user_data ? nullptr : user_data->pop_clip); } - void solid (void *paint_data, + void color (void *paint_data, unsigned int color_index, float alpha) - { func.solid (this, paint_data, + { func.color (this, paint_data, color_index, alpha, - !user_data ? nullptr : user_data->solid); } + !user_data ? nullptr : user_data->color); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, diff --git a/util/hb-test.c b/util/hb-test.c index ed91d2568..ebf01e5b2 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -275,11 +275,11 @@ pop_clip (hb_paint_funcs_t *funcs, } static void -solid (hb_paint_funcs_t *funcs, - void *paint_data, - unsigned int color_index, - float alpha, - void *user_data) +paint_color (hb_paint_funcs_t *funcs, + void *paint_data, + unsigned int color_index, + float alpha, + void *user_data) { paint_data_t *data = user_data; color_t c; @@ -368,13 +368,13 @@ normalize_color_line (hb_color_stop_t *stops, } static void -linear_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float x1, float y1, - float x2, float y2, - void *user_data) +paint_linear_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *user_data) { paint_data_t *data = user_data; unsigned int len; @@ -423,12 +423,12 @@ linear_gradient (hb_paint_funcs_t *funcs, } static void -radial_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, float r0, - float x1, float y1, float r1, - void *user_data) +paint_radial_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1, + void *user_data) { paint_data_t *data = user_data; unsigned int len; @@ -854,13 +854,13 @@ done: ; } static void -sweep_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float cx, float cy, - float start_angle, - float end_angle, - void *user_data) +paint_sweep_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float cx, float cy, + float start_angle, + float end_angle, + void *user_data) { paint_data_t *data = user_data; unsigned int len; @@ -1007,10 +1007,10 @@ int main (int argc, char *argv[]) hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); - hb_paint_funcs_set_solid_func (funcs, solid, &data, NULL); - hb_paint_funcs_set_linear_gradient_func (funcs, linear_gradient, &data, NULL); - hb_paint_funcs_set_radial_gradient_func (funcs, radial_gradient, &data, NULL); - hb_paint_funcs_set_sweep_gradient_func (funcs, sweep_gradient, &data, NULL); + hb_paint_funcs_set_color_func (funcs, paint_color, &data, NULL); + hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, &data, NULL); + hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, &data, NULL); + hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, &data, NULL); hb_font_paint_glyph (font, gid, funcs, NULL); From 0b33b35eb0fc50045adc614dc60567fad837762b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 23:22:15 -0500 Subject: [PATCH 032/219] COLRv1: Return bool from paint_glyph This will let hb_ot_font_paint_glyph() try multiple tables in turn. --- src/hb-ot-color-colr-table.hh | 41 ++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 146ba9e34..aeb8b02ae 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1950,7 +1950,7 @@ struct COLR return false; } - void + bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { VarStoreInstancer instancer (this+varStore, @@ -1959,16 +1959,16 @@ struct COLR hb_paint_context_t c (this, funcs, data, instancer); - const Paint *paint = get_base_glyph_paint (glyph); + int xscale, yscale; + unsigned int upem; + hb_font_get_scale (font, &xscale, &yscale); + upem = hb_face_get_upem (hb_font_get_face (font)); + + const Paint *paint = get_base_glyph_paint (glyph); if (paint) { - int xscale, yscale; - unsigned int upem; - - hb_font_get_scale (font, &xscale, &yscale); - upem = hb_face_get_upem (hb_font_get_face (font)); - + // COLRv1 glyph // FIXME handle slant funcs->push_transform (data, xscale/(float)upem, 0, 0, yscale/(float)upem, @@ -1976,21 +1976,36 @@ struct COLR c.recurse (*paint); - funcs->pop_transform (data); + c.funcs->pop_transform (c.data); + + return true; } - else + + const BaseGlyphRecord *record = get_base_glyph_record (glyph); + if (record && ((hb_codepoint_t) record->glyphId == glyph)) { - const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph); + // COLRv0 glyph + // FIXME handle slant + funcs->push_transform (data, xscale/(float)upem, 0, + 0, yscale/(float)upem, + 0, 0); + hb_array_t all_layers = (this+layersZ).as_array (numLayers); - for (unsigned int i = 0; i < record.numLayers; i++) + for (unsigned int i = 0; i < record->numLayers; i++) { - const LayerRecord *r = &all_layers[record.firstLayerIdx + i]; + const LayerRecord *r = &all_layers[record->firstLayerIdx + i]; c.funcs->push_clip_glyph (c.data, r->glyphId); c.funcs->color (c.data, r->colorIdx, 1.); c.funcs->pop_clip (c.data); } + + c.funcs->pop_transform (c.data); + + return true; } + + return false; } protected: From 2edd771cf58de4348d6c760e4fbe77ea0f1ba16a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 23:32:15 -0500 Subject: [PATCH 033/219] glyf: Implement paint_glyph --- src/OT/glyf/glyf.hh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index e0c92f0c9..9c343ea6b 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -13,6 +13,7 @@ #include "SubsetGlyph.hh" #include "loca.hh" #include "path-builder.hh" +#include "hb-paint.hh" namespace OT { @@ -332,6 +333,27 @@ struct glyf_accelerator_t return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } + bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data) const + { + int xscale, yscale; + unsigned int upem; + + hb_font_get_scale (font, &xscale, &yscale); + upem = hb_face_get_upem (hb_font_get_face (font)); + + funcs->push_transform (data, xscale/(float)upem, 0, + 0, yscale/(float)upem, + 0, 0); + + funcs->push_clip_glyph (data, gid); + funcs->color (data, 0xffff, 1.); + funcs->pop_clip (data); + + funcs->pop_transform (data); + + return false; + } + const glyf_impl::Glyph glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const { From df89b52130ce85ed481f8672f051744b947df6a5 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 23:46:05 -0500 Subject: [PATCH 034/219] cff1: Implement paint_glyph --- src/hb-ot-cff1-table.cc | 21 +++++++++++++++++++++ src/hb-ot-cff1-table.hh | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index c2fb26547..65bf6d739 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -553,6 +553,27 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin return true; } +bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const +{ + int xscale, yscale; + unsigned int upem; + + hb_font_get_scale (font, &xscale, &yscale); + upem = hb_face_get_upem (hb_font_get_face (font)); + + funcs->push_transform (data, xscale/(float)upem, 0, + 0, yscale/(float)upem, + 0, 0); + + funcs->push_clip_glyph (data, glyph); + funcs->color (data, 0xffff, 1.); + funcs->pop_clip (data); + + funcs->pop_transform (data); + + return false; +} + bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const { #ifdef HB_NO_OT_FONT_CFF diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index bb856c9dd..3bc37d9bb 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -30,6 +30,7 @@ #include "hb-ot-cff-common.hh" #include "hb-subset-cff1.hh" #include "hb-draw.hh" +#include "hb-paint.hh" #define HB_STRING_ARRAY_NAME cff1_std_strings #define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh" @@ -1426,6 +1427,7 @@ struct cff1 } HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; + HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const; HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; From 3e39dd492bd566e55183ff4e2b136288dfd5458c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 23:46:15 -0500 Subject: [PATCH 035/219] cff2: Implement paint_glyph --- src/hb-ot-cff2-table.cc | 21 +++++++++++++++++++++ src/hb-ot-cff2-table.hh | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index d530fc2ee..a6bdfac8a 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -143,6 +143,27 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, return true; } +bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const +{ + int xscale, yscale; + unsigned int upem; + + hb_font_get_scale (font, &xscale, &yscale); + upem = hb_face_get_upem (hb_font_get_face (font)); + + funcs->push_transform (data, xscale/(float)upem, 0, + 0, yscale/(float)upem, + 0, 0); + + funcs->push_clip_glyph (data, glyph); + funcs->color (data, 0xffff, 1.); + funcs->pop_clip (data); + + funcs->pop_transform (data); + + return false; +} + struct cff2_path_param_t { cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_) diff --git a/src/hb-ot-cff2-table.hh b/src/hb-ot-cff2-table.hh index 9081930bb..ddfe2d7c9 100644 --- a/src/hb-ot-cff2-table.hh +++ b/src/hb-ot-cff2-table.hh @@ -30,6 +30,7 @@ #include "hb-ot-cff-common.hh" #include "hb-subset-cff2.hh" #include "hb-draw.hh" +#include "hb-paint.hh" namespace CFF { @@ -516,6 +517,7 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; + HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; }; From 9461ab70883c4fa0492f5f71c902cdabba627d4f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 23:46:45 -0500 Subject: [PATCH 036/219] Try paint_glyph for more tables If the COLR table can't paint the glyph, try glyf, cff1 and cff2 too. --- src/hb-ot-font.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 0975d5ac6..bbb9a5953 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -448,7 +448,12 @@ hb_ot_get_glyph_paint (hb_font_t *font, void *user_data) { #ifndef HB_NO_COLOR - font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data); + if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data)) return; +#endif + if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data)) return; +#ifndef HB_NO_CFF + if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data)) return; #endif } #endif From 56b02b6599168aec8743145021fbc9cec0163113 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 16 Dec 2022 23:58:37 -0500 Subject: [PATCH 037/219] Update the docs Mention that the color index will always be 0xFFFF when using hb_paint API with fonts that don't have color palettes. And add an outline about which kinds of glyphs require which callbacks. --- src/hb-paint.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index a65eb9505..0f674a3c3 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -48,7 +48,13 @@ HB_BEGIN_DECLS * * The callbacks also assume that the caller uses * hb_ot_color_palette_get_colors() to obtain colors - * from one of the fonts color palettes. + * from one of the fonts color palettes. If the font does + * not have color palettes, the color index will always + * be 0xFFFF, indicating the use of the foreground color. + * + * Not all callbacks are required for all kinds of glyphs. + * For rendering COLRv0 or non-color outline glyphs, the + * gradient and composite callbacks are not needed. * * Since: REPLACEME **/ From 82e23f322a5e58e8fe7e74069f90507c09694c93 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 00:33:59 -0500 Subject: [PATCH 038/219] paint: Add a paint-image callback This will be used for image blobs like pngs and svgs. FIXME: nail down and document sizing. --- src/hb-paint.cc | 12 ++++++++++++ src/hb-paint.h | 43 +++++++++++++++++++++++++++++++++++++++++++ src/hb-paint.hh | 6 ++++++ 3 files changed, 61 insertions(+) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 5b8ab2c4f..0da27af3d 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -68,6 +68,11 @@ hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, float alpha, void *user_data) {} +static void +hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + void *user_data) {} + static void hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, @@ -337,6 +342,13 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, funcs->color (paint_data, color_index, alpha); } +void +hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph) +{ + funcs->image (paint_data, glyph); +} + void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, diff --git a/src/hb-paint.h b/src/hb-paint.h index 0f674a3c3..d2aee3b35 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -56,6 +56,9 @@ HB_BEGIN_DECLS * For rendering COLRv0 or non-color outline glyphs, the * gradient and composite callbacks are not needed. * + * The paint-image callback is only needed for glyphs + * with blobs in the CBDT, sbix or SVG tables. + * * Since: REPLACEME **/ typedef struct hb_paint_funcs_t hb_paint_funcs_t; @@ -218,6 +221,25 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, float alpha, void *user_data); +/** + * hb_paint_image_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions + * @glyph: the glyph ID + * @user_data: user data passed to the hb_font_paint_glyph() call + * + * A virtual method for the #hb_paint_funcs_t to paint the + * glyph image. + * + * This method is intended for glyphs with image blobs in the CBDT, + * sbix or SVG tables. + * + * Since: REPLACEME + */ +typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data); /** * hb_color_line_t: @@ -532,6 +554,23 @@ hb_paint_funcs_set_color_func (hb_paint_funcs_t *funcs, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_image_func: + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The paint-image callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the paint-image callback on the paint functions struct. + * + * Since: REPLACEME + */ +HB_EXTERN void +hb_paint_funcs_set_image_func (hb_paint_funcs_t *funcs, + hb_paint_image_func_t func, + void *user_data, + hb_destroy_func_t destroy); + /** * hb_paint_funcs_set_linear_gradient_func: * @funcs: A paint functions struct @@ -643,6 +682,10 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha); +HB_EXTERN void +hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph); + HB_EXTERN void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 58d0da7fd..adf4c8696 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -34,6 +34,7 @@ HB_PAINT_FUNC_IMPLEMENT (push_clip_rect) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ HB_PAINT_FUNC_IMPLEMENT (color) \ + HB_PAINT_FUNC_IMPLEMENT (image) \ HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \ HB_PAINT_FUNC_IMPLEMENT (radial_gradient) \ HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \ @@ -92,6 +93,11 @@ struct hb_paint_funcs_t { func.color (this, paint_data, color_index, alpha, !user_data ? nullptr : user_data->color); } + void image (void *paint_data, + hb_codepoint_t glyph) + { func.image (this, paint_data, + glyph, + !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, From 7996ae4c3d4d99066efa738a8ddca3851ff94ec5 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 01:04:00 -0500 Subject: [PATCH 039/219] CBDT: Implement paint glyph --- src/hb-ot-color-cbdt-table.hh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 4f8fa0123..c5946934b 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -28,6 +28,7 @@ #define HB_OT_COLOR_CBDT_TABLE_HH #include "hb-open-type.hh" +#include "hb-paint.hh" /* * CBLC -- Color Bitmap Location @@ -936,6 +937,18 @@ struct CBDT bool has_data () const { return cbdt.get_length (); } + bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const + { + hb_blob_t *blob = reference_png (font, glyph); + if (unlikely (blob == hb_blob_get_empty ())) + return false; + + funcs->image (data, glyph); + + hb_blob_destroy (blob); + return true; + } + private: hb_blob_ptr_t cblc; hb_blob_ptr_t cbdt; From 23c60fd9b293f09461926f47cdd0779af766aff8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 01:04:23 -0500 Subject: [PATCH 040/219] sbix: Implement paint_glyph --- src/hb-ot-color-sbix-table.hh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 1d1d2e89d..d874e790b 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" +#include "hb-paint.hh" /* * sbix -- Standard Bitmap Graphics @@ -231,6 +232,24 @@ struct sbix num_glyphs, available_ppem); } + bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const + { + if (!has_data ()) + return false; + + int x_offset = 0, y_offset = 0; + unsigned int strike_ppem = 0; + hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); + + if (blob == hb_blob_get_empty ()) + return false; + + funcs->image (data, glyph); + + hb_blob_destroy (blob); + return true; + } + private: const SBIXStrike &choose_strike (hb_font_t *font) const From e6c5a616aaf081d0603a6f6e74be66d89c2b1832 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 02:13:38 -0500 Subject: [PATCH 041/219] SVG Implement paint-glyph --- src/hb-ot-color-svg-table.hh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index fc649f100..427af9945 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -26,6 +26,8 @@ #define HB_OT_COLOR_SVG_TABLE_HH #include "hb-open-type.hh" +#include "hb-blob.hh" +#include "hb-paint.hh" /* * SVG -- SVG (Scalable Vector Graphics) @@ -91,8 +93,26 @@ struct SVG bool has_data () const { return table->has_data (); } + bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const + { + if (!has_data ()) + return false; + + hb_blob_t *blob = reference_blob_for_glyph (glyph); + + if (blob == hb_blob_get_empty ()) + return false; + + funcs->image (data, glyph); + + hb_blob_destroy (blob); + return true; + } + private: hb_blob_ptr_t table; + public: + DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t)); }; const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const From 6079173a5229b8f51a0ee15f4e4ea957f1e2e722 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 01:04:35 -0500 Subject: [PATCH 042/219] Try paint_glyph for more tables If the COLR table does not paint the glyph, try SVG, CBDT and sbix too, before giving up on color. --- src/hb-ot-font.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index bbb9a5953..055462f4d 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -46,6 +46,7 @@ #include "hb-ot-color-cbdt-table.hh" #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-svg-table.hh" /** @@ -449,6 +450,11 @@ hb_ot_get_glyph_paint (hb_font_t *font, { #ifndef HB_NO_COLOR if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return; +#ifndef HB_NO_OT_FONT_BITMAP + if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; +#endif #endif if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data)) return; #ifndef HB_NO_CFF From 9876e30c6ee8fc53ae4d26692b9482e6011d04a5 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 02:46:37 -0500 Subject: [PATCH 043/219] test: Support png images via paint_image --- util/hb-test.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/util/hb-test.c b/util/hb-test.c index ebf01e5b2..666a350dc 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -294,6 +295,63 @@ paint_color (hb_paint_funcs_t *funcs, cairo_paint (data->cr); } +typedef struct +{ + hb_blob_t *blob; + unsigned int offset; +} read_blob_data_t; + +cairo_status_t +read_blob (void *closure, + unsigned char *data, + unsigned int length) +{ + read_blob_data_t *r = closure; + const char *d; + unsigned int size; + + d = hb_blob_get_data (r->blob, &size); + + if (r->offset + length > size) + return CAIRO_STATUS_READ_ERROR; + + memcpy (data, d + r->offset, length); + r->offset += length; + + return CAIRO_STATUS_SUCCESS; +} + +static void +paint_image (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data) +{ + paint_data_t *data = user_data; + read_blob_data_t r; + cairo_surface_t *surface; + cairo_pattern_t *pattern; + cairo_matrix_t m; + hb_glyph_extents_t extents; + + hb_font_get_glyph_extents (data->font, glyph, &extents); + r.blob = hb_ot_color_glyph_reference_png (data->font, glyph); + r.offset = 0; + surface = cairo_image_surface_create_from_png_stream (read_blob, &r); + hb_blob_destroy (r.blob); + + pattern = cairo_pattern_create_for_surface (surface); + cairo_matrix_init_scale (&m, 1, -1); + cairo_matrix_translate (&m, extents.x_bearing, - extents.y_bearing); + cairo_pattern_set_matrix (pattern, &m); + cairo_set_source (data->cr, pattern); + + cairo_paint (data->cr); + + cairo_pattern_destroy (pattern); + cairo_surface_destroy (surface); +} + static void reduce_anchors (float x0, float y0, float x1, float y1, @@ -1008,6 +1066,7 @@ int main (int argc, char *argv[]) hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); hb_paint_funcs_set_color_func (funcs, paint_color, &data, NULL); + hb_paint_funcs_set_image_func (funcs, paint_image, &data, NULL); hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, &data, NULL); hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, &data, NULL); hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, &data, NULL); From 378bbeea015f492756cbe7ffc39e6144a0ffe5ee Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 10:02:30 -0500 Subject: [PATCH 044/219] Add more docs --- src/hb-font.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/hb-font.cc b/src/hb-font.cc index 078a84354..e8c63af98 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1388,6 +1388,21 @@ hb_font_get_glyph_shape (hb_font_t *font, font->get_glyph_shape (glyph, dfuncs, draw_data); } +/** + * hb_font_paint_glyph: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID + * @funcs: #hb_paint_funcs_t to paint with + * @paint_data: User data to pass to paint callbacks + * + * Paints the glyph. + * + * The painting instructions are returned by way of + * calls to the callbacks of the @funcs objects, + * with @paint_data passed to them. + * + * Since: REPLACEME + */ void hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, From 1953d26a8a9cc0e70055c8cf5e8e876d7b6ac664 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 08:59:33 -0700 Subject: [PATCH 045/219] [colr] Limit recursion depth --- src/hb-ot-color-colr-table.hh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index aeb8b02ae..5b950e1ae 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -70,6 +70,7 @@ public: hb_paint_funcs_t *funcs; void *data; VarStoreInstancer &instancer; + int depth_left = HB_COLRV1_MAX_NESTING_LEVEL; hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, @@ -2033,7 +2034,10 @@ struct COLR_accelerator_t : COLR::accelerator_t { void hb_paint_context_t::recurse (const Paint &paint) { - paint.dispatch (this); + depth_left--; + if (depth_left > 0) + paint.dispatch (this); + depth_left++; } } /* namespace OT */ From e799c33bb59b8699a6c6b0f43e7e5854515c5075 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 09:00:20 -0700 Subject: [PATCH 046/219] [paint] Fix function prototype --- src/hb-paint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index d2aee3b35..e20ca737d 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -64,7 +64,7 @@ HB_BEGIN_DECLS typedef struct hb_paint_funcs_t hb_paint_funcs_t; HB_EXTERN hb_paint_funcs_t * -hb_paint_funcs_create (); +hb_paint_funcs_create (void); HB_EXTERN hb_paint_funcs_t * hb_paint_funcs_reference (hb_paint_funcs_t *funcs); From 8a9069d55fdfe738103a2fea83317a7fd1857727 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 09:21:08 -0700 Subject: [PATCH 047/219] [colr] Fix radial gradient Broke it when adding variations. --- src/hb-ot-color-colr-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 5b950e1ae..b4efb9639 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -630,9 +630,9 @@ struct PaintRadialGradient c->funcs->radial_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), y0 + c->instancer (varIdxBase, 1), + radius0 + c->instancer (varIdxBase, 2), x1 + c->instancer (varIdxBase, 3), y1 + c->instancer (varIdxBase, 4), - radius0 + c->instancer (varIdxBase, 2), radius1 + c->instancer (varIdxBase, 5)); } From 601a596ca0837e36b45e117f70a5b7072c30d4e8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 09:22:55 -0700 Subject: [PATCH 048/219] [paint] Fix include path --- src/OT/glyf/glyf.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index 9c343ea6b..5d6705a6c 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -7,13 +7,13 @@ #include "../../hb-ot-hmtx-table.hh" #include "../../hb-ot-var-gvar-table.hh" #include "../../hb-draw.hh" +#include "../../hb-paint.hh" #include "glyf-helpers.hh" #include "Glyph.hh" #include "SubsetGlyph.hh" #include "loca.hh" #include "path-builder.hh" -#include "hb-paint.hh" namespace OT { From 452cfb95997cbc0a81f5533e1fa365cbf6888157 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 10:04:55 -0700 Subject: [PATCH 049/219] [colr] Simplify loop using iterators Or complexify?! --- src/hb-ot-color-colr-table.hh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index b4efb9639..71f669638 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1991,13 +1991,11 @@ struct COLR 0, yscale/(float)upem, 0, 0); - hb_array_t all_layers = (this+layersZ).as_array (numLayers); - for (unsigned int i = 0; i < record->numLayers; i++) + for (const auto &r : (this+layersZ).as_array (numLayers) + .sub_array (record->firstLayerIdx, record->numLayers)) { - const LayerRecord *r = &all_layers[record->firstLayerIdx + i]; - - c.funcs->push_clip_glyph (c.data, r->glyphId); - c.funcs->color (c.data, r->colorIdx, 1.); + c.funcs->push_clip_glyph (c.data, r.glyphId); + c.funcs->color (c.data, r.colorIdx, 1.); c.funcs->pop_clip (c.data); } From b722039c48b41c1e96c7a1bcbad072a2332d4e46 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 10:22:32 -0700 Subject: [PATCH 050/219] [colr] Simplify --- src/hb-ot-color-colr-table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 62f1319fb..e469fa25b 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -7,7 +7,7 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { - const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i]; + const Paint &paint = paint_offset_lists.get_paint (i); c->funcs->push_group (c->data); c->recurse (paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); From ea48d6c292bd248a6607a0cfe1d17f05fc4f018f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 11:51:37 -0500 Subject: [PATCH 051/219] Move hb_glyph_extents_t definition --- src/hb-common.h | 18 ++++++++++++++++++ src/hb-font.h | 20 +------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index e92feb989..7d72457a6 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -897,6 +897,24 @@ HB_EXTERN uint8_t hb_color_get_blue (hb_color_t color); #define hb_color_get_blue(color) (((color) >> 24) & 0xFF) +/** + * hb_glyph_extents_t: + * @x_bearing: Distance from the x-origin to the left extremum of the glyph. + * @y_bearing: Distance from the top extremum of the glyph to the y-origin. + * @width: Distance from the left extremum of the glyph to the right extremum. + * @height: Distance from the top extremum of the glyph to the bottom extremum. + * + * Glyph extent values, measured in font units. + * + * Note that @height is negative, in coordinate systems that grow up. + **/ +typedef struct hb_glyph_extents_t { + hb_position_t x_bearing; + hb_position_t y_bearing; + hb_position_t width; + hb_position_t height; +} hb_glyph_extents_t; + HB_END_DECLS #endif /* HB_COMMON_H */ diff --git a/src/hb-font.h b/src/hb-font.h index 69f011d68..5da4dc3db 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -98,7 +98,7 @@ HB_EXTERN hb_bool_t hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); -/* font and glyph extents */ +/* font extents */ /** * hb_font_extents_t: @@ -127,24 +127,6 @@ typedef struct hb_font_extents_t { hb_position_t reserved1; } hb_font_extents_t; -/** - * hb_glyph_extents_t: - * @x_bearing: Distance from the x-origin to the left extremum of the glyph. - * @y_bearing: Distance from the top extremum of the glyph to the y-origin. - * @width: Distance from the left extremum of the glyph to the right extremum. - * @height: Distance from the top extremum of the glyph to the bottom extremum. - * - * Glyph extent values, measured in font units. - * - * Note that @height is negative, in coordinate systems that grow up. - **/ -typedef struct hb_glyph_extents_t { - hb_position_t x_bearing; - hb_position_t y_bearing; - hb_position_t width; - hb_position_t height; -} hb_glyph_extents_t; - /* func types */ /** From 37f3f0fcc25ed5cc0ea822b1a780705ab842d7bd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 11:49:18 -0500 Subject: [PATCH 052/219] [paint] Change the image callback Instead of passing the glyph ID, give it the image blob, a mimetype, and glyph extents (if available). Update all callers. --- src/hb-ot-color-cbdt-table.hh | 6 +++++- src/hb-ot-color-sbix-table.hh | 6 +++++- src/hb-ot-color-svg-table.hh | 2 +- src/hb-paint.cc | 10 +++++++--- src/hb-paint.h | 18 ++++++++++++++---- src/hb-paint.hh | 6 ++++-- util/hb-test.c | 16 ++++++++++------ 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index c5946934b..66c083460 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -939,11 +939,15 @@ struct CBDT bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + hb_glyph_extents_t extents; hb_blob_t *blob = reference_png (font, glyph); if (unlikely (blob == hb_blob_get_empty ())) return false; - funcs->image (data, glyph); + if (unlikely (!get_extents (font, glyph, &extents))) + return false; + + funcs->image (data, blob, "image/png", &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index d874e790b..ef96b226c 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -240,11 +240,15 @@ struct sbix int x_offset = 0, y_offset = 0; unsigned int strike_ppem = 0; hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); + hb_glyph_extents_t extents; if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, glyph); + if (!get_extents (font, glyph, &extents)) + return false; + + funcs->image (data, blob, "image/png", &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 427af9945..b13b485c3 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,7 +103,7 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, glyph); + funcs->image (data, blob, "image/svg+xml", nullptr); hb_blob_destroy (blob); return true; diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 0da27af3d..7ef805376 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -70,7 +70,9 @@ hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, static void hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph, + hb_blob_t *image, + const char *mimetype, + hb_glyph_extents_t *extents, void *user_data) {} static void @@ -344,9 +346,11 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph) + hb_blob_t *image, + const char *mimetype, + hb_glyph_extents_t *extents) { - funcs->image (paint_data, glyph); + funcs->image (paint_data, image, mimetype, extents); } void diff --git a/src/hb-paint.h b/src/hb-paint.h index e20ca737d..ac990a11e 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -30,6 +30,7 @@ #define HB_PAINT_H #include "hb.h" +#include "hb-font.h" HB_BEGIN_DECLS @@ -225,20 +226,27 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * hb_paint_image_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions - * @glyph: the glyph ID + * @image: the image data + * @mimetype: the mime type for the image data + * @extents: (nullable): glyph extents * @user_data: user data passed to the hb_font_paint_glyph() call * * A virtual method for the #hb_paint_funcs_t to paint the * glyph image. * * This method is intended for glyphs with image blobs in the CBDT, - * sbix or SVG tables. + * sbix or SVG tables. The @mimetype identifies the kind of data + * that is contained in @image. Possible values include "image/png" + * and "image/svg+xml". The glyph extents are provided if available, + * and should be used to position the image. * * Since: REPLACEME */ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph, + hb_blob_t *image, + const char *mimetype, + hb_glyph_extents_t *extents, void *user_data); /** @@ -684,7 +692,9 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph); + hb_blob_t *image, + const char *mimetype, + hb_glyph_extents_t *extents); HB_EXTERN void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, diff --git a/src/hb-paint.hh b/src/hb-paint.hh index adf4c8696..7eaf8592e 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -94,9 +94,11 @@ struct hb_paint_funcs_t color_index, alpha, !user_data ? nullptr : user_data->color); } void image (void *paint_data, - hb_codepoint_t glyph) + hb_blob_t *image, + const char *mimetype, + hb_glyph_extents_t *extents) { func.image (this, paint_data, - glyph, + image, mimetype, extents, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, diff --git a/util/hb-test.c b/util/hb-test.c index 666a350dc..6708f87ba 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -324,7 +324,9 @@ read_blob (void *closure, static void paint_image (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph, + hb_blob_t *blob, + const char *mimetype, + hb_glyph_extents_t *extents, void *user_data) { paint_data_t *data = user_data; @@ -332,17 +334,19 @@ paint_image (hb_paint_funcs_t *funcs, cairo_surface_t *surface; cairo_pattern_t *pattern; cairo_matrix_t m; - hb_glyph_extents_t extents; - hb_font_get_glyph_extents (data->font, glyph, &extents); - r.blob = hb_ot_color_glyph_reference_png (data->font, glyph); + if (strcmp (mimetype, "image/png") != 0) + return; + + r.blob = blob; r.offset = 0; surface = cairo_image_surface_create_from_png_stream (read_blob, &r); - hb_blob_destroy (r.blob); pattern = cairo_pattern_create_for_surface (surface); cairo_matrix_init_scale (&m, 1, -1); - cairo_matrix_translate (&m, extents.x_bearing, - extents.y_bearing); + cairo_matrix_translate (&m, + extents ? extents->x_bearing : 0, + extents ? - extents->y_bearing : 0); cairo_pattern_set_matrix (pattern, &m); cairo_set_source (data->cr, pattern); From 485ba9beb36d16f91330f50fa6f403cdb192f294 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 12:25:04 -0500 Subject: [PATCH 053/219] [paint] Spell out rectangle in the API No need to abbreviate this. --- src/hb-paint.cc | 12 ++++++------ src/hb-paint.h | 32 ++++++++++++++++---------------- src/hb-paint.hh | 12 ++++++------ util/hb-test.c | 12 ++++++------ 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 7ef805376..ac5312148 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -54,9 +54,9 @@ hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) {} static void -hb_paint_push_clip_rect_nil (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, float xmax, float ymax, - void *user_data) {} +hb_paint_push_clip_rectangle_nil (hb_paint_funcs_t *funcs, void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) {} static void hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, @@ -324,10 +324,10 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, } void -hb_paint_push_clip_rect (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, float xmax, float ymax) +hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, + float xmin, float ymin, float xmax, float ymax) { - funcs->push_clip_rect (paint_data, xmin, ymin, xmax, ymax); + funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax); } void diff --git a/src/hb-paint.h b/src/hb-paint.h index ac990a11e..ecedcf829 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -153,7 +153,7 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, void *user_data); /** - * hb_paint_push_clip_rect_func_t: + * hb_paint_push_clip_rectangle_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions * @xmin: min X for the rectangle @@ -174,11 +174,11 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, * * Since: REPLACEME */ -typedef void (*hb_paint_push_clip_rect_func_t) (hb_paint_funcs_t *funcs, - void *paint_data, - float xmin, float ymin, - float xmax, float ymax, - void *user_data); +typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + float xmin, float ymin, + float xmax, float ymax, + void *user_data); /** * hb_paint_pop_clip_func_t: @@ -188,7 +188,7 @@ typedef void (*hb_paint_push_clip_rect_func_t) (hb_paint_funcs_t *funcs, * * A virtual method for the #hb_paint_funcs_t to undo * the effect of a prior call to the #hb_paint_funcs_push_clip_glyph_func_t - * or #hb_paint_funcs_push_clip_rect_func_t vfuncs. + * or #hb_paint_funcs_push_clip_rectangle_func_t vfuncs. * * Since: REPLACEME */ @@ -512,9 +512,9 @@ hb_paint_funcs_set_push_clip_glyph_func (hb_paint_funcs_t *funcs, hb_destroy_func_t destroy); /** - * hb_paint_funcs_set_push_clip_rect_func: + * hb_paint_funcs_set_push_clip_rectangle_func: * @funcs: A paint functions struct - * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-rect callback + * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-rectangle callback * @user_data: Data to pass to @func * @destroy: (nullable): Function to call when @user_data is no longer needed * @@ -523,10 +523,10 @@ hb_paint_funcs_set_push_clip_glyph_func (hb_paint_funcs_t *funcs, * Since: REPLACEME */ HB_EXTERN void -hb_paint_funcs_set_push_clip_rect_func (hb_paint_funcs_t *funcs, - hb_paint_push_clip_rect_func_t func, - void *user_data, - hb_destroy_func_t destroy); +hb_paint_funcs_set_push_clip_rectangle_func (hb_paint_funcs_t *funcs, + hb_paint_push_clip_rectangle_func_t func, + void *user_data, + hb_destroy_func_t destroy); /** * hb_paint_funcs_set_pop_clip_func: @@ -678,9 +678,9 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph); HB_EXTERN void -hb_paint_push_clip_rect (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, - float xmax, float ymax); +hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, + float xmin, float ymin, + float xmax, float ymax); HB_EXTERN void hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 7eaf8592e..c177e9c62 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -31,7 +31,7 @@ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ HB_PAINT_FUNC_IMPLEMENT (pop_transform) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \ - HB_PAINT_FUNC_IMPLEMENT (push_clip_rect) \ + HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ HB_PAINT_FUNC_IMPLEMENT (color) \ HB_PAINT_FUNC_IMPLEMENT (image) \ @@ -79,11 +79,11 @@ struct hb_paint_funcs_t { func.push_clip_glyph (this, paint_data, glyph, !user_data ? nullptr : user_data->push_clip_glyph); } - void push_clip_rect (void *paint_data, - float xmin, float ymin, float xmax, float ymax) - { func.push_clip_rect (this, paint_data, - xmin, ymin, xmax, ymax, - !user_data ? nullptr : user_data->push_clip_rect); } + void push_clip_rectangle (void *paint_data, + float xmin, float ymin, float xmax, float ymax) + { func.push_clip_rectangle (this, paint_data, + xmin, ymin, xmax, ymax, + !user_data ? nullptr : user_data->push_clip_rectangle); } void pop_clip (void *paint_data) { func.pop_clip (this, paint_data, !user_data ? nullptr : user_data->pop_clip); } diff --git a/util/hb-test.c b/util/hb-test.c index 6708f87ba..c993b499e 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -245,14 +245,14 @@ push_clip_glyph (hb_paint_funcs_t *funcs, } static void -push_clip_rect (hb_paint_funcs_t *funcs, - void *paint_data, - float xmin, float ymin, float xmax, float ymax, - void *user_data) +push_clip_rectangle (hb_paint_funcs_t *funcs, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) { paint_data_t *data = user_data; - print (data, "start clip rect %f %f %f %f", xmin, ymin, xmax, ymax); + print (data, "start clip rectangle %f %f %f %f", xmin, ymin, xmax, ymax); data->level++; cairo_save (data->cr); @@ -1065,7 +1065,7 @@ int main (int argc, char *argv[]) hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, &data, NULL); - hb_paint_funcs_set_push_clip_rect_func (funcs, push_clip_rect, &data, NULL); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, &data, NULL); hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); From c6dd56cc64d08defd661b3152a1ecd9b4b786db4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 10:38:23 -0700 Subject: [PATCH 054/219] [colr] Simplify color-stop handling --- src/hb-ot-color-colr-table.cc | 42 ++++++------------------------ src/hb-ot-color-colr-table.hh | 49 +++++++---------------------------- 2 files changed, 17 insertions(+), 74 deletions(-) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index e469fa25b..2172eb61c 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -31,43 +31,17 @@ hb_color_line_get_color_stops (hb_color_line_t *cl, unsigned int *count, hb_color_stop_t *color_stops) { - switch (cl->format) - { - case 4: - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); - case 5: - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); - case 6: - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); - case 7: - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); - case 8: - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); - case 9: - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); - default: assert (0); - } - return 0; + if (cl->is_variable) + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + else + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); } hb_paint_extend_t hb_color_line_get_extend (hb_color_line_t *cl) { - switch (cl->format) - { - case 4: - return reinterpret_cast *>(cl->base)->get_extend (); - case 5: - return reinterpret_cast *>(cl->base)->get_extend (); - case 6: - return reinterpret_cast *>(cl->base)->get_extend (); - case 7: - return reinterpret_cast *>(cl->base)->get_extend (); - case 8: - return reinterpret_cast *>(cl->base)->get_extend (); - case 9: - return reinterpret_cast *>(cl->base)->get_extend (); - default: assert (0); - } - return HB_PAINT_EXTEND_PAD; + if (cl->is_variable) + return reinterpret_cast *>(cl->base)->get_extend (); + else + return reinterpret_cast *>(cl->base)->get_extend (); } diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 71f669638..4fd1e2baf 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -44,9 +44,10 @@ #define HB_COLRV1_MAX_NESTING_LEVEL 128 #endif + struct hb_color_line_t { const void *base; - OT::HBUINT8 format; + bool is_variable; }; namespace OT { @@ -200,6 +201,8 @@ struct BaseGlyphRecord template struct Variable { + static constexpr bool is_variable = true; + Variable* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); @@ -248,6 +251,8 @@ struct Variable template struct NoVariable { + static constexpr bool is_variable = false; + static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION; NoVariable* copy (hb_serialize_context_t *c) const @@ -566,7 +571,7 @@ struct PaintLinearGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { this, format }; + hb_color_line_t cl = { &(this+colorLine), Var>::is_variable }; c->funcs->linear_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -577,18 +582,6 @@ struct PaintLinearGradient y2 + c->instancer (varIdxBase, 5)); } - unsigned int get_color_stops (unsigned int start, - unsigned int *count, - hb_color_stop_t *stops) const - { - return (this+colorLine).get_color_stops (start, count, stops); - } - - hb_paint_extend_t get_extend () const - { - return (this+colorLine).get_extend (); - } - HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintLinearGradient * table) to ColorLine subtable. */ @@ -625,7 +618,7 @@ struct PaintRadialGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { this, format }; + hb_color_line_t cl = { &(this+colorLine), Var>::is_variable }; c->funcs->radial_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -636,18 +629,6 @@ struct PaintRadialGradient radius1 + c->instancer (varIdxBase, 5)); } - unsigned int get_color_stops (unsigned int start, - unsigned int *count, - hb_color_stop_t *stops) const - { - return (this+colorLine).get_color_stops (start, count, stops); - } - - hb_paint_extend_t get_extend () const - { - return (this+colorLine).get_extend (); - } - HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintRadialGradient * table) to ColorLine subtable. */ @@ -684,7 +665,7 @@ struct PaintSweepGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { this, format }; + hb_color_line_t cl = { &(this+colorLine), Var>::is_variable }; c->funcs->sweep_gradient (c->data, &cl, centerX + c->instancer (varIdxBase, 0), @@ -693,18 +674,6 @@ struct PaintSweepGradient (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI); } - unsigned int get_color_stops (unsigned int start, - unsigned int *count, - hb_color_stop_t *stops) const - { - return (this+colorLine).get_color_stops (start, count, stops); - } - - hb_paint_extend_t get_extend () const - { - return (this+colorLine).get_extend (); - } - HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintSweepGradient * table) to ColorLine subtable. */ From 686e627bdf1ef28f0ced44c146d0b3cd7f2def33 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 12:44:16 -0500 Subject: [PATCH 055/219] [paint] Set up root transform in one place Instead of spreading this in all the tables, make hb_paint_funcs_t provide a push/pop_root_transform that does all the setup. --- src/OT/glyf/glyf.hh | 12 ++---------- src/hb-ot-cff1-table.cc | 12 ++---------- src/hb-ot-cff2-table.cc | 12 ++---------- src/hb-ot-color-colr-table.hh | 20 ++++---------------- src/hb-paint.hh | 12 ++++++++++++ 5 files changed, 22 insertions(+), 46 deletions(-) diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index 5d6705a6c..644b064ce 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -335,21 +335,13 @@ struct glyf_accelerator_t bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data) const { - int xscale, yscale; - unsigned int upem; - - hb_font_get_scale (font, &xscale, &yscale); - upem = hb_face_get_upem (hb_font_get_face (font)); - - funcs->push_transform (data, xscale/(float)upem, 0, - 0, yscale/(float)upem, - 0, 0); + funcs->push_root_transform (data, font); funcs->push_clip_glyph (data, gid); funcs->color (data, 0xffff, 1.); funcs->pop_clip (data); - funcs->pop_transform (data); + funcs->pop_root_transform (data); return false; } diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 65bf6d739..76a66f0c9 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -555,21 +555,13 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { - int xscale, yscale; - unsigned int upem; - - hb_font_get_scale (font, &xscale, &yscale); - upem = hb_face_get_upem (hb_font_get_face (font)); - - funcs->push_transform (data, xscale/(float)upem, 0, - 0, yscale/(float)upem, - 0, 0); + funcs->push_root_transform (data, font); funcs->push_clip_glyph (data, glyph); funcs->color (data, 0xffff, 1.); funcs->pop_clip (data); - funcs->pop_transform (data); + funcs->pop_root_transform (data); return false; } diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index a6bdfac8a..983305c22 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -145,21 +145,13 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { - int xscale, yscale; - unsigned int upem; - - hb_font_get_scale (font, &xscale, &yscale); - upem = hb_face_get_upem (hb_font_get_face (font)); - - funcs->push_transform (data, xscale/(float)upem, 0, - 0, yscale/(float)upem, - 0, 0); + funcs->push_root_transform (data, font); funcs->push_clip_glyph (data, glyph); funcs->color (data, 0xffff, 1.); funcs->pop_clip (data); - funcs->pop_transform (data); + funcs->pop_root_transform (data); return false; } diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 4fd1e2baf..815b11549 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1929,24 +1929,15 @@ struct COLR hb_paint_context_t c (this, funcs, data, instancer); - int xscale, yscale; - unsigned int upem; - - hb_font_get_scale (font, &xscale, &yscale); - upem = hb_face_get_upem (hb_font_get_face (font)); - const Paint *paint = get_base_glyph_paint (glyph); if (paint) { // COLRv1 glyph - // FIXME handle slant - funcs->push_transform (data, xscale/(float)upem, 0, - 0, yscale/(float)upem, - 0, 0); + c.funcs->push_root_transform (data, font); c.recurse (*paint); - c.funcs->pop_transform (c.data); + c.funcs->pop_root_transform (c.data); return true; } @@ -1955,10 +1946,7 @@ struct COLR if (record && ((hb_codepoint_t) record->glyphId == glyph)) { // COLRv0 glyph - // FIXME handle slant - funcs->push_transform (data, xscale/(float)upem, 0, - 0, yscale/(float)upem, - 0, 0); + funcs->push_root_transform (data, font); for (const auto &r : (this+layersZ).as_array (numLayers) .sub_array (record->firstLayerIdx, record->numLayers)) @@ -1968,7 +1956,7 @@ struct COLR c.funcs->pop_clip (c.data); } - c.funcs->pop_transform (c.data); + c.funcs->pop_root_transform (c.data); return true; } diff --git a/src/hb-paint.hh b/src/hb-paint.hh index c177e9c62..e97072e4c 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -132,6 +132,18 @@ struct hb_paint_funcs_t mode, !user_data ? nullptr : user_data->pop_group); } + void push_root_transform (void *paint_data, + hb_font_t *font) + { + int xscale, yscale; + float upem; + hb_font_get_scale (font, &xscale, &yscale); + upem = hb_face_get_upem (hb_font_get_face (font)); + func.push_transform (this, paint_data, xscale/upem, 0, 0, yscale/upem, 0, 0, + !user_data ? nullptr : user_data->push_transform); } + void pop_root_transform (void *paint_data) + { func.pop_transform (this, paint_data, + !user_data ? nullptr : user_data->pop_transform); } }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); From edf27382630a30070a33d9f65f005741fb15d95b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 10:47:55 -0700 Subject: [PATCH 056/219] [colr] Try fixing bot build I don't get the error. Let's see. ../../src/harfbuzz/src/hb-ot-color-colr-table.hh:574:66: error: incomplete definition of type 'OT::NoVariable>' --- src/hb-ot-color-colr-table.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 815b11549..ab968e188 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -571,7 +571,7 @@ struct PaintLinearGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { &(this+colorLine), Var>::is_variable }; + hb_color_line_t cl = { &(this+colorLine), Var::is_variable }; c->funcs->linear_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -618,7 +618,7 @@ struct PaintRadialGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { &(this+colorLine), Var>::is_variable }; + hb_color_line_t cl = { &(this+colorLine), Var::is_variable }; c->funcs->radial_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -665,7 +665,7 @@ struct PaintSweepGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { &(this+colorLine), Var>::is_variable }; + hb_color_line_t cl = { &(this+colorLine), Var::is_variable }; c->funcs->sweep_gradient (c->data, &cl, centerX + c->instancer (varIdxBase, 0), From a935e4b0c256451f50b2c0886f4fed5152735b62 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 12:59:58 -0500 Subject: [PATCH 057/219] [paint] Add synthetic slant to root transform --- src/hb-paint.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-paint.hh b/src/hb-paint.hh index e97072e4c..47088b41c 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -136,10 +136,11 @@ struct hb_paint_funcs_t hb_font_t *font) { int xscale, yscale; - float upem; + float upem, slant; hb_font_get_scale (font, &xscale, &yscale); + slant = hb_font_get_synthetic_slant (font); upem = hb_face_get_upem (hb_font_get_face (font)); - func.push_transform (this, paint_data, xscale/upem, 0, 0, yscale/upem, 0, 0, + func.push_transform (this, paint_data, xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0, !user_data ? nullptr : user_data->push_transform); } void pop_root_transform (void *paint_data) { func.pop_transform (this, paint_data, From b9314400eccb2dadce788f6af5d843d5341f2c11 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 10:58:52 -0700 Subject: [PATCH 058/219] [colr] Hook up color-line variation --- src/hb-ot-color-colr-table.cc | 4 ++-- src/hb-ot-color-colr-table.hh | 37 +++++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 2172eb61c..ff6c4714b 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -32,9 +32,9 @@ hb_color_line_get_color_stops (hb_color_line_t *cl, hb_color_stop_t *color_stops) { if (cl->is_variable) - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops, cl->c->instancer); else - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops); + return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops, cl->c->instancer); } hb_paint_extend_t diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index ab968e188..3dc7c6f6a 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -45,7 +45,12 @@ #endif +namespace OT { +struct hb_paint_context_t; +} + struct hb_color_line_t { + struct OT::hb_paint_context_t *c; const void *base; bool is_variable; }; @@ -230,9 +235,10 @@ struct Variable value.paint_glyph (c, varIdxBase); } - void get_color_stop (hb_color_stop_t *c) const + void get_color_stop (hb_color_stop_t *c, + const VarStoreInstancer &instancer) const { - value.get_color_stop (c); + value.get_color_stop (c, varIdxBase, instancer); } hb_paint_extend_t get_extend () const @@ -281,9 +287,10 @@ struct NoVariable value.paint_glyph (c, varIdxBase); } - void get_color_stop (hb_color_stop_t *c) const + void get_color_stop (hb_color_stop_t *c, + const VarStoreInstancer &instancer) const { - value.get_color_stop (c); + value.get_color_stop (c, VarIdx::NO_VARIATION, instancer); } hb_paint_extend_t get_extend () const @@ -318,11 +325,13 @@ struct ColorStop return_trace (c->check_struct (this)); } - void get_color_stop (hb_color_stop_t *out) const + void get_color_stop (hb_color_stop_t *out, + uint32_t varIdx, + const VarStoreInstancer &instancer) const { - out->offset = stopOffset.to_float(); + out->offset = stopOffset.to_float(instancer (varIdx, 0)); out->color_index = paletteIndex; - out->alpha = alpha.to_float(); + out->alpha = alpha.to_float(instancer (varIdx, 1)); } F2DOT14 stopOffset; @@ -379,8 +388,9 @@ struct ColorLine /* get up to count stops from start */ unsigned int get_color_stops (unsigned int start, - unsigned int *count, - hb_color_stop_t *color_stops) const + unsigned int *count, + hb_color_stop_t *color_stops, + const VarStoreInstancer &instancer) const { unsigned int len = stops.len; @@ -388,7 +398,8 @@ struct ColorLine { unsigned int i; for (i = 0; i < *count && start + i < len; i++) - stops[start + i].get_color_stop (&color_stops[i]); + stops[start + i].get_color_stop (&color_stops[i], + instancer); *count = i; } @@ -571,7 +582,7 @@ struct PaintLinearGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { &(this+colorLine), Var::is_variable }; + hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; c->funcs->linear_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -618,7 +629,7 @@ struct PaintRadialGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { &(this+colorLine), Var::is_variable }; + hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; c->funcs->radial_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -665,7 +676,7 @@ struct PaintSweepGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { &(this+colorLine), Var::is_variable }; + hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; c->funcs->sweep_gradient (c->data, &cl, centerX + c->instancer (varIdxBase, 0), From 4b0285bae60554c914f0b572fdaa5586be9f0611 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 11:18:42 -0700 Subject: [PATCH 059/219] [colr] Use slant_xy --- src/hb-paint.hh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 47088b41c..e700dd31a 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -26,6 +26,8 @@ #define HB_PAINT_HH #include "hb.hh" +#include "hb-face.hh" +#include "hb-font.hh" #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ @@ -135,16 +137,18 @@ struct hb_paint_funcs_t void push_root_transform (void *paint_data, hb_font_t *font) { - int xscale, yscale; - float upem, slant; - hb_font_get_scale (font, &xscale, &yscale); - slant = hb_font_get_synthetic_slant (font); - upem = hb_face_get_upem (hb_font_get_face (font)); + int xscale = font->x_scale, yscale = font->y_scale; + float upem = font->face->get_upem (); + float slant = font->slant_xy; + func.push_transform (this, paint_data, xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0, - !user_data ? nullptr : user_data->push_transform); } + !user_data ? nullptr : user_data->push_transform); + } void pop_root_transform (void *paint_data) - { func.pop_transform (this, paint_data, - !user_data ? nullptr : user_data->pop_transform); } + { + func.pop_transform (this, paint_data, + !user_data ? nullptr : user_data->pop_transform); + } }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); From 4c728e952b5f7fa29b6da6c674ac289fddaf875b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 13:33:56 -0500 Subject: [PATCH 060/219] [colr] Add a todo --- src/hb-ot-color-colr-table.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index ff6c4714b..112362662 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -19,6 +19,7 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const const COLR *colr_table = c->get_colr_table (); const Paint *paint = colr_table->get_base_glyph_paint (gid); + // TODO apply clipbox if (paint) c->recurse (*paint); } From 0a2f3673b9cbe340cdf329f3b303832b16f7d2ee Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 13:51:23 -0500 Subject: [PATCH 061/219] [paint] Use tags for image formats This fits better with the rest of the HarfBuzz API. --- src/hb-ot-color-cbdt-table.hh | 2 +- src/hb-ot-color-sbix-table.hh | 2 +- src/hb-ot-color-svg-table.hh | 2 +- src/hb-paint.cc | 6 +++--- src/hb-paint.h | 30 +++++++++++++++++++++++------- src/hb-paint.hh | 4 ++-- util/hb-test.c | 4 ++-- 7 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 66c083460..4ab0188df 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -947,7 +947,7 @@ struct CBDT if (unlikely (!get_extents (font, glyph, &extents))) return false; - funcs->image (data, blob, "image/png", &extents); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index ef96b226c..4190e6d1e 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -248,7 +248,7 @@ struct sbix if (!get_extents (font, glyph, &extents)) return false; - funcs->image (data, blob, "image/png", &extents); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index b13b485c3..3967a1196 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,7 +103,7 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, blob, "image/svg+xml", nullptr); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr); hb_blob_destroy (blob); return true; diff --git a/src/hb-paint.cc b/src/hb-paint.cc index ac5312148..537fccd2c 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -71,7 +71,7 @@ hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, static void hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, - const char *mimetype, + hb_tag_t format, hb_glyph_extents_t *extents, void *user_data) {} @@ -347,10 +347,10 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, - const char *mimetype, + hb_tag_t format, hb_glyph_extents_t *extents) { - funcs->image (paint_data, image, mimetype, extents); + funcs->image (paint_data, image, format, extents); } void diff --git a/src/hb-paint.h b/src/hb-paint.h index ecedcf829..12539b4de 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -222,12 +222,26 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, float alpha, void *user_data); +/** + * HB_PAINT_IMAGE_FORMAT_PNG: + * + * Tag identifying png images in #hb_paint_image_func_t callbacks. + */ +#define HB_PAINT_IMAGE_FORMAT_PNG HB_TAG('p','n','g',' ') + +/** + * HB_PAINT_IMAGE_FORMAT_SVG: + * + * Tag identifying svg images in #hb_paint_image_func_t callbacks. + */ +#define HB_PAINT_IMAGE_FORMAT_SVG HB_TAG('s','v','g',' ') + /** * hb_paint_image_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions * @image: the image data - * @mimetype: the mime type for the image data + * @format: the image format as a tag * @extents: (nullable): glyph extents * @user_data: user data passed to the hb_font_paint_glyph() call * @@ -235,17 +249,19 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * glyph image. * * This method is intended for glyphs with image blobs in the CBDT, - * sbix or SVG tables. The @mimetype identifies the kind of data - * that is contained in @image. Possible values include "image/png" - * and "image/svg+xml". The glyph extents are provided if available, - * and should be used to position the image. + * sbix or SVG tables. The @format identifies the kind of data that + * is contained in @image. Possible values include #HB_PAINT_IMAGE_FORMAT_PNG + * and HB_PAINT_IMAGE_FORMAT_SVG. + * + * The glyph extents are provided if available, and should be used + * to position the image. * * Since: REPLACEME */ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, - const char *mimetype, + hb_tag_t format, hb_glyph_extents_t *extents, void *user_data); @@ -693,7 +709,7 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, - const char *mimetype, + hb_tag_t format, hb_glyph_extents_t *extents); HB_EXTERN void diff --git a/src/hb-paint.hh b/src/hb-paint.hh index e700dd31a..9e7927ac0 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -97,10 +97,10 @@ struct hb_paint_funcs_t !user_data ? nullptr : user_data->color); } void image (void *paint_data, hb_blob_t *image, - const char *mimetype, + hb_tag_t format, hb_glyph_extents_t *extents) { func.image (this, paint_data, - image, mimetype, extents, + image, format, extents, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, diff --git a/util/hb-test.c b/util/hb-test.c index c993b499e..5eb83d123 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -325,7 +325,7 @@ static void paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *blob, - const char *mimetype, + hb_tag_t format, hb_glyph_extents_t *extents, void *user_data) { @@ -335,7 +335,7 @@ paint_image (hb_paint_funcs_t *funcs, cairo_pattern_t *pattern; cairo_matrix_t m; - if (strcmp (mimetype, "image/png") != 0) + if (format != HB_PAINT_IMAGE_FORMAT_PNG) return; r.blob = blob; From 0c77f1d9abf5f8dcd931ca1ae5856039daf3e3fc Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 14:10:28 -0500 Subject: [PATCH 062/219] [paint] Documentation tweaks --- src/hb-paint.cc | 149 +++++++++++++++++++++++++++++++++++++++++++++++- src/hb-paint.h | 25 ++++++-- 2 files changed, 168 insertions(+), 6 deletions(-) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 537fccd2c..d2cc04fc7 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -34,7 +34,12 @@ * @short_description: Glyph painting * @include: hb.h * - * Functions for painting (extracting) glyph color layers. + * Functions for painting glyphs. + * + * The main purpose of these functions is to paint + * (extract) color glyph layers from the COLRv1 table, + * but the API works for drawing ordinary outlines + * and images as well. **/ static void @@ -301,6 +306,21 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) return hb_object_is_immutable (funcs); } +/** + * hb_paint_push_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @xx: xx component of the transform matrix + * @yx: yx component of the transform matrix + * @xy: xy component of the transform matrix + * @yy: yy component of the transform matrix + * @dx: dx component of the transform matrix + * @dy: dy component of the transform matrix + * + * Perform a "push-transform" paint operation. + * + * Since: REPLACEME + */ void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, @@ -310,12 +330,31 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); } +/** + * hb_paint_pop_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * + * Perform a "pop-transform" paint operation. + * + * Since: REPLACEME + */ void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) { funcs->pop_transform (paint_data); } +/** + * hb_paint_push_clip_glyph: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @glyph: the glyph ID + * + * Perform a "push-clip-glyph" paint operation. + * + * Since: REPLACEME + */ void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph) @@ -323,6 +362,19 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, funcs->push_clip_glyph (paint_data, glyph); } +/** + * hb_paint_push_clip_rect: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @xmin: min X for the rectangle + * @ymin: min Y for the rectangle + * @xmax: max X for the rectangle + * @ymax: max Y for the rectangle + * + * Perform a "push-clip-rect" paint operation. + * + * Since: REPLACEME + */ void hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax) @@ -330,12 +382,32 @@ hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax); } +/** + * hb_paint_pop_clip: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * + * Perform a "pop-clip" paint operation. + * + * Since: REPLACEME + */ void hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) { funcs->pop_clip (paint_data); } +/** + * hb_paint_color: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @color_index: Index of a color in the fonts selected color palette + * @alpha: Alpha to apply in addition + * + * Perform a "color" paint operation. + * + * Since: REPLACEME + */ void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, @@ -344,6 +416,16 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, funcs->color (paint_data, color_index, alpha); } +/** + * hb_paint_image: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @glyph: the glyph ID + * + * Perform a "image" paint operation. + * + * Since: REPLACEME + */ void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, @@ -353,6 +435,22 @@ hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, funcs->image (paint_data, image, format, extents); } +/** + * hb_paint_linear_gradient: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @color_line: Color information for the gradient + * @x0: X coordinate of the first point + * @y0: Y coordinate of the first point + * @x1: X coordinate of the second point + * @y1: Y coordinate of the second point + * @x2: X coordinate of the third point + * @y2: Y coordinate of the third point + * + * Perform a "linear-gradient" paint operation. + * + * Since: REPLACEME + */ void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, @@ -363,6 +461,22 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); } +/** + * hb_paint_radial_gradient: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @color_line: Color information for the gradient + * @x0: X coordinate of the first circle's center + * @y0: Y coordinate of the first circle's center + * @r0: radius of the first circle + * @x1: X coordinate of the second circle's center + * @y1: Y coordinate of the second circle's center + * @r1: radius of the second circle + * + * Perform a "radial-gradient" paint operation. + * + * Since: REPLACEME + */ void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, @@ -372,6 +486,20 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); } +/** + * hb_paint_sweep_gradient: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @color_line: Color information for the gradient + * @x0: X coordinate of the circle's center + * @y0: Y coordinate of the circle's center + * @start_angle: the start angle + * @end_angle: the end angle + * + * Perform a "sweep-gradient" paint operation. + * + * Since: REPLACEME + */ void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, @@ -381,12 +509,31 @@ hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); } +/** + * hb_paint_push_group: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * + * Perform a "push-group" paint operation. + * + * Since: REPLACEME + */ void hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) { funcs->push_group (paint_data); } +/** + * hb_paint_pop_group: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @mode: the compositing mode to use + * + * Perform a "pop-group" paint operation. + * + * Since: REPLACEME + */ void hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode) diff --git a/src/hb-paint.h b/src/hb-paint.h index 12539b4de..f253852f3 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -39,8 +39,6 @@ HB_BEGIN_DECLS * * Glyph paint callbacks. * - * All the callbacks are necessary. - * * The callbacks assume that the caller maintains a stack * of current transforms, clips and intermediate surfaces, * as evidenced by the pairs of push/pop callbacks. The @@ -58,7 +56,7 @@ HB_BEGIN_DECLS * gradient and composite callbacks are not needed. * * The paint-image callback is only needed for glyphs - * with blobs in the CBDT, sbix or SVG tables. + * with image blobs in the CBDT, sbix or SVG tables. * * Since: REPLACEME **/ @@ -285,6 +283,13 @@ typedef struct hb_color_line_t hb_color_line_t; * Color lines typically have offsets ranging between 0 and 1, * but that is not required. * + * The @color_index can be either an index into one of the fonts + * color palettes, or the special value 0xFFFF, which indicates that + * the foreground color should be used. + * + * in either case, the @alpha value should be applied in addition + * (i.e. multiplied with) the alpha value found in the color. + * * Since: REPLACEME */ typedef struct { @@ -380,8 +385,8 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * @color_line: Color information for the gradient * @x0: X coordinate of the circle's center * @y0: Y coordinate of the circle's center - * @start_angle: the start angle - * @end_angle: the end angle + * @start_angle: the start angle, in radians + * @end_angle: the end angle, in radians * @user_data: user data passed to the hb_font_paint_glyph() call * * A virtual method for the #hb_paint_funcs_t to paint a sweep @@ -404,6 +409,16 @@ typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, float end_angle, void *user_data); +/** + * hb_paint_composite_mode_t: + * + * The values of this enumeration describe the compositing modes + * that can be used when combining temporary redirected drawing + * with the backdrop. + * + * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * for details. + */ typedef enum { HB_PAINT_COMPOSITE_MODE_CLEAR, HB_PAINT_COMPOSITE_MODE_SRC, From f07ce68f9cf8d5fd4eb37141a16e89cb0ec2bbae Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 13:48:05 -0700 Subject: [PATCH 063/219] Remove unused function --- util/hb-test.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/util/hb-test.c b/util/hb-test.c index 5eb83d123..91f9f6770 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -544,13 +544,6 @@ interpolate (float f0, float f1, float f) return f0 + f * (f1 - f0); } -static inline void -interpolate_points (Point *p0, Point *p1, float f, Point *out) -{ - out->x = interpolate (p0->x, p1->x, f); - out->y = interpolate (p0->y, p1->y, f); -} - void interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) { From e3153654cbb5132a9b06231fb4402a3849a0fb68 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 13:56:22 -0700 Subject: [PATCH 064/219] [colr] Fix PNG placement --- util/hb-test.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/util/hb-test.c b/util/hb-test.c index 91f9f6770..e48828f89 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -333,21 +333,24 @@ paint_image (hb_paint_funcs_t *funcs, read_blob_data_t r; cairo_surface_t *surface; cairo_pattern_t *pattern; - cairo_matrix_t m; - if (format != HB_PAINT_IMAGE_FORMAT_PNG) + if (format != HB_PAINT_IMAGE_FORMAT_PNG || !extents) return; r.blob = blob; r.offset = 0; surface = cairo_image_surface_create_from_png_stream (read_blob, &r); + int width = cairo_image_surface_get_width (surface); + int height = cairo_image_surface_get_width (surface); pattern = cairo_pattern_create_for_surface (surface); - cairo_matrix_init_scale (&m, 1, -1); - cairo_matrix_translate (&m, - extents ? extents->x_bearing : 0, - extents ? - extents->y_bearing : 0); - cairo_pattern_set_matrix (pattern, &m); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); + + cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; + cairo_pattern_set_matrix (pattern, &matrix); + + cairo_translate (data->cr, extents->x_bearing, extents->y_bearing); + cairo_scale (data->cr, extents->width, extents->height); cairo_set_source (data->cr, pattern); cairo_paint (data->cr); From 451414a27eeee7b47bed7cd8c5bb88b81f7f5cca Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 18:14:31 -0500 Subject: [PATCH 065/219] [paint] Documentation fixes --- src/hb-ot-color-colr-table.cc | 42 ++++++++++++++++++++++++++++------- src/hb-paint.cc | 4 +++- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 112362662..b2b5bac20 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -26,23 +26,49 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const } +/** + * hb_color_line_get_color_stops: + * @color_line: a #hb_color_line_t object + * @start: the index of the first color stop to return + * @count: (inout) (optional): Input = the maximum number of feature tags to return; + * Output = the actual number of feature tags returned (may be zero) + * @color_stops: (out) (array length=count) (optional): Array of #hb_color_stop_t to populate + * + * Fetches a list of color stops from the given color line object. + * + * Note that due to variations being applied, the returned color stops + * may be out of order. It is the callers responsibility to ensure that + * color stops are sorted by their offset before they are used. + * + * Return value: the total number of color stops in @cl + * + * Since: REPLACEME + */ unsigned int -hb_color_line_get_color_stops (hb_color_line_t *cl, +hb_color_line_get_color_stops (hb_color_line_t *color_line, unsigned int start, unsigned int *count, hb_color_stop_t *color_stops) { - if (cl->is_variable) - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops, cl->c->instancer); + if (color_line->is_variable) + return reinterpret_cast *>(color_line->base)->get_color_stops (start, count, color_stops, color_line->c->instancer); else - return reinterpret_cast *>(cl->base)->get_color_stops (start, count, color_stops, cl->c->instancer); + return reinterpret_cast *>(color_line->base)->get_color_stops (start, count, color_stops, color_line->c->instancer); } +/** + * hb_color_line_get_extend: + * @color_line: a #hb_color_line_t object + * + * Fetches the extend mode of the color line object. + * + * Since: REPLACEME + */ hb_paint_extend_t -hb_color_line_get_extend (hb_color_line_t *cl) +hb_color_line_get_extend (hb_color_line_t *color_line) { - if (cl->is_variable) - return reinterpret_cast *>(cl->base)->get_extend (); + if (color_line->is_variable) + return reinterpret_cast *>(color_line->base)->get_extend (); else - return reinterpret_cast *>(cl->base)->get_extend (); + return reinterpret_cast *>(color_line->base)->get_extend (); } diff --git a/src/hb-paint.cc b/src/hb-paint.cc index d2cc04fc7..0872479f4 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -420,7 +420,9 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, * hb_paint_image: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @glyph: the glyph ID + * @image: image data + * @format: tag describing the image data format + * @extents: (nullable): the extents of the glyph * * Perform a "image" paint operation. * From 30a6fd04d00624129b13b20fb755d6c1c4982637 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 18:20:00 -0500 Subject: [PATCH 066/219] [colr] Add some tests --- .../fonts/noto_handwriting-cff2_colr_1.otf | Bin 0 -> 4172 bytes test/api/fonts/test_glyphs-glyf_colr_1.ttf | Bin 0 -> 16704 bytes test/api/results/hand-20-0-10.txt | 79 +++++ test/api/results/hand-20-0.2-10.txt | 79 +++++ test/api/results/test-20-0-10.txt | 12 + test/api/results/test-20-0-106.txt | 18 + test/api/results/test-20-0-116.txt | 14 + test/api/results/test-20-0-123.txt | 31 ++ test/api/results/test-20-0-165.txt | 12 + test/api/results/test-20-0-175.txt | 22 ++ test/api/results/test-20-0-6.txt | 11 + test/api/results/test-20-0-92.txt | 11 + test/api/test-ot-color.c | 312 ++++++++++++++++++ 13 files changed, 601 insertions(+) create mode 100644 test/api/fonts/noto_handwriting-cff2_colr_1.otf create mode 100644 test/api/fonts/test_glyphs-glyf_colr_1.ttf create mode 100644 test/api/results/hand-20-0-10.txt create mode 100644 test/api/results/hand-20-0.2-10.txt create mode 100644 test/api/results/test-20-0-10.txt create mode 100644 test/api/results/test-20-0-106.txt create mode 100644 test/api/results/test-20-0-116.txt create mode 100644 test/api/results/test-20-0-123.txt create mode 100644 test/api/results/test-20-0-165.txt create mode 100644 test/api/results/test-20-0-175.txt create mode 100644 test/api/results/test-20-0-6.txt create mode 100644 test/api/results/test-20-0-92.txt diff --git a/test/api/fonts/noto_handwriting-cff2_colr_1.otf b/test/api/fonts/noto_handwriting-cff2_colr_1.otf new file mode 100644 index 0000000000000000000000000000000000000000..dfb30588e79ab24dfbbfd07dc98931d6cb115729 GIT binary patch literal 4172 zcmbVPd2keE7JuDy&7H5EzND%8jsyr2;YJ;K)G;5X0n{%+>cC zx$k5MB!FlDIYe=Bx71z5T6VptQgO8kwYJnnU2I6F?0wx6szR3CKkTXZzVE&7``-I~ z?|om->s9O4t%3xo1QWQ@mn@k%<5_bzfH?uc`bhe!<&XDweei1l+iKMPn7;bqRTjkMjE{?^(5W+RV>ZZ=MA}OhqaL~jCfzK+<+9QO-ck47d-b z8^3voZ57gDnD>iq-#f(mFU6QL#LjxeTm-vtX9b8YWf1CL>R~8S{Z!ziozU;he?KH1 zYe#Yi)Mph4!p$~eSYJ;<+Vf)urcWd>tIq%VbHhP616K(%QAM05caY_#KfI>O_Urde zGWYi1XMJsw>b3V>R{s3+wl7TdHHHf6u=1 zy_0RvJtHKQtv{J_%-`#KHP-n0VP)!Fwy#;oHuWKkpv+UZDHTs9e_ry*>wgJ#OKS5?}+N}PUl`N5|cE1XLG47>V(I-;VgtVV8ho>5kaAt@}$&g+N!66@Mx(N>T1 z(`Q;d;o`~?XaC`!M{t2)Aiz3PZ8XaXBFng?J8cc2nfwi`?PD7z>MBK_&p7D3{< zB#{?_Y@q+p&m$Z>$MYPgPWX-E1?6swC`zK3j6OzM!ZNy}d(7o!-f}O4E)rRm5Ap%$ zMsKjql7KoMBI)D4JMGp8SKYgQF`OdCVr)T&c z+psZ5oudv?dZ)U$CE8{O+IPuc9v)d`*z18m&C%?U0`PI>LAN}$2OeIaN zyh7a=rTojjF}tE@JLB>0t0-|l`lM=}y>5-q%lpNkSXu9G_E6>RZGm>W_m#F&e`lJy zV$uEd$s@aWA7&y!k;iTGPT}I?Z|qH$xdRM`BqEu~HclZ$9xu5kPU~0KKwvOG- z76(cLlvr6QdgxRehMuL}@}0JNjQkml{8e?NeW`fY$&6O2zA!(MNAKDd^cFKum0H+J z4_86wC4sz$Ck+#*F<&NRLo>I}s~ozbJ!r^8W75HO$ht*s565lXZwt=BAK zC@e(i7tTLd5o1D}a#>yUaTevTZ|2(Q=4Mf9WW?HPF-l9;4!)&yPm=oKFfZ%#`;+~C zFYBdQRz#=KT~9`~1%f_i zjYGkz-~S(o?}4@Fdep^S>>k6cWO8 zx7p|8`2d4=y9lp#*AJ`@r{bVsbZwUzPh5sK?}Q~8YtD!XM}-B4;N zXg}&cO4m0?p?c<(7E5(!ryQdX9t>0*VBRkLa_d_>C0mbnH?(&!JvH66T_S~B4bg{R z_4{HB9}4p!dVfdzeg@wP@mG$(3w-jvg1}DN?G_`I%-l3vL(#gnELxTNH`+y6kVW~l zGU+bc$JLI#Q`B(_EBzj?*Xz74Tt99s*3l}J9pK$yP5J9OEgdw^76O=JgXdC;AyA}Fuq2=p% zK*NH5nmC5@3qC2}=lyIjNL5zs^SM2ho(1m3lzXwe)?4qdgP(jkmLyOZ*S|8 z^~&IuXEI9pScqI6q_twr09b=yRfYe|!;#-_R3>v_1omA<-LZtw^+4!zh8z7cMnB2m zlMRlQDgN`vtI2<2dky`hVvF??fjEdMNHdT&B5g$qB0V3ULmbBz*Ai!t6f9h@av>c^ z^W)=WI`(tpb4bKbVpUAy8uB92fFBb5=r&B~%QP2hF;XTH8@FMS2gYkqhxMK564Fno zqvPY|d*b6}tdh)GSejX3`a^gK>G?9cmTzaGmU=;GLFvd`i z#wu?#*=nNTC9O`o$NW7)#3)!?7)l_F1y&e~HD)+4Jz3>@q= zC*B^=Si=f(oK$E4vcd#C5=1WXFzyIBmeoK`$p-tNsf%xmdOlplsmOKI=ucmg^cakH z!L$gB8?@ZOJLV?dfduGT-b6TzGl=~E2QtC1h8%G(GjQJ?(sFncAtApBX|xL_y$qvV zFzY-d4l-gu8a@P)#ekGT;29#2--M*chun#I1)USA*y3g>7tCjLJ_u6$NZxwHmcTh& zfSh`%nTeN7AHg(!kZMN%a?WdDlw54kcwfolwwK-2n+KQZrHh*)2wrFcidv;%! zmcHYFwx#N*mcyUca;39cX6UR|+I2x=dq32oXD(~Culz$RKmDZ!2fx)KfBIHyd*`b5 z;s@8XvmamA&V71AgTwd*cS6(de%ttxBM^xVzxQSW`N)#x>mYGQMsYr3(+?=%41Ju) z%*-n^-oS>0WBMq88Uokptp&F^795a_mMF|OiEnBWzs_vP&G@F)KNk{^TXD7?6!;JB CSdVZ3 literal 0 HcmV?d00001 diff --git a/test/api/fonts/test_glyphs-glyf_colr_1.ttf b/test/api/fonts/test_glyphs-glyf_colr_1.ttf new file mode 100644 index 0000000000000000000000000000000000000000..982ccc0a115ee9d58959eb54c27aa5a5a7491e0a GIT binary patch literal 16704 zcmeHOdw5humOtm-+mAduArArsXbAF5LZ|Z}C}Khq2oeb9;Y2~2kZwpYA+gguRFsH} zA}XT@h=9tVAPO>k>act+e|WPiWlZCCgMuu7dN#vcJP;{UMJETz-h}`?_RoO-mf+j*-xN+Wpkj>KiYoz z40PW^C~5`~vrXA8bdev^+!k8%=%VyF$fG^waBF*0-;TOH z)*5R^bY3Mzu=t^jdNgdub^MO#YP{`?UXvj+@Fkr&LYX9bj>Zkzf|~k!eu8Wk<|~q- zxKR<&P54n)7(ex>C<5&6Rn(0JVPWwTJxAz9IEL^lg1=WVbp~R?Rs(kEX@}n9rFUN1 zi!Z6?MbO7uf1Dq)MU=&l-{vQH5ocrMo}}%9!B3ST6Dct>MJ(oF0fv4CV#Sz6;V=<` z(1=GMI;A5~61hOSSkz-D7v_vhnT2#Lxj?y8G1qFyg~(-dBHchPOktN@=r@wffwV*D z1jq%k%PIIf$rXci3>2xIT5?(7t*3ZIzX-@q!EaIK(4b$pS7+7@idCOw2)fR%7gR-?M8_==mgfp59u6Tq$}*? zRCaSV7jrq!=Y`zNA@1VGcn818NBB6OTdOb`i6Q!eNX*R zJ*Qq&uV_v!RdZ|ETCrBH&DR!c&00w7(jL=xXfJ9|~F(XV}NsJ@#q#N_(AsvAxy4 z#=gP+gnhUDfc*{o3Hy8Y5AEmd7wuOZPDiT4?Z|c%JIWpN9Sa@Jj*z3v@tETo$3Dkv zjuVde9lv&b>iBoZRj1oI!@1nK#rdZ54>1`rV_w(Wff)>@<-l}KlXmCBnbT2D{44K-8^0yiBU$JoK@&3oWkR;o3mUQ zdG(_|kGyU?#_6l{IR}(clt36QoNCV+J+`p0peWy)o;I#vY}ROdT3Tv)zPG5519_7s zdc6}TdauhIHY{`a&|#UpYSz@LvvOulnKH|sH(^5FR8Mxc2d(-svo>J0N57|_-+tBI ztsMWd{Qq2XE&B}c#yA&C!%7#I%&o+%g5$C zO&L2p&1?Qw8q$V)Bmd!sh3D!LJSoS&rjCXiCiu<&O2dR3{E`2njz#FnCiog`@HQmV zV7(u9cpFmFjh+}?5q;S-zGA|5OF&%}!qaZ&2Uyq6JeS>X_dK$HFhi9Y)8pE<(cjOgBzPaU8&cp9F-62Yf$ztGoRL=HyL8L62CrV7 zOxtKEt(0jy{$BAt%q-Sozt)(T1^l#3+i4oVEB+$0 zD$iXTY7DhBx$6R*A@{7-yE~dYYXZwwwl)T@DR+B4UT==4I47^DE^o^9-s0=MMY+OX zl~-`>GP2UID{AycbjIjQjx0xIR83WI$*!V2n5mXRaKnb+_H06~4sO^^w7}$g0r5wb?z&t8KTX{5vt_NGJV-e-z#uZUMm^`HZ@_xE| z_4I$+s?|28Wvq6|>D8V-4)x)9O*jGxvjT5R?6a|RFLp*)N;c{q>Yk?iJCJesq33}44%c^r@D2|SS}VLi&>T%ODx&SNj< za{(7}5l?}~dMaPfH}EvRk*D)bT*9S1gUjH@uHczGiz|6H-^_Ekis$k?u7-E}7Ovr1 zuH$;XmA}Icd>h}+3*hs<18b;{7jq*o;U@NTfS2+zc*0wFIp4{x+{P=oojdq04ss{_ z<12X;ujVy;H{Zke@>;%+@8@;!nm@qn`9a>m-{pt+Vcy7(@Fso~zVyd=Gk*_j{gb?f zpW>~&jkojD@UTC_J9!uH=4bgiexCR6_jxbB0KfY_-p?=b0e+cZ;e&jLUrk)u5oq%* zXlt%0VHw9+s`B(2m_CM)!ai|<#WTdSu;Hib*+Q%H&otMx49mKSTWTu%kr zO=-P;WzvE@W#%oBR_s@3TC%5bcrR=AltxTrSX3X%#;}uD88N6uB=4NGXJ3Idr$r!} zF|FBGVj9yT8QGsLEppkxh$;JuB9^p>MjCd{!Etw^?QSjSpo zM1LbGT26K?GLZU6BI773F^wJ>Mtwx4#jG7MXTNDRt1My$%S^OfZp3i;_xWvRJ>=o?JXL1WE-wR>h;WABBv5Yrtbu3VM}2Ut7CBAXb9WUnMt;lJ(Up`VgETs&8!d zHMOq@HR27$@4Hrm+22glXgcScD(jt?D7Bm0gDv-nj zEM0D>uCa7^epP*~wJ&8g6&2RLi2hfV-eyrLFRhu=L#1l=tjfBId1=uLfG454##dfl zKC2?NH#?)gW}bztEUhW`=`~o$+Ul8geaQ0JGiO%RRLm=@uv}n8Lm4h$cJ(}q+2__* z)ytf7Y-HH_%fhVl9$D{z0Mxc~C) ztu21vwaZ(?D4*Qa+R~x#c|+|TzSh9fP-=u((jE%6x9MbBZ!*}jtT{9&!ivH=<%&?o zQ#wV@cQ!ZTxo5VJZs9C#4DL(oRT>?NR-uzdzYWr8DYIooXCUMgm2}`iC=D&24TB=j z#SX7etg8V(1{!WTG@Dw2O|5}W-zraEDlgWM`hta?I5UYACz`hKSYaZ(*TQ4fi}3k{ zp0rN=7U<230cYGR_;z&v;%Inz#*;YhSczkXOK{3MIpPu8kCc-R17C&iA$Tqi!k738 z{HZU)?|T5=RGWVO@>y}tO??f1O;S&ay3{|xdrsOQA=Rdc^K#m3aTZfs0PikoZSY)@ zwvKS%QF{`nGD&*@K5o)}NP~bs6<&Ak*YG-#_D4zseo5&#!97uU!EMvTNl)86;ZLliXaaB-O$5G5lYl>_Y~Vk^AxQR5;Qk{=5={n1M6S`NI7Gqw~T50@^*=TjT-c3J^^0OxHf{s0`m z6n~8F0-l7+m*PK!8<^tH!!=Ctm*EPg1ScHGl#olSfd#Y%cs(4(lu$zV0B6#@z$#h` ztfBjW4Rk+n5v>FIsSCKA9sqXGdZ0LSO9^Xf18_Zk7r2og0&b>-Ka3?(i+(Vmy z`{_~OA$kn>8a)m?Mw@|e!K+UR@8J9{CH$P81fIf4VM_Rbo&tVGTZs}C+6K%JC!iB^ z>1kj+?EtQ&XMhjmG%+P^p*FLbnZI_IJeXUEzeaFhLUO$M` zac(U2;s}T2#-@{+(t}A&B9(=f)X-8%`8PACd_IVjPlQzb+1$`jewR+lKN^g_&MJ6- z;1Q@1=OabR`w{l#e%ZJBvUc$~&wdr91+uXKD`1!P%dYL0O%lgB$gdm+p2VvyDpO0u zWyP42z~~sN?V-xwTvh2$6)nKr{4PE`Ii_xwxgQNBe&tFqYBoLyW{2}!^k(ogU>@o| zXki}CBn~;xk-QnadIYgw3jvgJoIu__yr1yRcZld4% zHmI{tfnC{$-HP#FEM9`hE0EvTb+>_?-G|+dmpu8x1gq(TA7jmpkM{H_g|uGy>1(Q` ztz|5TnnqgSg8j2s6;la|jrl zdYmfbOc{@nakh*LWIRpAQmf`VYh( zz({{Y{13QSpCJB;M)VQlw`@eeM0^xu=Uv2yG4uZ(@qU>0ZxKHiL-ac0?YJ!m5pRwo zdI9l6@kF~2-=9GA6yjBwiH{;);Uanv@zNxsdl4^6ChA0d>mYo+iFjTLQ4`{ssYDA9 zPfsJNMO>7QF@!jGFi{!eu^B`+ARaMc9~?n9Il5IF-mmyRV)-Tc?h4e>d6u^c0jLS<&d(M6|%|X0fp=`sVNj& zB77=Nu~F3PL)EH5g_oNY?3;v#7|v3vM=?*kv9}}qO7KrKfZGD^j9qwc7Ne3|#CNC- zNFrJ#wxG$5)LT^y1=>r(Q}wZ->ITYE^h? zgvSSIj79nhg8bnt;C%@A5}vxmC&3h6PjkW-)?WyJda*lPT|HTRBoCUx=YQH9<}=}N zS65f~<_QzSO{HVP8=HoOU$`$V{Pxbo@cFlF;qYnFwka5?QaM}Z3gp;>*hZ7ET chhyIQudw#Z%VGNc<$m?eI%H?X&A_$&H@@d%&;S4c literal 0 HcmV?d00001 diff --git a/test/api/results/hand-20-0-10.txt b/test/api/results/hand-20-0-10.txt new file mode 100644 index 000000000..4a9c0c8d4 --- /dev/null +++ b/test/api/results/hand-20-0-10.txt @@ -0,0 +1,79 @@ +start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + push group + start clip glyph 13 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + pop group mode 3 + push group + start clip glyph 14 + linear gradient + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 + colors + 0.000000 12 1.000000 + 1.000000 12 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 15 + solid 9 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 16 + solid 0 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 21 + solid 9 1.000000 + end clip + pop group mode 3 + push group + push group + start clip glyph 16 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 5 1.000000 + 1.000000 1 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 18 + solid 2 0.200012 + end clip + pop group mode 3 + pop group mode 3 + push group + start clip glyph 19 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + pop group mode 3 + push group + start clip glyph 20 + solid 9 1.000000 + end clip + pop group mode 3 +end transform diff --git a/test/api/results/hand-20-0.2-10.txt b/test/api/results/hand-20-0.2-10.txt new file mode 100644 index 000000000..f6e342b32 --- /dev/null +++ b/test/api/results/hand-20-0.2-10.txt @@ -0,0 +1,79 @@ +start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + push group + start clip glyph 13 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + pop group mode 3 + push group + start clip glyph 14 + linear gradient + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 + colors + 0.000000 12 1.000000 + 1.000000 12 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 15 + solid 9 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 16 + solid 0 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 21 + solid 9 1.000000 + end clip + pop group mode 3 + push group + push group + start clip glyph 16 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 5 1.000000 + 1.000000 1 1.000000 + end clip + pop group mode 3 + push group + start clip glyph 18 + solid 2 0.200012 + end clip + pop group mode 3 + pop group mode 3 + push group + start clip glyph 19 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + pop group mode 3 + push group + start clip glyph 20 + solid 9 1.000000 + end clip + pop group mode 3 +end transform diff --git a/test/api/results/test-20-0-10.txt b/test/api/results/test-20-0-10.txt new file mode 100644 index 000000000..79ae162f3 --- /dev/null +++ b/test/api/results/test-20-0-10.txt @@ -0,0 +1,12 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start clip glyph 174 + sweep gradient + center 500.000000 600.000000 + angles 0.000000 6.283185 + colors + 0.250000 7 1.000000 + 0.416687 4 1.000000 + 0.583313 0 1.000000 + 0.750000 8 1.000000 + end clip +end transform diff --git a/test/api/results/test-20-0-106.txt b/test/api/results/test-20-0-106.txt new file mode 100644 index 000000000..0377d9513 --- /dev/null +++ b/test/api/results/test-20-0-106.txt @@ -0,0 +1,18 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + push group + start clip glyph 3 + solid 4 0.500000 + end clip + push group + start transform 0.000000 0.000000 0.000000 0.000000 1000.000000 1000.000000 + start transform 1.000000 -0.363874 -0.176283 1.000000 0.000000 0.000000 + start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000 + start clip glyph 3 + solid 1 0.700012 + end clip + end transform + end transform + end transform + pop group mode 4 + pop group mode 3 +end transform diff --git a/test/api/results/test-20-0-116.txt b/test/api/results/test-20-0-116.txt new file mode 100644 index 000000000..01fbef52a --- /dev/null +++ b/test/api/results/test-20-0-116.txt @@ -0,0 +1,14 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + push group + start clip glyph 3 + solid 4 0.500000 + end clip + push group + start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 + start clip glyph 3 + solid 1 0.700012 + end clip + end transform + pop group mode 4 + pop group mode 3 +end transform diff --git a/test/api/results/test-20-0-123.txt b/test/api/results/test-20-0-123.txt new file mode 100644 index 000000000..f99ee44f6 --- /dev/null +++ b/test/api/results/test-20-0-123.txt @@ -0,0 +1,31 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + push group + start clip glyph 3 + solid 10 1.000000 + end clip + pop group mode 3 + push group + push group + start transform 0.000000 0.000000 0.000000 0.000000 333.000000 667.000000 + start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 + start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000 + start clip glyph 2 + solid 12 1.000000 + end clip + end transform + end transform + end transform + push group + start transform 0.000000 0.000000 0.000000 0.000000 667.000000 333.000000 + start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 + start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000 + start clip glyph 2 + solid 11 1.000000 + end clip + end transform + end transform + end transform + pop group mode 5 + pop group mode 3 + pop group mode 3 +end transform diff --git a/test/api/results/test-20-0-165.txt b/test/api/results/test-20-0-165.txt new file mode 100644 index 000000000..8db60bfbd --- /dev/null +++ b/test/api/results/test-20-0-165.txt @@ -0,0 +1,12 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start clip glyph 165 + linear gradient + p0 100.000000 950.000000 + p1 2300.000000 950.000000 + p2 -1000.000000 250.000000 + colors + 0.000000 0 1.000000 + 0.500000 4 1.000000 + 1.000000 2 1.000000 + end clip +end transform diff --git a/test/api/results/test-20-0-175.txt b/test/api/results/test-20-0-175.txt new file mode 100644 index 000000000..1c3a2f56c --- /dev/null +++ b/test/api/results/test-20-0-175.txt @@ -0,0 +1,22 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + push group + start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 + start clip glyph 174 + solid 3 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 1.000000 0.000000 0.000000 1.000000 -150.000000 0.000000 + start clip glyph 174 + linear gradient + p0 500.000000 250.000000 + p1 500.000000 950.000000 + p2 600.000000 250.000000 + colors + 0.000000 0 1.000000 + 1.000000 4 1.000000 + end clip + end transform + pop group mode 3 +end transform diff --git a/test/api/results/test-20-0-6.txt b/test/api/results/test-20-0-6.txt new file mode 100644 index 000000000..90b842ad5 --- /dev/null +++ b/test/api/results/test-20-0-6.txt @@ -0,0 +1,11 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start clip glyph 6 + linear gradient + p0 100.000000 250.000000 + p1 900.000000 250.000000 + p2 100.000000 300.000000 + colors + 0.000000 0 1.000000 + 1.000000 4 1.000000 + end clip +end transform diff --git a/test/api/results/test-20-0-92.txt b/test/api/results/test-20-0-92.txt new file mode 100644 index 000000000..f099bdd82 --- /dev/null +++ b/test/api/results/test-20-0-92.txt @@ -0,0 +1,11 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start clip glyph 2 + radial gradient + p0 166.000000 768.000000 radius 0.000000 + p1 166.000000 768.000000 radius 256.000000 + colors + 0.000000 3 1.000000 + 0.500000 9 1.000000 + 1.000000 0 1.000000 + end clip +end transform diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index c2bbad2d5..b98b8da68 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -103,6 +103,9 @@ static hb_face_t *sbix = NULL; static hb_face_t *svg = NULL; static hb_face_t *empty = NULL; +static hb_face_t *colr_v1 = NULL; +static hb_face_t *colr_v1_2 = NULL; + #define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START { \ const hb_color_t *_colors = (colors); \ const size_t _i = (i); \ @@ -452,6 +455,304 @@ test_hb_ot_color_png (void) hb_font_destroy (cbdt_font); } +/* ---- */ + +typedef struct { + int level; + GString *string; +} paint_data_t; + +static void +print (paint_data_t *data, + const char *format, + ...) +{ + va_list args; + + g_string_append_printf (data->string, "%*s", 2 * data->level, ""); + + va_start (args, format); + g_string_append_vprintf (data->string, format, args); + va_end (args); + + g_string_append (data->string, "\n"); +} + +static void +push_transform (hb_paint_funcs_t *funcs, + void *paint_data, + float xx, float yx, + float xy, float yy, + float dx, float dy, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "start transform %f %f %f %f %f %f", xx, yx, xy, yy, dx, dy); + data->level++; +} + +static void +pop_transform (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + + data->level--; + print (data, "end transform"); +} + +static void +push_clip_glyph (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "start clip glyph %u", glyph); + data->level++; +} + +static void +push_clip_rectangle (hb_paint_funcs_t *funcs, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "start clip rectangle %f %f %f %f", xmin, ymin, xmax, ymax); + data->level++; +} + +static void +pop_clip (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + + data->level--; + print (data, "end clip"); +} + +static void +paint_color (hb_paint_funcs_t *funcs, + void *paint_data, + unsigned int color_index, + float alpha, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "solid %u %f", color_index, alpha); +} + +static void +paint_image (hb_paint_funcs_t *funcs, + void *paint_data, + hb_blob_t *blob, + hb_tag_t format, + hb_glyph_extents_t *extents, + void *user_data) +{ + paint_data_t *data = user_data; + char buf[5] = { 0, }; + + hb_tag_to_string (format, buf); + print (data, "image type %s extents %d %d %d %d\n", + buf, extents->x_bearing, extents->y_bearing, extents->width, extents->height); +} + +static void +print_color_line (paint_data_t *data, + hb_color_line_t *color_line) +{ + hb_color_stop_t *stops; + unsigned int len; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + + print (data, "colors"); + data->level += 1; + for (unsigned int i = 0; i < len; i++) + print (data, "%f %u %f", stops[i].offset, stops[i].color_index, stops[i].alpha); + data->level -= 1; +} + +static void +paint_linear_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "linear gradient"); + data->level += 1; + print (data, "p0 %f %f", x0, y0); + print (data, "p1 %f %f", x1, y1); + print (data, "p2 %f %f", x2, y2); + + print_color_line (data, color_line); + data->level -= 1; +} + +static void +paint_radial_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "radial gradient"); + data->level += 1; + print (data, "p0 %f %f radius %f", x0, y0, r0); + print (data, "p1 %f %f radius %f", x1, y1, r1); + + print_color_line (data, color_line); + data->level -= 1; +} + +static void +paint_sweep_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float cx, float cy, + float start_angle, + float end_angle, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "sweep gradient"); + data->level++; + print (data, "center %f %f", cx, cy); + print (data, "angles %f %f", start_angle, end_angle); + + print_color_line (data, color_line); + data->level -= 1; +} + +static void +push_group (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "push group"); + data->level++; +} + +static void +pop_group (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data) +{ + paint_data_t *data = user_data; + data->level--; + print (data, "pop group mode %d", mode); +} + +typedef struct { + const char *font_file; + int scale; + float slant; + hb_codepoint_t glyph; + const char *output; +} colrv1_test_t; + +#define NOTO_HAND "fonts/noto_handwriting-cff2_colr_1.otf" +#define TEST_GLYPHS "fonts/test_glyphs-glyf_colr_1.ttf" + +static colrv1_test_t colrv1_tests[] = { + { NOTO_HAND, 20, 0., 10, "results/hand-20-0-10.txt" }, + { NOTO_HAND, 20, 0.2, 10, "results/hand-20-0.2-10.txt" }, + { TEST_GLYPHS, 20, 0, 6, "results/test-20-0-6.txt" }, + { TEST_GLYPHS, 20, 0, 10, "results/test-20-0-10.txt" }, + { TEST_GLYPHS, 20, 0, 92, "results/test-20-0-92.txt" }, + { TEST_GLYPHS, 20, 0, 106, "results/test-20-0-106.txt" }, + { TEST_GLYPHS, 20, 0, 116, "results/test-20-0-116.txt" }, + { TEST_GLYPHS, 20, 0, 123, "results/test-20-0-123.txt" }, + { TEST_GLYPHS, 20, 0, 165, "results/test-20-0-165.txt" }, + { TEST_GLYPHS, 20, 0, 175, "results/test-20-0-175.txt" }, +}; + +static void +test_hb_ot_color_colr_v1 (gconstpointer d) +{ + const colrv1_test_t *test = d; + hb_face_t *face; + hb_font_t *font; + hb_paint_funcs_t *funcs; + paint_data_t data; + char *file; + char *buffer; + gsize len; + GError *error = NULL; + + face = hb_test_open_font_file (test->font_file); + font = hb_font_create (face); + hb_font_set_scale (font, test->scale, test->scale); + hb_font_set_synthetic_slant (font, test->slant); + + funcs = hb_paint_funcs_create (); + hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); + hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); + hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, &data, NULL); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, &data, NULL); + hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); + hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); + hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); + hb_paint_funcs_set_color_func (funcs, paint_color, &data, NULL); + hb_paint_funcs_set_image_func (funcs, paint_image, &data, NULL); + hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, &data, NULL); + hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, &data, NULL); + hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, &data, NULL); + + data.string = g_string_new (""); + data.level = 0; + + hb_font_paint_glyph (font, test->glyph, funcs, &data); + + if (getenv ("GENERATE_DATA")) + { + g_print ("%s\n", data.string->str); + exit (0); + } + + file = g_test_build_filename (G_TEST_DIST, test->output, NULL); + if (!g_file_get_contents (file, &buffer, &len, &error)) + { + g_test_fail_printf ("%s", error->message); + return; + } + + if (strcmp (buffer, data.string->str) != 0) + { + g_test_fail_printf ("did not get the expected result"); + } + + g_free (buffer); + g_free (file); + + g_string_free (data.string, TRUE); + + hb_font_destroy (font); + hb_face_destroy (face); +} + int main (int argc, char **argv) { @@ -464,6 +765,8 @@ 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"); + colr_v1 = hb_test_open_font_file ("fonts/noto_handwriting-cff2_colr_1.otf"); + colr_v1_2 = hb_test_open_font_file ("fonts/test_glyphs-glyf_colr_1.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); @@ -480,6 +783,13 @@ main (int argc, char **argv) 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); + for (unsigned int i = 0; i < G_N_ELEMENTS (colrv1_tests); i++) + { + char buf[10] = { 0, }; + g_snprintf (buf, 10, "%d", i); + hb_test_add_data_flavor (&colrv1_tests[i], buf, test_hb_ot_color_colr_v1); + } + status = hb_test_run(); hb_face_destroy (cpal_v0); hb_face_destroy (cpal_v1); @@ -487,5 +797,7 @@ main (int argc, char **argv) hb_face_destroy (cbdt); hb_face_destroy (sbix); hb_face_destroy (svg); + hb_face_destroy (colr_v1); + hb_face_destroy (colr_v1_2); return status; } From 3b32eab38e3212464239f32ad294d30d943a3ae2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 17 Dec 2022 17:13:30 -0700 Subject: [PATCH 067/219] [colr] Fix compiler warning --- util/hb-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/hb-test.c b/util/hb-test.c index e48828f89..87370f400 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -41,7 +41,7 @@ print (paint_data_t *data, { va_list args; - printf ("%*s", 2 * data->level, ""); + printf ("%*s", INDENT * data->level, ""); va_start (args, format); vprintf (format, args); From 2d4678b6478874288312cfe773d735c351d04b0f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 22:30:31 -0500 Subject: [PATCH 068/219] Add a comment --- test/api/test-ot-color.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index b98b8da68..b48c5b12f 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -726,6 +726,12 @@ test_hb_ot_color_colr_v1 (gconstpointer d) hb_font_paint_glyph (font, test->glyph, funcs, &data); + /* Run + * + * GENERATE_DATA=1 G_TEST_SRCDIR=./test/api ./build/test/api/test-ot-color -p TESTCASE > test/api/results/OUTPUT + * + * to produce the expected results file. + */ if (getenv ("GENERATE_DATA")) { g_print ("%s\n", data.string->str); From 63fcb26c9b771f6ab492dad896a4da911fb0427e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Dec 2022 22:41:34 -0500 Subject: [PATCH 069/219] Add some more docs --- src/hb-ot-color.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 696ca3e17..621d36555 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -190,7 +190,15 @@ hb_ot_color_palette_get_colors (hb_face_t *face, * hb_ot_color_has_layers: * @face: #hb_face_t to work upon * - * Tests whether a face includes any `COLR` color layers. + * Tests whether a face includes a `COLR` table. + * + * Note that the `COLR` table may contain layers + * or (for v1) more complicated paint graphs, so + * it is not guaranteed that hb_ot_color_get_layers() + * will return information for each color glyph, + * even if this function returns `true`. See + * hb_font_paint_glyph() for an API that will work + * in either case. * * Return value: `true` if data found, `false` otherwise * From 021618e91ae26ef7af1fae4eb0693258e48a7d2a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 00:12:32 -0500 Subject: [PATCH 070/219] [colr] Add hb_ot_color_has_paint This is a counterpart to hb_ot_color_has_layers for COLRv1 data. --- src/hb-ot-color-colr-table.hh | 3 ++- src/hb-ot-color.cc | 30 ++++++++++++++++++++---------- src/hb-ot-color.h | 5 +++++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 3dc7c6f6a..cf13dfbbe 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1631,7 +1631,8 @@ struct COLR { static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; - bool has_data () const { return numBaseGlyphs; } + bool has_v0_data () const { return numBaseGlyphs; } + bool has_v1_data () const { return (this+baseGlyphList).len; } unsigned int get_glyph_layers (hb_codepoint_t glyph, unsigned int start_offset, diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 621d36555..734ac1022 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -190,15 +190,8 @@ hb_ot_color_palette_get_colors (hb_face_t *face, * hb_ot_color_has_layers: * @face: #hb_face_t to work upon * - * Tests whether a face includes a `COLR` table. - * - * Note that the `COLR` table may contain layers - * or (for v1) more complicated paint graphs, so - * it is not guaranteed that hb_ot_color_get_layers() - * will return information for each color glyph, - * even if this function returns `true`. See - * hb_font_paint_glyph() for an API that will work - * in either case. + * Tests whether a face includes a `COLR` table + * with data according to COLRv0. * * Return value: `true` if data found, `false` otherwise * @@ -207,7 +200,24 @@ hb_ot_color_palette_get_colors (hb_face_t *face, hb_bool_t hb_ot_color_has_layers (hb_face_t *face) { - return face->table.COLR->has_data (); + return face->table.COLR->has_v0_data (); +} + +/** + * hb_ot_color_has_paint: + * @face: #hb_face_t to work upon + * + * Tests where a face includes a `COLR` table + * with data according to COLRv1. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: REPLACEME + */ +hb_bool_t +hb_ot_color_has_paint (hb_face_t *face) +{ + return face->table.COLR->has_v1_data (); } /** diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index d11e07e23..f29d7cf5f 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -120,6 +120,11 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *layer_count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */); +/* COLRv1 */ + +HB_EXTERN hb_bool_t +hb_ot_color_has_paint (hb_face_t *face); + /* * SVG */ From 6c49822cad38b071212823a303059e0917aeedfa Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 01:52:39 -0500 Subject: [PATCH 071/219] wip: Use hb-paint in hb-view This doesn't paint anything yet. --- util/hb-cairo-utils.c | 727 ++++++++++++++++++++++++++++++++++++++ util/hb-cairo-utils.h | 104 ++++++ util/helper-cairo-user.hh | 390 ++++++++++++-------- util/meson.build | 1 + 4 files changed, 1075 insertions(+), 147 deletions(-) create mode 100644 util/hb-cairo-utils.c create mode 100644 util/hb-cairo-utils.h diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c new file mode 100644 index 000000000..694586a3a --- /dev/null +++ b/util/hb-cairo-utils.c @@ -0,0 +1,727 @@ +/* + * Copyright © 2022 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. + * + * Google Author(s): Matthias Clasen + */ + +#include +#include +#include +#include +#include +#include + +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif + +typedef struct { + float r, g, b, a; +} color_t; + +typedef struct { + cairo_t *cr; + hb_font_t *font; + hb_font_t *unscaled_font; +} paint_data_t; + + +static inline cairo_extend_t +cairo_extend (hb_paint_extend_t extend) +{ + switch (extend) + { + case HB_PAINT_EXTEND_PAD: return CAIRO_EXTEND_PAD; + case HB_PAINT_EXTEND_REPEAT: return CAIRO_EXTEND_REPEAT; + case HB_PAINT_EXTEND_REFLECT: return CAIRO_EXTEND_REFLECT; + default:; + } + + return CAIRO_EXTEND_PAD; +} + +void +hb_face_get_color (hb_face_t *face, + unsigned int palette_index, + unsigned int color_index, + float alpha, + float *r, float *g, float *b, float *a) +{ + if (color_index == 0xffff) + { + /* foreground color */ + *r = *g = *b = 0; + *a = alpha; + } + else + { + hb_color_t color; + unsigned int clen = 1; + + if (hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color)) + { + *r = hb_color_get_red (color) / 255.f; + *g = hb_color_get_green (color) / 255.f; + *b = hb_color_get_blue (color) / 255.f; + *a = (hb_color_get_alpha (color) / 255.f) * alpha; + } + else + { + *r = *g = *b = 0; + *a = alpha; + } + } +} + +typedef struct +{ + hb_blob_t *blob; + unsigned int offset; +} read_blob_data_t; + +static cairo_status_t +read_blob (void *closure, + unsigned char *data, + unsigned int length) +{ + read_blob_data_t *r = (read_blob_data_t *) closure; + const char *d; + unsigned int size; + + d = hb_blob_get_data (r->blob, &size); + + if (r->offset + length > size) + return CAIRO_STATUS_READ_ERROR; + + memcpy (data, d + r->offset, length); + r->offset += length; + + return CAIRO_STATUS_SUCCESS; +} + +void +hb_cairo_paint_glyph_image (hb_font_t *font, + cairo_t *cr, + hb_blob_t *blob, + hb_tag_t format, + hb_glyph_extents_t *extents) +{ + if (format != HB_PAINT_IMAGE_FORMAT_PNG || !extents) + return; + + read_blob_data_t r; + r.blob = blob; + r.offset = 0; + cairo_surface_t *surface = cairo_image_surface_create_from_png_stream (read_blob, &r); + int width = cairo_image_surface_get_width (surface); + int height = cairo_image_surface_get_width (surface); + + cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); + + cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; + cairo_pattern_set_matrix (pattern, &matrix); + + cairo_translate (cr, extents->x_bearing, extents->y_bearing); + cairo_scale (cr, extents->width, extents->height); + cairo_set_source (cr, pattern); + + cairo_paint (cr); + + cairo_pattern_destroy (pattern); + cairo_surface_destroy (surface); +} + +static void +reduce_anchors (float x0, float y0, + float x1, float y1, + float x2, float y2, + float *xx0, float *yy0, + float *xx1, float *yy1) +{ + float q1x, q1y, q2x, q2y; + float s; + float k; + + q2x = x2 - x0; + q2y = y2 - y0; + q1x = y1 - x0; + q1y = y1 - y0; + + s = q2x * q2x + q2y * q2y; + if (s < 0.000001f) + { + *xx0 = x0; *yy0 = y0; + *xx1 = x1; *yy1 = y1; + return; + } + + k = (q2x * q1x + q2y * q1y) / s; + *xx0 = x0; + *yy0 = y0; + *xx1 = x1 - k * q2x; + *yy1 = y1 - k * q2y; +} + +static int +cmp_color_stop (const void *p1, + const void *p2) +{ + const hb_color_stop_t *c1 = (const hb_color_stop_t *) p1; + const hb_color_stop_t *c2 = (const hb_color_stop_t *) p2; + + if (c1->offset < c2->offset) + return -1; + else if (c1->offset > c2->offset) + return 1; + else + return 0; +} + +static void +normalize_color_line (hb_color_stop_t *stops, + unsigned int len, + float *omin, + float *omax) +{ + float min, max; + + qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); + + min = max = stops[0].offset; + for (unsigned int i = 0; i < len; i++) + { + min = MIN (min, stops[i].offset); + max = MAX (max, stops[i].offset); + } + + if (min != max) + { + for (unsigned int i = 0; i < len; i++) + stops[i].offset = (stops[i].offset - min) / (max - min); + } + + *omin = min; + *omax = max; +} + +void +hb_cairo_paint_linear_gradient (cairo_t *cr, + hb_font_t *font, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2) +{ + hb_face_t *face = hb_font_get_face (font); + unsigned int len; + hb_color_stop_t *stops; + float xx0, yy0, xx1, yy1; + float xxx0, yyy0, xxx1, yyy1; + float min, max; + cairo_pattern_t *pattern; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = (hb_color_stop_t *) alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1); + normalize_color_line (stops, len, &min, &max); + + xxx0 = xx0 + min * (xx1 - xx0); + yyy0 = yy0 + min * (yy1 - yy0); + xxx1 = xx0 + max * (xx1 - xx0); + yyy1 = yy0 + max * (yy1 - yy0); + + pattern = cairo_pattern_create_linear (xxx0, yyy0, xxx1, yyy1); + cairo_pattern_set_extend (pattern, cairo_extend (hb_color_line_get_extend (color_line))); + for (unsigned int i = 0; i < len; i++) + { + float r, g, b, a; + hb_face_get_color (face, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); + } + + cairo_set_source (cr, pattern); + cairo_paint (cr); + + cairo_pattern_destroy (pattern); +} + +void +hb_cairo_paint_radial_gradient (cairo_t *cr, + hb_font_t *font, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1) +{ + hb_face_t *face = hb_font_get_face (font); + unsigned int len; + hb_color_stop_t *stops; + float min, max; + float xx0, yy0, xx1, yy1; + float rr0, rr1; + cairo_pattern_t *pattern; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = (hb_color_stop_t *) alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + normalize_color_line (stops, len, &min, &max); + + xx0 = x0 + min * (x1 - x0); + yy0 = y0 + min * (y1 - y0); + xx1 = x0 + max * (x1 - x0); + yy1 = y0 + max * (y1 - y0); + rr0 = r0 + min * (r1 - r0); + rr1 = r0 + max * (r1 - r0); + + pattern = cairo_pattern_create_radial (xx0, yy0, rr0, xx1, yy1, rr1); + cairo_pattern_set_extend (pattern, cairo_extend (hb_color_line_get_extend (color_line))); + + for (unsigned int i = 0; i < len; i++) + { + float r, g, b, a; + hb_face_get_color (face, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); + } + + cairo_set_source (cr, pattern); + cairo_paint (cr); + + cairo_pattern_destroy (pattern); +} + +typedef struct { + float x, y; +} Point; + +static inline float +interpolate (float f0, float f1, float f) +{ + return f0 + f * (f1 - f0); +} + +void +interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) +{ + c->r = c0->r + k * (c1->r - c0->r); + c->g = c0->g + k * (c1->g - c0->g); + c->b = c0->b + k * (c1->b - c0->b); + c->a = c0->a + k * (c1->a - c0->a); +} + +static inline float +dot (Point p, Point q) +{ + return p.x * q.x + p.y * q.y; +} + +static inline Point +normalize (Point p) +{ + float len = sqrt (dot (p, p)); + + return (Point) { p.x / len, p.y / len }; +} + +static inline Point +sum (Point p, Point q) +{ + return (Point) { p.x + q.x, p.y + q.y }; +} + +static inline Point +difference (Point p, Point q) +{ + return (Point) { p.x - q.x, p.y - q.y }; +} + +static inline Point +scale (Point p, float f) +{ + return (Point) { p.x * f, p.y * f }; +} + +typedef struct { + Point center, p0, c0, c1, p1; + color_t color0, color1; +} Patch; + +static void +add_patch (cairo_pattern_t *pattern, Point *center, Patch *p) +{ + cairo_mesh_pattern_begin_patch (pattern); + cairo_mesh_pattern_move_to (pattern, center->x, center->y); + cairo_mesh_pattern_line_to (pattern, p->p0.x, p->p0.y); + cairo_mesh_pattern_curve_to (pattern, + p->c0.x, p->c0.y, + p->c1.x, p->c1.y, + p->p1.x, p->p1.y); + cairo_mesh_pattern_line_to (pattern, center->x, center->y); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, + p->color0.r, + p->color0.g, + p->color0.b, + p->color0.a); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, + p->color0.r, + p->color0.g, + p->color0.b, + p->color0.a); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, + p->color1.r, + p->color1.g, + p->color1.b, + p->color1.a); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, + p->color1.r, + p->color1.g, + p->color1.b, + p->color1.a); + cairo_mesh_pattern_end_patch (pattern); +} + +#define MAX_ANGLE (M_PI / 8.) + +static void +add_sweep_gradient_patches1 (float cx, float cy, float radius, + float a0, color_t *c0, + float a1, color_t *c1, + cairo_pattern_t *pattern) +{ + Point center = (Point) { cx, cy }; + int num_splits; + Point p0; + color_t color0, color1; + + num_splits = ceilf (fabs (a1 - a0) / MAX_ANGLE); + p0 = (Point) { cosf (a0), sinf (a0) }; + color0 = *c0; + + for (int a = 0; a < num_splits; a++) + { + float k = (a + 1.) / num_splits; + float angle1; + Point p1; + Point A, U; + Point C0, C1; + Patch patch; + + angle1 = interpolate (a0, a1, k); + interpolate_colors (c0, c1, k, &color1); + + patch.color0 = color0; + patch.color1 = color1; + + p1 = (Point) { cosf (angle1), sinf (angle1) }; + patch.p0 = sum (center, scale (p0, radius)); + patch.p1 = sum (center, scale (p1, radius)); + + A = normalize (sum (p0, p1)); + U = (Point) { -A.y, A.x }; + C0 = sum (A, scale (U, dot (difference (p0, A), p0) / dot (U, p0))); + C1 = sum (A, scale (U, dot (difference (p1, A), p1) / dot (U, p1))); + + patch.c0 = sum (center, scale (sum (C0, scale (difference (C0, p0), 0.33333)), radius)); + patch.c1 = sum (center, scale (sum (C1, scale (difference (C1, p1), 0.33333)), radius)); + + add_patch (pattern, ¢er, &patch); + + p0 = p1; + color0 = color1; + } +} + +static void +add_sweep_gradient_patches (hb_font_t *font, + hb_color_stop_t *stops, + unsigned int n_stops, + cairo_extend_t extend, + float cx, float cy, + float radius, + float start_angle, + float end_angle, + cairo_pattern_t *pattern) +{ + hb_face_t *face = hb_font_get_face (font); + float *angles; + color_t *colors; + color_t color0, color1; + + if (start_angle == end_angle) + { + if (extend == CAIRO_EXTEND_PAD) + { + color_t c; + if (start_angle > 0) + { + hb_face_get_color (face, 0, stops[0].color_index, stops[0].alpha, &c.r, &c.g, &c.b, &c.a); + add_sweep_gradient_patches1 (cx, cy, radius, + 0., &c, + start_angle, &c, + pattern); + } + if (end_angle < 2 * M_PI) + { + hb_face_get_color (face, 0, stops[n_stops-1].color_index, stops[n_stops-1].alpha, &c.r, &c.g, &c.b, &c.a); + add_sweep_gradient_patches1 (cx, cy, radius, + end_angle, &c, + 2 * M_PI, &c, + pattern); + } + } + return; + } + + assert (start_angle != end_angle); + + /* handle directions */ + if (end_angle < start_angle) + { + float angle = end_angle; + end_angle = start_angle; + start_angle = angle; + + for (int i = 0; i < n_stops - 1 - i; i++) + { + hb_color_stop_t stop = stops[i]; + stops[i] = stops[n_stops - 1 - i]; + stops[n_stops - 1 - i] = stop; + } + } + + angles = alloca (sizeof (float) * n_stops); + colors = alloca (sizeof (color_t) * n_stops); + + for (int i = 0; i < n_stops; i++) + { + angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); + hb_face_get_color (face, 0, stops[i].color_index, stops[i].alpha, &colors[i].r, &colors[i].g, &colors[i].b, &colors[i].a); + } + + if (extend == CAIRO_EXTEND_PAD) + { + int pos; + + color0 = colors[0]; + for (pos = 0; pos < n_stops; pos++) + { + if (angles[pos] >= 0) + { + if (pos > 0) + { + float k = (0 - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); + interpolate_colors (&colors[pos-1], &colors[pos], k, &color0); + } + break; + } + } + if (pos == n_stops) + { + /* everything is below 0 */ + color0 = colors[n_stops-1]; + add_sweep_gradient_patches1 (cx, cy, radius, + 0., &color0, + 2 * M_PI, &color0, + pattern); + return; + } + + add_sweep_gradient_patches1 (cx, cy, radius, + 0., &color0, + angles[pos], &colors[pos], + pattern); + + for (pos++; pos < n_stops; pos++) + { + if (angles[pos] <= 2 * M_PI) + { + add_sweep_gradient_patches1 (cx, cy, radius, + angles[pos - 1], &colors[pos-1], + angles[pos], &colors[pos], + pattern); + } + else + { + float k = (2 * M_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); + interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1); + add_sweep_gradient_patches1 (cx, cy, radius, + angles[pos - 1], &colors[pos - 1], + 2 * M_PI, &color1, + pattern); + break; + } + } + + if (pos == n_stops) + { + /* everything is below 2*M_PI */ + color0 = colors[n_stops - 1]; + add_sweep_gradient_patches1 (cx, cy, radius, + angles[n_stops - 1], &color0, + 2 * M_PI, &color0, + pattern); + return; + } + } + else + { + int k; + float span; + + span = angles[n_stops - 1] - angles[0]; + k = 0; + if (angles[0] >= 0) + { + float ss = angles[0]; + while (ss > 0) + { + if (span > 0) + { + ss -= span; + k--; + } + else + { + ss += span; + k++; + } + } + } + else if (angles[0] < 0) + { + float ee = angles[n_stops - 1]; + while (ee < 0) + { + if (span > 0) + { + ee += span; + k++; + } + else + { + ee -= span; + k--; + } + } + } + + //assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span); + + for (int l = k; 1; l++) + { + for (int i = 1; i < n_stops; i++) + { + float a0, a1; + color_t *c0, *c1; + + if ((l % 2 != 0) && (extend == CAIRO_EXTEND_REFLECT)) + { + a0 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - (i-1)] + l * span; + a1 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - i] + l * span; + c0 = &colors[n_stops - 1 - (i - 1)]; + c1 = &colors[n_stops - 1 - i]; + } + else + { + a0 = angles[i-1] + l * span; + a1 = angles[i] + l * span; + c0 = &colors[i-1]; + c1 = &colors[i]; + } + + if (a1 < 0) + continue; + if (a0 < 0) + { + color_t color; + float f = (0 - a0)/(a1 - a0); + interpolate_colors (c0, c1, f, &color); + add_sweep_gradient_patches1 (cx, cy, radius, + 0, &color, + a1, c1, + pattern); + } + else if (a1 >= 2 * M_PI) + { + color_t color; + float f = (2 * M_PI - a0)/(a1 - a0); + interpolate_colors (c0, c1, f, &color); + add_sweep_gradient_patches1 (cx, cy, radius, + a0, c0, + 2 * M_PI, &color, + pattern); + goto done; + } + else + { + add_sweep_gradient_patches1 (cx, cy, radius, + a0, c0, + a1, c1, + pattern); + } + } + } +done: ; + } +} + +void +hb_cairo_paint_sweep_gradient (cairo_t *cr, + hb_font_t *font, + hb_color_line_t *color_line, + float cx, float cy, + float start_angle, + float end_angle) +{ + unsigned int len; + hb_color_stop_t *stops; + cairo_extend_t extend; + double x1, y1, x2, y2; + float max_x, max_y, radius; + cairo_pattern_t *pattern; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); + + cairo_clip_extents (cr, &x1, &y1, &x2, &y2); + max_x = MAX ((x1 - cx) * (x1 - cx), (x2 - cx) * (x2 - cx)); + max_y = MAX ((y1 - cy) * (y1 - cy), (y2 - cy) * (y2 - cy)); + radius = sqrt (max_x + max_y); + + extend = cairo_extend (hb_color_line_get_extend (color_line)); + pattern = cairo_pattern_create_mesh (); + + add_sweep_gradient_patches (font, stops, len, extend, cx, cy, + radius, start_angle, end_angle, pattern); + + cairo_set_source (cr, pattern); + cairo_paint (cr); + + cairo_pattern_destroy (pattern); +} diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h new file mode 100644 index 000000000..c36a3a6ff --- /dev/null +++ b/util/hb-cairo-utils.h @@ -0,0 +1,104 @@ +/* + * Copyright © 2022 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. + * + * Google Author(s): Matthias Clasen + */ + +#ifndef HB_CAIRO_UTILS_H +#define HB_CAIRO_UTILS_H + +extern "C" { + +static inline cairo_operator_t +hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) +{ + switch (mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: return CAIRO_OPERATOR_CLEAR; + case HB_PAINT_COMPOSITE_MODE_SRC: return CAIRO_OPERATOR_SOURCE; + case HB_PAINT_COMPOSITE_MODE_DEST: return CAIRO_OPERATOR_DEST; + case HB_PAINT_COMPOSITE_MODE_SRC_OVER: return CAIRO_OPERATOR_OVER; + case HB_PAINT_COMPOSITE_MODE_DEST_OVER: return CAIRO_OPERATOR_DEST_OVER; + case HB_PAINT_COMPOSITE_MODE_SRC_IN: return CAIRO_OPERATOR_IN; + case HB_PAINT_COMPOSITE_MODE_DEST_IN: return CAIRO_OPERATOR_DEST_IN; + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: return CAIRO_OPERATOR_OUT; + case HB_PAINT_COMPOSITE_MODE_DEST_OUT: return CAIRO_OPERATOR_DEST_OUT; + case HB_PAINT_COMPOSITE_MODE_SRC_ATOP: return CAIRO_OPERATOR_ATOP; + case HB_PAINT_COMPOSITE_MODE_DEST_ATOP: return CAIRO_OPERATOR_DEST_ATOP; + case HB_PAINT_COMPOSITE_MODE_XOR: return CAIRO_OPERATOR_XOR; + case HB_PAINT_COMPOSITE_MODE_PLUS: return CAIRO_OPERATOR_ADD; + case HB_PAINT_COMPOSITE_MODE_SCREEN: return CAIRO_OPERATOR_SCREEN; + case HB_PAINT_COMPOSITE_MODE_OVERLAY: return CAIRO_OPERATOR_OVERLAY; + case HB_PAINT_COMPOSITE_MODE_DARKEN: return CAIRO_OPERATOR_DARKEN; + case HB_PAINT_COMPOSITE_MODE_LIGHTEN: return CAIRO_OPERATOR_LIGHTEN; + case HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: return CAIRO_OPERATOR_COLOR_DODGE; + case HB_PAINT_COMPOSITE_MODE_COLOR_BURN: return CAIRO_OPERATOR_COLOR_BURN; + case HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: return CAIRO_OPERATOR_HARD_LIGHT; + case HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: return CAIRO_OPERATOR_SOFT_LIGHT; + case HB_PAINT_COMPOSITE_MODE_DIFFERENCE: return CAIRO_OPERATOR_DIFFERENCE; + case HB_PAINT_COMPOSITE_MODE_EXCLUSION: return CAIRO_OPERATOR_EXCLUSION; + case HB_PAINT_COMPOSITE_MODE_MULTIPLY: return CAIRO_OPERATOR_MULTIPLY; + case HB_PAINT_COMPOSITE_MODE_HSL_HUE: return CAIRO_OPERATOR_HSL_HUE; + case HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: return CAIRO_OPERATOR_HSL_SATURATION; + case HB_PAINT_COMPOSITE_MODE_HSL_COLOR: return CAIRO_OPERATOR_HSL_COLOR; + case HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: return CAIRO_OPERATOR_HSL_LUMINOSITY; + default:; + } + + return CAIRO_OPERATOR_SOURCE; +} + +void hb_face_get_color (hb_face_t *face, + unsigned int palette_index, + unsigned int color_index, + float alpha, + float *r, float *g, float *b, float *a); + +void hb_cairo_paint_glyph_image (cairo_t *cr, + hb_font_t *font, + hb_blob_t *blob, + hb_tag_t format, + hb_glyph_extents_t *extents); + +void hb_cairo_paint_linear_gradient (cairo_t *cr, + hb_font_t *font, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2); + +void hb_cairo_paint_radial_gradient (cairo_t *cr, + hb_font_t *font, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1); + +void hb_cairo_paint_sweep_gradient (cairo_t *cr, + hb_font_t *font, + hb_color_line_t *color_line, + float x0, float y0, + float start_angle, float end_angle); + +} + +#endif diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 8c1f9f222..d3f5e6aa8 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -27,12 +27,17 @@ #ifndef HELPER_CAIRO_USER_HH #define HELPER_CAIRO_USER_HH +#include "config.h" + #include "font-options.hh" #include #include #include "hb-blob.hh" +#include "hb-cairo-utils.h" + +static const cairo_user_data_key_t _hb_font_cairo_user_data_key = {0}; static void move_to (hb_draw_funcs_t *dfuncs, @@ -82,7 +87,7 @@ close_path (hb_draw_funcs_t *dfuncs, static hb_draw_funcs_t * -get_cairo_draw_funcs () +get_cairo_draw_funcs (void) { static hb_draw_funcs_t *funcs; @@ -98,7 +103,219 @@ get_cairo_draw_funcs () return funcs; } -static const cairo_user_data_key_t _hb_font_cairo_user_data_key = {0}; +#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC + +typedef struct { + cairo_t *cr; + hb_font_t *font; + hb_font_t *unscaled_font; +} paint_data_t; + +static void +push_transform (hb_paint_funcs_t *funcs, + void *paint_data, + float xx, float yx, + float xy, float yy, + float dx, float dy, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + cairo_matrix_t m; + + cairo_save (cr); + cairo_matrix_init (&m, xx, yx, xy, yy, dx, dy); + cairo_transform (data->cr, &m); +} + +static void +pop_transform (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_restore (cr); +} + +static void +push_clip_glyph (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_save (cr); + cairo_new_path (cr); + hb_font_get_glyph_shape (data->unscaled_font, glyph, get_cairo_draw_funcs (), cr); + cairo_close_path (cr); + cairo_clip (cr); +} + +static void +push_clip_rectangle (hb_paint_funcs_t *funcs, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_save (cr); + cairo_rectangle (cr, xmin, ymin, xmax - xmin, ymax - ymin); + cairo_clip (cr); +} + +static void +pop_clip (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_restore (cr); +} + +static void +push_group (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_save (cr); + cairo_push_group (cr); +} + +static void +pop_group (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_pop_group_to_source (cr); + cairo_set_operator (cr, hb_paint_composite_mode_to_cairo (mode)); + cairo_paint (cr); + + cairo_restore (cr); +} + +static void +paint_color (hb_paint_funcs_t *funcs, + void *paint_data, + unsigned int color_index, + float alpha, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + hb_face_t *face = hb_font_get_face (data->font); + cairo_t *cr = data->cr; + float r, g, b, a; + + hb_face_get_color (face, 0, color_index, alpha, &r, &g, &b, &a); + cairo_set_source_rgba (cr, r, g, b, a); + cairo_paint (cr); +} + +static void +paint_image (hb_paint_funcs_t *funcs, + void *paint_data, + hb_blob_t *blob, + hb_tag_t format, + hb_glyph_extents_t *extents, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; + + if (format != HB_PAINT_IMAGE_FORMAT_PNG || !extents) + return; + + hb_cairo_paint_glyph_image (cr, font, blob, format, extents); +} + +static void +paint_linear_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; + + hb_cairo_paint_linear_gradient (cr, font, color_line, x0, y0, x1, y1, x2, y2); +} + +static void +paint_radial_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; + + hb_cairo_paint_radial_gradient (cr, font, color_line, x0, y0, r0, x1, y1, r1); +} + +static void +paint_sweep_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float start_angle, float end_angle, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; + + hb_cairo_paint_sweep_gradient (cr, font, color_line, x0, y0, start_angle, end_angle); +} + +static hb_paint_funcs_t * +get_cairo_paint_funcs (void) +{ + static hb_paint_funcs_t *funcs; + + if (!funcs) + { + funcs = hb_paint_funcs_create (); + + hb_paint_funcs_set_push_transform_func (funcs, push_transform, nullptr, nullptr); + hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, nullptr, nullptr); + hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, nullptr, nullptr); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, nullptr, nullptr); + hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, nullptr, nullptr); + hb_paint_funcs_set_push_group_func (funcs, push_group, nullptr, nullptr); + hb_paint_funcs_set_pop_group_func (funcs, pop_group, nullptr, nullptr); + hb_paint_funcs_set_color_func (funcs, paint_color, nullptr, nullptr); + hb_paint_funcs_set_image_func (funcs, paint_image, nullptr, nullptr); + hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, nullptr, nullptr); + hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, nullptr, nullptr); + hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, nullptr, nullptr); + } + + return funcs; +} + +#endif static cairo_status_t render_glyph (cairo_scaled_font_t *scaled_font, @@ -121,158 +338,34 @@ render_glyph (cairo_scaled_font_t *scaled_font, #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC -#ifdef CAIRO_HAS_PNG_FUNCTIONS -static inline cairo_status_t -_hb_bytes_read_func (hb_bytes_t *src, - char *data, - unsigned length) -{ - if (unlikely (src->length < length)) - return CAIRO_STATUS_READ_ERROR; - - memcpy (data, src->arrayZ, length); - *src += length; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -render_color_glyph_png (cairo_scaled_font_t *scaled_font, - unsigned long glyph, - cairo_t *cr, - cairo_text_extents_t *extents) -{ - hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), - &_hb_font_cairo_user_data_key)); - - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph); - if (blob == hb_blob_get_empty ()) - return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; - - hb_position_t x_scale, y_scale; - hb_font_get_scale (font, &x_scale, &y_scale); - cairo_scale (cr, +1./x_scale, -1./y_scale); - - /* Draw PNG. */ - hb_bytes_t bytes = blob->as_bytes (); - cairo_surface_t *surface = cairo_image_surface_create_from_png_stream ((cairo_read_func_t) _hb_bytes_read_func, - std::addressof (bytes)); - hb_blob_destroy (blob); - - if (unlikely (cairo_surface_status (surface)) != CAIRO_STATUS_SUCCESS) - { - cairo_surface_destroy (surface); - return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; - } - - int width = cairo_image_surface_get_width (surface); - int height = cairo_image_surface_get_width (surface); - - hb_glyph_extents_t hb_extents; - if (unlikely (!hb_font_get_glyph_extents (font, glyph, &hb_extents))) - { - cairo_surface_destroy (surface); - return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; - } - - cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); - cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); - - cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; - cairo_pattern_set_matrix (pattern, &matrix); - - cairo_translate (cr, hb_extents.x_bearing, hb_extents.y_bearing); - cairo_scale (cr, hb_extents.width, hb_extents.height); - cairo_set_source (cr, pattern); - - cairo_rectangle (cr, 0, 0, 1, 1); - cairo_fill (cr); - cairo_pattern_destroy (pattern); - - cairo_surface_destroy (surface); - return CAIRO_STATUS_SUCCESS; -} -#endif - -static cairo_status_t -render_color_glyph_layers (cairo_scaled_font_t *scaled_font, - unsigned long glyph, - cairo_t *cr, - cairo_text_extents_t *extents) -{ - hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), - &_hb_font_cairo_user_data_key)); - hb_face_t *face = hb_font_get_face (font); - - unsigned count = hb_ot_color_glyph_get_layers (face, glyph, 0, nullptr, nullptr); - if (!count) - return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; - - hb_ot_color_layer_t layers[16]; - unsigned offset = 0, len; - do { - len = ARRAY_LENGTH (layers); - hb_ot_color_glyph_get_layers (face, glyph, - offset, - &len, - layers); - for (unsigned i = 0; i < len; i++) - { - hb_color_t color; - unsigned clen = 1; - unsigned color_index = layers[i].color_index; - bool is_foreground = color_index == 65535; - - if (!is_foreground) - { - hb_ot_color_palette_get_colors (face, - 0/*palette_index*/, - color_index/*start_offset*/, - &clen/*color_count*/, - &color); - if (clen < 1) - continue; - } - - cairo_save (cr); - { - if (!is_foreground) - cairo_set_source_rgba (cr, - hb_color_get_red (color) / 255., - hb_color_get_green (color) / 255., - hb_color_get_blue (color) / 255., - hb_color_get_alpha (color) / 255.); - - cairo_status_t ret = render_glyph (scaled_font, layers[i].glyph, cr, extents); - if (ret != CAIRO_STATUS_SUCCESS) - return ret; - } - cairo_restore (cr); - } - } - while (len == ARRAY_LENGTH (layers)); - return CAIRO_STATUS_SUCCESS; -} - static cairo_status_t render_color_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *extents) { - cairo_status_t ret = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; + hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), + &_hb_font_cairo_user_data_key)); + paint_data_t paint_data; -#ifdef CAIRO_HAS_PNG_FUNCTIONS - ret = render_color_glyph_png (scaled_font, glyph, cr, extents); - if (ret != CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED) - return ret; -#endif + paint_data.cr = cr; + paint_data.font = font; - ret = render_color_glyph_layers (scaled_font, glyph, cr, extents); - if (ret != CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED) - return ret; + hb_face_t *face = hb_font_get_face (font); + paint_data.unscaled_font = hb_font_create (face); + unsigned int upem = hb_face_get_upem (face); + hb_font_set_scale (paint_data.unscaled_font, upem, upem); + hb_font_set_synthetic_slant (paint_data.unscaled_font, 0.); - return render_glyph (scaled_font, glyph, cr, extents); + hb_position_t x_scale, y_scale; + hb_font_get_scale (font, &x_scale, &y_scale); + cairo_scale (cr, +1./x_scale, -1./y_scale); + + hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), (void *)&paint_data); + + hb_font_destroy (paint_data.unscaled_font); + + return CAIRO_STATUS_SUCCESS; } #endif @@ -288,10 +381,13 @@ helper_cairo_create_user_font_face (const font_options_t *font_opts) (cairo_destroy_func_t) hb_font_destroy); cairo_user_font_face_set_render_glyph_func (cairo_face, render_glyph); + #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC hb_face_t *face = hb_font_get_face (font_opts->font); - if (hb_ot_color_has_png (face) || hb_ot_color_has_layers (face)) + if (hb_ot_color_has_png (face) || hb_ot_color_has_layers (face) || hb_ot_color_has_paint (face)) + { cairo_user_font_face_set_render_color_glyph_func (cairo_face, render_color_glyph); + } #endif return cairo_face; @@ -310,7 +406,7 @@ helper_cairo_user_scaled_font_has_color (cairo_scaled_font_t *scaled_font) hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &_hb_font_cairo_user_data_key)); hb_face_t *face = hb_font_get_face (font); - return hb_ot_color_has_png (face) || hb_ot_color_has_layers (face); + return hb_ot_color_has_png (face) || hb_ot_color_has_layers (face) || hb_ot_color_has_paint (face); } #endif diff --git a/util/meson.build b/util/meson.build index 2e57cf1e4..8ac700b28 100644 --- a/util/meson.build +++ b/util/meson.build @@ -1,5 +1,6 @@ hb_view_sources = [ 'hb-view.cc', + 'hb-cairo-utils.c' ] hb_shape_sources = [ From f1f8d1e855a4628a59bfc9b8b55d94a9e35e31de Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 02:43:25 -0500 Subject: [PATCH 072/219] Small documentation addition --- src/hb-font.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-font.cc b/src/hb-font.cc index e8c63af98..7aa1a7170 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1401,6 +1401,9 @@ hb_font_get_glyph_shape (hb_font_t *font, * calls to the callbacks of the @funcs objects, * with @paint_data passed to them. * + * Note that this function applies the the scale and synthetic + * slant of the font as outermost transform. + * * Since: REPLACEME */ void From 8bcd13dd91916a436fa357fa73f9d4477d8a02ff Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 09:41:00 -0500 Subject: [PATCH 073/219] small fixup to hb-cairo-utils --- util/hb-cairo-utils.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index c36a3a6ff..9d353be67 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -24,10 +24,11 @@ * Google Author(s): Matthias Clasen */ -#ifndef HB_CAIRO_UTILS_H -#define HB_CAIRO_UTILS_H +#pragma once -extern "C" { +#include + +HB_BEGIN_DECLS static inline cairo_operator_t hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) @@ -99,6 +100,4 @@ void hb_cairo_paint_sweep_gradient (cairo_t *cr, float x0, float y0, float start_angle, float end_angle); -} - -#endif +HB_END_DECLS From 6cadf280f286f5ad59466d71fd2b7f8c2fd5d267 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 09:42:18 -0500 Subject: [PATCH 074/219] Use hb-cairo-utils in hb-test Just to prove that it works. --- util/hb-test.c | 1043 +++++++--------------------------------------- util/meson.build | 2 +- 2 files changed, 151 insertions(+), 894 deletions(-) diff --git a/util/hb-test.c b/util/hb-test.c index 87370f400..c984db67a 100644 --- a/util/hb-test.c +++ b/util/hb-test.c @@ -8,124 +8,80 @@ #include #include #include +#include "hb-cairo-utils.h" -#ifndef MIN -#define MIN(x,y) ((x) < (y) ? (x) : (y)) -#endif +static void +move_to (hb_draw_funcs_t *dfuncs, + cairo_t *cr, + hb_draw_state_t *st, + float to_x, float to_y, + void *) +{ + cairo_move_to (cr, + (double) to_x, (double) to_y); +} -#ifndef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#endif +static void +line_to (hb_draw_funcs_t *dfuncs, + cairo_t *cr, + hb_draw_state_t *st, + float to_x, float to_y, + void *) +{ + cairo_line_to (cr, + (double) to_x, (double) to_y); +} + +static void +cubic_to (hb_draw_funcs_t *dfuncs, + cairo_t *cr, + hb_draw_state_t *st, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *) +{ + cairo_curve_to (cr, + (double) control1_x, (double) control1_y, + (double) control2_x, (double) control2_y, + (double) to_x, (double) to_y); +} + +static void +close_path (hb_draw_funcs_t *dfuncs, + cairo_t *cr, + hb_draw_state_t *st, + void *) +{ + cairo_close_path (cr); +} + + +static hb_draw_funcs_t * +get_cairo_draw_funcs (void) +{ + static hb_draw_funcs_t *funcs; + + if (!funcs) + { + funcs = hb_draw_funcs_create (); + hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, NULL, NULL); + hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, NULL, NULL); + hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL); + hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL); + } + + return funcs; +} -#ifndef FALSE -#define FALSE 0 -#define TRUE 1 -#endif typedef struct { - int level; cairo_t *cr; hb_font_t *font; hb_font_t *unscaled_font; - hb_color_t *colors; - unsigned int num_colors; - hb_color_t foreground_color; + int level; } paint_data_t; -#define INDENT 2 - -static void -print (paint_data_t *data, - const char *format, - ...) -{ - va_list args; - - printf ("%*s", INDENT * data->level, ""); - - va_start (args, format); - vprintf (format, args); - va_end (args); - - printf ("\n"); -} - -typedef struct { - float r, g, b, a; -} color_t; - -static void -get_color (paint_data_t *data, - unsigned int color_index, - float alpha, - color_t *c) -{ - hb_color_t color; - - if (color_index == 0xffff) - color = data->foreground_color; - else - color = data->colors[color_index]; - - c->r = hb_color_get_red (color) / 255.; - c->g = hb_color_get_green (color) / 255.; - c->b = hb_color_get_blue (color) / 255.; - c->a = (hb_color_get_alpha (color) / 255.) * alpha; -} - -static cairo_operator_t -to_operator (hb_paint_composite_mode_t mode) -{ - switch (mode) - { - case HB_PAINT_COMPOSITE_MODE_CLEAR: return CAIRO_OPERATOR_CLEAR; - case HB_PAINT_COMPOSITE_MODE_SRC: return CAIRO_OPERATOR_SOURCE; - case HB_PAINT_COMPOSITE_MODE_DEST: return CAIRO_OPERATOR_DEST; - case HB_PAINT_COMPOSITE_MODE_SRC_OVER: return CAIRO_OPERATOR_OVER; - case HB_PAINT_COMPOSITE_MODE_DEST_OVER: return CAIRO_OPERATOR_DEST_OVER; - case HB_PAINT_COMPOSITE_MODE_SRC_IN: return CAIRO_OPERATOR_IN; - case HB_PAINT_COMPOSITE_MODE_DEST_IN: return CAIRO_OPERATOR_DEST_IN; - case HB_PAINT_COMPOSITE_MODE_SRC_OUT: return CAIRO_OPERATOR_OUT; - case HB_PAINT_COMPOSITE_MODE_DEST_OUT: return CAIRO_OPERATOR_DEST_OUT; - case HB_PAINT_COMPOSITE_MODE_SRC_ATOP: return CAIRO_OPERATOR_ATOP; - case HB_PAINT_COMPOSITE_MODE_DEST_ATOP: return CAIRO_OPERATOR_DEST_ATOP; - case HB_PAINT_COMPOSITE_MODE_XOR: return CAIRO_OPERATOR_XOR; - case HB_PAINT_COMPOSITE_MODE_PLUS: return CAIRO_OPERATOR_ADD; - case HB_PAINT_COMPOSITE_MODE_SCREEN: return CAIRO_OPERATOR_SCREEN; - case HB_PAINT_COMPOSITE_MODE_OVERLAY: return CAIRO_OPERATOR_OVERLAY; - case HB_PAINT_COMPOSITE_MODE_DARKEN: return CAIRO_OPERATOR_DARKEN; - case HB_PAINT_COMPOSITE_MODE_LIGHTEN: return CAIRO_OPERATOR_LIGHTEN; - case HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: return CAIRO_OPERATOR_COLOR_DODGE; - case HB_PAINT_COMPOSITE_MODE_COLOR_BURN: return CAIRO_OPERATOR_COLOR_BURN; - case HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: return CAIRO_OPERATOR_HARD_LIGHT; - case HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: return CAIRO_OPERATOR_SOFT_LIGHT; - case HB_PAINT_COMPOSITE_MODE_DIFFERENCE: return CAIRO_OPERATOR_DIFFERENCE; - case HB_PAINT_COMPOSITE_MODE_EXCLUSION: return CAIRO_OPERATOR_EXCLUSION; - case HB_PAINT_COMPOSITE_MODE_MULTIPLY: return CAIRO_OPERATOR_MULTIPLY; - case HB_PAINT_COMPOSITE_MODE_HSL_HUE: return CAIRO_OPERATOR_HSL_HUE; - case HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: return CAIRO_OPERATOR_HSL_SATURATION; - case HB_PAINT_COMPOSITE_MODE_HSL_COLOR: return CAIRO_OPERATOR_HSL_COLOR; - case HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: return CAIRO_OPERATOR_HSL_LUMINOSITY; - default:; - } - - return CAIRO_OPERATOR_SOURCE; -} - -static cairo_extend_t -cairo_extend (hb_paint_extend_t extend) -{ - switch (extend) - { - case HB_PAINT_EXTEND_PAD: return CAIRO_EXTEND_PAD; - case HB_PAINT_EXTEND_REPEAT: return CAIRO_EXTEND_REPEAT; - case HB_PAINT_EXTEND_REFLECT: return CAIRO_EXTEND_REFLECT; - default:; - } - - return CAIRO_EXTEND_PAD; -} - static void push_transform (hb_paint_funcs_t *funcs, void *paint_data, @@ -134,16 +90,13 @@ push_transform (hb_paint_funcs_t *funcs, float dx, float dy, void *user_data) { - paint_data_t *data = user_data; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; cairo_matrix_t m; - print (data, "start transform %f %f %f %f %f %f", xx, yx, xy, yy, dx, dy); - - cairo_save (data->cr); + cairo_save (cr); cairo_matrix_init (&m, xx, yx, xy, yy, dx, dy); cairo_transform (data->cr, &m); - - data->level++; } static void @@ -151,66 +104,10 @@ pop_transform (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) { - paint_data_t *data = user_data; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; - data->level--; - - cairo_restore (data->cr); - - print (data, "end transform"); -} - -static void -move_to (hb_draw_funcs_t *funcs, void *draw_data, - hb_draw_state_t *st, - float x, float y, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "move to %f %f", x, y); - - cairo_move_to (data->cr, x, y); -} - -static void -line_to (hb_draw_funcs_t *funcs, void *draw_data, - hb_draw_state_t *st, - float x, float y, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "line to %f %f", x, y); - - cairo_line_to (data->cr, x, y); -} - -static void -cubic_to (hb_draw_funcs_t *funcs, void *draw_data, - hb_draw_state_t *st, - float c1x, float c1y, - float c2x, float c2y, - float x, float y, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "curve to %f %f %f %f %f %f", c1x, c1y, c2x, c2y, x, y); - - cairo_curve_to (data->cr, c1x, c1y, c2x, c2y, x, y); -} - -static void -close_path (hb_draw_funcs_t *funcs, void *draw_data, - hb_draw_state_t *st, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "close path\n"); - - cairo_close_path (data->cr); + cairo_restore (cr); } static void @@ -219,29 +116,14 @@ push_clip_glyph (hb_paint_funcs_t *funcs, hb_codepoint_t glyph, void *user_data) { - paint_data_t *data = user_data; - hb_draw_funcs_t *dfuncs; - print (data, "start clip glyph %u", glyph); - data->level++; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; - cairo_save (data->cr); - - dfuncs = hb_draw_funcs_create (); - hb_draw_funcs_set_move_to_func (dfuncs, move_to, data, NULL); - hb_draw_funcs_set_line_to_func (dfuncs, line_to, data, NULL); - hb_draw_funcs_set_cubic_to_func (dfuncs, cubic_to, data, NULL); - hb_draw_funcs_set_close_path_func (dfuncs, close_path, data, NULL); - - cairo_new_path (data->cr); - /* Note: we need to use a upem-scaled, unslanted copy of the font here, - * since hb has already applied the root transform. - */ - hb_font_get_glyph_shape (data->unscaled_font, glyph, dfuncs, data); - cairo_close_path (data->cr); - - cairo_clip (data->cr); - - hb_draw_funcs_destroy (dfuncs); + cairo_save (cr); + cairo_new_path (cr); + hb_font_get_glyph_shape (data->unscaled_font, glyph, get_cairo_draw_funcs (), cr); + cairo_close_path (cr); + cairo_clip (cr); } static void @@ -250,16 +132,12 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, float xmin, float ymin, float xmax, float ymax, void *user_data) { - paint_data_t *data = user_data; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; - print (data, "start clip rectangle %f %f %f %f", xmin, ymin, xmax, ymax); - data->level++; - - cairo_save (data->cr); - - cairo_rectangle (data->cr, xmin, ymin, xmax - xmin, ymax - ymin); - - cairo_clip (data->cr); + cairo_save (cr); + cairo_rectangle (cr, xmin, ymin, xmax - xmin, ymax - ymin); + cairo_clip (cr); } static void @@ -267,12 +145,38 @@ pop_clip (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) { - paint_data_t *data = user_data; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; - cairo_restore (data->cr); + cairo_restore (cr); +} - data->level--; - print (data, "end clip"); +static void +push_group (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_save (cr); + cairo_push_group (cr); +} + +static void +pop_group (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data) +{ + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + + cairo_pop_group_to_source (cr); + cairo_set_operator (cr, hb_paint_composite_mode_to_cairo (mode)); + cairo_paint (cr); + + cairo_restore (cr); } static void @@ -282,43 +186,14 @@ paint_color (hb_paint_funcs_t *funcs, float alpha, void *user_data) { - paint_data_t *data = user_data; - color_t c; + paint_data_t *data = (paint_data_t *) paint_data; + hb_face_t *face = hb_font_get_face (data->font); + cairo_t *cr = data->cr; + float r, g, b, a; - print (data, "solid %u %f", color_index, alpha); - - get_color (data, color_index, alpha, &c); - data->level++; - print (data, "color %f %f %f %f", c.r, c.g, c.b, c.a); - data->level--; - cairo_set_source_rgba (data->cr, c.r, c.g, c.b, c.a); - cairo_paint (data->cr); -} - -typedef struct -{ - hb_blob_t *blob; - unsigned int offset; -} read_blob_data_t; - -cairo_status_t -read_blob (void *closure, - unsigned char *data, - unsigned int length) -{ - read_blob_data_t *r = closure; - const char *d; - unsigned int size; - - d = hb_blob_get_data (r->blob, &size); - - if (r->offset + length > size) - return CAIRO_STATUS_READ_ERROR; - - memcpy (data, d + r->offset, length); - r->offset += length; - - return CAIRO_STATUS_SUCCESS; + hb_face_get_color (face, 0, color_index, alpha, &r, &g, &b, &a); + cairo_set_source_rgba (cr, r, g, b, a); + cairo_paint (cr); } static void @@ -329,107 +204,11 @@ paint_image (hb_paint_funcs_t *funcs, hb_glyph_extents_t *extents, void *user_data) { - paint_data_t *data = user_data; - read_blob_data_t r; - cairo_surface_t *surface; - cairo_pattern_t *pattern; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; - if (format != HB_PAINT_IMAGE_FORMAT_PNG || !extents) - return; - - r.blob = blob; - r.offset = 0; - surface = cairo_image_surface_create_from_png_stream (read_blob, &r); - int width = cairo_image_surface_get_width (surface); - int height = cairo_image_surface_get_width (surface); - - pattern = cairo_pattern_create_for_surface (surface); - cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); - - cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; - cairo_pattern_set_matrix (pattern, &matrix); - - cairo_translate (data->cr, extents->x_bearing, extents->y_bearing); - cairo_scale (data->cr, extents->width, extents->height); - cairo_set_source (data->cr, pattern); - - cairo_paint (data->cr); - - cairo_pattern_destroy (pattern); - cairo_surface_destroy (surface); -} - -static void -reduce_anchors (float x0, float y0, - float x1, float y1, - float x2, float y2, - float *xx0, float *yy0, - float *xx1, float *yy1) -{ - float q1x, q1y, q2x, q2y; - float s; - float k; - - q2x = x2 - x0; - q2y = y2 - y0; - q1x = y1 - x0; - q1y = y1 - y0; - - s = q2x * q2x + q2y * q2y; - if (s < 0.000001) - { - *xx0 = x0; *yy0 = y0; - *xx1 = x1; *yy1 = y1; - return; - } - - k = (q2x * q1x + q2y * q1y) / s; - *xx0 = x0; - *yy0 = y0; - *xx1 = x1 - k * q2x; - *yy1 = y1 - k * q2y; -} - -static int -cmp_color_stop (const void *p1, - const void *p2) -{ - const hb_color_stop_t *c1 = p1; - const hb_color_stop_t *c2 = p2; - - if (c1->offset < c2->offset) - return -1; - else if (c1->offset > c2->offset) - return 1; - else - return 0; -} - -static void -normalize_color_line (hb_color_stop_t *stops, - unsigned int len, - float *omin, - float *omax) -{ - float min, max; - - qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); - - min = max = stops[0].offset; - for (unsigned int i = 0; i < len; i++) - { - min = MIN (min, stops[i].offset); - max = MAX (max, stops[i].offset); - } - - if (min != max) - { - for (unsigned int i = 0; i < len; i++) - stops[i].offset = (stops[i].offset - min) / (max - min); - } - - *omin = min; - *omax = max; + hb_cairo_paint_glyph_image (cr, font, blob, format, extents); } static void @@ -441,50 +220,11 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, float x2, float y2, void *user_data) { - paint_data_t *data = user_data; - unsigned int len; - hb_color_stop_t *stops; - float xx0, yy0, xx1, yy1; - float xxx0, yyy0, xxx1, yyy1; - float min, max; - cairo_pattern_t *pattern; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; - len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = alloca (len * sizeof (hb_color_stop_t)); - hb_color_line_get_color_stops (color_line, 0, &len, stops); - - print (data, "linear gradient"); - data->level += 1; - print (data, "p0 %f %f", x0, y0); - print (data, "p1 %f %f", x1, y1); - print (data, "p2 %f %f", x2, y2); - print (data, "colors"); - data->level += 1; - for (unsigned int i = 0; i < len; i++) - print (data, "%f %u %f", stops[i].offset, stops[i].color_index, stops[i].alpha); - data->level -= 2; - - reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1); - normalize_color_line (stops, len, &min, &max); - - xxx0 = xx0 + min * (xx1 - xx0); - yyy0 = yy0 + min * (yy1 - yy0); - xxx1 = xx0 + max * (xx1 - xx0); - yyy1 = yy0 + max * (yy1 - yy0); - - pattern = cairo_pattern_create_linear (xxx0, yyy0, xxx1, yyy1); - cairo_pattern_set_extend (pattern, cairo_extend (hb_color_line_get_extend (color_line))); - for (unsigned int i = 0; i < len; i++) - { - color_t c; - get_color (data, stops[i].color_index, stops[i].alpha, &c); - cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, c.r, c.g, c.b, c.a); - } - - cairo_set_source (data->cr, pattern); - cairo_paint (data->cr); - - cairo_pattern_destroy (pattern); + hb_cairo_paint_linear_gradient (cr, font, color_line, x0, y0, x1, y1, x2, y2); } static void @@ -495,504 +235,28 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, float x1, float y1, float r1, void *user_data) { - paint_data_t *data = user_data; - unsigned int len; - hb_color_stop_t *stops; - cairo_extend_t extend; - float min, max; - float xx0, yy0, xx1, yy1; - float rr0, rr1; - cairo_pattern_t *pattern; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; - print (data, "radial gradient"); - - len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = alloca (len * sizeof (hb_color_stop_t)); - hb_color_line_get_color_stops (color_line, 0, &len, stops); - - extend = cairo_extend (hb_color_line_get_extend (color_line)); - - normalize_color_line (stops, len, &min, &max); - xx0 = x0 + min * (x1 - x0); - yy0 = y0 + min * (y1 - y0); - xx1 = x0 + max * (x1 - x0); - yy1 = y0 + max * (y1 - y0); - rr0 = r0 + min * (r1 - r0); - rr1 = r0 + max * (r1 - r0); - - pattern = cairo_pattern_create_radial (xx0, yy0, rr0, xx1, yy1, rr1); - cairo_pattern_set_extend (pattern, extend); - - for (unsigned int i = 0; i < len; i++) - { - color_t c; - - get_color (data, stops[i].color_index, stops[i].alpha, &c); - cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, c.r, c.g, c.b, c.a); - } - - cairo_set_source (data->cr, pattern); - cairo_paint (data->cr); - - cairo_pattern_destroy (pattern); -} - -typedef struct { - float x, y; -} Point; - -static inline float -interpolate (float f0, float f1, float f) -{ - return f0 + f * (f1 - f0); -} - -void -interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) -{ - c->r = c0->r + k * (c1->r - c0->r); - c->g = c0->g + k * (c1->g - c0->g); - c->b = c0->b + k * (c1->b - c0->b); - c->a = c0->a + k * (c1->a - c0->a); -} - -static inline float -dot (Point p, Point q) -{ - return p.x * q.x + p.y * q.y; -} - -static inline Point -normalize (Point p) -{ - float len = sqrt (dot (p, p)); - - return (Point) { p.x / len, p.y / len }; -} - -static inline Point -sum (Point p, Point q) -{ - return (Point) { p.x + q.x, p.y + q.y }; -} - -static inline Point -difference (Point p, Point q) -{ - return (Point) { p.x - q.x, p.y - q.y }; -} - -static inline Point -scale (Point p, float f) -{ - return (Point) { p.x * f, p.y * f }; -} - -typedef struct { - Point center, p0, c0, c1, p1; - color_t color0, color1; -} Patch; - -static void -add_patch (cairo_pattern_t *pattern, Point *center, Patch *p) -{ - cairo_mesh_pattern_begin_patch (pattern); - cairo_mesh_pattern_move_to (pattern, center->x, center->y); - cairo_mesh_pattern_line_to (pattern, p->p0.x, p->p0.y); - cairo_mesh_pattern_curve_to (pattern, - p->c0.x, p->c0.y, - p->c1.x, p->c1.y, - p->p1.x, p->p1.y); - cairo_mesh_pattern_line_to (pattern, center->x, center->y); - cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, - p->color0.r, - p->color0.g, - p->color0.b, - p->color0.a); - cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, - p->color0.r, - p->color0.g, - p->color0.b, - p->color0.a); - cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, - p->color1.r, - p->color1.g, - p->color1.b, - p->color1.a); - cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, - p->color1.r, - p->color1.g, - p->color1.b, - p->color1.a); - cairo_mesh_pattern_end_patch (pattern); -} - -#define MAX_ANGLE (M_PI / 8.) - -static void -add_sweep_gradient_patches1 (float cx, float cy, float radius, - float a0, color_t *c0, - float a1, color_t *c1, - cairo_pattern_t *pattern) -{ - Point center = (Point) { cx, cy }; - int num_splits; - Point p0; - color_t color0, color1; - - num_splits = ceilf (fabs (a1 - a0) / MAX_ANGLE); - p0 = (Point) { cosf (a0), sinf (a0) }; - color0 = *c0; - - for (int a = 0; a < num_splits; a++) - { - float k = (a + 1.) / num_splits; - float angle1; - Point p1; - Point A, U; - Point C0, C1; - Patch patch; - - angle1 = interpolate (a0, a1, k); - interpolate_colors (c0, c1, k, &color1); - - patch.color0 = color0; - patch.color1 = color1; - - p1 = (Point) { cosf (angle1), sinf (angle1) }; - patch.p0 = sum (center, scale (p0, radius)); - patch.p1 = sum (center, scale (p1, radius)); - - A = normalize (sum (p0, p1)); - U = (Point) { -A.y, A.x }; - C0 = sum (A, scale (U, dot (difference (p0, A), p0) / dot (U, p0))); - C1 = sum (A, scale (U, dot (difference (p1, A), p1) / dot (U, p1))); - - patch.c0 = sum (center, scale (sum (C0, scale (difference (C0, p0), 0.33333)), radius)); - patch.c1 = sum (center, scale (sum (C1, scale (difference (C1, p1), 0.33333)), radius)); - - add_patch (pattern, ¢er, &patch); - - p0 = p1; - color0 = color1; - } -} - -static void -add_sweep_gradient_patches (paint_data_t *data, - hb_color_stop_t *stops, - unsigned int n_stops, - cairo_extend_t extend, - float cx, float cy, - float radius, - float start_angle, - float end_angle, - cairo_pattern_t *pattern) -{ - float *angles; - color_t *colors; - color_t color0, color1; - - if (start_angle == end_angle) - { - if (extend == CAIRO_EXTEND_PAD) - { - color_t c; - if (start_angle > 0) - { - get_color (data, stops[0].color_index, stops[0].alpha, &c); - add_sweep_gradient_patches1 (cx, cy, radius, - 0., &c, - start_angle, &c, - pattern); - } - if (end_angle < 2 * M_PI) - { - get_color (data, stops[n_stops - 1].color_index, stops[n_stops - 1].alpha, &c); - add_sweep_gradient_patches1 (cx, cy, radius, - end_angle, &c, - 2 * M_PI, &c, - pattern); - } - } - return; - } - - assert (start_angle != end_angle); - - /* handle directions */ - if (end_angle < start_angle) - { - float angle = end_angle; - end_angle = start_angle; - start_angle = angle; - - for (int i = 0; i < n_stops - 1 - i; i++) - { - hb_color_stop_t stop = stops[i]; - stops[i] = stops[n_stops - 1 - i]; - stops[n_stops - 1 - i] = stop; - } - } - - angles = alloca (sizeof (float) * n_stops); - colors = alloca (sizeof (color_t) * n_stops); - - for (int i = 0; i < n_stops; i++) - { - angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); - get_color (data, stops[i].color_index, stops[i].alpha, &colors[i]); - } - - if (extend == CAIRO_EXTEND_PAD) - { - int pos; - - color0 = colors[0]; - for (pos = 0; pos < n_stops; pos++) - { - if (angles[pos] >= 0) - { - if (pos > 0) - { - float k = (0 - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); - interpolate_colors (&colors[pos-1], &colors[pos], k, &color0); - } - break; - } - } - if (pos == n_stops) - { - /* everything is below 0 */ - color0 = colors[n_stops-1]; - add_sweep_gradient_patches1 (cx, cy, radius, - 0., &color0, - 2 * M_PI, &color0, - pattern); - return; - } - - add_sweep_gradient_patches1 (cx, cy, radius, - 0., &color0, - angles[pos], &colors[pos], - pattern); - - for (pos++; pos < n_stops; pos++) - { - if (angles[pos] <= 2 * M_PI) - { - add_sweep_gradient_patches1 (cx, cy, radius, - angles[pos - 1], &colors[pos-1], - angles[pos], &colors[pos], - pattern); - } - else - { - float k = (2 * M_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); - interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1); - add_sweep_gradient_patches1 (cx, cy, radius, - angles[pos - 1], &colors[pos - 1], - 2 * M_PI, &color1, - pattern); - break; - } - } - - if (pos == n_stops) - { - /* everything is below 2*M_PI */ - color0 = colors[n_stops - 1]; - add_sweep_gradient_patches1 (cx, cy, radius, - angles[n_stops - 1], &color0, - 2 * M_PI, &color0, - pattern); - return; - } - } - else - { - int k; - float span; - - span = angles[n_stops - 1] - angles[0]; - k = 0; - if (angles[0] >= 0) - { - float ss = angles[0]; - while (ss > 0) - { - if (span > 0) - { - ss -= span; - k--; - } - else - { - ss += span; - k++; - } - } - } - else if (angles[0] < 0) - { - float ee = angles[n_stops - 1]; - while (ee < 0) - { - if (span > 0) - { - ee += span; - k++; - } - else - { - ee -= span; - k--; - } - } - } - - //assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span); - - for (int l = k; TRUE; l++) - { - for (int i = 1; i < n_stops; i++) - { - float a0, a1; - color_t *c0, *c1; - - if ((l % 2 != 0) && (extend == CAIRO_EXTEND_REFLECT)) - { - a0 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - (i-1)] + l * span; - a1 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - i] + l * span; - c0 = &colors[n_stops - 1 - (i - 1)]; - c1 = &colors[n_stops - 1 - i]; - } - else - { - a0 = angles[i-1] + l * span; - a1 = angles[i] + l * span; - c0 = &colors[i-1]; - c1 = &colors[i]; - } - - if (a1 < 0) - continue; - if (a0 < 0) - { - color_t color; - float f = (0 - a0)/(a1 - a0); - interpolate_colors (c0, c1, f, &color); - add_sweep_gradient_patches1 (cx, cy, radius, - 0, &color, - a1, c1, - pattern); - } - else if (a1 >= 2 * M_PI) - { - color_t color; - float f = (2 * M_PI - a0)/(a1 - a0); - interpolate_colors (c0, c1, f, &color); - add_sweep_gradient_patches1 (cx, cy, radius, - a0, c0, - 2 * M_PI, &color, - pattern); - goto done; - } - else - { - add_sweep_gradient_patches1 (cx, cy, radius, - a0, c0, - a1, c1, - pattern); - } - } - } -done: ; - } + hb_cairo_paint_radial_gradient (cr, font, color_line, x0, y0, r0, x1, y1, r1); } static void paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, - float cx, float cy, - float start_angle, - float end_angle, + float x0, float y0, + float start_angle, float end_angle, void *user_data) { - paint_data_t *data = user_data; - unsigned int len; - hb_color_stop_t *stops; - cairo_extend_t extend; - double x1, y1, x2, y2; - float max_x, max_y, radius; - cairo_pattern_t *pattern; + paint_data_t *data = (paint_data_t *) paint_data; + cairo_t *cr = data->cr; + hb_font_t *font = data->font; - len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = alloca (len * sizeof (hb_color_stop_t)); - hb_color_line_get_color_stops (color_line, 0, &len, stops); - qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); - - print (data, "sweep gradient"); - data->level++; - print (data, "center %f %f", cx, cy); - print (data, "angles %f %f", start_angle, end_angle); - - data->level += 1; - for (unsigned int i = 0; i < len; i++) - print (data, "%f %u %f", stops[i].offset, stops[i].color_index, stops[i].alpha); - data->level -= 2; - - cairo_clip_extents (data->cr, &x1, &y1, &x2, &y2); - max_x = MAX ((x1 - cx) * (x1 - cx), (x2 - cx) * (x2 - cx)); - max_y = MAX ((y1 - cy) * (y1 - cy), (y2 - cy) * (y2 - cy)); - radius = sqrt (max_x + max_y); - - extend = cairo_extend (hb_color_line_get_extend (color_line)); - - pattern = cairo_pattern_create_mesh (); - - add_sweep_gradient_patches (data, stops, len, extend, cx, cy, - radius, start_angle, end_angle, pattern); - - cairo_set_source (data->cr, pattern); - cairo_paint (data->cr); - - cairo_pattern_destroy (pattern); - - data->level--; + hb_cairo_paint_sweep_gradient (cr, font, color_line, x0, y0, start_angle, end_angle); } -static void -push_group (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data) -{ - paint_data_t *data = user_data; - print (data, "push group"); - data->level++; - - cairo_save (data->cr); - cairo_push_group (data->cr); -} - -static void -pop_group (hb_paint_funcs_t *funcs, - void *paint_data, - hb_paint_composite_mode_t mode, - void *user_data) -{ - paint_data_t *data = user_data; - - cairo_pop_group_to_source (data->cr); - cairo_set_operator (data->cr, to_operator (mode)); - cairo_paint (data->cr); - - cairo_restore (data->cr); - - data->level--; - print (data, "pop group mode %d", mode); -} int main (int argc, char *argv[]) { @@ -1049,29 +313,22 @@ int main (int argc, char *argv[]) data.font = font; data.unscaled_font = unscaled_font; - data.foreground_color = HB_COLOR (0, 0, 0, 255); - - data.num_colors = hb_ot_color_palette_get_colors (hb_font_get_face (font), - 0, 0, NULL, NULL); - data.colors = alloca (data.num_colors * sizeof (hb_color_t)); - hb_ot_color_palette_get_colors (hb_font_get_face (font), - 0, 0, &data.num_colors, data.colors); funcs = hb_paint_funcs_create (); - hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); - hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); - hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, &data, NULL); - hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, &data, NULL); - hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); - hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); - hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); - hb_paint_funcs_set_color_func (funcs, paint_color, &data, NULL); - hb_paint_funcs_set_image_func (funcs, paint_image, &data, NULL); - hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, &data, NULL); - hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, &data, NULL); - hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, &data, NULL); + hb_paint_funcs_set_push_transform_func (funcs, push_transform, NULL, NULL); + hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, NULL, NULL); + hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, NULL, NULL); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, NULL, NULL); + hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, NULL, NULL); + hb_paint_funcs_set_push_group_func (funcs, push_group, NULL, NULL); + hb_paint_funcs_set_pop_group_func (funcs, pop_group, NULL, NULL); + hb_paint_funcs_set_color_func (funcs, paint_color, NULL, NULL); + hb_paint_funcs_set_image_func (funcs, paint_image, NULL, NULL); + hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, NULL, NULL); + hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, NULL, NULL); + hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, NULL, NULL); - hb_font_paint_glyph (font, gid, funcs, NULL); + hb_font_paint_glyph (font, gid, funcs, &data); pattern = cairo_pop_group (data.cr); diff --git a/util/meson.build b/util/meson.build index 8ac700b28..e28df67d6 100644 --- a/util/meson.build +++ b/util/meson.build @@ -17,7 +17,7 @@ hb_subset_cli_sources = [ util_deps = [freetype_dep, cairo_dep, cairo_ft_dep, glib_dep] -hb_test = executable('hb-test', [ 'hb-test.c' ], +hb_test = executable('hb-test', [ 'hb-test.c', 'hb-cairo-utils.c' ], cpp_args: cpp_args, include_directories: [incconfig, incsrc], dependencies: [util_deps, chafa_dep], From 95ccd66481768d443ac7aaeb1588823a79948944 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 11:08:25 -0700 Subject: [PATCH 075/219] [hb-view] Set glyph extents in render_color_glyph Works around limitation in cairo-recording-surface unboundedness. Extents are wrong but at least renders something now. --- util/helper-cairo-user.hh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index d3f5e6aa8..6822b959a 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -363,6 +363,13 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), (void *)&paint_data); + hb_glyph_extents_t hb_extents; + hb_font_get_glyph_extents (font, glyph, &hb_extents); + extents->x_bearing = (double) hb_extents.x_bearing / x_scale; + extents->y_bearing = (double) hb_extents.y_bearing / y_scale; + extents->width = (double) hb_extents.width / x_scale; + extents->height = (double) hb_extents.height / y_scale; + hb_font_destroy (paint_data.unscaled_font); return CAIRO_STATUS_SUCCESS; From bec5354030e003e17aff2c0394c0b706d69cda73 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 11:26:46 -0700 Subject: [PATCH 076/219] [hb-view] Fix render_color_glyph extents coordinate system Needs cairo fix: https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/371 --- util/helper-cairo-user.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 6822b959a..43bae0f28 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -366,7 +366,7 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, hb_glyph_extents_t hb_extents; hb_font_get_glyph_extents (font, glyph, &hb_extents); extents->x_bearing = (double) hb_extents.x_bearing / x_scale; - extents->y_bearing = (double) hb_extents.y_bearing / y_scale; + extents->y_bearing = (double)-hb_extents.y_bearing / y_scale; extents->width = (double) hb_extents.width / x_scale; extents->height = (double) hb_extents.height / y_scale; From c996fc58ec8997242d853b8bfac4f4f9c3d96605 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 11:36:58 -0700 Subject: [PATCH 077/219] [hb-view] Remove redundant check --- util/helper-cairo-user.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 43bae0f28..8d7510850 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -237,9 +237,6 @@ paint_image (hb_paint_funcs_t *funcs, cairo_t *cr = data->cr; hb_font_t *font = data->font; - if (format != HB_PAINT_IMAGE_FORMAT_PNG || !extents) - return; - hb_cairo_paint_glyph_image (cr, font, blob, format, extents); } From bcc9ab27fcf02d57333a9bfc06261eede85c0746 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 11:59:54 -0700 Subject: [PATCH 078/219] [hb-view] Fix transformation No need for cairo patch; that patch was wrong. --- util/helper-cairo-user.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 8d7510850..a48a472ef 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -365,7 +365,7 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, extents->x_bearing = (double) hb_extents.x_bearing / x_scale; extents->y_bearing = (double)-hb_extents.y_bearing / y_scale; extents->width = (double) hb_extents.width / x_scale; - extents->height = (double) hb_extents.height / y_scale; + extents->height = (double)-hb_extents.height / y_scale; hb_font_destroy (paint_data.unscaled_font); From 529dc40d7db9bee1075fc16ba0971ad265ffac11 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 12:35:50 -0700 Subject: [PATCH 079/219] [util] Adjust scaling Still doesn't render PNGs. Fix a few compiler warnings --- util/hb-cairo-utils.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 694586a3a..5c1e9da7e 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -146,6 +146,10 @@ hb_cairo_paint_glyph_image (hb_font_t *font, cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; cairo_pattern_set_matrix (pattern, &matrix); + hb_position_t x_scale, y_scale; + hb_font_get_scale (font, &x_scale, &y_scale); + cairo_scale (cr, +1./x_scale, -1./y_scale); + cairo_translate (cr, extents->x_bearing, extents->y_bearing); cairo_scale (cr, extents->width, extents->height); cairo_set_source (cr, pattern); @@ -505,7 +509,7 @@ add_sweep_gradient_patches (hb_font_t *font, end_angle = start_angle; start_angle = angle; - for (int i = 0; i < n_stops - 1 - i; i++) + for (unsigned i = 0; i < n_stops - 1 - i; i++) { hb_color_stop_t stop = stops[i]; stops[i] = stops[n_stops - 1 - i]; @@ -516,7 +520,7 @@ add_sweep_gradient_patches (hb_font_t *font, angles = alloca (sizeof (float) * n_stops); colors = alloca (sizeof (color_t) * n_stops); - for (int i = 0; i < n_stops; i++) + for (unsigned i = 0; i < n_stops; i++) { angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); hb_face_get_color (face, 0, stops[i].color_index, stops[i].alpha, &colors[i].r, &colors[i].g, &colors[i].b, &colors[i].a); @@ -524,7 +528,7 @@ add_sweep_gradient_patches (hb_font_t *font, if (extend == CAIRO_EXTEND_PAD) { - int pos; + unsigned pos; color0 = colors[0]; for (pos = 0; pos < n_stops; pos++) @@ -631,9 +635,9 @@ add_sweep_gradient_patches (hb_font_t *font, //assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span); - for (int l = k; 1; l++) + for (unsigned l = k; 1; l++) { - for (int i = 1; i < n_stops; i++) + for (unsigned i = 1; i < n_stops; i++) { float a0, a1; color_t *c0, *c1; From 7accbe97d8dd0e55484fd4d1e76acea1c89c8ae1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 12:51:26 -0700 Subject: [PATCH 080/219] [util] Fix argument order and root transform PNGs --- src/hb-ot-color-cbdt-table.hh | 6 +++++- src/hb-ot-color-sbix-table.hh | 6 +++++- util/hb-cairo-utils.c | 9 +++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 4ab0188df..bb776483a 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -944,11 +944,15 @@ struct CBDT if (unlikely (blob == hb_blob_get_empty ())) return false; - if (unlikely (!get_extents (font, glyph, &extents))) + if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; + funcs->push_root_transform (data, font); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); + funcs->pop_root_transform (data); + hb_blob_destroy (blob); return true; } diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 4190e6d1e..32b5b074d 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -245,11 +245,15 @@ struct sbix if (blob == hb_blob_get_empty ()) return false; - if (!get_extents (font, glyph, &extents)) + if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; + funcs->push_root_transform (data, font); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); + funcs->pop_root_transform (data); + hb_blob_destroy (blob); return true; } diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 5c1e9da7e..f79e0b73d 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -123,9 +123,10 @@ read_blob (void *closure, return CAIRO_STATUS_SUCCESS; } +#include void -hb_cairo_paint_glyph_image (hb_font_t *font, - cairo_t *cr, +hb_cairo_paint_glyph_image (cairo_t *cr, + hb_font_t *font, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents) @@ -146,10 +147,6 @@ hb_cairo_paint_glyph_image (hb_font_t *font, cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; cairo_pattern_set_matrix (pattern, &matrix); - hb_position_t x_scale, y_scale; - hb_font_get_scale (font, &x_scale, &y_scale); - cairo_scale (cr, +1./x_scale, -1./y_scale); - cairo_translate (cr, extents->x_bearing, extents->y_bearing); cairo_scale (cr, extents->width, extents->height); cairo_set_source (cr, pattern); From 35739567058b61a4545228ea5b832576f2824f63 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 12:56:01 -0700 Subject: [PATCH 081/219] [util] Include stdio.h --- util/hb-cairo-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index f79e0b73d..871705466 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -123,7 +124,6 @@ read_blob (void *closure, return CAIRO_STATUS_SUCCESS; } -#include void hb_cairo_paint_glyph_image (cairo_t *cr, hb_font_t *font, From 955bd30365d8bb7998515e0714c3aec94e284440 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 14:55:56 -0500 Subject: [PATCH 082/219] Fix hb-cairo-utils This was a stupid mistake, and hard to track down. --- util/hb-cairo-utils.c | 2 ++ util/hb-cairo-utils.h | 1 + 2 files changed, 3 insertions(+) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 871705466..4005cb19f 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -24,6 +24,8 @@ * Google Author(s): Matthias Clasen */ +#include "hb-cairo-utils.h" + #include #include #include diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index 9d353be67..ddff56839 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -27,6 +27,7 @@ #pragma once #include +#include HB_BEGIN_DECLS From 9672aa8610d605617fc2465b0c5d5dc2fc33079f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 12:57:42 -0700 Subject: [PATCH 083/219] [util] Fix compiler warning --- util/hb-cairo-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 4005cb19f..bf8d4c085 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -327,7 +327,7 @@ interpolate (float f0, float f1, float f) return f0 + f * (f1 - f0); } -void +static void interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) { c->r = c0->r + k * (c1->r - c0->r); From 14bf3aaa8d276470c826f095bc0f8d57ff930b38 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 12:59:35 -0700 Subject: [PATCH 084/219] [colr] Make paint_image work again --- src/hb-ot-color-cbdt-table.hh | 4 ---- src/hb-ot-color-sbix-table.hh | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index bb776483a..d956a7272 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -947,12 +947,8 @@ struct CBDT if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; - funcs->push_root_transform (data, font); - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); - funcs->pop_root_transform (data); - hb_blob_destroy (blob); return true; } diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 32b5b074d..bafb45417 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -248,12 +248,8 @@ struct sbix if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; - funcs->push_root_transform (data, font); - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); - funcs->pop_root_transform (data); - hb_blob_destroy (blob); return true; } From 85917e5b2143e212224e7950d8ee97ccd14b9ee0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:08:45 -0700 Subject: [PATCH 085/219] [paint] Fix docs --- src/hb-paint.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index f253852f3..06e4095fc 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -87,7 +87,7 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to apply * a transform to subsequent paint calls. @@ -109,7 +109,7 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, * hb_paint_pop_transform_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to undo * the effect of a prior call to the #hb_paint_funcs_push_transform_func_t @@ -126,7 +126,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions * @glyph: the glyph ID - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to clip * subsequent paint calls to the outline of a glyph. @@ -158,7 +158,7 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to clip * subsequent paint calls to a rectangle. @@ -182,7 +182,7 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, * hb_paint_pop_clip_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to undo * the effect of a prior call to the #hb_paint_funcs_push_clip_glyph_func_t @@ -200,7 +200,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * @paint_data: The data accompanying the paint functions * @color_index: Index of a color in the fonts selected color palette * @alpha: alpha to apply in addition - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to paint a * color everywhere within the current clip. @@ -241,7 +241,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @image: the image data * @format: the image format as a tag * @extents: (nullable): glyph extents - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to paint the * glyph image. @@ -324,7 +324,7 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to paint a linear * gradient everywhere within the current clip. @@ -357,7 +357,7 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to paint a radial * gradient everywhere within the current clip. @@ -387,7 +387,7 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * @y0: Y coordinate of the circle's center * @start_angle: the start angle, in radians * @end_angle: the end angle, in radians - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to paint a sweep * gradient everywhere within the current clip. @@ -454,7 +454,7 @@ typedef enum { * hb_paint_push_group_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to use * an intermediate surface for subsequent paint calls. @@ -474,7 +474,7 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions * @mode: the compositing mode to use - * @user_data: user data passed to the hb_font_paint_glyph() call + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_paint_funcs_t to undo * the effect of a prior call to the #hb_paint_funcs_push_group_func_t From c65f580b932daf7492d09c30462bf470247f794d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 15:13:55 -0500 Subject: [PATCH 086/219] Drop hb-test This was a test binary to assist in developing the hb-paint code. Not needed anymore, now that hb-view has the same code in the cairo userfont backend. --- util/hb-test.c | 350 ----------------------------------------------- util/meson.build | 7 - 2 files changed, 357 deletions(-) delete mode 100644 util/hb-test.c diff --git a/util/hb-test.c b/util/hb-test.c deleted file mode 100644 index c984db67a..000000000 --- a/util/hb-test.c +++ /dev/null @@ -1,350 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "hb-cairo-utils.h" - -static void -move_to (hb_draw_funcs_t *dfuncs, - cairo_t *cr, - hb_draw_state_t *st, - float to_x, float to_y, - void *) -{ - cairo_move_to (cr, - (double) to_x, (double) to_y); -} - -static void -line_to (hb_draw_funcs_t *dfuncs, - cairo_t *cr, - hb_draw_state_t *st, - float to_x, float to_y, - void *) -{ - cairo_line_to (cr, - (double) to_x, (double) to_y); -} - -static void -cubic_to (hb_draw_funcs_t *dfuncs, - cairo_t *cr, - hb_draw_state_t *st, - float control1_x, float control1_y, - float control2_x, float control2_y, - float to_x, float to_y, - void *) -{ - cairo_curve_to (cr, - (double) control1_x, (double) control1_y, - (double) control2_x, (double) control2_y, - (double) to_x, (double) to_y); -} - -static void -close_path (hb_draw_funcs_t *dfuncs, - cairo_t *cr, - hb_draw_state_t *st, - void *) -{ - cairo_close_path (cr); -} - - -static hb_draw_funcs_t * -get_cairo_draw_funcs (void) -{ - static hb_draw_funcs_t *funcs; - - if (!funcs) - { - funcs = hb_draw_funcs_create (); - hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, NULL, NULL); - hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, NULL, NULL); - hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL); - hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL); - } - - return funcs; -} - - -typedef struct { - cairo_t *cr; - hb_font_t *font; - hb_font_t *unscaled_font; - int level; -} paint_data_t; - -static void -push_transform (hb_paint_funcs_t *funcs, - void *paint_data, - float xx, float yx, - float xy, float yy, - float dx, float dy, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - cairo_matrix_t m; - - cairo_save (cr); - cairo_matrix_init (&m, xx, yx, xy, yy, dx, dy); - cairo_transform (data->cr, &m); -} - -static void -pop_transform (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - - cairo_restore (cr); -} - -static void -push_clip_glyph (hb_paint_funcs_t *funcs, - void *paint_data, - hb_codepoint_t glyph, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - - cairo_save (cr); - cairo_new_path (cr); - hb_font_get_glyph_shape (data->unscaled_font, glyph, get_cairo_draw_funcs (), cr); - cairo_close_path (cr); - cairo_clip (cr); -} - -static void -push_clip_rectangle (hb_paint_funcs_t *funcs, - void *paint_data, - float xmin, float ymin, float xmax, float ymax, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - - cairo_save (cr); - cairo_rectangle (cr, xmin, ymin, xmax - xmin, ymax - ymin); - cairo_clip (cr); -} - -static void -pop_clip (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - - cairo_restore (cr); -} - -static void -push_group (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - - cairo_save (cr); - cairo_push_group (cr); -} - -static void -pop_group (hb_paint_funcs_t *funcs, - void *paint_data, - hb_paint_composite_mode_t mode, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - - cairo_pop_group_to_source (cr); - cairo_set_operator (cr, hb_paint_composite_mode_to_cairo (mode)); - cairo_paint (cr); - - cairo_restore (cr); -} - -static void -paint_color (hb_paint_funcs_t *funcs, - void *paint_data, - unsigned int color_index, - float alpha, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - hb_face_t *face = hb_font_get_face (data->font); - cairo_t *cr = data->cr; - float r, g, b, a; - - hb_face_get_color (face, 0, color_index, alpha, &r, &g, &b, &a); - cairo_set_source_rgba (cr, r, g, b, a); - cairo_paint (cr); -} - -static void -paint_image (hb_paint_funcs_t *funcs, - void *paint_data, - hb_blob_t *blob, - hb_tag_t format, - hb_glyph_extents_t *extents, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; - - hb_cairo_paint_glyph_image (cr, font, blob, format, extents); -} - -static void -paint_linear_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float x1, float y1, - float x2, float y2, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; - - hb_cairo_paint_linear_gradient (cr, font, color_line, x0, y0, x1, y1, x2, y2); -} - -static void -paint_radial_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, float r0, - float x1, float y1, float r1, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; - - hb_cairo_paint_radial_gradient (cr, font, color_line, x0, y0, r0, x1, y1, r1); -} - -static void -paint_sweep_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float start_angle, float end_angle, - void *user_data) -{ - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; - - hb_cairo_paint_sweep_gradient (cr, font, color_line, x0, y0, start_angle, end_angle); -} - - -int main (int argc, char *argv[]) -{ - paint_data_t data; - hb_paint_funcs_t *funcs; - hb_blob_t *blob = hb_blob_create_from_file (argv[1]); - hb_face_t *face = hb_face_create (blob, 0); - hb_font_t *font = hb_font_create (face); - hb_font_t *unscaled_font; - hb_font_set_scale (font, 20, 20); - hb_codepoint_t gid = atoi (argv[2]); - hb_glyph_extents_t extents; - cairo_surface_t *surface; - cairo_pattern_t *pattern; - cairo_matrix_t m; - float xmin, ymin, xmax, ymax; - unsigned int upem; - - float size = 120.; - - hb_font_set_scale (font, size, size); - hb_font_get_glyph_extents (font, gid, &extents); - - unscaled_font = hb_font_create (face); - upem = hb_face_get_upem (face); - hb_font_set_scale (unscaled_font, upem, upem); - hb_font_set_synthetic_slant (unscaled_font, 0.); - - printf ("size %f upem %u\n", size, upem); - - xmin = extents.x_bearing; - xmax = xmin + extents.width; - ymin = - extents.y_bearing; - ymax = - extents.y_bearing - extents.height; - - printf ("surface %f %f, offset %f %f\n", ceil (xmax - xmin), ceil (ymax - ymin), - xmin, - ymin); - - if ((int) ceil (xmax - xmin) == 0 || - (int) ceil (ymax - ymin) == 0) - { - printf ("ERROR: empty surface\n"); - return 1; - } - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - (int) ceil (xmax - xmin), - (int) ceil (ymax - ymin)); - - cairo_surface_set_device_offset (surface, - xmin, ymax); - - data.level = 0; - data.cr = cairo_create (surface); - cairo_push_group (data.cr); - - data.font = font; - data.unscaled_font = unscaled_font; - - funcs = hb_paint_funcs_create (); - hb_paint_funcs_set_push_transform_func (funcs, push_transform, NULL, NULL); - hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, NULL, NULL); - hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, NULL, NULL); - hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, NULL, NULL); - hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, NULL, NULL); - hb_paint_funcs_set_push_group_func (funcs, push_group, NULL, NULL); - hb_paint_funcs_set_pop_group_func (funcs, pop_group, NULL, NULL); - hb_paint_funcs_set_color_func (funcs, paint_color, NULL, NULL); - hb_paint_funcs_set_image_func (funcs, paint_image, NULL, NULL); - hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, NULL, NULL); - hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, NULL, NULL); - hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, NULL, NULL); - - hb_font_paint_glyph (font, gid, funcs, &data); - - pattern = cairo_pop_group (data.cr); - - cairo_matrix_init_scale (&m, 1, -1); - cairo_matrix_translate (&m, 0, (ymax - ymin) + 2 * ymin); - cairo_pattern_set_matrix (pattern, &m); - cairo_set_source (data.cr, pattern); - - cairo_paint (data.cr); - - cairo_surface_set_device_offset (surface, - xmin, - ymin); - - printf ("writing glyph.png\n"); - cairo_surface_write_to_png (surface, "glyph.png"); - - execvp ("eog", (char *const[]) { "eog", "glyph.png", NULL }); - - return 0; -} diff --git a/util/meson.build b/util/meson.build index e28df67d6..23b8f1ca9 100644 --- a/util/meson.build +++ b/util/meson.build @@ -17,13 +17,6 @@ hb_subset_cli_sources = [ util_deps = [freetype_dep, cairo_dep, cairo_ft_dep, glib_dep] -hb_test = executable('hb-test', [ 'hb-test.c', 'hb-cairo-utils.c' ], - cpp_args: cpp_args, - include_directories: [incconfig, incsrc], - dependencies: [util_deps, chafa_dep], - link_with: [libharfbuzz], - ) - if conf.get('HAVE_GLIB', 0) == 1 if conf.get('HAVE_CAIRO', 0) == 1 hb_view = executable('hb-view', hb_view_sources, From 81bf08927361ae57563b02774523f7ce83903ea1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:15:49 -0700 Subject: [PATCH 087/219] [hb-view] Use color render callback if HB_DRAW >= 2 --- util/helper-cairo-user.hh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index a48a472ef..e223e5ef0 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -314,12 +314,24 @@ get_cairo_paint_funcs (void) #endif +static cairo_status_t +render_color_glyph (cairo_scaled_font_t *scaled_font, + unsigned long glyph, + cairo_t *cr, + cairo_text_extents_t *extents); + static cairo_status_t render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *extents) { +#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC + static char *p = getenv ("HB_DRAW"); + if (p && atoi (p) >= 2) + return render_color_glyph (scaled_font, glyph, cr, extents); +#endif + hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &_hb_font_cairo_user_data_key)); From 815544a1f7ce0cd9da6cb632e7309ba31ed53faf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:33:54 -0700 Subject: [PATCH 088/219] [font] Adapt paint_glyph to parent transform --- src/hb-font.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index 7aa1a7170..499c6d9fb 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -657,8 +657,18 @@ hb_font_get_glyph_paint_default (hb_font_t *font, void *paint_data, void *user_data) { - // FIXME adaptor like for draw funcs + paint_funcs->push_transform (paint_data, + font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, + font->parent->y_scale ? (font->slant - font->parent->slant) * + (float) font->x_scale / (float) font->parent->y_scale : 0.f, + 0.f, + font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, + 0.f, + 0.f); + font->parent->get_glyph_paint (glyph, paint_funcs, paint_data); + + paint_funcs->pop_transform (paint_data); } DEFINE_NULL_INSTANCE (hb_font_funcs_t) = From a9b37206eb1e254b24226b5115932aa40f20f7d9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:37:32 -0700 Subject: [PATCH 089/219] [font] Minor rename --- src/hb-font.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-font.h b/src/hb-font.h index 5da4dc3db..070d173e3 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -892,7 +892,7 @@ hb_font_get_glyph_shape (hb_font_t *font, HB_EXTERN void hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, - hb_paint_funcs_t *funcs, void *paint_data); + hb_paint_funcs_t *pfuncs, void *paint_data); /* high-level funcs, with fallback */ From 9a7422c5fb9eefa3c73cde387512e1de4adaa946 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:46:32 -0700 Subject: [PATCH 090/219] [font] Minor doc fix --- src/hb-font.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index 499c6d9fb..ce2514d5f 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1402,7 +1402,7 @@ hb_font_get_glyph_shape (hb_font_t *font, * hb_font_paint_glyph: * @font: #hb_font_t to work upon * @glyph: The glyph ID - * @funcs: #hb_paint_funcs_t to paint with + * @pfuncs: #hb_paint_funcs_t to paint with * @paint_data: User data to pass to paint callbacks * * Paints the glyph. @@ -1419,10 +1419,10 @@ hb_font_get_glyph_shape (hb_font_t *font, void hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, - hb_paint_funcs_t *funcs, void *paint_data) + hb_paint_funcs_t *pfuncs, void *paint_data) { // TODO add an adapter for child fonts like get_glyph_shape does - font->get_glyph_paint (glyph, funcs, paint_data); + font->get_glyph_paint (glyph, pfuncs, paint_data); } /* A bit higher-level, and with fallback */ From 21a9db875ed9204ac45093e97354158012b4b35f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:47:22 -0700 Subject: [PATCH 091/219] [draw] Add get_empty / [sg]et_user_data --- docs/harfbuzz-sections.txt | 3 ++ src/hb-cplusplus.hh | 2 ++ src/hb-draw.cc | 58 ++++++++++++++++++++++++++++++++++++++ src/hb-draw.h | 15 ++++++++++ 4 files changed, 78 insertions(+) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index a35d3aa39..c1b847f01 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -191,8 +191,11 @@ HB_DEPRECATED_FOR
hb-draw hb_draw_funcs_create +hb_draw_funcs_get_empty hb_draw_funcs_reference hb_draw_funcs_destroy +hb_draw_funcs_set_user_data +hb_draw_funcs_get_user_data hb_draw_funcs_make_immutable hb_draw_funcs_is_immutable hb_draw_move_to_func_t diff --git a/src/hb-cplusplus.hh b/src/hb-cplusplus.hh index a210ab796..f9e44aafd 100644 --- a/src/hb-cplusplus.hh +++ b/src/hb-cplusplus.hh @@ -160,6 +160,8 @@ HB_DEFINE_VTABLE (map); HB_DEFINE_VTABLE (set); HB_DEFINE_VTABLE (shape_plan); HB_DEFINE_VTABLE (unicode_funcs); +HB_DEFINE_VTABLE (draw_funcs); +//HB_DEFINE_VTABLE (paint_funcs); #undef HB_DEFINE_VTABLE diff --git a/src/hb-draw.cc b/src/hb-draw.cc index 9d75c6537..dde7e39cc 100644 --- a/src/hb-draw.cc +++ b/src/hb-draw.cc @@ -198,6 +198,21 @@ DEFINE_NULL_INSTANCE (hb_draw_funcs_t) = } }; +/** + * hb_draw_funcs_get_empty: + * + * Fetches the singleton empty draw-functions structure. + * + * Return value: (transfer full): The empty draw-functions structure + * + * Since: REPLACEME + **/ +hb_draw_funcs_t * +hb_draw_funcs_get_empty () +{ + return const_cast (&Null (hb_draw_funcs_t)); +} + /** * hb_draw_funcs_reference: (skip) @@ -248,6 +263,49 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs) hb_free (dfuncs); } +/** + * hb_draw_funcs_set_user_data: (skip) + * @dfuncs: The draw-functions structure + * @key: The user-data key + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the specified draw-functions structure. + * + * Return value: `true` if success, `false` otherwise + * + * Since: REPLACEME + **/ +hb_bool_t +hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (dfuncs, key, data, destroy, replace); +} + +/** + * hb_draw_funcs_get_user_data: (skip) + * @dfuncs: The draw-functions structure + * @key: The user-data key to query + * + * Fetches the user-data associated with the specified key, + * attached to the specified draw-functions structure. + * + * Return value: (transfer none): A pointer to the user data + * + * Since: REPLACEME + **/ +void * +hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (dfuncs, key); +} + /** * hb_draw_funcs_make_immutable: * @dfuncs: draw functions diff --git a/src/hb-draw.h b/src/hb-draw.h index 9bcdd9947..47bb45d87 100644 --- a/src/hb-draw.h +++ b/src/hb-draw.h @@ -279,12 +279,27 @@ hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *dfuncs, HB_EXTERN hb_draw_funcs_t * hb_draw_funcs_create (void); +HB_EXTERN hb_draw_funcs_t * +hb_draw_funcs_get_empty (void); + HB_EXTERN hb_draw_funcs_t * hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs); HB_EXTERN void hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs); +HB_EXTERN hb_bool_t +hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace); + + +HB_EXTERN void * +hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs, + hb_user_data_key_t *key); + HB_EXTERN void hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs); From ee2204469ebfe3a3e9c76e856a7e0c8aab1dd946 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:50:34 -0700 Subject: [PATCH 092/219] [paint] Add get_empty / [sg]et_user_data --- src/hb-cplusplus.hh | 2 +- src/hb-draw.cc | 1 - src/hb-paint.cc | 58 +++++++++++++++++++++++++++++++++++++++++++++ src/hb-paint.h | 15 ++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/hb-cplusplus.hh b/src/hb-cplusplus.hh index f9e44aafd..531ef1b7c 100644 --- a/src/hb-cplusplus.hh +++ b/src/hb-cplusplus.hh @@ -161,7 +161,7 @@ HB_DEFINE_VTABLE (set); HB_DEFINE_VTABLE (shape_plan); HB_DEFINE_VTABLE (unicode_funcs); HB_DEFINE_VTABLE (draw_funcs); -//HB_DEFINE_VTABLE (paint_funcs); +HB_DEFINE_VTABLE (paint_funcs); #undef HB_DEFINE_VTABLE diff --git a/src/hb-draw.cc b/src/hb-draw.cc index dde7e39cc..c0d12992a 100644 --- a/src/hb-draw.cc +++ b/src/hb-draw.cc @@ -213,7 +213,6 @@ hb_draw_funcs_get_empty () return const_cast (&Null (hb_draw_funcs_t)); } - /** * hb_draw_funcs_reference: (skip) * @dfuncs: draw functions diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 0872479f4..18f52f2bf 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -225,6 +225,21 @@ DEFINE_NULL_INSTANCE (hb_paint_funcs_t) = } }; +/** + * hb_paint_funcs_get_empty: + * + * Fetches the singleton empty paint-functions structure. + * + * Return value: (transfer full): The empty paint-functions structure + * + * Since: REPLACEME + **/ +hb_paint_funcs_t * +hb_paint_funcs_get_empty () +{ + return const_cast (&Null (hb_paint_funcs_t)); +} + /** * hb_paint_funcs_reference: (skip) * @funcs: The paint-functions structure @@ -270,6 +285,49 @@ hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) hb_free (funcs); } +/** + * hb_paint_funcs_set_user_data: (skip) + * @pfuncs: The paint-functions structure + * @key: The user-data key + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the specified paint-functions structure. + * + * Return value: `true` if success, `false` otherwise + * + * Since: REPLACEME + **/ +hb_bool_t +hb_paint_funcs_set_user_data (hb_paint_funcs_t *pfuncs, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (pfuncs, key, data, destroy, replace); +} + +/** + * hb_paint_funcs_get_user_data: (skip) + * @pfuncs: The paint-functions structure + * @key: The user-data key to query + * + * Fetches the user-data associated with the specified key, + * attached to the specified paint-functions structure. + * + * Return value: (transfer none): A pointer to the user data + * + * Since: REPLACEME + **/ +void * +hb_paint_funcs_get_user_data (const hb_paint_funcs_t *pfuncs, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (pfuncs, key); +} + /** * hb_paint_funcs_make_immutable: * @funcs: The paint-functions structure diff --git a/src/hb-paint.h b/src/hb-paint.h index 06e4095fc..6793a6349 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -65,12 +65,27 @@ typedef struct hb_paint_funcs_t hb_paint_funcs_t; HB_EXTERN hb_paint_funcs_t * hb_paint_funcs_create (void); +HB_EXTERN hb_paint_funcs_t * +hb_paint_funcs_get_empty (void); + HB_EXTERN hb_paint_funcs_t * hb_paint_funcs_reference (hb_paint_funcs_t *funcs); HB_EXTERN void hb_paint_funcs_destroy (hb_paint_funcs_t *funcs); +HB_EXTERN hb_bool_t +hb_paint_funcs_set_user_data (hb_paint_funcs_t *funcs, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace); + + +HB_EXTERN void * +hb_paint_funcs_get_user_data (const hb_paint_funcs_t *funcs, + hb_user_data_key_t *key); + HB_EXTERN void hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs); From 3590ee74f49fa571af145f788f2db6e122021116 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 13:59:56 -0700 Subject: [PATCH 093/219] [util] Fix bot --- util/helper-cairo-user.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index e223e5ef0..354531935 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -314,11 +314,13 @@ get_cairo_paint_funcs (void) #endif +#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC static cairo_status_t render_color_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *extents); +#endif static cairo_status_t render_glyph (cairo_scaled_font_t *scaled_font, From 5d1fc9ee9dcec13a45bfc19f53894ad83f42a2a0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 14:25:39 -0700 Subject: [PATCH 094/219] [paint] Fix annotations --- src/hb-paint.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 18f52f2bf..793a27e1f 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -287,7 +287,7 @@ hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) /** * hb_paint_funcs_set_user_data: (skip) - * @pfuncs: The paint-functions structure + * @funcs: The paint-functions structure * @key: The user-data key * @data: A pointer to the user data * @destroy: (nullable): A callback to call when @data is not needed anymore @@ -300,18 +300,18 @@ hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) * Since: REPLACEME **/ hb_bool_t -hb_paint_funcs_set_user_data (hb_paint_funcs_t *pfuncs, +hb_paint_funcs_set_user_data (hb_paint_funcs_t *funcs, hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy, hb_bool_t replace) { - return hb_object_set_user_data (pfuncs, key, data, destroy, replace); + return hb_object_set_user_data (funcs, key, data, destroy, replace); } /** * hb_paint_funcs_get_user_data: (skip) - * @pfuncs: The paint-functions structure + * @funcs: The paint-functions structure * @key: The user-data key to query * * Fetches the user-data associated with the specified key, @@ -322,10 +322,10 @@ hb_paint_funcs_set_user_data (hb_paint_funcs_t *pfuncs, * Since: REPLACEME **/ void * -hb_paint_funcs_get_user_data (const hb_paint_funcs_t *pfuncs, +hb_paint_funcs_get_user_data (const hb_paint_funcs_t *funcs, hb_user_data_key_t *key) { - return hb_object_get_user_data (pfuncs, key); + return hb_object_get_user_data (funcs, key); } /** From d8cb7ceefb31600b288da05c2c09476953dafc91 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 18 Dec 2022 14:35:36 -0700 Subject: [PATCH 095/219] [test] Try fixing bots with old glib --- test/api/test-ot-color.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index b48c5b12f..72823e99d 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -741,13 +741,13 @@ test_hb_ot_color_colr_v1 (gconstpointer d) file = g_test_build_filename (G_TEST_DIST, test->output, NULL); if (!g_file_get_contents (file, &buffer, &len, &error)) { - g_test_fail_printf ("%s", error->message); + g_test_fail (); return; } if (strcmp (buffer, data.string->str) != 0) { - g_test_fail_printf ("did not get the expected result"); + g_test_fail (); } g_free (buffer); From d2b420589bb65e92385383966cf2a8c9865abc49 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 16:43:19 -0500 Subject: [PATCH 096/219] [docs] Add hb-paint apis --- docs/harfbuzz-docs.xml | 1 + docs/harfbuzz-sections.txt | 62 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 2d2827a66..b685bfd3a 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -57,6 +57,7 @@ + diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index c1b847f01..1295d60f5 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -218,6 +218,66 @@ hb_draw_funcs_t hb_draw_state_t
+
+hb-paint +hb_paint_funcs_t +hb_paint_funcs_create +hb_paint_funcs_get_empty +hb_paint_funcs_reference +hb_paint_funcs_destroy +hb_paint_funcs_set_user_data +hb_paint_funcs_get_user_data +hb_paint_funcs_make_immutable +hb_paint_funcs_is_immutable + +hb_paint_push_transform_func_t +hb_paint_pop_transform_func_t +hb_paint_push_clip_glyph_func_t +hb_paint_push_clip_rectangle_func_t +hb_paint_pop_clip_func_t +hb_paint_color_func_t +HB_PAINT_IMAGE_FORMAT_PNG +HB_PAINT_IMAGE_FORMAT_SVG +hb_paint_image_func_t +hb_color_line_t +hb_color_stop_t +hb_color_line_get_color_stops +hb_paint_extend_t +hb_color_line_get_extend +hb_paint_linear_gradient_func_t +hb_paint_radial_gradient_func_t +hb_paint_sweep_gradient_func_t +hb_paint_composite_mode_t +hb_paint_push_group_func_t +hb_paint_pop_group_func_t + +hb_paint_funcs_set_push_transform_func +hb_paint_funcs_set_pop_transform_func +hb_paint_funcs_set_push_clip_glyph_func +hb_paint_funcs_set_push_clip_rectangle_func +hb_paint_funcs_set_pop_clip_func +hb_paint_funcs_set_color_func +hb_paint_funcs_set_image_func +hb_paint_funcs_set_linear_gradient_func +hb_paint_funcs_set_radial_gradient_func +hb_paint_funcs_set_sweep_gradient_func +hb_paint_funcs_set_push_group_func +hb_paint_funcs_set_pop_group_func + +hb_paint_push_transform +hb_paint_pop_transform +hb_paint_push_clip_glyph +hb_paint_push_clip_rectangle +hb_paint_pop_clip +hb_paint_color +hb_paint_image +hb_paint_linear_gradient +hb_paint_radial_gradient +hb_paint_sweep_gradient +hb_paint_push_group +hb_paint_pop_group +
+
hb-deprecated HB_BUFFER_FLAGS_DEFAULT @@ -327,6 +387,7 @@ hb_font_get_glyph_v_origin hb_font_get_glyph_origin_for_direction hb_font_get_glyph_name hb_font_get_glyph_shape +hb_font_paint_glyph hb_font_get_nominal_glyph hb_font_get_nominal_glyphs hb_font_get_variation_glyph @@ -488,6 +549,7 @@ hb_ot_color_glyph_get_layers hb_ot_color_glyph_reference_png hb_ot_color_glyph_reference_svg hb_ot_color_has_layers +hb_ot_color_has_paint hb_ot_color_has_palettes hb_ot_color_has_png hb_ot_color_has_svg From 7c12db46ff3fd771db4cc2d2cc6fea8937b34532 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 18 Dec 2022 23:36:05 -0500 Subject: [PATCH 097/219] Try to fix msvc build --- src/hb-ot-color-colr-table.hh | 2 +- util/hb-cairo-utils.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index cf13dfbbe..9b1f7f7c0 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -28,11 +28,11 @@ #ifndef HB_OT_COLOR_COLR_TABLE_HH #define HB_OT_COLOR_COLR_TABLE_HH +#include "hb.hh" #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-var-common.hh" #include "hb-paint.hh" -#include /* * COLR -- Color diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index bf8d4c085..285811afb 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -24,6 +24,8 @@ * Google Author(s): Matthias Clasen */ +#include "config.h" + #include "hb-cairo-utils.h" #include @@ -31,6 +33,7 @@ #include #include #include +#define _USE_MATH_DEFINES #include #include @@ -133,6 +136,7 @@ hb_cairo_paint_glyph_image (cairo_t *cr, hb_tag_t format, hb_glyph_extents_t *extents) { +#ifdef CAIRO_HAS_PNG_FUNCTIONS if (format != HB_PAINT_IMAGE_FORMAT_PNG || !extents) return; @@ -157,6 +161,7 @@ hb_cairo_paint_glyph_image (cairo_t *cr, cairo_pattern_destroy (pattern); cairo_surface_destroy (surface); +#endif } static void From 5451b78f4a4d97277d3a411762844e97adda62cd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 00:07:18 -0500 Subject: [PATCH 098/219] Don't use alloca It complicates things on Windows, for no big win. Just preallocate a reasonable amount. --- util/hb-cairo-utils.c | 58 +++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 285811afb..11aedb6ea 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -36,6 +36,7 @@ #define _USE_MATH_DEFINES #include #include +#include #ifndef MIN #define MIN(x,y) ((x) < (y) ? (x) : (y)) @@ -45,6 +46,8 @@ #define MAX(x,y) ((x) > (y) ? (x) : (y)) #endif +#define PREALLOCATED_COLOR_STOPS 16 + typedef struct { float r, g, b, a; } color_t; @@ -246,16 +249,19 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, float x2, float y2) { hb_face_t *face = hb_font_get_face (font); + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; unsigned int len; - hb_color_stop_t *stops; float xx0, yy0, xx1, yy1; float xxx0, yyy0, xxx1, yyy1; float min, max; cairo_pattern_t *pattern; len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = (hb_color_stop_t *) alloca (len * sizeof (hb_color_stop_t)); + if (len > PREALLOCATED_COLOR_STOPS) + stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t)); hb_color_line_get_color_stops (color_line, 0, &len, stops); + reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1); normalize_color_line (stops, len, &min, &max); @@ -277,6 +283,9 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, cairo_paint (cr); cairo_pattern_destroy (pattern); + + if (stops != stops_) + free (stops); } void @@ -287,16 +296,19 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, float x1, float y1, float r1) { hb_face_t *face = hb_font_get_face (font); + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; unsigned int len; - hb_color_stop_t *stops; float min, max; float xx0, yy0, xx1, yy1; float rr0, rr1; cairo_pattern_t *pattern; len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = (hb_color_stop_t *) alloca (len * sizeof (hb_color_stop_t)); + if (len > PREALLOCATED_COLOR_STOPS) + stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t)); hb_color_line_get_color_stops (color_line, 0, &len, stops); + normalize_color_line (stops, len, &min, &max); xx0 = x0 + min * (x1 - x0); @@ -320,6 +332,9 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, cairo_paint (cr); cairo_pattern_destroy (pattern); + + if (stops != stops_) + free (stops); } typedef struct { @@ -475,8 +490,10 @@ add_sweep_gradient_patches (hb_font_t *font, cairo_pattern_t *pattern) { hb_face_t *face = hb_font_get_face (font); - float *angles; - color_t *colors; + float angles_[PREALLOCATED_COLOR_STOPS]; + float *angles = angles_; + color_t colors_[PREALLOCATED_COLOR_STOPS]; + color_t *colors = colors_; color_t color0, color1; if (start_angle == end_angle) @@ -521,8 +538,11 @@ add_sweep_gradient_patches (hb_font_t *font, } } - angles = alloca (sizeof (float) * n_stops); - colors = alloca (sizeof (color_t) * n_stops); + if (n_stops > PREALLOCATED_COLOR_STOPS) + { + angles = (float *) malloc (sizeof (float) * n_stops); + colors = (color_t *) malloc (sizeof (color_t) * n_stops); + } for (unsigned i = 0; i < n_stops; i++) { @@ -555,7 +575,7 @@ add_sweep_gradient_patches (hb_font_t *font, 0., &color0, 2 * M_PI, &color0, pattern); - return; + goto done; } add_sweep_gradient_patches1 (cx, cy, radius, @@ -592,7 +612,7 @@ add_sweep_gradient_patches (hb_font_t *font, angles[n_stops - 1], &color0, 2 * M_PI, &color0, pattern); - return; + goto done; } } else @@ -693,8 +713,14 @@ add_sweep_gradient_patches (hb_font_t *font, } } } -done: ; } + +done: + + if (angles != angles_) + free (angles); + if (colors != colors_) + free (colors); } void @@ -706,15 +732,18 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr, float end_angle) { unsigned int len; - hb_color_stop_t *stops; + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; cairo_extend_t extend; double x1, y1, x2, y2; float max_x, max_y, radius; cairo_pattern_t *pattern; len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = alloca (len * sizeof (hb_color_stop_t)); + if (len > PREALLOCATED_COLOR_STOPS) + stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t)); hb_color_line_get_color_stops (color_line, 0, &len, stops); + qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); cairo_clip_extents (cr, &x1, &y1, &x2, &y2); @@ -732,4 +761,7 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr, cairo_paint (cr); cairo_pattern_destroy (pattern); + + if (stops != stops_) + free (stops); } From 5ac218865ad7df1643c8b70e527cc792415c28d0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 19 Dec 2022 10:26:54 -0700 Subject: [PATCH 099/219] [paint] A doc fix --- src/hb-font.h | 4 ++++ src/hb-paint.cc | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hb-font.h b/src/hb-font.h index 070d173e3..1e36796da 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -798,6 +798,10 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable): + * + * Sets the implementation function for #hb_font_get_glyph_paint_func_t. + * + * Since: REPLACEME */ HB_EXTERN void hb_font_funcs_set_glyph_paint_func (hb_font_funcs_t *ffuncs, diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 793a27e1f..a37483eee 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -421,7 +421,7 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, } /** - * hb_paint_push_clip_rect: + * hb_paint_push_clip_rectangle: * @funcs: paint functions * @paint_data: associated data passed by the caller * @xmin: min X for the rectangle From 0800d1879c7aafb038e47793c9f3495da0221969 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 00:59:40 -0500 Subject: [PATCH 100/219] Try to fix autotools build --- src/Makefile.sources | 3 +++ util/Makefile.sources | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/Makefile.sources b/src/Makefile.sources index 4253426f3..5988ff575 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -89,6 +89,8 @@ HB_BASE_sources = \ hb-ot-layout-common.hh \ hb-ot-layout-gdef-table.hh \ hb-ot-layout-gpos-table.hh \ + hb-paint.cc \ + hb-paint.hh \ hb-ot-layout-gsub-table.hh \ OT/glyf/glyf.hh \ OT/glyf/glyf-helpers.hh \ @@ -291,6 +293,7 @@ HB_BASE_headers = \ hb-ot-shape.h \ hb-ot-var.h \ hb-ot.h \ + hb-paint.h \ hb-set.h \ hb-shape-plan.h \ hb-shape.h \ diff --git a/util/Makefile.sources b/util/Makefile.sources index 628de050e..e17b4fda1 100644 --- a/util/Makefile.sources +++ b/util/Makefile.sources @@ -2,6 +2,8 @@ HB_VIEW_sources = \ ansi-print.hh \ face-options.hh \ font-options.hh \ + hb-cairo-utils.h \ + hb-cairo-utils.c \ hb-view.cc \ helper-cairo-ansi.hh \ helper-cairo-ft.hh \ From 084291108ac59a0a99b2cde58073ad4377dfdd82 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 01:08:41 -0500 Subject: [PATCH 101/219] Tests: Fix memleak pointed out by valgrind --- test/api/test-ot-color.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 72823e99d..ab7d3d45a 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -755,6 +755,7 @@ test_hb_ot_color_colr_v1 (gconstpointer d) g_string_free (data.string, TRUE); + hb_paint_funcs_destroy (funcs); hb_font_destroy (font); hb_face_destroy (face); } From 74ccc1e76df3dafbc48e02818403d0f0688cf8ca Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 00:49:02 -0500 Subject: [PATCH 102/219] tests: Produce useful output on failure --- test/api/test-ot-color.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index ab7d3d45a..3491859c3 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -745,10 +745,38 @@ test_hb_ot_color_colr_v1 (gconstpointer d) return; } - if (strcmp (buffer, data.string->str) != 0) + char **lines = g_strsplit (data.string->str, "\n", 0); + char **expected; + if (strstr (buffer, "\r\n")) + expected = g_strsplit (buffer, "\r\n", 0); + else + expected = g_strsplit (buffer, "\n", 0); + + if (g_strv_length (lines) != g_strv_length (expected)) { - g_test_fail (); + g_test_message ("Unexpected number of lines in output (%d instead of %d)", g_strv_length (lines), g_strv_length (expected)); + g_test_fail (); } + else + { + unsigned int length = g_strv_length (lines); + for (unsigned int i = 0; i < length; i++) + { + if (strcmp (lines[i], expected[i]) != 0) + { + int pos; + for (pos = 0; lines[i][pos]; pos++) + if (lines[i][pos] != expected[i][pos]) + break; + + g_test_message ("Unxpected output at %d:%d (%#x instead of %#x):\n%s", i, pos, (unsigned int)lines[i][pos], (unsigned int)expected[i][pos], data.string->str); + g_test_fail (); + } + } + } + + g_strfreev (lines); + g_strfreev (expected); g_free (buffer); g_free (file); From a3ba723876d4da299cd13d70a3accab1b0672ffb Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 02:22:34 -0500 Subject: [PATCH 103/219] Drop an unneeded include --- util/hb-cairo-utils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 11aedb6ea..df1bbb38e 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -36,7 +36,6 @@ #define _USE_MATH_DEFINES #include #include -#include #ifndef MIN #define MIN(x,y) ((x) < (y) ? (x) : (y)) From 290bb338bf9a881e38899cd0391146ef7a52b2b1 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 02:39:14 -0500 Subject: [PATCH 104/219] Dist test result files --- test/api/Makefile.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/api/Makefile.am b/test/api/Makefile.am index ffd4a0fc6..e10773e9c 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -14,7 +14,10 @@ libs: EXTRA_DIST += meson.build -EXTRA_DIST += fonts +EXTRA_DIST += \ + fonts \ + results \ + $(NULL) LINK = $(CXXLINK) From 96cda3886ceffc4264587576100d56f16c150ad0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 09:59:33 -0500 Subject: [PATCH 105/219] [paint] Clarify docs Spell out where the different datas originate. --- src/hb-paint.h | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index 6793a6349..fb2db6223 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -95,14 +95,14 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); /** * hb_paint_push_transform_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @xx: xx component of the transform matrix * @yx: yx component of the transform matrix * @xy: xy component of the transform matrix * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_push_transform_func() * * A virtual method for the #hb_paint_funcs_t to apply * a transform to subsequent paint calls. @@ -123,8 +123,8 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_pop_transform_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions - * @user_data: User data pointer passed by the caller + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @user_data: User data pointer passed to hb_paint_funcs_set_pop_transform_func() * * A virtual method for the #hb_paint_funcs_t to undo * the effect of a prior call to the #hb_paint_funcs_push_transform_func_t @@ -139,9 +139,9 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_push_clip_glyph_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @glyph: the glyph ID - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_glyph_func() * * A virtual method for the #hb_paint_funcs_t to clip * subsequent paint calls to the outline of a glyph. @@ -168,12 +168,12 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_push_clip_rectangle_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @xmin: min X for the rectangle * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_rectangle_func() * * A virtual method for the #hb_paint_funcs_t to clip * subsequent paint calls to a rectangle. @@ -196,8 +196,8 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_pop_clip_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions - * @user_data: User data pointer passed by the caller + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @user_data: User data pointer passed to hb_paint_funcs_set_pop_clip_func() * * A virtual method for the #hb_paint_funcs_t to undo * the effect of a prior call to the #hb_paint_funcs_push_clip_glyph_func_t @@ -212,10 +212,10 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_color_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @color_index: Index of a color in the fonts selected color palette * @alpha: alpha to apply in addition - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_color_func() * * A virtual method for the #hb_paint_funcs_t to paint a * color everywhere within the current clip. @@ -252,11 +252,11 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_image_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @image: the image data * @format: the image format as a tag * @extents: (nullable): glyph extents - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * * A virtual method for the #hb_paint_funcs_t to paint the * glyph image. @@ -267,7 +267,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * and HB_PAINT_IMAGE_FORMAT_SVG. * * The glyph extents are provided if available, and should be used - * to position the image. + * to size and position the image. * * Since: REPLACEME */ @@ -331,7 +331,7 @@ hb_color_line_get_extend (hb_color_line_t *color_line); /** * hb_paint_linear_gradient_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @color_line: Color information for the gradient * @x0: X coordinate of the first point * @y0: Y coordinate of the first point @@ -339,7 +339,7 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_linear_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a linear * gradient everywhere within the current clip. @@ -364,7 +364,7 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_radial_gradient_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @color_line: Color information for the gradient * @x0: X coordinate of the first circle's center * @y0: Y coordinate of the first circle's center @@ -372,7 +372,7 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_radial_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a radial * gradient everywhere within the current clip. @@ -396,13 +396,13 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_sweep_gradient_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @color_line: Color information for the gradient * @x0: X coordinate of the circle's center * @y0: Y coordinate of the circle's center * @start_angle: the start angle, in radians * @end_angle: the end angle, in radians - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_sweep_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a sweep * gradient everywhere within the current clip. @@ -468,8 +468,8 @@ typedef enum { /** * hb_paint_push_group_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions - * @user_data: User data pointer passed by the caller + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @user_data: User data pointer passed to hb_paint_funcs_set_push_group_func() * * A virtual method for the #hb_paint_funcs_t to use * an intermediate surface for subsequent paint calls. @@ -487,9 +487,9 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_pop_group_func_t: * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @mode: the compositing mode to use - * @user_data: User data pointer passed by the caller + * @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func() * * A virtual method for the #hb_paint_funcs_t to undo * the effect of a prior call to the #hb_paint_funcs_push_group_func_t From 0ef2dc9be557cc247621019933ca5151a4bd80cd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 10:02:17 -0500 Subject: [PATCH 106/219] Drop a TODO This was addressed in 61bd602791d801 --- src/hb-font.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index ce2514d5f..ce6cdbb82 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1421,7 +1421,6 @@ hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *pfuncs, void *paint_data) { - // TODO add an adapter for child fonts like get_glyph_shape does font->get_glyph_paint (glyph, pfuncs, paint_data); } From 3a219cfa6a2bef8eb79dd86c2210485a71aece1d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 11:15:37 -0500 Subject: [PATCH 107/219] [config] Make HB_LEAN imply HB_NO_PAINT --- src/hb-config.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 98b1e9d0c..22ae1613d 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -64,6 +64,7 @@ #define HB_NO_CFF #define HB_NO_COLOR #define HB_NO_DRAW +#define HB_NO_PAINT #define HB_NO_ERRNO #define HB_NO_FACE_COLLECT_UNICODES #define HB_NO_GETENV From ddd2039265e3bf20bb4809d57905f83c42e61b97 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 12:20:07 -0500 Subject: [PATCH 108/219] [paint] Improve the docs --- src/hb-paint.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index a37483eee..55acc3c25 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -197,7 +197,12 @@ HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS * hb_paint_funcs_create: * * Creates a new #hb_paint_funcs_t structure of paint functions. - + * + * The initial reference count of 1 should be released with hb_paint_funcs_destroy() + * when you are done using the #hb_paint_funcs_t. This function never returns + * `NULL`. If memory cannot be allocated, a special singleton #hb_paint_funcs_t + * object will be returned. + * * Returns value: (transfer full): the paint-functions structure * * Since: REPLACEME @@ -246,6 +251,9 @@ hb_paint_funcs_get_empty () * * Increases the reference count on a paint-functions structure. * + * This prevents @funcs from being destroyed until a matching + * call to hb_paint_funcs_destroy() is made. + * * Return value: The paint-functions structure * * Since: REPLACEME @@ -293,7 +301,7 @@ hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the specified paint-functions structure. + * Attaches a user-data key/data pair to the specified paint-functions structure. * * Return value: `true` if success, `false` otherwise * From b0fa40b2ece482818bfc9e71b2f173e43b9dd6dd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 13:16:10 -0500 Subject: [PATCH 109/219] tests: More diagnostics --- test/api/test-ot-color.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 3491859c3..6bb1130aa 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -741,6 +741,7 @@ test_hb_ot_color_colr_v1 (gconstpointer d) file = g_test_build_filename (G_TEST_DIST, test->output, NULL); if (!g_file_get_contents (file, &buffer, &len, &error)) { + g_test_message ("File %s not found.", file); g_test_fail (); return; } From 0f287e75ece6364bc3fcdd752de837f8ef51529d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 13:45:45 -0500 Subject: [PATCH 110/219] [paint] Rename hb_font_get_glyph_paint_func_t The 'get' was just there due to implementation choices. Work around that and call the vfunc what it should be: hb_font_paint_glyph_func_t. --- src/hb-font.cc | 40 +++++++++++++++++------------------ src/hb-font.h | 16 +++++++------- src/hb-font.hh | 54 +++++++++++++++++++++++------------------------ src/hb-ot-font.cc | 12 +++++------ 4 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index ce6cdbb82..52030453f 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -514,12 +514,12 @@ hb_font_get_glyph_shape_nil (hb_font_t *font HB_UNUSED, } static void -hb_font_get_glyph_paint_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - hb_paint_funcs_t *paint_funcs HB_UNUSED, - void *paint_data HB_UNUSED, - void *user_data HB_UNUSED) +hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_paint_funcs_t *paint_funcs HB_UNUSED, + void *paint_data HB_UNUSED, + void *user_data HB_UNUSED) { } @@ -650,12 +650,12 @@ hb_font_get_glyph_shape_default (hb_font_t *font, } static void -hb_font_get_glyph_paint_default (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, - void *paint_data, - void *user_data) +hb_font_paint_glyph_default (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, + void *paint_data, + void *user_data) { paint_funcs->push_transform (paint_data, font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, @@ -666,7 +666,7 @@ hb_font_get_glyph_paint_default (hb_font_t *font, 0.f, 0.f); - font->parent->get_glyph_paint (glyph, paint_funcs, paint_data); + font->parent->paint_glyph (glyph, paint_funcs, paint_data); paint_funcs->pop_transform (paint_data); } @@ -679,7 +679,7 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) = nullptr, { { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_nil, HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } @@ -693,7 +693,7 @@ static const hb_font_funcs_t _hb_font_funcs_default = { nullptr, { { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default, +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_default, HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } @@ -771,7 +771,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) if (ffuncs->destroy) { -#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy->name) \ +#define HB_FONT_FUNC_IMPLEMENT(get_,name) if (ffuncs->destroy->name) \ ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT @@ -911,11 +911,11 @@ fail: return false; } -#define HB_FONT_FUNC_IMPLEMENT(name) \ +#define HB_FONT_FUNC_IMPLEMENT(get_,name) \ \ void \ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ - hb_font_get_##name##_func_t func, \ + hb_font_##get_##name##_func_t func, \ void *user_data, \ hb_destroy_func_t destroy) \ { \ @@ -931,7 +931,7 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ if (func) \ ffuncs->get.f.name = func; \ else \ - ffuncs->get.f.name = hb_font_get_##name##_default; \ + ffuncs->get.f.name = hb_font_##get_##name##_default; \ \ if (ffuncs->user_data) \ ffuncs->user_data->name = user_data; \ @@ -1421,7 +1421,7 @@ hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *pfuncs, void *paint_data) { - font->get_glyph_paint (glyph, pfuncs, paint_data); + font->paint_glyph (glyph, pfuncs, paint_data); } /* A bit higher-level, and with fallback */ diff --git a/src/hb-font.h b/src/hb-font.h index 1e36796da..693f2b505 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -513,10 +513,10 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data); -typedef void (*hb_font_get_glyph_paint_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - void *user_data); +typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + void *user_data); /* func setters */ @@ -793,19 +793,19 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, void *user_data, hb_destroy_func_t destroy); /** - * hb_font_funcs_set_glyph_paint_func: + * hb_font_funcs_set_paint_glyph_func: * @ffuncs: * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: * @destroy: (nullable): * - * Sets the implementation function for #hb_font_get_glyph_paint_func_t. + * Sets the implementation function for #hb_font_paint_glyph_func_t. * * Since: REPLACEME */ HB_EXTERN void -hb_font_funcs_set_glyph_paint_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_paint_func_t func, +hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_func_t func, void *user_data, hb_destroy_func_t destroy); /* func dispatch */ diff --git a/src/hb-font.hh b/src/hb-font.hh index d45c6a8f7..086700f0d 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -40,25 +40,25 @@ */ #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ - HB_FONT_FUNC_IMPLEMENT (font_h_extents) \ - HB_FONT_FUNC_IMPLEMENT (font_v_extents) \ - HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \ - HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \ - HB_FONT_FUNC_IMPLEMENT (variation_glyph) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_advances) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \ - HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \ - HB_FONT_FUNC_IMPLEMENT (glyph_extents) \ - HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \ - HB_FONT_FUNC_IMPLEMENT (glyph_name) \ - HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ - HB_FONT_FUNC_IMPLEMENT (glyph_shape) \ - HB_FONT_FUNC_IMPLEMENT (glyph_paint) \ + HB_FONT_FUNC_IMPLEMENT (get_,font_h_extents) \ + HB_FONT_FUNC_IMPLEMENT (get_,font_v_extents) \ + HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyph) \ + HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyphs) \ + HB_FONT_FUNC_IMPLEMENT (get_,variation_glyph) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advance) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advance) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advances) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \ + HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_shape) \ + HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \ /* ^--- Add new callbacks here */ struct hb_font_funcs_t @@ -66,13 +66,13 @@ struct hb_font_funcs_t hb_object_header_t header; struct { -#define HB_FONT_FUNC_IMPLEMENT(name) void *name; +#define HB_FONT_FUNC_IMPLEMENT(get_,name) void *name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } *user_data; struct { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name; +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_destroy_func_t name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } *destroy; @@ -80,12 +80,12 @@ struct hb_font_funcs_t /* Don't access these directly. Call font->get_*() instead. */ union get_t { struct get_funcs_t { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; +#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_func_t name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } f; void (*array[0 -#define HB_FONT_FUNC_IMPLEMENT(name) +1 +#define HB_FONT_FUNC_IMPLEMENT(get_,name) +1 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT ]) (); @@ -199,7 +199,7 @@ struct hb_font_t HB_INTERNAL bool has_func_set (unsigned int i); /* has_* ... */ -#define HB_FONT_FUNC_IMPLEMENT(name) \ +#define HB_FONT_FUNC_IMPLEMENT(get_,name) \ bool \ has_##name##_func () \ { \ @@ -402,13 +402,13 @@ struct hb_font_t !klass->user_data ? nullptr : klass->user_data->glyph_shape); } - void get_glyph_paint (hb_codepoint_t glyph, + void paint_glyph (hb_codepoint_t glyph, hb_paint_funcs_t *paint_funcs, void *paint_data) { - klass->get.f.glyph_paint (this, user_data, + klass->get.f.paint_glyph (this, user_data, glyph, paint_funcs, paint_data, - !klass->user_data ? nullptr : klass->user_data->glyph_paint); + !klass->user_data ? nullptr : klass->user_data->paint_glyph); } /* A bit higher-level, and with fallback */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 055462f4d..acddde825 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -442,11 +442,11 @@ hb_ot_get_glyph_shape (hb_font_t *font, #ifndef HB_NO_PAINT static void -hb_ot_get_glyph_paint (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - void *user_data) +hb_ot_paint_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + void *user_data) { #ifndef HB_NO_COLOR if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data)) return; @@ -491,7 +491,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t Date: Mon, 19 Dec 2022 13:48:08 -0500 Subject: [PATCH 111/219] [paint] Document hb_font_paint_glyph_func_t --- docs/harfbuzz-sections.txt | 2 ++ src/hb-font.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 1295d60f5..ce079f25d 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -450,6 +450,8 @@ hb_font_get_glyph_name_func_t hb_font_funcs_set_glyph_name_func hb_font_get_glyph_shape_func_t hb_font_funcs_set_glyph_shape_func +hb_font_paint_glyph_func_t +hb_font_funcs_set_paint_glyph_func hb_font_get_nominal_glyph_func_t hb_font_funcs_set_nominal_glyph_func hb_font_get_nominal_glyphs_func_t diff --git a/src/hb-font.h b/src/hb-font.h index 693f2b505..9a08bd963 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -513,6 +513,19 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data); +/** + * hb_font_paint_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @paint_funcs: The paint functions to use + * @paint_data: The data accompanying the paint functions + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: REPLACEME + */ typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_paint_funcs_t *paint_funcs, void *paint_data, From 9437f719a7217ddb2231709ead03c4b62cbdb42f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 14:29:39 -0500 Subject: [PATCH 112/219] [paint] Document hb_paint_extend_t --- src/hb-paint.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hb-paint.h b/src/hb-paint.h index fb2db6223..67574d05b 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -319,6 +319,16 @@ hb_color_line_get_color_stops (hb_color_line_t *color_line, unsigned int *count, hb_color_stop_t *color_stops); +/** + * hb_paint_extend_t: + * + * The values of this enumeration determine how color values + * outside the minimum and maximum defined offset on a #hb_color_line_t + * are determined. + * + * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * for details. + */ typedef enum { HB_PAINT_EXTEND_PAD, HB_PAINT_EXTEND_REPEAT, From 08da126523d1cdfdcd527f7bdf10c2d3525196e4 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 14:36:29 -0500 Subject: [PATCH 113/219] [docs] Linkify links --- src/hb-paint.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index 67574d05b..041eabb05 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -326,8 +326,8 @@ hb_color_line_get_color_stops (hb_color_line_t *color_line, * outside the minimum and maximum defined offset on a #hb_color_line_t * are determined. * - * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) - * for details. + * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * section for details. */ typedef enum { HB_PAINT_EXTEND_PAD, @@ -357,9 +357,9 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * The coordinates of the points are interpreted according * to the current transform. * - * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) - * for details on how the points define the direction of the - * gradient, and how to interpret the @color_line. + * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * section for details on how the points define the direction + * of the gradient, and how to interpret the @color_line. * * Since: REPLACEME */ @@ -390,9 +390,9 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * The coordinates of the points are interpreted according * to the current transform. * - * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) - * for details on how the points define the direction of the - * gradient, and how to interpret the @color_line. + * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * section for details on how the points define the direction + * of the gradient, and how to interpret the @color_line. * * Since: REPLACEME */ @@ -420,9 +420,9 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * The coordinates of the points are interpreted according * to the current transform. * - * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) - * for details on how the points define the direction of the - * gradient, and how to interpret the @color_line. + * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * section for details on how the points define the direction + * of the gradient, and how to interpret the @color_line. * * Since: REPLACEME */ @@ -441,8 +441,8 @@ typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, * that can be used when combining temporary redirected drawing * with the backdrop. * - * See the OpenType spec COLR section (https://learn.microsoft.com/en-us/typography/opentype/spec/colr) - * for details. + * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * section for details. */ typedef enum { HB_PAINT_COMPOSITE_MODE_CLEAR, From 14b026ff86f55436897702e268cf6c7eddbb0859 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 13:53:49 -0500 Subject: [PATCH 114/219] [draw] Add hb_font_draw_glyph hb_font_draw_glyph(), hb_font_draw_glyph_func_t and hb_font_funcs_set_draw_glyph_func() are just alternative names for hb_font_get_glyph_shape and friends, to better align with hb_font_paint_glyph. --- src/hb-draw.cc | 2 ++ src/hb-font.cc | 76 +++++++++++++++++++++++++++++++++-------------- src/hb-font.h | 46 +++++++++++++++++++++++++++- src/hb-font.hh | 14 ++++----- src/hb-ot-font.cc | 12 ++++---- 5 files changed, 114 insertions(+), 36 deletions(-) diff --git a/src/hb-draw.cc b/src/hb-draw.cc index c0d12992a..9877dd41b 100644 --- a/src/hb-draw.cc +++ b/src/hb-draw.cc @@ -35,6 +35,8 @@ * @include: hb.h * * Functions for drawing (extracting) glyph shapes. + * + * The #hb_draw_funcs_t struct can be used with hb_font_draw_glyph(). **/ static void diff --git a/src/hb-font.cc b/src/hb-font.cc index 52030453f..123447633 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -504,12 +504,12 @@ hb_font_get_glyph_from_name_default (hb_font_t *font, } static void -hb_font_get_glyph_shape_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, - void *draw_data, - void *user_data HB_UNUSED) +hb_font_draw_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data HB_UNUSED) { } @@ -523,13 +523,13 @@ hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED, { } -typedef struct hb_font_get_glyph_shape_default_adaptor_t { +typedef struct hb_font_draw_glyph_default_adaptor_t { hb_draw_funcs_t *draw_funcs; void *draw_data; float x_scale; float y_scale; float slant; -} hb_font_get_glyph_shape_default_adaptor_t; +} hb_font_draw_glyph_default_adaptor_t; static void hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, @@ -538,7 +538,7 @@ hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; float slant = adaptor->slant; @@ -553,7 +553,7 @@ hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; float slant = adaptor->slant; @@ -572,7 +572,7 @@ hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; float slant = adaptor->slant; @@ -593,7 +593,7 @@ hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; float slant = adaptor->slant; @@ -612,7 +612,7 @@ hb_draw_close_path_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, hb_draw_state_t *st, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data; + hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st); } @@ -628,14 +628,14 @@ static const hb_draw_funcs_t _hb_draw_funcs_default = { }; static void -hb_font_get_glyph_shape_default (hb_font_t *font, +hb_font_draw_glyph_default (hb_font_t *font, void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data HB_UNUSED) { - hb_font_get_glyph_shape_default_adaptor_t adaptor = { + hb_font_draw_glyph_default_adaptor_t adaptor = { draw_funcs, draw_data, font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, @@ -644,7 +644,7 @@ hb_font_get_glyph_shape_default (hb_font_t *font, (float) font->x_scale / (float) font->parent->y_scale : 0.f }; - font->parent->get_glyph_shape (glyph, + font->parent->draw_glyph (glyph, const_cast (&_hb_draw_funcs_default), &adaptor); } @@ -1388,14 +1388,37 @@ hb_font_get_glyph_from_name (hb_font_t *font, * The shape is returned by way of calls to the callbacks of the @dfuncs * objects, with @draw_data passed to them. * - * Since: 4.0.0 - **/ + * Since: REPLACEME + * + * Deprecated: REPLACEME: Use hb_font_draw_glyph() instead. + */ void hb_font_get_glyph_shape (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + hb_font_draw_glyph (font, glyph, dfuncs, draw_data); +} + +/** + * hb_font_draw_glyph: + * @font: #hb_font_t to work upon + * @glyph: : The glyph ID + * @dfuncs: #hb_draw_funcs_t to draw to + * @draw_data: User data to pass to draw callbacks + * + * Fetches the glyph shape that corresponds to a glyph in the specified @font. + * The shape is returned by way of calls to the callbacks of the @dfuncs + * objects, with @draw_data passed to them. + * + * Since: REPLACEME + **/ +void +hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_draw_funcs_t *dfuncs, void *draw_data) { - font->get_glyph_shape (glyph, dfuncs, draw_data); + font->draw_glyph (glyph, dfuncs, draw_data); } /** @@ -2386,9 +2409,8 @@ hb_font_get_ptem (hb_font_t *font) * HarfBuzz needs to know this value to adjust shaping results, * metrics, and style values to match the slanted rendering. * - * Note: The glyph shape fetched via the - * hb_font_get_glyph_shape() is slanted to reflect this value - * as well. + * Note: The glyph shape fetched via the hb_font_draw_glyph() + * function is slanted to reflect this value as well. * * Note: The slant value is a ratio. For example, a * 20% slant would be represented as a 0.2 value. @@ -2812,3 +2834,13 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, trampoline_destroy); } #endif + + +void +hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_shape_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) +{ + hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); +} diff --git a/src/hb-font.h b/src/hb-font.h index 9a08bd963..09edb1890 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -507,12 +507,32 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * Since: 4.0.0 * + * Deprecated: REPLACEME: Use #hb_font_draw_glyph_func_t instead **/ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data); +/** + * hb_font_draw_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @draw_funcs: The draw functions to send the shape data to + * @draw_data: The data accompanying the draw functions + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: REPLACEME + * + **/ +typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data); + /** * hb_font_paint_glyph_func_t: * @font: #hb_font_t to work upon @@ -796,15 +816,34 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, * @user_data: Data to pass to @func * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * Sets the implementation function for #hb_font_get_glyph_shape_func_t. + * Sets the implementation function for #hb_font_get_glyph_shape_func_t, + * which is the same as #hb_font_draw_glyph_func_t. * * Since: 4.0.0 + * + * Deprecated: REPLACEME: Use hb_font_set_draw_glyph_func() instead **/ HB_EXTERN void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_font_funcs_set_draw_glyph_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_draw_glyph_func_t. + * + * Since: REPLACEME + **/ +HB_EXTERN void +hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + /** * hb_font_funcs_set_paint_glyph_func: * @ffuncs: @@ -906,6 +945,11 @@ hb_font_get_glyph_shape (hb_font_t *font, hb_codepoint_t glyph, hb_draw_funcs_t *dfuncs, void *draw_data); +HB_EXTERN void +hb_font_draw_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data); + HB_EXTERN void hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, diff --git a/src/hb-font.hh b/src/hb-font.hh index 086700f0d..60fc53238 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -57,7 +57,7 @@ HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \ - HB_FONT_FUNC_IMPLEMENT (get_,glyph_shape) \ + HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \ HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \ /* ^--- Add new callbacks here */ @@ -393,13 +393,13 @@ struct hb_font_t !klass->user_data ? nullptr : klass->user_data->glyph_from_name); } - void get_glyph_shape (hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data) + void draw_glyph (hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data) { - klass->get.f.glyph_shape (this, user_data, - glyph, - draw_funcs, draw_data, - !klass->user_data ? nullptr : klass->user_data->glyph_shape); + klass->get.f.draw_glyph (this, user_data, + glyph, + draw_funcs, draw_data, + !klass->user_data ? nullptr : klass->user_data->draw_glyph); } void paint_glyph (hb_codepoint_t glyph, diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index acddde825..86b1fb665 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -425,11 +425,11 @@ hb_ot_get_font_v_extents (hb_font_t *font, #ifndef HB_NO_DRAW static void -hb_ot_get_glyph_shape (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data) +hb_ot_draw_glyph (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) { hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); if (font->face->table.glyf->get_path (font, glyph, draw_session)) return; @@ -487,7 +487,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t Date: Tue, 20 Dec 2022 11:52:39 -0700 Subject: [PATCH 115/219] [cairo] Remove unused struct --- util/hb-cairo-utils.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index df1bbb38e..ee998a531 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -51,13 +51,6 @@ typedef struct { float r, g, b, a; } color_t; -typedef struct { - cairo_t *cr; - hb_font_t *font; - hb_font_t *unscaled_font; -} paint_data_t; - - static inline cairo_extend_t cairo_extend (hb_paint_extend_t extend) { From 2333a566edbe99402d66086dd820a02335f56899 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 20 Dec 2022 22:43:04 -0500 Subject: [PATCH 116/219] Drop the deprecation No need to drop hb_font_get_glyph_shape, just because hb_font_draw_glyph does the same. Its fine to keep both around. --- src/hb-font.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hb-font.h b/src/hb-font.h index 09edb1890..e1151c1c2 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -506,8 +506,6 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * Since: 4.0.0 - * - * Deprecated: REPLACEME: Use #hb_font_draw_glyph_func_t instead **/ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -820,8 +818,6 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, * which is the same as #hb_font_draw_glyph_func_t. * * Since: 4.0.0 - * - * Deprecated: REPLACEME: Use hb_font_set_draw_glyph_func() instead **/ HB_EXTERN void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, From 754528914d98db1e30192cc07de4e3df879d5d8a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 00:09:25 -0500 Subject: [PATCH 117/219] [docs] Reorder paint section --- docs/harfbuzz-sections.txt | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index ce079f25d..f758721d5 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -231,37 +231,36 @@ hb_paint_funcs_make_immutable hb_paint_funcs_is_immutable hb_paint_push_transform_func_t +hb_paint_funcs_set_push_transform_func hb_paint_pop_transform_func_t +hb_paint_funcs_set_pop_transform_func hb_paint_push_clip_glyph_func_t +hb_paint_funcs_set_push_clip_glyph_func hb_paint_push_clip_rectangle_func_t +hb_paint_funcs_set_push_clip_rectangle_func hb_paint_pop_clip_func_t +hb_paint_funcs_set_pop_clip_func hb_paint_color_func_t +hb_paint_funcs_set_color_func HB_PAINT_IMAGE_FORMAT_PNG HB_PAINT_IMAGE_FORMAT_SVG hb_paint_image_func_t +hb_paint_funcs_set_image_func hb_color_line_t hb_color_stop_t hb_color_line_get_color_stops hb_paint_extend_t hb_color_line_get_extend hb_paint_linear_gradient_func_t +hb_paint_funcs_set_linear_gradient_func hb_paint_radial_gradient_func_t +hb_paint_funcs_set_radial_gradient_func hb_paint_sweep_gradient_func_t +hb_paint_funcs_set_sweep_gradient_func hb_paint_composite_mode_t hb_paint_push_group_func_t -hb_paint_pop_group_func_t - -hb_paint_funcs_set_push_transform_func -hb_paint_funcs_set_pop_transform_func -hb_paint_funcs_set_push_clip_glyph_func -hb_paint_funcs_set_push_clip_rectangle_func -hb_paint_funcs_set_pop_clip_func -hb_paint_funcs_set_color_func -hb_paint_funcs_set_image_func -hb_paint_funcs_set_linear_gradient_func -hb_paint_funcs_set_radial_gradient_func -hb_paint_funcs_set_sweep_gradient_func hb_paint_funcs_set_push_group_func +hb_paint_pop_group_func_t hb_paint_funcs_set_pop_group_func hb_paint_push_transform From a20999b9df313702643f012845cee4e266236985 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 00:20:37 -0500 Subject: [PATCH 118/219] [font] Fix a few documentation mistakes --- src/hb-font.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index 123447633..5baf407cb 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1388,9 +1388,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, * The shape is returned by way of calls to the callbacks of the @dfuncs * objects, with @draw_data passed to them. * - * Since: REPLACEME - * - * Deprecated: REPLACEME: Use hb_font_draw_glyph() instead. + * Since: 4.0.0 */ void hb_font_get_glyph_shape (hb_font_t *font, @@ -1407,8 +1405,9 @@ hb_font_get_glyph_shape (hb_font_t *font, * @dfuncs: #hb_draw_funcs_t to draw to * @draw_data: User data to pass to draw callbacks * - * Fetches the glyph shape that corresponds to a glyph in the specified @font. - * The shape is returned by way of calls to the callbacks of the @dfuncs + * Draws the outline that corresponds to a glyph in the specified @font. + * + * The outline is returned by way of calls to the callbacks of the @dfuncs * objects, with @draw_data passed to them. * * Since: REPLACEME From 8364d9130f72a80802153efc7e22ac85bb38fe8f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 00:59:13 -0500 Subject: [PATCH 119/219] Document hb_font_set_draw_glyph_func --- src/hb-font.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/hb-font.h b/src/hb-font.h index e1151c1c2..e117eaa4c 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -831,7 +831,8 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, * @user_data: Data to pass to @func * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * Sets the implementation function for #hb_font_draw_glyph_func_t. + * Sets the implementation function for #hb_font_draw_glyph_func_t, + * which is the same as #hb_font_get_glyph_shape_func_t. * * Since: REPLACEME **/ @@ -842,10 +843,10 @@ hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_paint_glyph_func: - * @ffuncs: - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: (nullable): + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is no longer needed * * Sets the implementation function for #hb_font_paint_glyph_func_t. * From 32ce29f99ea7387ce32de1114b1ce1c876fb6fbe Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 07:42:36 -0500 Subject: [PATCH 120/219] [font] Move hb_font_t typedef This is needed to avoid circular header dependencies. --- src/hb-common.h | 8 ++++++++ src/hb-font.h | 9 --------- src/hb-paint.h | 3 +-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index 7d72457a6..a5da4e76a 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -915,6 +915,14 @@ typedef struct hb_glyph_extents_t { hb_position_t height; } hb_glyph_extents_t; +/** + * hb_font_t: + * + * Data type for holding fonts. + * + */ +typedef struct hb_font_t hb_font_t; + HB_END_DECLS #endif /* HB_COMMON_H */ diff --git a/src/hb-font.h b/src/hb-font.h index e117eaa4c..4574a5769 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -38,15 +38,6 @@ HB_BEGIN_DECLS -/** - * hb_font_t: - * - * Data type for holding fonts. - * - */ -typedef struct hb_font_t hb_font_t; - - /* * hb_font_funcs_t */ diff --git a/src/hb-paint.h b/src/hb-paint.h index 041eabb05..7466f5bc8 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -29,8 +29,7 @@ #ifndef HB_PAINT_H #define HB_PAINT_H -#include "hb.h" -#include "hb-font.h" +#include "hb-common.h" HB_BEGIN_DECLS From 97224f3b63e7d8ec74acabc1270ebf021c19afd6 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 02:11:36 -0500 Subject: [PATCH 121/219] [paint] Pass font to all callbacks This will lead to easier implementations. At the same time, we change the push_clip_glyph callback to use the font as-is, no unscaling needed. Update all callers and expected test results. --- src/OT/glyf/glyf.hh | 8 +- src/hb-font.cc | 5 +- src/hb-ot-cff1-table.cc | 8 +- src/hb-ot-cff2-table.cc | 8 +- src/hb-ot-color-cbdt-table.hh | 2 +- src/hb-ot-color-colr-table.cc | 4 +- src/hb-ot-color-colr-table.hh | 137 ++++++++++-------- src/hb-ot-color-sbix-table.hh | 2 +- src/hb-ot-color-svg-table.hh | 2 +- src/hb-paint.cc | 84 ++++++++--- src/hb-paint.h | 65 ++++++--- src/hb-paint.hh | 79 +++++++--- src/hb.h | 2 +- test/api/results/hand-20-0-10 | 97 +++++++++++++ test/api/results/hand-20-0-10.txt | 79 ---------- test/api/results/hand-20-0.2-10 | 97 +++++++++++++ test/api/results/hand-20-0.2-10.txt | 79 ---------- test/api/results/test-20-0-10 | 14 ++ test/api/results/test-20-0-10.txt | 12 -- .../{test-20-0-106.txt => test-20-0-106} | 16 +- test/api/results/test-20-0-116 | 18 +++ test/api/results/test-20-0-116.txt | 14 -- .../{test-20-0-123.txt => test-20-0-123} | 24 +-- test/api/results/test-20-0-165 | 14 ++ test/api/results/test-20-0-165.txt | 12 -- test/api/results/test-20-0-175 | 26 ++++ test/api/results/test-20-0-175.txt | 22 --- test/api/results/test-20-0-6 | 13 ++ test/api/results/test-20-0-6.txt | 11 -- test/api/results/test-20-0-92 | 13 ++ test/api/results/test-20-0-92.txt | 11 -- test/api/test-ot-color.c | 40 +++-- util/helper-cairo-user.hh | 78 ++++------ 33 files changed, 639 insertions(+), 457 deletions(-) create mode 100644 test/api/results/hand-20-0-10 delete mode 100644 test/api/results/hand-20-0-10.txt create mode 100644 test/api/results/hand-20-0.2-10 delete mode 100644 test/api/results/hand-20-0.2-10.txt create mode 100644 test/api/results/test-20-0-10 delete mode 100644 test/api/results/test-20-0-10.txt rename test/api/results/{test-20-0-106.txt => test-20-0-106} (56%) create mode 100644 test/api/results/test-20-0-116 delete mode 100644 test/api/results/test-20-0-116.txt rename test/api/results/{test-20-0-123.txt => test-20-0-123} (64%) create mode 100644 test/api/results/test-20-0-165 delete mode 100644 test/api/results/test-20-0-165.txt create mode 100644 test/api/results/test-20-0-175 delete mode 100644 test/api/results/test-20-0-175.txt create mode 100644 test/api/results/test-20-0-6 delete mode 100644 test/api/results/test-20-0-6.txt create mode 100644 test/api/results/test-20-0-92 delete mode 100644 test/api/results/test-20-0-92.txt diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index 644b064ce..fa9f90d86 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -337,11 +337,11 @@ struct glyf_accelerator_t { funcs->push_root_transform (data, font); - funcs->push_clip_glyph (data, gid); - funcs->color (data, 0xffff, 1.); - funcs->pop_clip (data); + funcs->push_clip_glyph (data, gid, font); + funcs->color (data, 0xffff, 1., font); + funcs->pop_clip (data, font); - funcs->pop_root_transform (data); + funcs->pop_root_transform (data, font); return false; } diff --git a/src/hb-font.cc b/src/hb-font.cc index 5baf407cb..cbf323a1c 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -664,11 +664,12 @@ hb_font_paint_glyph_default (hb_font_t *font, 0.f, font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, 0.f, - 0.f); + 0.f, + font); font->parent->paint_glyph (glyph, paint_funcs, paint_data); - paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data, font); } DEFINE_NULL_INSTANCE (hb_font_funcs_t) = diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 76a66f0c9..c6cb48eb2 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -557,11 +557,11 @@ bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph { funcs->push_root_transform (data, font); - funcs->push_clip_glyph (data, glyph); - funcs->color (data, 0xffff, 1.); - funcs->pop_clip (data); + funcs->push_clip_glyph (data, glyph, font); + funcs->color (data, 0xffff, 1., font); + funcs->pop_clip (data, font); - funcs->pop_root_transform (data); + funcs->pop_root_transform (data, font); return false; } diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 983305c22..97e8100b6 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -147,11 +147,11 @@ bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph { funcs->push_root_transform (data, font); - funcs->push_clip_glyph (data, glyph); - funcs->color (data, 0xffff, 1.); - funcs->pop_clip (data); + funcs->push_clip_glyph (data, glyph, font); + funcs->color (data, 0xffff, 1., font); + funcs->pop_clip (data, font); - funcs->pop_root_transform (data); + funcs->pop_root_transform (data, font); return false; } diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index d956a7272..f32406daa 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -947,7 +947,7 @@ struct CBDT if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, font); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index b2b5bac20..9df0a0783 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -8,9 +8,9 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { const Paint &paint = paint_offset_lists.get_paint (i); - c->funcs->push_group (c->data); + c->funcs->push_group (c->data, c->font); c->recurse (paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, c->font); } } diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 9b1f7f7c0..9237f7436 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -75,16 +75,19 @@ public: const void *base; hb_paint_funcs_t *funcs; void *data; + hb_font_t *font; VarStoreInstancer &instancer; int depth_left = HB_COLRV1_MAX_NESTING_LEVEL; hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, void *data_, + hb_font_t *font_, VarStoreInstancer &instancer_) : base (base_), funcs (funcs_), data (data_), + font (font_), instancer (instancer_) {} @@ -482,7 +485,8 @@ struct Affine2x3 xy.to_float (c->instancer (varIdxBase, 2)), yy.to_float (c->instancer (varIdxBase, 3)), dx.to_float (c->instancer (varIdxBase, 4)), - dy.to_float (c->instancer (varIdxBase, 5))); + dy.to_float (c->instancer (varIdxBase, 5)), + c->font); } F16DOT16 xx; @@ -548,8 +552,9 @@ struct PaintSolid void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->color (c->data, - paletteIndex, - alpha.to_float (c->instancer (varIdxBase, 0))); + paletteIndex, + alpha.to_float (c->instancer (varIdxBase, 0)), + c->font); } HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ @@ -590,7 +595,8 @@ struct PaintLinearGradient x1 + c->instancer (varIdxBase, 2), y1 + c->instancer (varIdxBase, 3), x2 + c->instancer (varIdxBase, 4), - y2 + c->instancer (varIdxBase, 5)); + y2 + c->instancer (varIdxBase, 5), + c->font); } HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ @@ -637,7 +643,8 @@ struct PaintRadialGradient radius0 + c->instancer (varIdxBase, 2), x1 + c->instancer (varIdxBase, 3), y1 + c->instancer (varIdxBase, 4), - radius1 + c->instancer (varIdxBase, 5)); + radius1 + c->instancer (varIdxBase, 5), + c->font); } HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ @@ -682,7 +689,8 @@ struct PaintSweepGradient centerX + c->instancer (varIdxBase, 0), centerY + c->instancer (varIdxBase, 1), (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI, - (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI); + (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI, + c->font); } HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ @@ -722,9 +730,11 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_clip_glyph (c->data, gid); + c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_clip_glyph (c->data, gid, c->font); c->recurse (this+paint); - c->funcs->pop_clip (c->data); + c->funcs->pop_clip (c->data, c->font); + c->funcs->pop_inverse_root_transform (c->data, c->font); } HBUINT8 format; /* format = 10 */ @@ -788,7 +798,7 @@ struct PaintTransform { (this+transform).paint_glyph (c); c->recurse (this+src); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ @@ -822,9 +832,10 @@ struct PaintTranslate c->funcs->push_transform (c->data, 1., 0., 0., 1., dx + c->instancer (varIdxBase, 0), - dy + c->instancer (varIdxBase, 0)); + dy + c->instancer (varIdxBase, 0), + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ @@ -860,9 +871,10 @@ struct PaintScale scaleX.to_float (c->instancer (varIdxBase, 0)), 0., 0., scaleY.to_float (c->instancer (varIdxBase, 1)), - 0., 0.); + 0., 0., + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ @@ -896,17 +908,20 @@ struct PaintScaleAroundCenter { float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, + c->font); c->funcs->push_transform (c->data, scaleX.to_float (c->instancer (varIdxBase, 0)), 0., 0., scaleY.to_float (c->instancer (varIdxBase, 1)), - 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); + 0., 0., + c->font); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ @@ -941,9 +956,10 @@ struct PaintScaleUniform void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float s = scale + c->instancer (varIdxBase, 0); - c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); + c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0., + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ @@ -977,13 +993,16 @@ struct PaintScaleUniformAroundCenter float s = scale + c->instancer (varIdxBase, 0); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); - c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, + c->font); + c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0., + c->font); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ @@ -1019,9 +1038,10 @@ struct PaintRotate float a = angle.to_float (c->instancer (varIdxBase, 0)); float cc = cosf (a * (float) M_PI); float ss = sinf (a * (float) M_PI); - c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0., + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ @@ -1057,13 +1077,16 @@ struct PaintRotateAroundCenter float ss = sinf (a * (float) M_PI); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); - c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, + c->font); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0., + c->font); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ @@ -1098,9 +1121,10 @@ struct PaintSkew { float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); - c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); + c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0., + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ @@ -1136,13 +1160,16 @@ struct PaintSkewAroundCenter float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); - c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, + c->font); + c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0., + c->font); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, + c->font); c->recurse (this+src); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); - c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, c->font); } HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ @@ -1179,12 +1206,12 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_group (c->data); + c->funcs->push_group (c->data, c->font); c->recurse (this+backdrop); - c->funcs->push_group (c->data); + c->funcs->push_group (c->data, c->font); c->recurse (this+src); - c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode, c->font); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, c->font); } HBUINT8 format; /* format = 32 */ @@ -1939,17 +1966,17 @@ struct COLR this+varIdxMap, hb_array (font->coords, font->num_coords)); - hb_paint_context_t c (this, funcs, data, instancer); + hb_paint_context_t c (this, funcs, data, font, instancer); const Paint *paint = get_base_glyph_paint (glyph); if (paint) { // COLRv1 glyph - c.funcs->push_root_transform (data, font); + c.funcs->push_root_transform (c.data, c.font); c.recurse (*paint); - c.funcs->pop_root_transform (c.data); + c.funcs->pop_root_transform (c.data, c.font); return true; } @@ -1958,18 +1985,14 @@ struct COLR if (record && ((hb_codepoint_t) record->glyphId == glyph)) { // COLRv0 glyph - funcs->push_root_transform (data, font); - for (const auto &r : (this+layersZ).as_array (numLayers) .sub_array (record->firstLayerIdx, record->numLayers)) { - c.funcs->push_clip_glyph (c.data, r.glyphId); - c.funcs->color (c.data, r.colorIdx, 1.); - c.funcs->pop_clip (c.data); + c.funcs->push_clip_glyph (c.data, r.glyphId, c.font); + c.funcs->color (c.data, r.colorIdx, 1., c.font); + c.funcs->pop_clip (c.data, c.font); } - c.funcs->pop_root_transform (c.data); - return true; } diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index bafb45417..0a93c488e 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -248,7 +248,7 @@ struct sbix if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, font); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 3967a1196..d5a55133d 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,7 +103,7 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr, font); hb_blob_destroy (blob); return true; diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 55acc3c25..5fa39a451 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -47,30 +47,36 @@ hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, float dx, float dy, + hb_font_t *font, void *user_data) {} static void hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) {} static void hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, + hb_font_t *font, void *user_data) {} static void hb_paint_push_clip_rectangle_nil (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, + hb_font_t *font, void *user_data) {} static void hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) {} static void hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, + hb_font_t *font, void *user_data) {} static void @@ -78,6 +84,7 @@ hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, + hb_font_t *font, void *user_data) {} static void @@ -86,6 +93,7 @@ hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float x1, float y1, float x2, float y2, + hb_font_t *font, void *user_data) {} static void @@ -93,6 +101,7 @@ hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, + hb_font_t *font, void *user_data) {} static void @@ -101,15 +110,18 @@ hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float start_angle, float end_angle, + hb_font_t *font, void *user_data) {} static void hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) {} static void hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, + hb_font_t *font, void *user_data) {} static bool @@ -382,6 +394,7 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix + * @font: the font * * Perform a "push-transform" paint operation. * @@ -391,24 +404,27 @@ void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, - float dx, float dy) + float dx, float dy, + hb_font_t *font) { - funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); + funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy, font); } /** * hb_paint_pop_transform: * @funcs: paint functions * @paint_data: associated data passed by the caller + * @font: the font * * Perform a "pop-transform" paint operation. * * Since: REPLACEME */ void -hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) +hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font) { - funcs->pop_transform (paint_data); + funcs->pop_transform (paint_data, font); } /** @@ -416,6 +432,7 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) * @funcs: paint functions * @paint_data: associated data passed by the caller * @glyph: the glyph ID + * @font: the font * * Perform a "push-clip-glyph" paint operation. * @@ -423,9 +440,10 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) */ void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph) + hb_codepoint_t glyph, + hb_font_t *font) { - funcs->push_clip_glyph (paint_data, glyph); + funcs->push_clip_glyph (paint_data, glyph, font); } /** @@ -436,6 +454,7 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle + * @font: the font * * Perform a "push-clip-rect" paint operation. * @@ -443,24 +462,27 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, float xmax, float ymax) + float xmin, float ymin, float xmax, float ymax, + hb_font_t *font) { - funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax); + funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax, font); } /** * hb_paint_pop_clip: * @funcs: paint functions * @paint_data: associated data passed by the caller + * @font: the font * * Perform a "pop-clip" paint operation. * * Since: REPLACEME */ void -hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) +hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font) { - funcs->pop_clip (paint_data); + funcs->pop_clip (paint_data, font); } /** @@ -469,6 +491,7 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) * @paint_data: associated data passed by the caller * @color_index: Index of a color in the fonts selected color palette * @alpha: Alpha to apply in addition + * @font: the font * * Perform a "color" paint operation. * @@ -477,9 +500,10 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, - float alpha) + float alpha, + hb_font_t *font) { - funcs->color (paint_data, color_index, alpha); + funcs->color (paint_data, color_index, alpha, font); } /** @@ -489,6 +513,7 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, * @image: image data * @format: tag describing the image data format * @extents: (nullable): the extents of the glyph + * @font: the font * * Perform a "image" paint operation. * @@ -498,9 +523,10 @@ void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, - hb_glyph_extents_t *extents) + hb_glyph_extents_t *extents, + hb_font_t *font) { - funcs->image (paint_data, image, format, extents); + funcs->image (paint_data, image, format, extents, font); } /** @@ -514,6 +540,7 @@ hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point + * @font: the font * * Perform a "linear-gradient" paint operation. * @@ -524,9 +551,10 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, - float x2, float y2) + float x2, float y2, + hb_font_t *font) { - funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); + funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2, font); } /** @@ -540,6 +568,7 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle + * @font: the font * * Perform a "radial-gradient" paint operation. * @@ -549,9 +578,10 @@ void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, - float x1, float y1, float r1) + float x1, float y1, float r1, + hb_font_t *font) { - funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); + funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1, font); } /** @@ -563,6 +593,7 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, * @y0: Y coordinate of the circle's center * @start_angle: the start angle * @end_angle: the end angle + * @font: the font * * Perform a "sweep-gradient" paint operation. * @@ -572,24 +603,27 @@ void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, - float start_angle, float end_angle) + float start_angle, float end_angle, + hb_font_t *font) { - funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); + funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle, font); } /** * hb_paint_push_group: * @funcs: paint functions * @paint_data: associated data passed by the caller + * @font: the font * * Perform a "push-group" paint operation. * * Since: REPLACEME */ void -hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) +hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font) { - funcs->push_group (paint_data); + funcs->push_group (paint_data, font); } /** @@ -597,6 +631,7 @@ hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) * @funcs: paint functions * @paint_data: associated data passed by the caller * @mode: the compositing mode to use + * @font: the font * * Perform a "pop-group" paint operation. * @@ -604,9 +639,10 @@ hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) */ void hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode) + hb_paint_composite_mode_t mode, + hb_font_t *font) { - funcs->pop_group (paint_data, mode); + funcs->pop_group (paint_data, mode, font); } #endif diff --git a/src/hb-paint.h b/src/hb-paint.h index 7466f5bc8..8db53b324 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -101,6 +101,7 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_push_transform_func() * * A virtual method for the #hb_paint_funcs_t to apply @@ -117,12 +118,14 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, + hb_font_t *font, void *user_data); /** * hb_paint_pop_transform_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_pop_transform_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -133,6 +136,7 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, */ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data); /** @@ -140,6 +144,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @glyph: the glyph ID + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_glyph_func() * * A virtual method for the #hb_paint_funcs_t to clip @@ -148,11 +153,6 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * The coordinates of the glyph outline are interpreted according * to the current transform. * - * Note that hb_font_paint_glyph() applies the scale and slant of - * the font as a transform, so you need to pass an unscaled, unslanted - * copy of the font to hb_font_get_glyph_shape() when obtaining outlines, - * to avoid double scaling. - * * This clip is applied in addition to the current clip, * and remains in effect until a matching call to * the #hb_paint_funcs_pop_clip_func_t vfunc. @@ -162,6 +162,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, + hb_font_t *font, void *user_data); /** @@ -172,6 +173,7 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_rectangle_func() * * A virtual method for the #hb_paint_funcs_t to clip @@ -190,12 +192,14 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, + hb_font_t *font, void *user_data); /** * hb_paint_pop_clip_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_pop_clip_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -206,6 +210,7 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, */ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data); /** @@ -214,6 +219,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @color_index: Index of a color in the fonts selected color palette * @alpha: alpha to apply in addition + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_color_func() * * A virtual method for the #hb_paint_funcs_t to paint a @@ -232,6 +238,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, + hb_font_t *font, void *user_data); /** @@ -255,6 +262,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @image: the image data * @format: the image format as a tag * @extents: (nullable): glyph extents + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * * A virtual method for the #hb_paint_funcs_t to paint the @@ -275,6 +283,7 @@ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, + hb_font_t *font, void *user_data); /** @@ -348,6 +357,7 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_linear_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a linear @@ -368,6 +378,7 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, + hb_font_t *font, void *user_data); /** @@ -381,6 +392,7 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_radial_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a radial @@ -400,6 +412,7 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, + hb_font_t *font, void *user_data); /** @@ -411,6 +424,7 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * @y0: Y coordinate of the circle's center * @start_angle: the start angle, in radians * @end_angle: the end angle, in radians + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_sweep_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a sweep @@ -431,6 +445,7 @@ typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, float x0, float y0, float start_angle, float end_angle, + hb_font_t *font, void *user_data); /** @@ -478,6 +493,7 @@ typedef enum { * hb_paint_push_group_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_push_group_func() * * A virtual method for the #hb_paint_funcs_t to use @@ -491,6 +507,7 @@ typedef enum { */ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data); /** @@ -498,6 +515,7 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @mode: the compositing mode to use + * @font: the font that is being painted * @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -513,6 +531,7 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, + hb_font_t *font, void *user_data); /** @@ -723,40 +742,48 @@ HB_EXTERN void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, - float dx, float dy); + float dx, float dy, + hb_font_t *font); HB_EXTERN void -hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); +hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font); HB_EXTERN void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph); + hb_codepoint_t glyph, + hb_font_t *font); HB_EXTERN void hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, - float xmax, float ymax); + float xmax, float ymax, + hb_font_t *font); HB_EXTERN void -hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); +hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font); HB_EXTERN void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, - float alpha); + float alpha, + hb_font_t *font); HB_EXTERN void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, - hb_glyph_extents_t *extents); + hb_glyph_extents_t *extents, + hb_font_t *font); HB_EXTERN void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, - float x2, float y2); + float x2, float y2, + hb_font_t *font); HB_EXTERN void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, @@ -764,20 +791,24 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float r0, float x1, float y1, - float r1); + float r1, + hb_font_t *font); HB_EXTERN void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, - float start_angle, float end_angle); + float start_angle, float end_angle, + hb_font_t *font); HB_EXTERN void -hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data); +hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font); HB_EXTERN void hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode); + hb_paint_composite_mode_t mode, + hb_font_t *font); HB_END_DECLS diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 9e7927ac0..cc9c87d3b 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -69,69 +69,90 @@ struct hb_paint_funcs_t void push_transform (void *paint_data, float xx, float yx, float xy, float yy, - float dx, float dy) + float dx, float dy, + hb_font_t *font) { func.push_transform (this, paint_data, xx, yx, xy, yy, dx, dy, + font, !user_data ? nullptr : user_data->push_transform); } - void pop_transform (void *paint_data) - { func.pop_transform (this, paint_data, + void pop_transform (void *paint_data, + hb_font_t *font) + { func.pop_transform (this, paint_data, font, !user_data ? nullptr : user_data->pop_transform); } void push_clip_glyph (void *paint_data, - hb_codepoint_t glyph) + hb_codepoint_t glyph, + hb_font_t *font) { func.push_clip_glyph (this, paint_data, glyph, + font, !user_data ? nullptr : user_data->push_clip_glyph); } void push_clip_rectangle (void *paint_data, - float xmin, float ymin, float xmax, float ymax) + float xmin, float ymin, float xmax, float ymax, + hb_font_t *font) { func.push_clip_rectangle (this, paint_data, xmin, ymin, xmax, ymax, + font, !user_data ? nullptr : user_data->push_clip_rectangle); } - void pop_clip (void *paint_data) - { func.pop_clip (this, paint_data, + void pop_clip (void *paint_data, + hb_font_t *font) + { func.pop_clip (this, paint_data, font, !user_data ? nullptr : user_data->pop_clip); } void color (void *paint_data, unsigned int color_index, - float alpha) + float alpha, + hb_font_t *font) { func.color (this, paint_data, color_index, alpha, + font, !user_data ? nullptr : user_data->color); } void image (void *paint_data, hb_blob_t *image, hb_tag_t format, - hb_glyph_extents_t *extents) + hb_glyph_extents_t *extents, + hb_font_t *font) { func.image (this, paint_data, image, format, extents, + font, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, - float x2, float y2) + float x2, float y2, + hb_font_t *font) { func.linear_gradient (this, paint_data, color_line, x0, y0, x1, y1, x2, y2, + font, !user_data ? nullptr : user_data->linear_gradient); } void radial_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, - float x1, float y1, float r1) + float x1, float y1, float r1, + hb_font_t *font) { func.radial_gradient (this, paint_data, color_line, x0, y0, r0, x1, y1, r1, + font, !user_data ? nullptr : user_data->radial_gradient); } void sweep_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float start_angle, - float end_angle) + float end_angle, + hb_font_t *font) { func.sweep_gradient (this, paint_data, color_line, x0, y0, start_angle, end_angle, + font, !user_data ? nullptr : user_data->sweep_gradient); } - void push_group (void *paint_data) - { func.push_group (this, paint_data, + void push_group (void *paint_data, + hb_font_t *font) + { func.push_group (this, paint_data, font, !user_data ? nullptr : user_data->push_group); } void pop_group (void *paint_data, - hb_paint_composite_mode_t mode) + hb_paint_composite_mode_t mode, + hb_font_t *font) { func.pop_group (this, paint_data, mode, + font, !user_data ? nullptr : user_data->pop_group); } void push_root_transform (void *paint_data, @@ -141,12 +162,34 @@ struct hb_paint_funcs_t float upem = font->face->get_upem (); float slant = font->slant_xy; - func.push_transform (this, paint_data, xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0, + func.push_transform (this, paint_data, + xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0, + font, !user_data ? nullptr : user_data->push_transform); } - void pop_root_transform (void *paint_data) + void pop_root_transform (void *paint_data, + hb_font_t *font) { - func.pop_transform (this, paint_data, + func.pop_transform (this, paint_data, font, + !user_data ? nullptr : user_data->pop_transform); + } + + void push_inverse_root_transform (void *paint_data, + hb_font_t *font) + { + int xscale = font->x_scale, yscale = font->y_scale; + float upem = font->face->get_upem (); + float slant = font->slant_xy; + + func.push_transform (this, paint_data, + upem/xscale, 0, slant * upem/xscale, upem/yscale, 0, 0, + font, + !user_data ? nullptr : user_data->push_transform); + } + void pop_inverse_root_transform (void *paint_data, + hb_font_t *font) + { + func.pop_transform (this, paint_data, font, !user_data ? nullptr : user_data->pop_transform); } }; diff --git a/src/hb.h b/src/hb.h index d4c241c7f..5a6ae6607 100644 --- a/src/hb.h +++ b/src/hb.h @@ -33,10 +33,10 @@ #include "hb-common.h" #include "hb-deprecated.h" #include "hb-draw.h" -#include "hb-paint.h" #include "hb-face.h" #include "hb-font.h" #include "hb-map.h" +#include "hb-paint.h" #include "hb-set.h" #include "hb-shape.h" #include "hb-shape-plan.h" diff --git a/test/api/results/hand-20-0-10 b/test/api/results/hand-20-0-10 new file mode 100644 index 000000000..42160b529 --- /dev/null +++ b/test/api/results/hand-20-0-10 @@ -0,0 +1,97 @@ +start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 13 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 14 + linear gradient + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 + colors + 0.000000 12 1.000000 + 1.000000 12 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 15 + solid 9 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 16 + solid 0 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 21 + solid 9 1.000000 + end clip + end transform + pop group mode 3 + push group + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 16 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 5 1.000000 + 1.000000 1 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 18 + solid 2 0.200012 + end clip + end transform + pop group mode 3 + pop group mode 3 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 19 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start clip glyph 20 + solid 9 1.000000 + end clip + end transform + pop group mode 3 +end transform diff --git a/test/api/results/hand-20-0-10.txt b/test/api/results/hand-20-0-10.txt deleted file mode 100644 index 4a9c0c8d4..000000000 --- a/test/api/results/hand-20-0-10.txt +++ /dev/null @@ -1,79 +0,0 @@ -start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - push group - start clip glyph 13 - start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 - radial gradient - p0 280.000000 440.000000 radius 0.000000 - p1 280.000000 440.000000 radius 467.000000 - colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 - end transform - end clip - pop group mode 3 - push group - start clip glyph 14 - linear gradient - p0 231.000000 -27.000000 - p1 1019.000000 -27.000000 - p2 231.000000 -815.000000 - colors - 0.000000 12 1.000000 - 1.000000 12 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 15 - solid 9 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 16 - solid 0 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 21 - solid 9 1.000000 - end clip - pop group mode 3 - push group - push group - start clip glyph 16 - linear gradient - p0 669.000000 776.000000 - p1 180.000000 -106.000000 - p2 -212.000000 1265.000000 - colors - 0.000000 5 1.000000 - 1.000000 1 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 18 - solid 2 0.200012 - end clip - pop group mode 3 - pop group mode 3 - push group - start clip glyph 19 - start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 - radial gradient - p0 588.000000 198.000000 radius 0.000000 - p1 588.000000 198.000000 radius 342.000000 - colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 - end transform - end clip - pop group mode 3 - push group - start clip glyph 20 - solid 9 1.000000 - end clip - pop group mode 3 -end transform diff --git a/test/api/results/hand-20-0.2-10 b/test/api/results/hand-20-0.2-10 new file mode 100644 index 000000000..569bd24db --- /dev/null +++ b/test/api/results/hand-20-0.2-10 @@ -0,0 +1,97 @@ +start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 13 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 14 + linear gradient + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 + colors + 0.000000 12 1.000000 + 1.000000 12 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 15 + solid 9 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 16 + solid 0 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 21 + solid 9 1.000000 + end clip + end transform + pop group mode 3 + push group + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 16 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 5 1.000000 + 1.000000 1 1.000000 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 18 + solid 2 0.200012 + end clip + end transform + pop group mode 3 + pop group mode 3 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 19 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 16 1.000000 + 0.448792 15 1.000000 + 0.808594 14 1.000000 + 1.000000 12 1.000000 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start clip glyph 20 + solid 9 1.000000 + end clip + end transform + pop group mode 3 +end transform diff --git a/test/api/results/hand-20-0.2-10.txt b/test/api/results/hand-20-0.2-10.txt deleted file mode 100644 index f6e342b32..000000000 --- a/test/api/results/hand-20-0.2-10.txt +++ /dev/null @@ -1,79 +0,0 @@ -start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - push group - start clip glyph 13 - start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 - radial gradient - p0 280.000000 440.000000 radius 0.000000 - p1 280.000000 440.000000 radius 467.000000 - colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 - end transform - end clip - pop group mode 3 - push group - start clip glyph 14 - linear gradient - p0 231.000000 -27.000000 - p1 1019.000000 -27.000000 - p2 231.000000 -815.000000 - colors - 0.000000 12 1.000000 - 1.000000 12 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 15 - solid 9 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 16 - solid 0 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 21 - solid 9 1.000000 - end clip - pop group mode 3 - push group - push group - start clip glyph 16 - linear gradient - p0 669.000000 776.000000 - p1 180.000000 -106.000000 - p2 -212.000000 1265.000000 - colors - 0.000000 5 1.000000 - 1.000000 1 1.000000 - end clip - pop group mode 3 - push group - start clip glyph 18 - solid 2 0.200012 - end clip - pop group mode 3 - pop group mode 3 - push group - start clip glyph 19 - start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 - radial gradient - p0 588.000000 198.000000 radius 0.000000 - p1 588.000000 198.000000 radius 342.000000 - colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 - end transform - end clip - pop group mode 3 - push group - start clip glyph 20 - solid 9 1.000000 - end clip - pop group mode 3 -end transform diff --git a/test/api/results/test-20-0-10 b/test/api/results/test-20-0-10 new file mode 100644 index 000000000..e3238328a --- /dev/null +++ b/test/api/results/test-20-0-10 @@ -0,0 +1,14 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 174 + sweep gradient + center 500.000000 600.000000 + angles 0.000000 6.283185 + colors + 0.250000 7 1.000000 + 0.416687 4 1.000000 + 0.583313 0 1.000000 + 0.750000 8 1.000000 + end clip + end transform +end transform diff --git a/test/api/results/test-20-0-10.txt b/test/api/results/test-20-0-10.txt deleted file mode 100644 index 79ae162f3..000000000 --- a/test/api/results/test-20-0-10.txt +++ /dev/null @@ -1,12 +0,0 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start clip glyph 174 - sweep gradient - center 500.000000 600.000000 - angles 0.000000 6.283185 - colors - 0.250000 7 1.000000 - 0.416687 4 1.000000 - 0.583313 0 1.000000 - 0.750000 8 1.000000 - end clip -end transform diff --git a/test/api/results/test-20-0-106.txt b/test/api/results/test-20-0-106 similarity index 56% rename from test/api/results/test-20-0-106.txt rename to test/api/results/test-20-0-106 index 0377d9513..e16d01c71 100644 --- a/test/api/results/test-20-0-106.txt +++ b/test/api/results/test-20-0-106 @@ -1,15 +1,19 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group - start clip glyph 3 - solid 4 0.500000 - end clip + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + solid 4 0.500000 + end clip + end transform push group start transform 0.000000 0.000000 0.000000 0.000000 1000.000000 1000.000000 start transform 1.000000 -0.363874 -0.176283 1.000000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000 - start clip glyph 3 - solid 1 0.700012 - end clip + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + solid 1 0.700012 + end clip + end transform end transform end transform end transform diff --git a/test/api/results/test-20-0-116 b/test/api/results/test-20-0-116 new file mode 100644 index 000000000..751b8e8a8 --- /dev/null +++ b/test/api/results/test-20-0-116 @@ -0,0 +1,18 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + push group + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + solid 4 0.500000 + end clip + end transform + push group + start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + solid 1 0.700012 + end clip + end transform + end transform + pop group mode 4 + pop group mode 3 +end transform diff --git a/test/api/results/test-20-0-116.txt b/test/api/results/test-20-0-116.txt deleted file mode 100644 index 01fbef52a..000000000 --- a/test/api/results/test-20-0-116.txt +++ /dev/null @@ -1,14 +0,0 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - push group - start clip glyph 3 - solid 4 0.500000 - end clip - push group - start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 - start clip glyph 3 - solid 1 0.700012 - end clip - end transform - pop group mode 4 - pop group mode 3 -end transform diff --git a/test/api/results/test-20-0-123.txt b/test/api/results/test-20-0-123 similarity index 64% rename from test/api/results/test-20-0-123.txt rename to test/api/results/test-20-0-123 index f99ee44f6..b97987fc7 100644 --- a/test/api/results/test-20-0-123.txt +++ b/test/api/results/test-20-0-123 @@ -1,17 +1,21 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group - start clip glyph 3 - solid 10 1.000000 - end clip + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + solid 10 1.000000 + end clip + end transform pop group mode 3 push group push group start transform 0.000000 0.000000 0.000000 0.000000 333.000000 667.000000 start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000 - start clip glyph 2 - solid 12 1.000000 - end clip + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 2 + solid 12 1.000000 + end clip + end transform end transform end transform end transform @@ -19,9 +23,11 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 667.000000 333.000000 start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000 - start clip glyph 2 - solid 11 1.000000 - end clip + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 2 + solid 11 1.000000 + end clip + end transform end transform end transform end transform diff --git a/test/api/results/test-20-0-165 b/test/api/results/test-20-0-165 new file mode 100644 index 000000000..2fade5352 --- /dev/null +++ b/test/api/results/test-20-0-165 @@ -0,0 +1,14 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 165 + linear gradient + p0 100.000000 950.000000 + p1 2300.000000 950.000000 + p2 -1000.000000 250.000000 + colors + 0.000000 0 1.000000 + 0.500000 4 1.000000 + 1.000000 2 1.000000 + end clip + end transform +end transform diff --git a/test/api/results/test-20-0-165.txt b/test/api/results/test-20-0-165.txt deleted file mode 100644 index 8db60bfbd..000000000 --- a/test/api/results/test-20-0-165.txt +++ /dev/null @@ -1,12 +0,0 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start clip glyph 165 - linear gradient - p0 100.000000 950.000000 - p1 2300.000000 950.000000 - p2 -1000.000000 250.000000 - colors - 0.000000 0 1.000000 - 0.500000 4 1.000000 - 1.000000 2 1.000000 - end clip -end transform diff --git a/test/api/results/test-20-0-175 b/test/api/results/test-20-0-175 new file mode 100644 index 000000000..1b13c45f3 --- /dev/null +++ b/test/api/results/test-20-0-175 @@ -0,0 +1,26 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + push group + start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 174 + solid 3 1.000000 + end clip + end transform + end transform + pop group mode 3 + push group + start transform 1.000000 0.000000 0.000000 1.000000 -150.000000 0.000000 + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 174 + linear gradient + p0 500.000000 250.000000 + p1 500.000000 950.000000 + p2 600.000000 250.000000 + colors + 0.000000 0 1.000000 + 1.000000 4 1.000000 + end clip + end transform + end transform + pop group mode 3 +end transform diff --git a/test/api/results/test-20-0-175.txt b/test/api/results/test-20-0-175.txt deleted file mode 100644 index 1c3a2f56c..000000000 --- a/test/api/results/test-20-0-175.txt +++ /dev/null @@ -1,22 +0,0 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - push group - start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 - start clip glyph 174 - solid 3 1.000000 - end clip - end transform - pop group mode 3 - push group - start transform 1.000000 0.000000 0.000000 1.000000 -150.000000 0.000000 - start clip glyph 174 - linear gradient - p0 500.000000 250.000000 - p1 500.000000 950.000000 - p2 600.000000 250.000000 - colors - 0.000000 0 1.000000 - 1.000000 4 1.000000 - end clip - end transform - pop group mode 3 -end transform diff --git a/test/api/results/test-20-0-6 b/test/api/results/test-20-0-6 new file mode 100644 index 000000000..4bd5c8f0a --- /dev/null +++ b/test/api/results/test-20-0-6 @@ -0,0 +1,13 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 6 + linear gradient + p0 100.000000 250.000000 + p1 900.000000 250.000000 + p2 100.000000 300.000000 + colors + 0.000000 0 1.000000 + 1.000000 4 1.000000 + end clip + end transform +end transform diff --git a/test/api/results/test-20-0-6.txt b/test/api/results/test-20-0-6.txt deleted file mode 100644 index 90b842ad5..000000000 --- a/test/api/results/test-20-0-6.txt +++ /dev/null @@ -1,11 +0,0 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start clip glyph 6 - linear gradient - p0 100.000000 250.000000 - p1 900.000000 250.000000 - p2 100.000000 300.000000 - colors - 0.000000 0 1.000000 - 1.000000 4 1.000000 - end clip -end transform diff --git a/test/api/results/test-20-0-92 b/test/api/results/test-20-0-92 new file mode 100644 index 000000000..40bd05742 --- /dev/null +++ b/test/api/results/test-20-0-92 @@ -0,0 +1,13 @@ +start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start clip glyph 2 + radial gradient + p0 166.000000 768.000000 radius 0.000000 + p1 166.000000 768.000000 radius 256.000000 + colors + 0.000000 3 1.000000 + 0.500000 9 1.000000 + 1.000000 0 1.000000 + end clip + end transform +end transform diff --git a/test/api/results/test-20-0-92.txt b/test/api/results/test-20-0-92.txt deleted file mode 100644 index f099bdd82..000000000 --- a/test/api/results/test-20-0-92.txt +++ /dev/null @@ -1,11 +0,0 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start clip glyph 2 - radial gradient - p0 166.000000 768.000000 radius 0.000000 - p1 166.000000 768.000000 radius 256.000000 - colors - 0.000000 3 1.000000 - 0.500000 9 1.000000 - 1.000000 0 1.000000 - end clip -end transform diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 6bb1130aa..de5d81b26 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -484,6 +484,7 @@ push_transform (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -495,6 +496,7 @@ push_transform (hb_paint_funcs_t *funcs, static void pop_transform (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -507,6 +509,7 @@ static void push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -519,6 +522,7 @@ static void push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -530,6 +534,7 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, static void pop_clip (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -543,6 +548,7 @@ paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -556,6 +562,7 @@ paint_image (hb_paint_funcs_t *funcs, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -591,6 +598,7 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -611,6 +619,7 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -631,6 +640,7 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, float cx, float cy, float start_angle, float end_angle, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -647,6 +657,7 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, static void push_group (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -658,6 +669,7 @@ static void pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -677,16 +689,16 @@ typedef struct { #define TEST_GLYPHS "fonts/test_glyphs-glyf_colr_1.ttf" static colrv1_test_t colrv1_tests[] = { - { NOTO_HAND, 20, 0., 10, "results/hand-20-0-10.txt" }, - { NOTO_HAND, 20, 0.2, 10, "results/hand-20-0.2-10.txt" }, - { TEST_GLYPHS, 20, 0, 6, "results/test-20-0-6.txt" }, - { TEST_GLYPHS, 20, 0, 10, "results/test-20-0-10.txt" }, - { TEST_GLYPHS, 20, 0, 92, "results/test-20-0-92.txt" }, - { TEST_GLYPHS, 20, 0, 106, "results/test-20-0-106.txt" }, - { TEST_GLYPHS, 20, 0, 116, "results/test-20-0-116.txt" }, - { TEST_GLYPHS, 20, 0, 123, "results/test-20-0-123.txt" }, - { TEST_GLYPHS, 20, 0, 165, "results/test-20-0-165.txt" }, - { TEST_GLYPHS, 20, 0, 175, "results/test-20-0-175.txt" }, + { NOTO_HAND, 20, 0., 10, "hand-20-0-10" }, + { NOTO_HAND, 20, 0.2, 10, "hand-20-0.2-10" }, + { TEST_GLYPHS, 20, 0, 6, "test-20-0-6" }, + { TEST_GLYPHS, 20, 0, 10, "test-20-0-10" }, + { TEST_GLYPHS, 20, 0, 92, "test-20-0-92" }, + { TEST_GLYPHS, 20, 0, 106, "test-20-0-106" }, + { TEST_GLYPHS, 20, 0, 116, "test-20-0-116" }, + { TEST_GLYPHS, 20, 0, 123, "test-20-0-123" }, + { TEST_GLYPHS, 20, 0, 165, "test-20-0-165" }, + { TEST_GLYPHS, 20, 0, 175, "test-20-0-175" }, }; static void @@ -738,7 +750,7 @@ test_hb_ot_color_colr_v1 (gconstpointer d) exit (0); } - file = g_test_build_filename (G_TEST_DIST, test->output, NULL); + file = g_test_build_filename (G_TEST_DIST, "results", test->output, NULL); if (!g_file_get_contents (file, &buffer, &len, &error)) { g_test_message ("File %s not found.", file); @@ -820,11 +832,7 @@ main (int argc, char **argv) hb_test_add (test_hb_ot_color_png); hb_test_add (test_hb_ot_color_svg); for (unsigned int i = 0; i < G_N_ELEMENTS (colrv1_tests); i++) - { - char buf[10] = { 0, }; - g_snprintf (buf, 10, "%d", i); - hb_test_add_data_flavor (&colrv1_tests[i], buf, test_hb_ot_color_colr_v1); - } + hb_test_add_data_flavor (&colrv1_tests[i], colrv1_tests[i].output, test_hb_ot_color_colr_v1); status = hb_test_run(); hb_face_destroy (cpal_v0); diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 354531935..aef956785 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -105,36 +105,30 @@ get_cairo_draw_funcs (void) #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC -typedef struct { - cairo_t *cr; - hb_font_t *font; - hb_font_t *unscaled_font; -} paint_data_t; - static void push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, float dx, float dy, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; cairo_matrix_t m; cairo_save (cr); cairo_matrix_init (&m, xx, yx, xy, yy, dx, dy); - cairo_transform (data->cr, &m); + cairo_transform (cr, &m); } static void pop_transform (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; cairo_restore (cr); } @@ -143,14 +137,14 @@ static void push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; cairo_save (cr); cairo_new_path (cr); - hb_font_get_glyph_shape (data->unscaled_font, glyph, get_cairo_draw_funcs (), cr); + hb_font_get_glyph_shape (font, glyph, get_cairo_draw_funcs (), cr); cairo_close_path (cr); cairo_clip (cr); } @@ -159,10 +153,10 @@ static void push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; cairo_save (cr); cairo_rectangle (cr, xmin, ymin, xmax - xmin, ymax - ymin); @@ -172,10 +166,10 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, static void pop_clip (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; cairo_restore (cr); } @@ -183,10 +177,10 @@ pop_clip (hb_paint_funcs_t *funcs, static void push_group (hb_paint_funcs_t *funcs, void *paint_data, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; cairo_save (cr); cairo_push_group (cr); @@ -196,10 +190,10 @@ static void pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; cairo_pop_group_to_source (cr); cairo_set_operator (cr, hb_paint_composite_mode_to_cairo (mode)); @@ -213,11 +207,11 @@ paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - hb_face_t *face = hb_font_get_face (data->font); - cairo_t *cr = data->cr; + cairo_t *cr = (cairo_t *)paint_data; + hb_face_t *face = hb_font_get_face (font); float r, g, b, a; hb_face_get_color (face, 0, color_index, alpha, &r, &g, &b, &a); @@ -231,11 +225,10 @@ paint_image (hb_paint_funcs_t *funcs, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; + cairo_t *cr = (cairo_t *)paint_data; hb_cairo_paint_glyph_image (cr, font, blob, format, extents); } @@ -247,11 +240,10 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; + cairo_t *cr = (cairo_t *)paint_data; hb_cairo_paint_linear_gradient (cr, font, color_line, x0, y0, x1, y1, x2, y2); } @@ -262,11 +254,10 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; + cairo_t *cr = (cairo_t *)paint_data; hb_cairo_paint_radial_gradient (cr, font, color_line, x0, y0, r0, x1, y1, r1); } @@ -277,11 +268,10 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle, + hb_font_t *font, void *user_data) { - paint_data_t *data = (paint_data_t *) paint_data; - cairo_t *cr = data->cr; - hb_font_t *font = data->font; + cairo_t *cr = (cairo_t *)paint_data; hb_cairo_paint_sweep_gradient (cr, font, color_line, x0, y0, start_angle, end_angle); } @@ -357,22 +347,12 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, { hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &_hb_font_cairo_user_data_key)); - paint_data_t paint_data; - - paint_data.cr = cr; - paint_data.font = font; - - hb_face_t *face = hb_font_get_face (font); - paint_data.unscaled_font = hb_font_create (face); - unsigned int upem = hb_face_get_upem (face); - hb_font_set_scale (paint_data.unscaled_font, upem, upem); - hb_font_set_synthetic_slant (paint_data.unscaled_font, 0.); hb_position_t x_scale, y_scale; hb_font_get_scale (font, &x_scale, &y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale); - hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), (void *)&paint_data); + hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr); hb_glyph_extents_t hb_extents; hb_font_get_glyph_extents (font, glyph, &hb_extents); @@ -381,8 +361,6 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, extents->width = (double) hb_extents.width / x_scale; extents->height = (double)-hb_extents.height / y_scale; - hb_font_destroy (paint_data.unscaled_font); - return CAIRO_STATUS_SUCCESS; } From b1500babaae38cb6d81bc4287adeb4678dfde1b3 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 09:49:42 -0500 Subject: [PATCH 122/219] utils: Some cairo helper tweaks --- util/hb-cairo-utils.c | 64 +++++++++++++++++++-------------------- util/hb-cairo-utils.h | 10 +++--- util/helper-cairo-user.hh | 19 +++++++----- 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index ee998a531..95b2feca5 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -45,6 +45,11 @@ #define MAX(x,y) ((x) > (y) ? (x) : (y)) #endif +#ifndef FALSE +#define TRUE 1 +#define FALSE 0 +#endif + #define PREALLOCATED_COLOR_STOPS 16 typedef struct { @@ -65,37 +70,35 @@ cairo_extend (hb_paint_extend_t extend) return CAIRO_EXTEND_PAD; } -void -hb_face_get_color (hb_face_t *face, - unsigned int palette_index, - unsigned int color_index, - float alpha, - float *r, float *g, float *b, float *a) +hb_bool_t +hb_cairo_get_font_color (hb_font_t *font, + unsigned int palette_index, + unsigned int color_index, + float alpha, + float *r, float *g, float *b, float *a) { - if (color_index == 0xffff) - { - /* foreground color */ - *r = *g = *b = 0; - *a = alpha; - } - else + if (color_index != 0xffff) { hb_color_t color; unsigned int clen = 1; + hb_face_t *face = hb_font_get_face (font); if (hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color)) - { - *r = hb_color_get_red (color) / 255.f; - *g = hb_color_get_green (color) / 255.f; - *b = hb_color_get_blue (color) / 255.f; - *a = (hb_color_get_alpha (color) / 255.f) * alpha; - } - else - { - *r = *g = *b = 0; - *a = alpha; - } + { + *r = hb_color_get_red (color) / 255.f; + *g = hb_color_get_green (color) / 255.f; + *b = hb_color_get_blue (color) / 255.f; + *a = (hb_color_get_alpha (color) / 255.f) * alpha; + + return TRUE; + } } + + /* foreground color */ + *r = *g = *b = 0; + *a = alpha; + + return FALSE; } typedef struct @@ -240,7 +243,6 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, float x1, float y1, float x2, float y2) { - hb_face_t *face = hb_font_get_face (font); hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; hb_color_stop_t *stops = stops_; unsigned int len; @@ -267,7 +269,7 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, for (unsigned int i = 0; i < len; i++) { float r, g, b, a; - hb_face_get_color (face, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + hb_cairo_get_font_color (font, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); } @@ -287,7 +289,6 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, float x0, float y0, float r0, float x1, float y1, float r1) { - hb_face_t *face = hb_font_get_face (font); hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; hb_color_stop_t *stops = stops_; unsigned int len; @@ -316,7 +317,7 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, for (unsigned int i = 0; i < len; i++) { float r, g, b, a; - hb_face_get_color (face, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + hb_cairo_get_font_color (font, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); } @@ -481,7 +482,6 @@ add_sweep_gradient_patches (hb_font_t *font, float end_angle, cairo_pattern_t *pattern) { - hb_face_t *face = hb_font_get_face (font); float angles_[PREALLOCATED_COLOR_STOPS]; float *angles = angles_; color_t colors_[PREALLOCATED_COLOR_STOPS]; @@ -495,7 +495,7 @@ add_sweep_gradient_patches (hb_font_t *font, color_t c; if (start_angle > 0) { - hb_face_get_color (face, 0, stops[0].color_index, stops[0].alpha, &c.r, &c.g, &c.b, &c.a); + hb_cairo_get_font_color (font, 0, stops[0].color_index, stops[0].alpha, &c.r, &c.g, &c.b, &c.a); add_sweep_gradient_patches1 (cx, cy, radius, 0., &c, start_angle, &c, @@ -503,7 +503,7 @@ add_sweep_gradient_patches (hb_font_t *font, } if (end_angle < 2 * M_PI) { - hb_face_get_color (face, 0, stops[n_stops-1].color_index, stops[n_stops-1].alpha, &c.r, &c.g, &c.b, &c.a); + hb_cairo_get_font_color (font, 0, stops[n_stops-1].color_index, stops[n_stops-1].alpha, &c.r, &c.g, &c.b, &c.a); add_sweep_gradient_patches1 (cx, cy, radius, end_angle, &c, 2 * M_PI, &c, @@ -539,7 +539,7 @@ add_sweep_gradient_patches (hb_font_t *font, for (unsigned i = 0; i < n_stops; i++) { angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); - hb_face_get_color (face, 0, stops[i].color_index, stops[i].alpha, &colors[i].r, &colors[i].g, &colors[i].b, &colors[i].a); + hb_cairo_get_font_color (font, 0, stops[i].color_index, stops[i].alpha, &colors[i].r, &colors[i].g, &colors[i].b, &colors[i].a); } if (extend == CAIRO_EXTEND_PAD) diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index ddff56839..359616658 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -70,11 +70,11 @@ hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) return CAIRO_OPERATOR_SOURCE; } -void hb_face_get_color (hb_face_t *face, - unsigned int palette_index, - unsigned int color_index, - float alpha, - float *r, float *g, float *b, float *a); +hb_bool_t hb_cairo_get_font_color (hb_font_t *font, + unsigned int palette_index, + unsigned int color_index, + float alpha, + float *r, float *g, float *b, float *a); void hb_cairo_paint_glyph_image (cairo_t *cr, hb_font_t *font, diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index aef956785..ce5ebda46 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -118,7 +118,9 @@ push_transform (hb_paint_funcs_t *funcs, cairo_matrix_t m; cairo_save (cr); - cairo_matrix_init (&m, xx, yx, xy, yy, dx, dy); + cairo_matrix_init (&m, (double)xx, (double)yx, + (double)xy, (double)yy, + (double)dx, (double)dy); cairo_transform (cr, &m); } @@ -144,7 +146,7 @@ push_clip_glyph (hb_paint_funcs_t *funcs, cairo_save (cr); cairo_new_path (cr); - hb_font_get_glyph_shape (font, glyph, get_cairo_draw_funcs (), cr); + hb_font_draw_glyph (font, glyph, get_cairo_draw_funcs (), cr); cairo_close_path (cr); cairo_clip (cr); } @@ -159,7 +161,9 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, cairo_t *cr = (cairo_t *)paint_data; cairo_save (cr); - cairo_rectangle (cr, xmin, ymin, xmax - xmin, ymax - ymin); + cairo_rectangle (cr, + (double)xmin, (double)ymin, + (double)(xmax - xmin), (double)(ymax - ymin)); cairo_clip (cr); } @@ -211,11 +215,10 @@ paint_color (hb_paint_funcs_t *funcs, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_face_t *face = hb_font_get_face (font); float r, g, b, a; - hb_face_get_color (face, 0, color_index, alpha, &r, &g, &b, &a); - cairo_set_source_rgba (cr, r, g, b, a); + hb_cairo_get_font_color (font, 0, color_index, alpha, &r, &g, &b, &a); + cairo_set_source_rgba (cr, (double)r, (double)g, (double)b, (double)a); cairo_paint (cr); } @@ -277,7 +280,7 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, } static hb_paint_funcs_t * -get_cairo_paint_funcs (void) +get_cairo_paint_funcs () { static hb_paint_funcs_t *funcs; @@ -331,7 +334,7 @@ render_glyph (cairo_scaled_font_t *scaled_font, hb_font_get_scale (font, &x_scale, &y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale); - hb_font_get_glyph_shape (font, glyph, get_cairo_draw_funcs (), cr); + hb_font_draw_glyph (font, glyph, get_cairo_draw_funcs (), cr); cairo_fill (cr); return CAIRO_STATUS_SUCCESS; From 8495395397e5a26dacad0cad689a41b06ef5314c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Dec 2022 09:03:13 -0700 Subject: [PATCH 123/219] [paint] Fix slant --- src/hb-paint.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-paint.hh b/src/hb-paint.hh index cc9c87d3b..7e301c00f 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -182,7 +182,7 @@ struct hb_paint_funcs_t float slant = font->slant_xy; func.push_transform (this, paint_data, - upem/xscale, 0, slant * upem/xscale, upem/yscale, 0, 0, + upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0, font, !user_data ? nullptr : user_data->push_transform); } From 6c71c530caaa40c0038ac1f33549a5a7f96266c3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Dec 2022 10:54:22 -0700 Subject: [PATCH 124/219] [paint] Rename hb_paint_context_t to hb_ot_paint_context_t --- src/hb-ot-color-colr-table.cc | 4 +-- src/hb-ot-color-colr-table.hh | 56 +++++++++++++++++------------------ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 9df0a0783..3f1e9f474 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -2,7 +2,7 @@ namespace OT { -void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const +void PaintColrLayers::paint_glyph (hb_ot_paint_context_t *c) const { const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) @@ -14,7 +14,7 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const } } -void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const +void PaintColrGlyph::paint_glyph (hb_ot_paint_context_t *c) const { const COLR *colr_table = c->get_colr_table (); const Paint *paint = colr_table->get_base_glyph_paint (gid); diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 9237f7436..5c5bf4902 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -46,11 +46,11 @@ namespace OT { -struct hb_paint_context_t; +struct hb_ot_paint_context_t; } struct hb_color_line_t { - struct OT::hb_paint_context_t *c; + struct OT::hb_ot_paint_context_t *c; const void *base; bool is_variable; }; @@ -61,8 +61,8 @@ struct COLR; struct Paint; -struct hb_paint_context_t : - hb_dispatch_context_t +struct hb_ot_paint_context_t : + hb_dispatch_context_t { template return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); } @@ -79,7 +79,7 @@ public: VarStoreInstancer &instancer; int depth_left = HB_COLRV1_MAX_NESTING_LEVEL; - hb_paint_context_t (const void *base_, + hb_ot_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, void *data_, hb_font_t *font_, @@ -233,7 +233,7 @@ struct Variable return_trace (c->check_struct (this) && value.sanitize (c)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_ot_paint_context_t *c) const { value.paint_glyph (c, varIdxBase); } @@ -285,7 +285,7 @@ struct NoVariable return_trace (c->check_struct (this) && value.sanitize (c)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_ot_paint_context_t *c) const { value.paint_glyph (c, varIdxBase); } @@ -477,7 +477,7 @@ struct Affine2x3 return_trace (c->check_struct (this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, xx.to_float (c->instancer (varIdxBase, 0)), @@ -520,7 +520,7 @@ struct PaintColrLayers return_trace (c->check_struct (this)); } - HB_INTERNAL void paint_glyph (hb_paint_context_t *c) const; + HB_INTERNAL void paint_glyph (hb_ot_paint_context_t *c) const; HBUINT8 format; /* format = 1 */ HBUINT8 numLayers; @@ -549,7 +549,7 @@ struct PaintSolid return_trace (c->check_struct (this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->color (c->data, paletteIndex, @@ -585,7 +585,7 @@ struct PaintLinearGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; @@ -633,7 +633,7 @@ struct PaintRadialGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; @@ -681,7 +681,7 @@ struct PaintSweepGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; @@ -728,7 +728,7 @@ struct PaintGlyph return_trace (c->check_struct (this) && paint.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_ot_paint_context_t *c) const { c->funcs->push_inverse_root_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); @@ -764,7 +764,7 @@ struct PaintColrGlyph return_trace (c->check_struct (this)); } - HB_INTERNAL void paint_glyph (hb_paint_context_t *c) const; + HB_INTERNAL void paint_glyph (hb_ot_paint_context_t *c) const; HBUINT8 format; /* format = 11 */ HBUINT16 gid; @@ -794,7 +794,7 @@ struct PaintTransform transform.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_ot_paint_context_t *c) const { (this+transform).paint_glyph (c); c->recurse (this+src); @@ -827,7 +827,7 @@ struct PaintTranslate return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, 1., 0., 0., 1., @@ -865,7 +865,7 @@ struct PaintScale return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, scaleX.to_float (c->instancer (varIdxBase, 0)), @@ -904,7 +904,7 @@ struct PaintScaleAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); @@ -953,7 +953,7 @@ struct PaintScaleUniform return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { float s = scale + c->instancer (varIdxBase, 0); c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0., @@ -988,7 +988,7 @@ struct PaintScaleUniformAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { float s = scale + c->instancer (varIdxBase, 0); float tCenterX = centerX + c->instancer (varIdxBase, 1); @@ -1033,7 +1033,7 @@ struct PaintRotate return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { float a = angle.to_float (c->instancer (varIdxBase, 0)); float cc = cosf (a * (float) M_PI); @@ -1070,7 +1070,7 @@ struct PaintRotateAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { float a = angle.to_float (c->instancer (varIdxBase, 0)); float cc = cosf (a * (float) M_PI); @@ -1117,7 +1117,7 @@ struct PaintSkew return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); @@ -1154,7 +1154,7 @@ struct PaintSkewAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); @@ -1204,7 +1204,7 @@ struct PaintComposite backdrop.sanitize (c, this)); } - void paint_glyph (hb_paint_context_t *c) const + void paint_glyph (hb_ot_paint_context_t *c) const { c->funcs->push_group (c->data, c->font); c->recurse (this+backdrop); @@ -1966,7 +1966,7 @@ struct COLR this+varIdxMap, hb_array (font->coords, font->num_coords)); - hb_paint_context_t c (this, funcs, data, font, instancer); + hb_ot_paint_context_t c (this, funcs, data, font, instancer); const Paint *paint = get_base_glyph_paint (glyph); if (paint) @@ -2022,7 +2022,7 @@ struct COLR_accelerator_t : COLR::accelerator_t { }; void -hb_paint_context_t::recurse (const Paint &paint) +hb_ot_paint_context_t::recurse (const Paint &paint) { depth_left--; if (depth_left > 0) From 9be01b6bff054e3edb516ca680a1e33b05a74e9b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 14:04:32 -0500 Subject: [PATCH 125/219] [paint] Pass hb_paint_context_t along Replace the font argument with a hb_paint_context_t that carries the font, the palette index and the foreground color. The hb_font_paint_glyph() api now takes the palette index and the foreground color as extra arguments. Update all callers and regenerate test results. --- src/OT/glyf/glyf.hh | 18 +++-- src/hb-font.cc | 24 +++++-- src/hb-font.h | 9 ++- src/hb-font.hh | 5 +- src/hb-ot-cff1-table.cc | 19 +++-- src/hb-ot-cff1-table.hh | 2 +- src/hb-ot-cff2-table.cc | 20 ++++-- src/hb-ot-cff2-table.hh | 2 +- src/hb-ot-color-cbdt-table.hh | 8 ++- src/hb-ot-color-colr-table.cc | 4 +- src/hb-ot-color-colr-table.hh | 119 ++++++++++++++++---------------- src/hb-ot-color-sbix-table.hh | 3 +- src/hb-ot-color-svg-table.hh | 4 +- src/hb-ot-font.cc | 10 +-- src/hb-paint.cc | 98 +++++++++++++------------- src/hb-paint.h | 95 +++++++++++++++---------- src/hb-paint.hh | 66 +++++++++--------- test/api/results/hand-20-0-10 | 18 ++--- test/api/results/hand-20-0.2-10 | 18 ++--- test/api/results/test-20-0-10 | 2 +- test/api/results/test-20-0-106 | 4 +- test/api/results/test-20-0-116 | 4 +- test/api/results/test-20-0-123 | 6 +- test/api/results/test-20-0-165 | 2 +- test/api/results/test-20-0-175 | 4 +- test/api/results/test-20-0-6 | 2 +- test/api/results/test-20-0-92 | 2 +- test/api/test-ot-color.c | 26 +++---- util/hb-cairo-utils.c | 51 ++++++-------- util/hb-cairo-utils.h | 17 +++-- util/helper-cairo-user.hh | 38 +++++----- 31 files changed, 384 insertions(+), 316 deletions(-) diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index fa9f90d86..084a73c2e 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -333,15 +333,21 @@ struct glyf_accelerator_t return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } - bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data) const + bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - funcs->push_root_transform (data, font); + hb_paint_context_t ctx; - funcs->push_clip_glyph (data, gid, font); - funcs->color (data, 0xffff, 1., font); - funcs->pop_clip (data, font); + ctx.font = font; + ctx.palette = 0; + ctx.foreground = foreground; - funcs->pop_root_transform (data, font); + funcs->push_root_transform (data, &ctx); + + funcs->push_clip_glyph (data, gid, &ctx); + funcs->color (data, 0xffff, 1., &ctx); + funcs->pop_clip (data, &ctx); + + funcs->pop_root_transform (data, &ctx); return false; } diff --git a/src/hb-font.cc b/src/hb-font.cc index cbf323a1c..cd32aa1b6 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -519,6 +519,8 @@ hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph HB_UNUSED, hb_paint_funcs_t *paint_funcs HB_UNUSED, void *paint_data HB_UNUSED, + unsigned int palette HB_UNUSED, + hb_color_t foreground HB_UNUSED, void *user_data HB_UNUSED) { } @@ -655,8 +657,16 @@ hb_font_paint_glyph_default (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, void *user_data) { + hb_paint_context_t ctx; + + ctx.font = font; + ctx.palette = palette; + ctx.foreground = foreground; + paint_funcs->push_transform (paint_data, font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, font->parent->y_scale ? (font->slant - font->parent->slant) * @@ -665,11 +675,11 @@ hb_font_paint_glyph_default (hb_font_t *font, font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, 0.f, 0.f, - font); + &ctx); - font->parent->paint_glyph (glyph, paint_funcs, paint_data); + font->parent->paint_glyph (glyph, paint_funcs, paint_data, palette, foreground); - paint_funcs->pop_transform (paint_data, font); + paint_funcs->pop_transform (paint_data, &ctx); } DEFINE_NULL_INSTANCE (hb_font_funcs_t) = @@ -1427,6 +1437,8 @@ hb_font_draw_glyph (hb_font_t *font, * @glyph: The glyph ID * @pfuncs: #hb_paint_funcs_t to paint with * @paint_data: User data to pass to paint callbacks + * @palette: The palette index to use + * @foreground: The foreground color * * Paints the glyph. * @@ -1442,9 +1454,11 @@ hb_font_draw_glyph (hb_font_t *font, void hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, - hb_paint_funcs_t *pfuncs, void *paint_data) + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette, + hb_color_t foreground) { - font->paint_glyph (glyph, pfuncs, paint_data); + font->paint_glyph (glyph, pfuncs, paint_data, palette, foreground); } /* A bit higher-level, and with fallback */ diff --git a/src/hb-font.h b/src/hb-font.h index 4574a5769..1978b57cd 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -529,6 +529,8 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, * @glyph: The glyph ID to query * @paint_funcs: The paint functions to use * @paint_data: The data accompanying the paint functions + * @palette: The color palette to use + * @foreground: The foreground color * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. @@ -538,6 +540,8 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, void *user_data); /* func setters */ @@ -941,8 +945,9 @@ hb_font_draw_glyph (hb_font_t *font, HB_EXTERN void hb_font_paint_glyph (hb_font_t *font, hb_codepoint_t glyph, - hb_paint_funcs_t *pfuncs, void *paint_data); - + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette, + hb_color_t foreground); /* high-level funcs, with fallback */ diff --git a/src/hb-font.hh b/src/hb-font.hh index 60fc53238..83f0d8701 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -403,11 +403,14 @@ struct hb_font_t } void paint_glyph (hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data) + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground) { klass->get.f.paint_glyph (this, user_data, glyph, paint_funcs, paint_data, + palette, foreground, !klass->user_data ? nullptr : klass->user_data->paint_glyph); } diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index c6cb48eb2..61e2cb177 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -553,17 +553,22 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin return true; } -bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const +bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - funcs->push_root_transform (data, font); + hb_paint_context_t ctx; - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, 0xffff, 1., font); - funcs->pop_clip (data, font); + ctx.font = font; + ctx.palette = 0; + ctx.foreground = foreground; + funcs->push_root_transform (data, &ctx); - funcs->pop_root_transform (data, font); + funcs->push_clip_glyph (data, glyph, &ctx); + funcs->color (data, 0xffff, 1., &ctx); + funcs->pop_clip (data, &ctx); - return false; + funcs->pop_root_transform (data, &ctx); + + return false; } bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index 3bc37d9bb..c68763fe4 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -1427,7 +1427,7 @@ struct cff1 } HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const; + HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 97e8100b6..991693811 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -143,17 +143,23 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, return true; } -bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const +bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - funcs->push_root_transform (data, font); + hb_paint_context_t ctx; - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, 0xffff, 1., font); - funcs->pop_clip (data, font); + ctx.font = font; + ctx.palette = 0; + ctx.foreground = foreground; - funcs->pop_root_transform (data, font); + funcs->push_root_transform (data, &ctx); - return false; + funcs->push_clip_glyph (data, glyph, &ctx); + funcs->color (data, 0xffff, 1., &ctx); + funcs->pop_clip (data, &ctx); + + funcs->pop_root_transform (data, &ctx); + + return false; } struct cff2_path_param_t diff --git a/src/hb-ot-cff2-table.hh b/src/hb-ot-cff2-table.hh index ddfe2d7c9..9a3d2d013 100644 --- a/src/hb-ot-cff2-table.hh +++ b/src/hb-ot-cff2-table.hh @@ -517,7 +517,7 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const; + HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; }; diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index f32406daa..3fe8fa943 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -939,15 +939,21 @@ struct CBDT bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + hb_paint_context_t ctx; hb_glyph_extents_t extents; hb_blob_t *blob = reference_png (font, glyph); + if (unlikely (blob == hb_blob_get_empty ())) return false; if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, font); + ctx.font = font; + ctx.palette = 0; + ctx.foreground = HB_COLOR (0, 0, 0, 255); + + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, &ctx); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 3f1e9f474..99b0d927c 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -8,9 +8,9 @@ void PaintColrLayers::paint_glyph (hb_ot_paint_context_t *c) const for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { const Paint &paint = paint_offset_lists.get_paint (i); - c->funcs->push_group (c->data, c->font); + c->funcs->push_group (c->data, &c->ctx); c->recurse (paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, c->font); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, &c->ctx); } } diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 5c5bf4902..29404eb77 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -75,7 +75,7 @@ public: const void *base; hb_paint_funcs_t *funcs; void *data; - hb_font_t *font; + hb_paint_context_t ctx; VarStoreInstancer &instancer; int depth_left = HB_COLRV1_MAX_NESTING_LEVEL; @@ -83,13 +83,16 @@ public: hb_paint_funcs_t *funcs_, void *data_, hb_font_t *font_, + unsigned int palette, + hb_color_t foreground, VarStoreInstancer &instancer_) : base (base_), funcs (funcs_), data (data_), - font (font_), instancer (instancer_) - {} + { ctx.font = font_; + ctx.palette = palette; + ctx.foreground = foreground; } inline void recurse (const Paint &paint); }; @@ -486,7 +489,7 @@ struct Affine2x3 yy.to_float (c->instancer (varIdxBase, 3)), dx.to_float (c->instancer (varIdxBase, 4)), dy.to_float (c->instancer (varIdxBase, 5)), - c->font); + &c->ctx); } F16DOT16 xx; @@ -554,7 +557,7 @@ struct PaintSolid c->funcs->color (c->data, paletteIndex, alpha.to_float (c->instancer (varIdxBase, 0)), - c->font); + &c->ctx); } HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ @@ -596,7 +599,7 @@ struct PaintLinearGradient y1 + c->instancer (varIdxBase, 3), x2 + c->instancer (varIdxBase, 4), y2 + c->instancer (varIdxBase, 5), - c->font); + &c->ctx); } HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ @@ -644,7 +647,7 @@ struct PaintRadialGradient x1 + c->instancer (varIdxBase, 3), y1 + c->instancer (varIdxBase, 4), radius1 + c->instancer (varIdxBase, 5), - c->font); + &c->ctx); } HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ @@ -690,7 +693,7 @@ struct PaintSweepGradient centerY + c->instancer (varIdxBase, 1), (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI, (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI, - c->font); + &c->ctx); } HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ @@ -730,11 +733,11 @@ struct PaintGlyph void paint_glyph (hb_ot_paint_context_t *c) const { - c->funcs->push_inverse_root_transform (c->data, c->font); - c->funcs->push_clip_glyph (c->data, gid, c->font); + c->funcs->push_inverse_root_transform (c->data, &c->ctx); + c->funcs->push_clip_glyph (c->data, gid, &c->ctx); c->recurse (this+paint); - c->funcs->pop_clip (c->data, c->font); - c->funcs->pop_inverse_root_transform (c->data, c->font); + c->funcs->pop_clip (c->data, &c->ctx); + c->funcs->pop_inverse_root_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 10 */ @@ -798,7 +801,7 @@ struct PaintTransform { (this+transform).paint_glyph (c); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ @@ -833,9 +836,9 @@ struct PaintTranslate 1., 0., 0., 1., dx + c->instancer (varIdxBase, 0), dy + c->instancer (varIdxBase, 0), - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ @@ -872,9 +875,9 @@ struct PaintScale 0., 0., scaleY.to_float (c->instancer (varIdxBase, 1)), 0., 0., - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ @@ -909,19 +912,19 @@ struct PaintScaleAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - c->font); + &c->ctx); c->funcs->push_transform (c->data, scaleX.to_float (c->instancer (varIdxBase, 0)), 0., 0., scaleY.to_float (c->instancer (varIdxBase, 1)), 0., 0., - c->font); + &c->ctx); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ @@ -957,9 +960,9 @@ struct PaintScaleUniform { float s = scale + c->instancer (varIdxBase, 0); c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0., - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ @@ -994,15 +997,15 @@ struct PaintScaleUniformAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - c->font); + &c->ctx); c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0., - c->font); + &c->ctx); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ @@ -1039,9 +1042,9 @@ struct PaintRotate float cc = cosf (a * (float) M_PI); float ss = sinf (a * (float) M_PI); c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0., - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ @@ -1078,15 +1081,15 @@ struct PaintRotateAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - c->font); + &c->ctx); c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0., - c->font); + &c->ctx); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ @@ -1122,9 +1125,9 @@ struct PaintSkew float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0., - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ @@ -1161,15 +1164,15 @@ struct PaintSkewAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - c->font); + &c->ctx); c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0., - c->font); + &c->ctx); c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - c->font); + &c->ctx); c->recurse (this+src); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); - c->funcs->pop_transform (c->data, c->font); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data, &c->ctx); } HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ @@ -1206,12 +1209,12 @@ struct PaintComposite void paint_glyph (hb_ot_paint_context_t *c) const { - c->funcs->push_group (c->data, c->font); + c->funcs->push_group (c->data, &c->ctx); c->recurse (this+backdrop); - c->funcs->push_group (c->data, c->font); + c->funcs->push_group (c->data, &c->ctx); c->recurse (this+src); - c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode, c->font); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, c->font); + c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode, &c->ctx); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, &c->ctx); } HBUINT8 format; /* format = 32 */ @@ -1960,23 +1963,23 @@ struct COLR } bool - paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const + paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette, hb_color_t foreground) const { VarStoreInstancer instancer (this+varStore, this+varIdxMap, hb_array (font->coords, font->num_coords)); - hb_ot_paint_context_t c (this, funcs, data, font, instancer); + hb_ot_paint_context_t c (this, funcs, data, font, palette, foreground, instancer); const Paint *paint = get_base_glyph_paint (glyph); if (paint) { // COLRv1 glyph - c.funcs->push_root_transform (c.data, c.font); + c.funcs->push_root_transform (c.data, &c.ctx); c.recurse (*paint); - c.funcs->pop_root_transform (c.data, c.font); + c.funcs->pop_root_transform (c.data, &c.ctx); return true; } @@ -1988,9 +1991,9 @@ struct COLR for (const auto &r : (this+layersZ).as_array (numLayers) .sub_array (record->firstLayerIdx, record->numLayers)) { - c.funcs->push_clip_glyph (c.data, r.glyphId, c.font); - c.funcs->color (c.data, r.colorIdx, 1., c.font); - c.funcs->pop_clip (c.data, c.font); + c.funcs->push_clip_glyph (c.data, r.glyphId, &c.ctx); + c.funcs->color (c.data, r.colorIdx, 1., &c.ctx); + c.funcs->pop_clip (c.data, &c.ctx); } return true; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 0a93c488e..d1737501b 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -234,6 +234,7 @@ struct sbix bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + hb_paint_context_t ctx = { font, 0, HB_COLOR (0, 0, 0, 255) }; if (!has_data ()) return false; @@ -248,7 +249,7 @@ struct sbix if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, font); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, &ctx); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index d5a55133d..dae4419bd 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -95,6 +95,8 @@ struct SVG bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + hb_paint_context_t ctx = { font, 0, HB_COLOR (0, 0, 0, 255) }; + if (!has_data ()) return false; @@ -103,7 +105,7 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr, font); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr, &ctx); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 86b1fb665..270710993 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -446,20 +446,22 @@ hb_ot_paint_glyph (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, void *user_data) { #ifndef HB_NO_COLOR - if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return; if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return; #ifndef HB_NO_OT_FONT_BITMAP if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return; if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; #endif #endif - if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; #ifndef HB_NO_CFF - if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data)) return; - if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; + if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; #endif } #endif diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 5fa39a451..b7d09ab44 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -47,36 +47,36 @@ hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, float dx, float dy, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_push_clip_rectangle_nil (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void @@ -84,7 +84,7 @@ hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void @@ -93,7 +93,7 @@ hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float x1, float y1, float x2, float y2, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void @@ -101,7 +101,7 @@ hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void @@ -110,18 +110,18 @@ hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float start_angle, float end_angle, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) {} static bool @@ -394,7 +394,7 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix - * @font: the font + * @ctx: the paint context * * Perform a "push-transform" paint operation. * @@ -405,16 +405,16 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, float dx, float dy, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy, font); + funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy, ctx); } /** * hb_paint_pop_transform: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @font: the font + * @ctx: the paint context * * Perform a "pop-transform" paint operation. * @@ -422,9 +422,9 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->pop_transform (paint_data, font); + funcs->pop_transform (paint_data, ctx); } /** @@ -432,7 +432,7 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, * @funcs: paint functions * @paint_data: associated data passed by the caller * @glyph: the glyph ID - * @font: the font + * @ctx: the paint context * * Perform a "push-clip-glyph" paint operation. * @@ -441,9 +441,9 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->push_clip_glyph (paint_data, glyph, font); + funcs->push_clip_glyph (paint_data, glyph, ctx); } /** @@ -454,7 +454,7 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle - * @font: the font + * @ctx: the paint context * * Perform a "push-clip-rect" paint operation. * @@ -463,16 +463,16 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax, font); + funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax, ctx); } /** * hb_paint_pop_clip: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @font: the font + * @ctx: the paint context * * Perform a "pop-clip" paint operation. * @@ -480,18 +480,18 @@ hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->pop_clip (paint_data, font); + funcs->pop_clip (paint_data, ctx); } /** * hb_paint_color: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @color_index: Index of a color in the fonts selected color palette + * @color_index: Index of a color in the color palette * @alpha: Alpha to apply in addition - * @font: the font + * @ctx: the paint context * * Perform a "color" paint operation. * @@ -501,9 +501,9 @@ void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->color (paint_data, color_index, alpha, font); + funcs->color (paint_data, color_index, alpha, ctx); } /** @@ -513,7 +513,7 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, * @image: image data * @format: tag describing the image data format * @extents: (nullable): the extents of the glyph - * @font: the font + * @ctx: the paint context * * Perform a "image" paint operation. * @@ -524,9 +524,9 @@ hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->image (paint_data, image, format, extents, font); + funcs->image (paint_data, image, format, extents, ctx); } /** @@ -540,7 +540,7 @@ hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point - * @font: the font + * @ctx: the paint context * * Perform a "linear-gradient" paint operation. * @@ -552,9 +552,9 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float x1, float y1, float x2, float y2, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2, font); + funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2, ctx); } /** @@ -568,7 +568,7 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle - * @font: the font + * @ctx: the paint context * * Perform a "radial-gradient" paint operation. * @@ -579,9 +579,9 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1, font); + funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1, ctx); } /** @@ -593,7 +593,7 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, * @y0: Y coordinate of the circle's center * @start_angle: the start angle * @end_angle: the end angle - * @font: the font + * @ctx: the paint context * * Perform a "sweep-gradient" paint operation. * @@ -604,16 +604,16 @@ hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle, font); + funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle, ctx); } /** * hb_paint_push_group: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @font: the font + * @ctx: the paint context * * Perform a "push-group" paint operation. * @@ -621,9 +621,9 @@ hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->push_group (paint_data, font); + funcs->push_group (paint_data, ctx); } /** @@ -631,7 +631,7 @@ hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, * @funcs: paint functions * @paint_data: associated data passed by the caller * @mode: the compositing mode to use - * @font: the font + * @ctx: the paint context * * Perform a "pop-group" paint operation. * @@ -640,9 +640,9 @@ hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - hb_font_t *font) + const hb_paint_context_t *ctx) { - funcs->pop_group (paint_data, mode, font); + funcs->pop_group (paint_data, mode, ctx); } #endif diff --git a/src/hb-paint.h b/src/hb-paint.h index 8db53b324..ccbc33bbb 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -91,6 +91,29 @@ hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs); HB_EXTERN hb_bool_t hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); +/** + * hb_paint_context_t: + * @font: the font that is painted with + * @palette: the palette index + * @foreground: the foreground color + * + * Context information that is passed to paint functions. + */ +typedef struct hb_paint_context_t { + hb_font_t *font; + unsigned int palette; + hb_color_t foreground; + + /*< private >*/ + hb_var_num_t reserved1; + hb_var_num_t reserved2; + hb_var_num_t reserved3; + hb_var_num_t reserved4; + hb_var_num_t reserved5; + hb_var_num_t reserved6; + hb_var_num_t reserved7; +} hb_paint_context_t; + /** * hb_paint_push_transform_func_t: * @funcs: paint functions object @@ -101,7 +124,7 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_push_transform_func() * * A virtual method for the #hb_paint_funcs_t to apply @@ -118,14 +141,14 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** * hb_paint_pop_transform_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_pop_transform_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -136,7 +159,7 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, */ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -144,7 +167,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @glyph: the glyph ID - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_glyph_func() * * A virtual method for the #hb_paint_funcs_t to clip @@ -162,7 +185,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -173,7 +196,7 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_rectangle_func() * * A virtual method for the #hb_paint_funcs_t to clip @@ -192,14 +215,14 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** * hb_paint_pop_clip_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_pop_clip_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -210,7 +233,7 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, */ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -219,7 +242,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @color_index: Index of a color in the fonts selected color palette * @alpha: alpha to apply in addition - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_color_func() * * A virtual method for the #hb_paint_funcs_t to paint a @@ -238,7 +261,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -262,7 +285,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @image: the image data * @format: the image format as a tag * @extents: (nullable): glyph extents - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * * A virtual method for the #hb_paint_funcs_t to paint the @@ -283,7 +306,7 @@ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -357,7 +380,7 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_linear_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a linear @@ -378,7 +401,7 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -392,7 +415,7 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_radial_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a radial @@ -412,7 +435,7 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -424,7 +447,7 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * @y0: Y coordinate of the circle's center * @start_angle: the start angle, in radians * @end_angle: the end angle, in radians - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_sweep_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a sweep @@ -445,7 +468,7 @@ typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, float x0, float y0, float start_angle, float end_angle, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -493,7 +516,7 @@ typedef enum { * hb_paint_push_group_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_push_group_func() * * A virtual method for the #hb_paint_funcs_t to use @@ -507,7 +530,7 @@ typedef enum { */ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -515,7 +538,7 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @mode: the compositing mode to use - * @font: the font that is being painted + * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -531,7 +554,7 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data); /** @@ -743,39 +766,39 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, float dx, float dy, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, @@ -783,7 +806,7 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float x1, float y1, float x2, float y2, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, @@ -792,23 +815,23 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, float r0, float x1, float y1, float r1, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_EXTERN void hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - hb_font_t *font); + const hb_paint_context_t *ctx); HB_END_DECLS diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 7e301c00f..4412d81d3 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -70,126 +70,128 @@ struct hb_paint_funcs_t float xx, float yx, float xy, float yy, float dx, float dy, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.push_transform (this, paint_data, xx, yx, xy, yy, dx, dy, - font, + ctx, !user_data ? nullptr : user_data->push_transform); } void pop_transform (void *paint_data, - hb_font_t *font) - { func.pop_transform (this, paint_data, font, + const hb_paint_context_t *ctx) + { func.pop_transform (this, paint_data, ctx, !user_data ? nullptr : user_data->pop_transform); } void push_clip_glyph (void *paint_data, hb_codepoint_t glyph, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.push_clip_glyph (this, paint_data, glyph, - font, + ctx, !user_data ? nullptr : user_data->push_clip_glyph); } void push_clip_rectangle (void *paint_data, float xmin, float ymin, float xmax, float ymax, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.push_clip_rectangle (this, paint_data, xmin, ymin, xmax, ymax, - font, + ctx, !user_data ? nullptr : user_data->push_clip_rectangle); } void pop_clip (void *paint_data, - hb_font_t *font) - { func.pop_clip (this, paint_data, font, + const hb_paint_context_t *ctx) + { func.pop_clip (this, paint_data, ctx, !user_data ? nullptr : user_data->pop_clip); } void color (void *paint_data, unsigned int color_index, float alpha, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.color (this, paint_data, color_index, alpha, - font, + ctx, !user_data ? nullptr : user_data->color); } void image (void *paint_data, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.image (this, paint_data, image, format, extents, - font, + ctx, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, float x2, float y2, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.linear_gradient (this, paint_data, color_line, x0, y0, x1, y1, x2, y2, - font, + ctx, !user_data ? nullptr : user_data->linear_gradient); } void radial_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.radial_gradient (this, paint_data, color_line, x0, y0, r0, x1, y1, r1, - font, + ctx, !user_data ? nullptr : user_data->radial_gradient); } void sweep_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.sweep_gradient (this, paint_data, color_line, x0, y0, start_angle, end_angle, - font, + ctx, !user_data ? nullptr : user_data->sweep_gradient); } void push_group (void *paint_data, - hb_font_t *font) - { func.push_group (this, paint_data, font, + const hb_paint_context_t *ctx) + { func.push_group (this, paint_data, ctx, !user_data ? nullptr : user_data->push_group); } void pop_group (void *paint_data, hb_paint_composite_mode_t mode, - hb_font_t *font) + const hb_paint_context_t *ctx) { func.pop_group (this, paint_data, mode, - font, + ctx, !user_data ? nullptr : user_data->pop_group); } void push_root_transform (void *paint_data, - hb_font_t *font) + const hb_paint_context_t *ctx) { + hb_font_t *font = ctx->font; int xscale = font->x_scale, yscale = font->y_scale; float upem = font->face->get_upem (); float slant = font->slant_xy; func.push_transform (this, paint_data, xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0, - font, + ctx, !user_data ? nullptr : user_data->push_transform); } void pop_root_transform (void *paint_data, - hb_font_t *font) + const hb_paint_context_t *ctx) { - func.pop_transform (this, paint_data, font, + func.pop_transform (this, paint_data, ctx, !user_data ? nullptr : user_data->pop_transform); } void push_inverse_root_transform (void *paint_data, - hb_font_t *font) + const hb_paint_context_t *ctx) { + hb_font_t *font = ctx->font; int xscale = font->x_scale, yscale = font->y_scale; float upem = font->face->get_upem (); float slant = font->slant_xy; func.push_transform (this, paint_data, upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0, - font, + ctx, !user_data ? nullptr : user_data->push_transform); } void pop_inverse_root_transform (void *paint_data, - hb_font_t *font) + const hb_paint_context_t *ctx) { - func.pop_transform (this, paint_data, font, + func.pop_transform (this, paint_data, ctx, !user_data ? nullptr : user_data->pop_transform); } }; diff --git a/test/api/results/hand-20-0-10 b/test/api/results/hand-20-0-10 index 42160b529..dc022ef00 100644 --- a/test/api/results/hand-20-0-10 +++ b/test/api/results/hand-20-0-10 @@ -1,6 +1,6 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 13 start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 radial gradient @@ -16,7 +16,7 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 14 linear gradient p0 231.000000 -27.000000 @@ -29,21 +29,21 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 15 solid 9 1.000000 end clip end transform pop group mode 3 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 16 solid 0 1.000000 end clip end transform pop group mode 3 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 21 solid 9 1.000000 end clip @@ -51,7 +51,7 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 pop group mode 3 push group push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 16 linear gradient p0 669.000000 776.000000 @@ -64,7 +64,7 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 18 solid 2 0.200012 end clip @@ -72,7 +72,7 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 pop group mode 3 pop group mode 3 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 19 start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 radial gradient @@ -88,7 +88,7 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 0.000000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 20 solid 9 1.000000 end clip diff --git a/test/api/results/hand-20-0.2-10 b/test/api/results/hand-20-0.2-10 index 569bd24db..536cd0c1b 100644 --- a/test/api/results/hand-20-0.2-10 +++ b/test/api/results/hand-20-0.2-10 @@ -1,6 +1,6 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 13 start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 radial gradient @@ -16,7 +16,7 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 14 linear gradient p0 231.000000 -27.000000 @@ -29,21 +29,21 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 15 solid 9 1.000000 end clip end transform pop group mode 3 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 16 solid 0 1.000000 end clip end transform pop group mode 3 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 21 solid 9 1.000000 end clip @@ -51,7 +51,7 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 pop group mode 3 push group push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 16 linear gradient p0 669.000000 776.000000 @@ -64,7 +64,7 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 18 solid 2 0.200012 end clip @@ -72,7 +72,7 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 pop group mode 3 pop group mode 3 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 19 start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 radial gradient @@ -88,7 +88,7 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 end transform pop group mode 3 push group - start transform 51.200001 0.000000 10.240000 51.200001 0.000000 0.000000 + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 20 solid 9 1.000000 end clip diff --git a/test/api/results/test-20-0-10 b/test/api/results/test-20-0-10 index e3238328a..1c34a136f 100644 --- a/test/api/results/test-20-0-10 +++ b/test/api/results/test-20-0-10 @@ -1,5 +1,5 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 174 sweep gradient center 500.000000 600.000000 diff --git a/test/api/results/test-20-0-106 b/test/api/results/test-20-0-106 index e16d01c71..323940afe 100644 --- a/test/api/results/test-20-0-106 +++ b/test/api/results/test-20-0-106 @@ -1,6 +1,6 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 solid 4 0.500000 end clip @@ -9,7 +9,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 1000.000000 1000.000000 start transform 1.000000 -0.363874 -0.176283 1.000000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 solid 1 0.700012 end clip diff --git a/test/api/results/test-20-0-116 b/test/api/results/test-20-0-116 index 751b8e8a8..6c7ffd355 100644 --- a/test/api/results/test-20-0-116 +++ b/test/api/results/test-20-0-116 @@ -1,13 +1,13 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 solid 4 0.500000 end clip end transform push group start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 solid 1 0.700012 end clip diff --git a/test/api/results/test-20-0-123 b/test/api/results/test-20-0-123 index b97987fc7..296c3eebb 100644 --- a/test/api/results/test-20-0-123 +++ b/test/api/results/test-20-0-123 @@ -1,6 +1,6 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 solid 10 1.000000 end clip @@ -11,7 +11,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 333.000000 667.000000 start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 solid 12 1.000000 end clip @@ -23,7 +23,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 667.000000 333.000000 start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 solid 11 1.000000 end clip diff --git a/test/api/results/test-20-0-165 b/test/api/results/test-20-0-165 index 2fade5352..cea5dd9ce 100644 --- a/test/api/results/test-20-0-165 +++ b/test/api/results/test-20-0-165 @@ -1,5 +1,5 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 165 linear gradient p0 100.000000 950.000000 diff --git a/test/api/results/test-20-0-175 b/test/api/results/test-20-0-175 index 1b13c45f3..83dac5ee3 100644 --- a/test/api/results/test-20-0-175 +++ b/test/api/results/test-20-0-175 @@ -1,7 +1,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 174 solid 3 1.000000 end clip @@ -10,7 +10,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 pop group mode 3 push group start transform 1.000000 0.000000 0.000000 1.000000 -150.000000 0.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 174 linear gradient p0 500.000000 250.000000 diff --git a/test/api/results/test-20-0-6 b/test/api/results/test-20-0-6 index 4bd5c8f0a..c165e62d4 100644 --- a/test/api/results/test-20-0-6 +++ b/test/api/results/test-20-0-6 @@ -1,5 +1,5 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 6 linear gradient p0 100.000000 250.000000 diff --git a/test/api/results/test-20-0-92 b/test/api/results/test-20-0-92 index 40bd05742..51d5b2fa2 100644 --- a/test/api/results/test-20-0-92 +++ b/test/api/results/test-20-0-92 @@ -1,5 +1,5 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 0.000000 50.000000 0.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 radial gradient p0 166.000000 768.000000 radius 0.000000 diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index de5d81b26..a63ecc9da 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -484,7 +484,7 @@ push_transform (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -496,7 +496,7 @@ push_transform (hb_paint_funcs_t *funcs, static void pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -509,7 +509,7 @@ static void push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -522,7 +522,7 @@ static void push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -534,7 +534,7 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, static void pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -548,7 +548,7 @@ paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -562,7 +562,7 @@ paint_image (hb_paint_funcs_t *funcs, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -598,7 +598,7 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -619,7 +619,7 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -640,7 +640,7 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, float cx, float cy, float start_angle, float end_angle, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -657,7 +657,7 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, static void push_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -669,7 +669,7 @@ static void pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -736,7 +736,7 @@ test_hb_ot_color_colr_v1 (gconstpointer d) data.string = g_string_new (""); data.level = 0; - hb_font_paint_glyph (font, test->glyph, funcs, &data); + hb_font_paint_glyph (font, test->glyph, funcs, &data, 0, HB_COLOR (0, 0, 0, 255)); /* Run * diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 95b2feca5..f3eb69435 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -70,35 +70,26 @@ cairo_extend (hb_paint_extend_t extend) return CAIRO_EXTEND_PAD; } -hb_bool_t -hb_cairo_get_font_color (hb_font_t *font, - unsigned int palette_index, +void +hb_cairo_get_font_color (const hb_paint_context_t *ctx, unsigned int color_index, float alpha, float *r, float *g, float *b, float *a) { + hb_color_t color = ctx->foreground; + if (color_index != 0xffff) { - hb_color_t color; unsigned int clen = 1; - hb_face_t *face = hb_font_get_face (font); + hb_face_t *face = hb_font_get_face (ctx->font); - if (hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color)) - { - *r = hb_color_get_red (color) / 255.f; - *g = hb_color_get_green (color) / 255.f; - *b = hb_color_get_blue (color) / 255.f; - *a = (hb_color_get_alpha (color) / 255.f) * alpha; - - return TRUE; - } + hb_ot_color_palette_get_colors (face, ctx->palette, color_index, &clen, &color); } - /* foreground color */ - *r = *g = *b = 0; - *a = alpha; - - return FALSE; + *r = hb_color_get_red (color) / 255.f; + *g = hb_color_get_green (color) / 255.f; + *b = hb_color_get_blue (color) / 255.f; + *a = (hb_color_get_alpha (color) / 255.f) * alpha; } typedef struct @@ -129,7 +120,7 @@ read_blob (void *closure, void hb_cairo_paint_glyph_image (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents) @@ -237,7 +228,7 @@ normalize_color_line (hb_color_stop_t *stops, void hb_cairo_paint_linear_gradient (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, @@ -269,7 +260,7 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, for (unsigned int i = 0; i < len; i++) { float r, g, b, a; - hb_cairo_get_font_color (font, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + hb_cairo_get_font_color (ctx, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); } @@ -284,7 +275,7 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, void hb_cairo_paint_radial_gradient (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1) @@ -317,7 +308,7 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, for (unsigned int i = 0; i < len; i++) { float r, g, b, a; - hb_cairo_get_font_color (font, 0, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + hb_cairo_get_font_color (ctx, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); } @@ -472,7 +463,7 @@ add_sweep_gradient_patches1 (float cx, float cy, float radius, } static void -add_sweep_gradient_patches (hb_font_t *font, +add_sweep_gradient_patches (const hb_paint_context_t *ctx, hb_color_stop_t *stops, unsigned int n_stops, cairo_extend_t extend, @@ -495,7 +486,7 @@ add_sweep_gradient_patches (hb_font_t *font, color_t c; if (start_angle > 0) { - hb_cairo_get_font_color (font, 0, stops[0].color_index, stops[0].alpha, &c.r, &c.g, &c.b, &c.a); + hb_cairo_get_font_color (ctx, stops[0].color_index, stops[0].alpha, &c.r, &c.g, &c.b, &c.a); add_sweep_gradient_patches1 (cx, cy, radius, 0., &c, start_angle, &c, @@ -503,7 +494,7 @@ add_sweep_gradient_patches (hb_font_t *font, } if (end_angle < 2 * M_PI) { - hb_cairo_get_font_color (font, 0, stops[n_stops-1].color_index, stops[n_stops-1].alpha, &c.r, &c.g, &c.b, &c.a); + hb_cairo_get_font_color (ctx, stops[n_stops-1].color_index, stops[n_stops-1].alpha, &c.r, &c.g, &c.b, &c.a); add_sweep_gradient_patches1 (cx, cy, radius, end_angle, &c, 2 * M_PI, &c, @@ -539,7 +530,7 @@ add_sweep_gradient_patches (hb_font_t *font, for (unsigned i = 0; i < n_stops; i++) { angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); - hb_cairo_get_font_color (font, 0, stops[i].color_index, stops[i].alpha, &colors[i].r, &colors[i].g, &colors[i].b, &colors[i].a); + hb_cairo_get_font_color (ctx, stops[i].color_index, stops[i].alpha, &colors[i].r, &colors[i].g, &colors[i].b, &colors[i].a); } if (extend == CAIRO_EXTEND_PAD) @@ -717,7 +708,7 @@ done: void hb_cairo_paint_sweep_gradient (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_color_line_t *color_line, float cx, float cy, float start_angle, @@ -746,7 +737,7 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr, extend = cairo_extend (hb_color_line_get_extend (color_line)); pattern = cairo_pattern_create_mesh (); - add_sweep_gradient_patches (font, stops, len, extend, cx, cy, + add_sweep_gradient_patches (ctx, stops, len, extend, cx, cy, radius, start_angle, end_angle, pattern); cairo_set_source (cr, pattern); diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index 359616658..e372336c1 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -70,33 +70,32 @@ hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) return CAIRO_OPERATOR_SOURCE; } -hb_bool_t hb_cairo_get_font_color (hb_font_t *font, - unsigned int palette_index, - unsigned int color_index, - float alpha, - float *r, float *g, float *b, float *a); +void hb_cairo_get_font_color (const hb_paint_context_t *ctx, + unsigned int color_index, + float alpha, + float *r, float *g, float *b, float *a); void hb_cairo_paint_glyph_image (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents); void hb_cairo_paint_linear_gradient (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, float x2, float y2); void hb_cairo_paint_radial_gradient (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1); void hb_cairo_paint_sweep_gradient (cairo_t *cr, - hb_font_t *font, + const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle); diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index ce5ebda46..b4ca8f9e2 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -111,7 +111,7 @@ push_transform (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -127,7 +127,7 @@ push_transform (hb_paint_funcs_t *funcs, static void pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -139,14 +139,14 @@ static void push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; cairo_save (cr); cairo_new_path (cr); - hb_font_draw_glyph (font, glyph, get_cairo_draw_funcs (), cr); + hb_font_draw_glyph (ctx->font, glyph, get_cairo_draw_funcs (), cr); cairo_close_path (cr); cairo_clip (cr); } @@ -155,7 +155,7 @@ static void push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -170,7 +170,7 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, static void pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -181,7 +181,7 @@ pop_clip (hb_paint_funcs_t *funcs, static void push_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -194,7 +194,7 @@ static void pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -211,13 +211,13 @@ paint_color (hb_paint_funcs_t *funcs, void *paint_data, unsigned int color_index, float alpha, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; float r, g, b, a; - hb_cairo_get_font_color (font, 0, color_index, alpha, &r, &g, &b, &a); + hb_cairo_get_font_color (ctx, color_index, alpha, &r, &g, &b, &a); cairo_set_source_rgba (cr, (double)r, (double)g, (double)b, (double)a); cairo_paint (cr); } @@ -228,12 +228,12 @@ paint_image (hb_paint_funcs_t *funcs, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_glyph_image (cr, font, blob, format, extents); + hb_cairo_paint_glyph_image (cr, ctx, blob, format, extents); } static void @@ -243,12 +243,12 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_linear_gradient (cr, font, color_line, x0, y0, x1, y1, x2, y2); + hb_cairo_paint_linear_gradient (cr, ctx, color_line, x0, y0, x1, y1, x2, y2); } static void @@ -257,12 +257,12 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_radial_gradient (cr, font, color_line, x0, y0, r0, x1, y1, r1); + hb_cairo_paint_radial_gradient (cr, ctx, color_line, x0, y0, r0, x1, y1, r1); } static void @@ -271,12 +271,12 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle, - hb_font_t *font, + const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_sweep_gradient (cr, font, color_line, x0, y0, start_angle, end_angle); + hb_cairo_paint_sweep_gradient (cr, ctx, color_line, x0, y0, start_angle, end_angle); } static hb_paint_funcs_t * @@ -355,7 +355,7 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, hb_font_get_scale (font, &x_scale, &y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale); - hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr); + hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, 0, HB_COLOR (0, 0, 0, 255)); hb_glyph_extents_t hb_extents; hb_font_get_glyph_extents (font, glyph, &hb_extents); From d094e76cbc84dc13de35e2837ffe6d1a8aa51fab Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 15:02:41 -0500 Subject: [PATCH 126/219] hb-view: Pass fg color to hb_font_paint_glyph --- util/helper-cairo-user.hh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index b4ca8f9e2..f115d7be1 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -350,12 +350,21 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, { hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &_hb_font_cairo_user_data_key)); + hb_color_t color = HB_COLOR (0, 0, 0, 255); + cairo_pattern_t *pattern = cairo_get_source (cr); + + if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID) + { + double r, g, b, a; + cairo_pattern_get_rgba (pattern, &r, &g, &b, &a); + color = HB_COLOR ((int)(b * 255.), (int)(g * 255.), (int) (r * 255.), (int)(a * 255.)); + } hb_position_t x_scale, y_scale; hb_font_get_scale (font, &x_scale, &y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale); - hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, 0, HB_COLOR (0, 0, 0, 255)); + hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, 0, color); hb_glyph_extents_t hb_extents; hb_font_get_glyph_extents (font, glyph, &hb_extents); From 5d7553d38f178c1c071f356f98bbf43d21b4ce29 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 15:18:02 -0500 Subject: [PATCH 127/219] view: Add a --font-palette option --- util/font-options.hh | 2 ++ util/helper-cairo-user.hh | 10 +++++++++- util/helper-cairo.hh | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/util/font-options.hh b/util/font-options.hh index 331efd7da..6dd8e3b12 100644 --- a/util/font-options.hh +++ b/util/font-options.hh @@ -69,6 +69,7 @@ struct font_options_t : face_options_t mutable double font_size_y = DEFAULT_FONT_SIZE; char *font_funcs = nullptr; int ft_load_flags = 2; + unsigned int palette = 0; hb_font_t *font = nullptr; }; @@ -287,6 +288,7 @@ font_options_t::add_options (option_parser_t *parser) G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"}, {"font-slant", 0, 0, G_OPTION_ARG_DOUBLE, &this->slant, "Set synthetic slant (default: 0)", "slant ratio; eg. 0.2"}, + {"font-palette", 0, 0, G_OPTION_ARG_INT, &this->palette, "Set font palette (default: 0)", "index"}, {"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"}, {"sub-font", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &this->sub_font, "Create a sub-font (default: false)", "boolean"}, diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index f115d7be1..00ca3cc90 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -350,6 +350,14 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, { hb_font_t *font = (hb_font_t *) (cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), &_hb_font_cairo_user_data_key)); + unsigned int palette = 0; +#ifdef CAIRO_COLOR_PALETTE_DEFAULT + cairo_font_options_t *options = cairo_font_options_create (); + cairo_scaled_font_get_font_options (scaled_font, options); + palette = cairo_font_options_get_color_palette (options); + cairo_font_options_destroy (options); +#endif + hb_color_t color = HB_COLOR (0, 0, 0, 255); cairo_pattern_t *pattern = cairo_get_source (cr); @@ -364,7 +372,7 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, hb_font_get_scale (font, &x_scale, &y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale); - hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, 0, color); + hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, palette, color); hb_glyph_extents_t hb_extents; hb_font_get_glyph_extents (font, glyph, &hb_extents); diff --git a/util/helper-cairo.hh b/util/helper-cairo.hh index a8463de4d..a877ed394 100644 --- a/util/helper-cairo.hh +++ b/util/helper-cairo.hh @@ -118,6 +118,9 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts) font_options = cairo_font_options_create (); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); +#ifdef CAIRO_COLOR_PALETTE_DEFAULT + cairo_font_options_set_color_palette (font_options, font_opts->palette); +#endif cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (cairo_face, &font_matrix, From bd1389bedf891311177b3aa9804aa4474c6758d0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 15:23:43 -0500 Subject: [PATCH 128/219] [paint] Add hb_paint_context_t to docs --- docs/harfbuzz-sections.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index f758721d5..ebea175ac 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -230,6 +230,7 @@ hb_paint_funcs_get_user_data hb_paint_funcs_make_immutable hb_paint_funcs_is_immutable +hb_paint_context_t hb_paint_push_transform_func_t hb_paint_funcs_set_push_transform_func hb_paint_pop_transform_func_t From 71bd5a0dfc34efdf61a641b8ba98303524adeb9a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 16:18:46 -0500 Subject: [PATCH 129/219] [paint] Resolve colors We don't need to pass the index/alpha pairs to client callbacks, and can just resolve the colors internally. Update test results. --- src/OT/glyf/glyf.hh | 2 +- src/hb-ot-cff1-table.cc | 3 ++- src/hb-ot-cff2-table.cc | 2 +- src/hb-ot-color-colr-table.cc | 4 ++-- src/hb-ot-color-colr-table.hh | 31 +++++++++++++++++------------- src/hb-paint.cc | 11 ++++------- src/hb-paint.h | 33 +++++++------------------------- src/hb-paint.hh | 27 +++++++++++++++++++++++--- test/api/results/hand-20-0-10 | 34 ++++++++++++++++----------------- test/api/results/hand-20-0.2-10 | 34 ++++++++++++++++----------------- test/api/results/test-20-0-10 | 8 ++++---- test/api/results/test-20-0-106 | 4 ++-- test/api/results/test-20-0-116 | 4 ++-- test/api/results/test-20-0-123 | 6 +++--- test/api/results/test-20-0-165 | 6 +++--- test/api/results/test-20-0-175 | 6 +++--- test/api/results/test-20-0-6 | 4 ++-- test/api/results/test-20-0-92 | 6 +++--- test/api/test-ot-color.c | 18 ++++++++++++----- util/hb-cairo-utils.c | 29 +++++++++++++++++++++------- util/helper-cairo-user.hh | 11 ++++++----- 21 files changed, 156 insertions(+), 127 deletions(-) diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index 084a73c2e..74e47359a 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -344,7 +344,7 @@ struct glyf_accelerator_t funcs->push_root_transform (data, &ctx); funcs->push_clip_glyph (data, gid, &ctx); - funcs->color (data, 0xffff, 1., &ctx); + funcs->color (data, hb_paint_get_color (&ctx, 0xffff, 1.), &ctx); funcs->pop_clip (data, &ctx); funcs->pop_root_transform (data, &ctx); diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 61e2cb177..fa93c3da6 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -560,10 +560,11 @@ bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph ctx.font = font; ctx.palette = 0; ctx.foreground = foreground; + funcs->push_root_transform (data, &ctx); funcs->push_clip_glyph (data, glyph, &ctx); - funcs->color (data, 0xffff, 1., &ctx); + funcs->color (data, hb_paint_get_color (&ctx, 0xffff, 1.), &ctx); funcs->pop_clip (data, &ctx); funcs->pop_root_transform (data, &ctx); diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 991693811..af5e3027d 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -154,7 +154,7 @@ bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph funcs->push_root_transform (data, &ctx); funcs->push_clip_glyph (data, glyph, &ctx); - funcs->color (data, 0xffff, 1., &ctx); + funcs->color (data, hb_paint_get_color (&ctx, 0xffff, 1.), &ctx); funcs->pop_clip (data, &ctx); funcs->pop_root_transform (data, &ctx); diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 99b0d927c..05de5b22d 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -51,9 +51,9 @@ hb_color_line_get_color_stops (hb_color_line_t *color_line, hb_color_stop_t *color_stops) { if (color_line->is_variable) - return reinterpret_cast *>(color_line->base)->get_color_stops (start, count, color_stops, color_line->c->instancer); + return reinterpret_cast *>(color_line->base)->get_color_stops (&color_line->c->ctx, start, count, color_stops, color_line->c->instancer); else - return reinterpret_cast *>(color_line->base)->get_color_stops (start, count, color_stops, color_line->c->instancer); + return reinterpret_cast *>(color_line->base)->get_color_stops (&color_line->c->ctx, start, count, color_stops, color_line->c->instancer); } /** diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 29404eb77..f84e57654 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -241,10 +241,11 @@ struct Variable value.paint_glyph (c, varIdxBase); } - void get_color_stop (hb_color_stop_t *c, + void get_color_stop (hb_paint_context_t *ctx, + hb_color_stop_t *c, const VarStoreInstancer &instancer) const { - value.get_color_stop (c, varIdxBase, instancer); + value.get_color_stop (ctx, c, varIdxBase, instancer); } hb_paint_extend_t get_extend () const @@ -293,10 +294,11 @@ struct NoVariable value.paint_glyph (c, varIdxBase); } - void get_color_stop (hb_color_stop_t *c, + void get_color_stop (hb_paint_context_t *ctx, + hb_color_stop_t *c, const VarStoreInstancer &instancer) const { - value.get_color_stop (c, VarIdx::NO_VARIATION, instancer); + value.get_color_stop (ctx, c, VarIdx::NO_VARIATION, instancer); } hb_paint_extend_t get_extend () const @@ -331,13 +333,15 @@ struct ColorStop return_trace (c->check_struct (this)); } - void get_color_stop (hb_color_stop_t *out, + void get_color_stop (hb_paint_context_t *ctx, + hb_color_stop_t *out, uint32_t varIdx, const VarStoreInstancer &instancer) const { out->offset = stopOffset.to_float(instancer (varIdx, 0)); - out->color_index = paletteIndex; - out->alpha = alpha.to_float(instancer (varIdx, 1)); + out->color = hb_paint_get_color (ctx, + paletteIndex, + alpha.to_float (instancer (varIdx, 1))); } F2DOT14 stopOffset; @@ -393,7 +397,8 @@ struct ColorLine /* get up to count stops from start */ unsigned int - get_color_stops (unsigned int start, + get_color_stops (hb_paint_context_t *ctx, + unsigned int start, unsigned int *count, hb_color_stop_t *color_stops, const VarStoreInstancer &instancer) const @@ -404,8 +409,7 @@ struct ColorLine { unsigned int i; for (i = 0; i < *count && start + i < len; i++) - stops[start + i].get_color_stop (&color_stops[i], - instancer); + stops[start + i].get_color_stop (ctx, &color_stops[i], instancer); *count = i; } @@ -555,8 +559,9 @@ struct PaintSolid void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->color (c->data, - paletteIndex, - alpha.to_float (c->instancer (varIdxBase, 0)), + hb_paint_get_color (&c->ctx, + paletteIndex, + alpha.to_float (c->instancer (varIdxBase, 0))), &c->ctx); } @@ -1992,7 +1997,7 @@ struct COLR .sub_array (record->firstLayerIdx, record->numLayers)) { c.funcs->push_clip_glyph (c.data, r.glyphId, &c.ctx); - c.funcs->color (c.data, r.colorIdx, 1., &c.ctx); + c.funcs->color (c.data, hb_paint_get_color (&c.ctx, r.colorIdx, 1.), &c.ctx); c.funcs->pop_clip (c.data, &c.ctx); } diff --git a/src/hb-paint.cc b/src/hb-paint.cc index b7d09ab44..ede2c8e67 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -74,8 +74,7 @@ hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, static void hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index, - float alpha, + hb_color_t color, const hb_paint_context_t *ctx, void *user_data) {} @@ -489,8 +488,7 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, * hb_paint_color: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @color_index: Index of a color in the color palette - * @alpha: Alpha to apply in addition + * @color: The color to use * @ctx: the paint context * * Perform a "color" paint operation. @@ -499,11 +497,10 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index, - float alpha, + hb_color_t color, const hb_paint_context_t *ctx) { - funcs->color (paint_data, color_index, alpha, ctx); + funcs->color (paint_data, color, ctx); } /** diff --git a/src/hb-paint.h b/src/hb-paint.h index ccbc33bbb..bfeaba200 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -46,7 +46,7 @@ HB_BEGIN_DECLS * * The callbacks also assume that the caller uses * hb_ot_color_palette_get_colors() to obtain colors - * from one of the fonts color palettes. If the font does + * from the color palette that is selected. If the font does * not have color palettes, the color index will always * be 0xFFFF, indicating the use of the foreground color. * @@ -240,27 +240,18 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * hb_paint_color_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @color_index: Index of a color in the fonts selected color palette - * @alpha: alpha to apply in addition - * @ctx: the paint context + * @color: The color to use + * @ctx: The paint context * @user_data: User data pointer passed to hb_paint_funcs_set_color_func() * * A virtual method for the #hb_paint_funcs_t to paint a * color everywhere within the current clip. * - * The @color_index can be either an index into one of the fonts - * color palettes, or the special value 0xFFFF, which indicates that - * the foreground color should be used. - * - * In either case, the @alpha value should be applied in addition - * (i.e. multiplied with) the alpha value found in the color. - * * Since: REPLACEME */ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index, - float alpha, + hb_color_t color, const hb_paint_context_t *ctx, void *user_data); @@ -321,27 +312,18 @@ typedef struct hb_color_line_t hb_color_line_t; /** * hb_color_stop_t: * @offset: the offset of the color stop - * @color_index: either a color palette index or the special value 0xFFFF - * @alpha: alpha to apply + * @color: the color * * Information about a color stop on a color line. * * Color lines typically have offsets ranging between 0 and 1, * but that is not required. * - * The @color_index can be either an index into one of the fonts - * color palettes, or the special value 0xFFFF, which indicates that - * the foreground color should be used. - * - * in either case, the @alpha value should be applied in addition - * (i.e. multiplied with) the alpha value found in the color. - * * Since: REPLACEME */ typedef struct { float offset; - unsigned int color_index; - float alpha; + hb_color_t color; } hb_color_stop_t; HB_EXTERN unsigned int @@ -789,8 +771,7 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index, - float alpha, + hb_color_t color, const hb_paint_context_t *ctx); HB_EXTERN void diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 4412d81d3..458aca7f3 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -98,11 +98,10 @@ struct hb_paint_funcs_t { func.pop_clip (this, paint_data, ctx, !user_data ? nullptr : user_data->pop_clip); } void color (void *paint_data, - unsigned int color_index, - float alpha, + hb_color_t color, const hb_paint_context_t *ctx) { func.color (this, paint_data, - color_index, alpha, + color, ctx, !user_data ? nullptr : user_data->color); } void image (void *paint_data, @@ -197,4 +196,26 @@ struct hb_paint_funcs_t }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); +static inline hb_color_t +hb_paint_get_color (const hb_paint_context_t *ctx, + unsigned int color_index, + float alpha) +{ + hb_color_t color = ctx->foreground; + + if (color_index != 0xffff) + { + unsigned int clen = 1; + hb_face_t *face = hb_font_get_face (ctx->font); + + hb_ot_color_palette_get_colors (face, ctx->palette, color_index, &clen, &color); + } + + return HB_COLOR (hb_color_get_blue (color), + hb_color_get_green (color), + hb_color_get_red (color), + hb_color_get_alpha (color) * alpha); +} + + #endif /* HB_PAINT_HH */ diff --git a/test/api/results/hand-20-0-10 b/test/api/results/hand-20-0-10 index dc022ef00..e6e82f49b 100644 --- a/test/api/results/hand-20-0-10 +++ b/test/api/results/hand-20-0-10 @@ -7,10 +7,10 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 p0 280.000000 440.000000 radius 0.000000 p1 280.000000 440.000000 radius 467.000000 colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 end transform end clip end transform @@ -23,29 +23,29 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 p1 1019.000000 -27.000000 p2 231.000000 -815.000000 colors - 0.000000 12 1.000000 - 1.000000 12 1.000000 + 0.000000 164 123 98 255 + 1.000000 164 123 98 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 15 - solid 9 1.000000 + solid 145 103 77 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 16 - solid 0 1.000000 + solid 30 136 229 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 21 - solid 9 1.000000 + solid 145 103 77 255 end clip end transform pop group mode 3 @@ -58,15 +58,15 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 p1 180.000000 -106.000000 p2 -212.000000 1265.000000 colors - 0.000000 5 1.000000 - 1.000000 1 1.000000 + 0.000000 100 181 246 255 + 1.000000 33 150 243 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 18 - solid 2 0.200012 + solid 66 66 66 51 end clip end transform pop group mode 3 @@ -79,10 +79,10 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 p0 588.000000 198.000000 radius 0.000000 p1 588.000000 198.000000 radius 342.000000 colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 end transform end clip end transform @@ -90,7 +90,7 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 20 - solid 9 1.000000 + solid 145 103 77 255 end clip end transform pop group mode 3 diff --git a/test/api/results/hand-20-0.2-10 b/test/api/results/hand-20-0.2-10 index 536cd0c1b..a285dedcd 100644 --- a/test/api/results/hand-20-0.2-10 +++ b/test/api/results/hand-20-0.2-10 @@ -7,10 +7,10 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 p0 280.000000 440.000000 radius 0.000000 p1 280.000000 440.000000 radius 467.000000 colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 end transform end clip end transform @@ -23,29 +23,29 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 p1 1019.000000 -27.000000 p2 231.000000 -815.000000 colors - 0.000000 12 1.000000 - 1.000000 12 1.000000 + 0.000000 164 123 98 255 + 1.000000 164 123 98 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 15 - solid 9 1.000000 + solid 145 103 77 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 16 - solid 0 1.000000 + solid 30 136 229 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 21 - solid 9 1.000000 + solid 145 103 77 255 end clip end transform pop group mode 3 @@ -58,15 +58,15 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 p1 180.000000 -106.000000 p2 -212.000000 1265.000000 colors - 0.000000 5 1.000000 - 1.000000 1 1.000000 + 0.000000 100 181 246 255 + 1.000000 33 150 243 255 end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 18 - solid 2 0.200012 + solid 66 66 66 51 end clip end transform pop group mode 3 @@ -79,10 +79,10 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 p0 588.000000 198.000000 radius 0.000000 p1 588.000000 198.000000 radius 342.000000 colors - 0.000000 16 1.000000 - 0.448792 15 1.000000 - 0.808594 14 1.000000 - 1.000000 12 1.000000 + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 end transform end clip end transform @@ -90,7 +90,7 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 20 - solid 9 1.000000 + solid 145 103 77 255 end clip end transform pop group mode 3 diff --git a/test/api/results/test-20-0-10 b/test/api/results/test-20-0-10 index 1c34a136f..332c00a48 100644 --- a/test/api/results/test-20-0-10 +++ b/test/api/results/test-20-0-10 @@ -5,10 +5,10 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 center 500.000000 600.000000 angles 0.000000 6.283185 colors - 0.250000 7 1.000000 - 0.416687 4 1.000000 - 0.583313 0 1.000000 - 0.750000 8 1.000000 + 0.250000 250 240 230 255 + 0.416687 0 0 255 255 + 0.583313 255 0 0 255 + 0.750000 47 79 79 255 end clip end transform end transform diff --git a/test/api/results/test-20-0-106 b/test/api/results/test-20-0-106 index 323940afe..9f59e4c06 100644 --- a/test/api/results/test-20-0-106 +++ b/test/api/results/test-20-0-106 @@ -2,7 +2,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 4 0.500000 + solid 0 0 255 127 end clip end transform push group @@ -11,7 +11,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 1 0.700012 + solid 255 165 0 178 end clip end transform end transform diff --git a/test/api/results/test-20-0-116 b/test/api/results/test-20-0-116 index 6c7ffd355..fdc4f9951 100644 --- a/test/api/results/test-20-0-116 +++ b/test/api/results/test-20-0-116 @@ -2,14 +2,14 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 4 0.500000 + solid 0 0 255 127 end clip end transform push group start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 1 0.700012 + solid 255 165 0 178 end clip end transform end transform diff --git a/test/api/results/test-20-0-123 b/test/api/results/test-20-0-123 index 296c3eebb..40d40f843 100644 --- a/test/api/results/test-20-0-123 +++ b/test/api/results/test-20-0-123 @@ -2,7 +2,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 10 1.000000 + solid 0 0 0 255 end clip end transform pop group mode 3 @@ -13,7 +13,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 - solid 12 1.000000 + solid 255 220 1 255 end clip end transform end transform @@ -25,7 +25,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 - solid 11 1.000000 + solid 104 199 232 255 end clip end transform end transform diff --git a/test/api/results/test-20-0-165 b/test/api/results/test-20-0-165 index cea5dd9ce..8ce13633b 100644 --- a/test/api/results/test-20-0-165 +++ b/test/api/results/test-20-0-165 @@ -6,9 +6,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 p1 2300.000000 950.000000 p2 -1000.000000 250.000000 colors - 0.000000 0 1.000000 - 0.500000 4 1.000000 - 1.000000 2 1.000000 + 0.000000 255 0 0 255 + 0.500000 0 0 255 255 + 1.000000 255 255 0 255 end clip end transform end transform diff --git a/test/api/results/test-20-0-175 b/test/api/results/test-20-0-175 index 83dac5ee3..4488375f9 100644 --- a/test/api/results/test-20-0-175 +++ b/test/api/results/test-20-0-175 @@ -3,7 +3,7 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 174 - solid 3 1.000000 + solid 0 128 0 255 end clip end transform end transform @@ -17,8 +17,8 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 p1 500.000000 950.000000 p2 600.000000 250.000000 colors - 0.000000 0 1.000000 - 1.000000 4 1.000000 + 0.000000 255 0 0 255 + 1.000000 0 0 255 255 end clip end transform end transform diff --git a/test/api/results/test-20-0-6 b/test/api/results/test-20-0-6 index c165e62d4..8fe765ac9 100644 --- a/test/api/results/test-20-0-6 +++ b/test/api/results/test-20-0-6 @@ -6,8 +6,8 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 p1 900.000000 250.000000 p2 100.000000 300.000000 colors - 0.000000 0 1.000000 - 1.000000 4 1.000000 + 0.000000 255 0 0 255 + 1.000000 0 0 255 255 end clip end transform end transform diff --git a/test/api/results/test-20-0-92 b/test/api/results/test-20-0-92 index 51d5b2fa2..7c7916dac 100644 --- a/test/api/results/test-20-0-92 +++ b/test/api/results/test-20-0-92 @@ -5,9 +5,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 p0 166.000000 768.000000 radius 0.000000 p1 166.000000 768.000000 radius 256.000000 colors - 0.000000 3 1.000000 - 0.500000 9 1.000000 - 1.000000 0 1.000000 + 0.000000 0 128 0 255 + 0.500000 255 255 255 255 + 1.000000 255 0 0 255 end clip end transform end transform diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index a63ecc9da..737a02050 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -546,14 +546,17 @@ pop_clip (hb_paint_funcs_t *funcs, static void paint_color (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index, - float alpha, + hb_color_t color, const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; - print (data, "solid %u %f", color_index, alpha); + print (data, "solid %d %d %d %d", + hb_color_get_red (color), + hb_color_get_green (color), + hb_color_get_blue (color), + hb_color_get_alpha (color)); } static void @@ -587,7 +590,12 @@ print_color_line (paint_data_t *data, print (data, "colors"); data->level += 1; for (unsigned int i = 0; i < len; i++) - print (data, "%f %u %f", stops[i].offset, stops[i].color_index, stops[i].alpha); + print (data, "%f %d %d %d %d", + stops[i].offset, + hb_color_get_red (stops[i].color), + hb_color_get_green (stops[i].color), + hb_color_get_blue (stops[i].color), + hb_color_get_alpha (stops[i].color)); data->level -= 1; } @@ -746,7 +754,7 @@ test_hb_ot_color_colr_v1 (gconstpointer d) */ if (getenv ("GENERATE_DATA")) { - g_print ("%s\n", data.string->str); + g_print ("%s", data.string->str); exit (0); } diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index f3eb69435..10e18e10a 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -259,8 +259,11 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, cairo_pattern_set_extend (pattern, cairo_extend (hb_color_line_get_extend (color_line))); for (unsigned int i = 0; i < len; i++) { - float r, g, b, a; - hb_cairo_get_font_color (ctx, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + double r, g, b, a; + r = hb_color_get_red (stops[i].color) / 255.; + g = hb_color_get_green (stops[i].color) / 255.; + b = hb_color_get_blue (stops[i].color) / 255.; + a = hb_color_get_alpha (stops[i].color) / 255.; cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); } @@ -307,8 +310,11 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, for (unsigned int i = 0; i < len; i++) { - float r, g, b, a; - hb_cairo_get_font_color (ctx, stops[i].color_index, stops[i].alpha, &r, &g, &b, &a); + double r, g, b, a; + r = hb_color_get_red (stops[i].color) / 255.; + g = hb_color_get_green (stops[i].color) / 255.; + b = hb_color_get_blue (stops[i].color) / 255.; + a = hb_color_get_alpha (stops[i].color) / 255.; cairo_pattern_add_color_stop_rgba (pattern, stops[i].offset, r, g, b, a); } @@ -486,7 +492,10 @@ add_sweep_gradient_patches (const hb_paint_context_t *ctx, color_t c; if (start_angle > 0) { - hb_cairo_get_font_color (ctx, stops[0].color_index, stops[0].alpha, &c.r, &c.g, &c.b, &c.a); + c.r = hb_color_get_red (stops[0].color) / 255.; + c.g = hb_color_get_green (stops[0].color) / 255.; + c.b = hb_color_get_blue (stops[0].color) / 255.; + c.a = hb_color_get_alpha (stops[0].color) / 255.; add_sweep_gradient_patches1 (cx, cy, radius, 0., &c, start_angle, &c, @@ -494,7 +503,10 @@ add_sweep_gradient_patches (const hb_paint_context_t *ctx, } if (end_angle < 2 * M_PI) { - hb_cairo_get_font_color (ctx, stops[n_stops-1].color_index, stops[n_stops-1].alpha, &c.r, &c.g, &c.b, &c.a); + c.r = hb_color_get_red (stops[n_stops - 1].color) / 255.; + c.g = hb_color_get_green (stops[n_stops - 1].color) / 255.; + c.b = hb_color_get_blue (stops[n_stops - 1].color) / 255.; + c.a = hb_color_get_alpha (stops[n_stops - 1].color) / 255.; add_sweep_gradient_patches1 (cx, cy, radius, end_angle, &c, 2 * M_PI, &c, @@ -530,7 +542,10 @@ add_sweep_gradient_patches (const hb_paint_context_t *ctx, for (unsigned i = 0; i < n_stops; i++) { angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); - hb_cairo_get_font_color (ctx, stops[i].color_index, stops[i].alpha, &colors[i].r, &colors[i].g, &colors[i].b, &colors[i].a); + colors[i].r = hb_color_get_red (stops[i].color) / 255.; + colors[i].g = hb_color_get_green (stops[i].color) / 255.; + colors[i].b = hb_color_get_blue (stops[i].color) / 255.; + colors[i].a = hb_color_get_alpha (stops[i].color) / 255.; } if (extend == CAIRO_EXTEND_PAD) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 00ca3cc90..cc680f7f4 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -209,16 +209,17 @@ pop_group (hb_paint_funcs_t *funcs, static void paint_color (hb_paint_funcs_t *funcs, void *paint_data, - unsigned int color_index, - float alpha, + hb_color_t color, const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - float r, g, b, a; - hb_cairo_get_font_color (ctx, color_index, alpha, &r, &g, &b, &a); - cairo_set_source_rgba (cr, (double)r, (double)g, (double)b, (double)a); + cairo_set_source_rgba (cr, + hb_color_get_red (color) / 255., + hb_color_get_green (color) / 255., + hb_color_get_blue (color) / 255., + hb_color_get_alpha (color) / 255.); cairo_paint (cr); } From 6387004cadd8f5bc755f5b14c95fd71153bcc48b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 16:43:19 -0500 Subject: [PATCH 130/219] [paint] Simplify api Drop the hb_paint_context_t struct from the API, and only pass the font where we need it. --- docs/harfbuzz-sections.txt | 1 - src/OT/glyf/glyf.hh | 16 +-- src/hb-font.cc | 12 +- src/hb-ot-cff1-table.cc | 16 +-- src/hb-ot-cff2-table.cc | 16 +-- src/hb-ot-color-cbdt-table.hh | 7 +- src/hb-ot-color-colr-table.cc | 12 +- src/hb-ot-color-colr-table.hh | 242 +++++++++++++++++----------------- src/hb-ot-color-sbix-table.hh | 3 +- src/hb-ot-color-svg-table.hh | 4 +- src/hb-paint.cc | 85 ++++-------- src/hb-paint.h | 84 ++---------- src/hb-paint.hh | 90 ++++--------- test/api/test-ot-color.c | 13 +- util/hb-cairo-utils.c | 31 +---- util/hb-cairo-utils.h | 9 -- util/helper-cairo-user.hh | 23 +--- 17 files changed, 216 insertions(+), 448 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index ebea175ac..f758721d5 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -230,7 +230,6 @@ hb_paint_funcs_get_user_data hb_paint_funcs_make_immutable hb_paint_funcs_is_immutable -hb_paint_context_t hb_paint_push_transform_func_t hb_paint_funcs_set_push_transform_func hb_paint_pop_transform_func_t diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index 74e47359a..39ce65608 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -335,19 +335,13 @@ struct glyf_accelerator_t bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - hb_paint_context_t ctx; + funcs->push_root_transform (data, font); - ctx.font = font; - ctx.palette = 0; - ctx.foreground = foreground; + funcs->push_clip_glyph (data, gid, font); + funcs->color (data, foreground); + funcs->pop_clip (data); - funcs->push_root_transform (data, &ctx); - - funcs->push_clip_glyph (data, gid, &ctx); - funcs->color (data, hb_paint_get_color (&ctx, 0xffff, 1.), &ctx); - funcs->pop_clip (data, &ctx); - - funcs->pop_root_transform (data, &ctx); + funcs->pop_root_transform (data); return false; } diff --git a/src/hb-font.cc b/src/hb-font.cc index cd32aa1b6..903af6d98 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -661,25 +661,17 @@ hb_font_paint_glyph_default (hb_font_t *font, hb_color_t foreground, void *user_data) { - hb_paint_context_t ctx; - - ctx.font = font; - ctx.palette = palette; - ctx.foreground = foreground; - paint_funcs->push_transform (paint_data, font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, font->parent->y_scale ? (font->slant - font->parent->slant) * (float) font->x_scale / (float) font->parent->y_scale : 0.f, 0.f, font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, - 0.f, - 0.f, - &ctx); + 0.f, 0.f); font->parent->paint_glyph (glyph, paint_funcs, paint_data, palette, foreground); - paint_funcs->pop_transform (paint_data, &ctx); + paint_funcs->pop_transform (paint_data); } DEFINE_NULL_INSTANCE (hb_font_funcs_t) = diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index fa93c3da6..b00441fe5 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -555,19 +555,13 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - hb_paint_context_t ctx; + funcs->push_root_transform (data, font); - ctx.font = font; - ctx.palette = 0; - ctx.foreground = foreground; + funcs->push_clip_glyph (data, glyph, font); + funcs->color (data, foreground); + funcs->pop_clip (data); - funcs->push_root_transform (data, &ctx); - - funcs->push_clip_glyph (data, glyph, &ctx); - funcs->color (data, hb_paint_get_color (&ctx, 0xffff, 1.), &ctx); - funcs->pop_clip (data, &ctx); - - funcs->pop_root_transform (data, &ctx); + funcs->pop_root_transform (data); return false; } diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index af5e3027d..6bbd5383a 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -145,19 +145,13 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - hb_paint_context_t ctx; + funcs->push_root_transform (data, font); - ctx.font = font; - ctx.palette = 0; - ctx.foreground = foreground; + funcs->push_clip_glyph (data, glyph, font); + funcs->color (data, foreground); + funcs->pop_clip (data); - funcs->push_root_transform (data, &ctx); - - funcs->push_clip_glyph (data, glyph, &ctx); - funcs->color (data, hb_paint_get_color (&ctx, 0xffff, 1.), &ctx); - funcs->pop_clip (data, &ctx); - - funcs->pop_root_transform (data, &ctx); + funcs->pop_root_transform (data); return false; } diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 3fe8fa943..63536aa92 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -939,7 +939,6 @@ struct CBDT bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { - hb_paint_context_t ctx; hb_glyph_extents_t extents; hb_blob_t *blob = reference_png (font, glyph); @@ -949,11 +948,7 @@ struct CBDT if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; - ctx.font = font; - ctx.palette = 0; - ctx.foreground = HB_COLOR (0, 0, 0, 255); - - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, &ctx); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 05de5b22d..449da1691 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -2,19 +2,19 @@ namespace OT { -void PaintColrLayers::paint_glyph (hb_ot_paint_context_t *c) const +void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { const Paint &paint = paint_offset_lists.get_paint (i); - c->funcs->push_group (c->data, &c->ctx); + c->funcs->push_group (c->data); c->recurse (paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, &c->ctx); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } } -void PaintColrGlyph::paint_glyph (hb_ot_paint_context_t *c) const +void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { const COLR *colr_table = c->get_colr_table (); const Paint *paint = colr_table->get_base_glyph_paint (gid); @@ -51,9 +51,9 @@ hb_color_line_get_color_stops (hb_color_line_t *color_line, hb_color_stop_t *color_stops) { if (color_line->is_variable) - return reinterpret_cast *>(color_line->base)->get_color_stops (&color_line->c->ctx, start, count, color_stops, color_line->c->instancer); + return reinterpret_cast *>(color_line->base)->get_color_stops (color_line->c, start, count, color_stops, color_line->c->instancer); else - return reinterpret_cast *>(color_line->base)->get_color_stops (&color_line->c->ctx, start, count, color_stops, color_line->c->instancer); + return reinterpret_cast *>(color_line->base)->get_color_stops (color_line->c, start, count, color_stops, color_line->c->instancer); } /** diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index f84e57654..d5f233df7 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -46,11 +46,11 @@ namespace OT { -struct hb_ot_paint_context_t; +struct hb_paint_context_t; } struct hb_color_line_t { - struct OT::hb_ot_paint_context_t *c; + struct OT::hb_paint_context_t *c; const void *base; bool is_variable; }; @@ -61,8 +61,8 @@ struct COLR; struct Paint; -struct hb_ot_paint_context_t : - hb_dispatch_context_t +struct hb_paint_context_t : + hb_dispatch_context_t { template return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); } @@ -75,24 +75,45 @@ public: const void *base; hb_paint_funcs_t *funcs; void *data; - hb_paint_context_t ctx; + hb_font_t *font; + unsigned int palette; + hb_color_t foreground; VarStoreInstancer &instancer; int depth_left = HB_COLRV1_MAX_NESTING_LEVEL; - hb_ot_paint_context_t (const void *base_, + hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, void *data_, hb_font_t *font_, - unsigned int palette, - hb_color_t foreground, + unsigned int palette_, + hb_color_t foreground_, VarStoreInstancer &instancer_) : base (base_), funcs (funcs_), data (data_), + font (font_), + palette (palette_), + foreground (foreground_), instancer (instancer_) - { ctx.font = font_; - ctx.palette = palette; - ctx.foreground = foreground; } + { } + + hb_color_t get_color (unsigned int color_index, float alpha) + { + hb_color_t color = foreground; + + if (color_index != 0xffff) + { + unsigned int clen = 1; + hb_face_t *face = hb_font_get_face (font); + + hb_ot_color_palette_get_colors (face, palette, color_index, &clen, &color); + } + + return HB_COLOR (hb_color_get_blue (color), + hb_color_get_green (color), + hb_color_get_red (color), + hb_color_get_alpha (color) * alpha); + } inline void recurse (const Paint &paint); }; @@ -236,16 +257,16 @@ struct Variable return_trace (c->check_struct (this) && value.sanitize (c)); } - void paint_glyph (hb_ot_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c) const { value.paint_glyph (c, varIdxBase); } - void get_color_stop (hb_paint_context_t *ctx, - hb_color_stop_t *c, + void get_color_stop (hb_paint_context_t *c, + hb_color_stop_t *stop, const VarStoreInstancer &instancer) const { - value.get_color_stop (ctx, c, varIdxBase, instancer); + value.get_color_stop (c, stop, varIdxBase, instancer); } hb_paint_extend_t get_extend () const @@ -289,16 +310,16 @@ struct NoVariable return_trace (c->check_struct (this) && value.sanitize (c)); } - void paint_glyph (hb_ot_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c) const { value.paint_glyph (c, varIdxBase); } - void get_color_stop (hb_paint_context_t *ctx, - hb_color_stop_t *c, + void get_color_stop (hb_paint_context_t *c, + hb_color_stop_t *stop, const VarStoreInstancer &instancer) const { - value.get_color_stop (ctx, c, VarIdx::NO_VARIATION, instancer); + value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer); } hb_paint_extend_t get_extend () const @@ -333,15 +354,13 @@ struct ColorStop return_trace (c->check_struct (this)); } - void get_color_stop (hb_paint_context_t *ctx, + void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *out, uint32_t varIdx, const VarStoreInstancer &instancer) const { out->offset = stopOffset.to_float(instancer (varIdx, 0)); - out->color = hb_paint_get_color (ctx, - paletteIndex, - alpha.to_float (instancer (varIdx, 1))); + out->color = c->get_color (paletteIndex, alpha.to_float (instancer (varIdx, 1))); } F2DOT14 stopOffset; @@ -397,7 +416,7 @@ struct ColorLine /* get up to count stops from start */ unsigned int - get_color_stops (hb_paint_context_t *ctx, + get_color_stops (hb_paint_context_t *c, unsigned int start, unsigned int *count, hb_color_stop_t *color_stops, @@ -409,7 +428,7 @@ struct ColorLine { unsigned int i; for (i = 0; i < *count && start + i < len; i++) - stops[start + i].get_color_stop (ctx, &color_stops[i], instancer); + stops[start + i].get_color_stop (c, &color_stops[i], instancer); *count = i; } @@ -484,7 +503,7 @@ struct Affine2x3 return_trace (c->check_struct (this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, xx.to_float (c->instancer (varIdxBase, 0)), @@ -492,8 +511,7 @@ struct Affine2x3 xy.to_float (c->instancer (varIdxBase, 2)), yy.to_float (c->instancer (varIdxBase, 3)), dx.to_float (c->instancer (varIdxBase, 4)), - dy.to_float (c->instancer (varIdxBase, 5)), - &c->ctx); + dy.to_float (c->instancer (varIdxBase, 5))); } F16DOT16 xx; @@ -527,7 +545,7 @@ struct PaintColrLayers return_trace (c->check_struct (this)); } - HB_INTERNAL void paint_glyph (hb_ot_paint_context_t *c) const; + HB_INTERNAL void paint_glyph (hb_paint_context_t *c) const; HBUINT8 format; /* format = 1 */ HBUINT8 numLayers; @@ -556,13 +574,11 @@ struct PaintSolid return_trace (c->check_struct (this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->color (c->data, - hb_paint_get_color (&c->ctx, - paletteIndex, - alpha.to_float (c->instancer (varIdxBase, 0))), - &c->ctx); + c->get_color (paletteIndex, + alpha.to_float (c->instancer (varIdxBase, 0)))); } HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ @@ -593,7 +609,7 @@ struct PaintLinearGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; @@ -603,8 +619,7 @@ struct PaintLinearGradient x1 + c->instancer (varIdxBase, 2), y1 + c->instancer (varIdxBase, 3), x2 + c->instancer (varIdxBase, 4), - y2 + c->instancer (varIdxBase, 5), - &c->ctx); + y2 + c->instancer (varIdxBase, 5)); } HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ @@ -641,7 +656,7 @@ struct PaintRadialGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; @@ -651,8 +666,7 @@ struct PaintRadialGradient radius0 + c->instancer (varIdxBase, 2), x1 + c->instancer (varIdxBase, 3), y1 + c->instancer (varIdxBase, 4), - radius1 + c->instancer (varIdxBase, 5), - &c->ctx); + radius1 + c->instancer (varIdxBase, 5)); } HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ @@ -689,7 +703,7 @@ struct PaintSweepGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; @@ -697,8 +711,7 @@ struct PaintSweepGradient centerX + c->instancer (varIdxBase, 0), centerY + c->instancer (varIdxBase, 1), (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI, - (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI, - &c->ctx); + (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI); } HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ @@ -736,13 +749,13 @@ struct PaintGlyph return_trace (c->check_struct (this) && paint.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_inverse_root_transform (c->data, &c->ctx); - c->funcs->push_clip_glyph (c->data, gid, &c->ctx); + c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_clip_glyph (c->data, gid, c->font); c->recurse (this+paint); - c->funcs->pop_clip (c->data, &c->ctx); - c->funcs->pop_inverse_root_transform (c->data, &c->ctx); + c->funcs->pop_clip (c->data); + c->funcs->pop_inverse_root_transform (c->data); } HBUINT8 format; /* format = 10 */ @@ -772,7 +785,7 @@ struct PaintColrGlyph return_trace (c->check_struct (this)); } - HB_INTERNAL void paint_glyph (hb_ot_paint_context_t *c) const; + HB_INTERNAL void paint_glyph (hb_paint_context_t *c) const; HBUINT8 format; /* format = 11 */ HBUINT16 gid; @@ -802,11 +815,11 @@ struct PaintTransform transform.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c) const { (this+transform).paint_glyph (c); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ @@ -835,15 +848,14 @@ struct PaintTranslate return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, 1., 0., 0., 1., dx + c->instancer (varIdxBase, 0), - dy + c->instancer (varIdxBase, 0), - &c->ctx); + dy + c->instancer (varIdxBase, 0)); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ @@ -873,16 +885,15 @@ struct PaintScale return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, scaleX.to_float (c->instancer (varIdxBase, 0)), 0., 0., scaleY.to_float (c->instancer (varIdxBase, 1)), - 0., 0., - &c->ctx); + 0., 0.); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ @@ -912,24 +923,21 @@ struct PaintScaleAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - &c->ctx); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_transform (c->data, scaleX.to_float (c->instancer (varIdxBase, 0)), 0., 0., scaleY.to_float (c->instancer (varIdxBase, 1)), - 0., 0., - &c->ctx); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - &c->ctx); + 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ @@ -961,13 +969,12 @@ struct PaintScaleUniform return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float s = scale + c->instancer (varIdxBase, 0); - c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0., - &c->ctx); + c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ @@ -996,21 +1003,18 @@ struct PaintScaleUniformAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float s = scale + c->instancer (varIdxBase, 0); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - &c->ctx); - c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0., - &c->ctx); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - &c->ctx); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); + c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ @@ -1041,15 +1045,14 @@ struct PaintRotate return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float a = angle.to_float (c->instancer (varIdxBase, 0)); float cc = cosf (a * (float) M_PI); float ss = sinf (a * (float) M_PI); - c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0., - &c->ctx); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ @@ -1078,23 +1081,20 @@ struct PaintRotateAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float a = angle.to_float (c->instancer (varIdxBase, 0)); float cc = cosf (a * (float) M_PI); float ss = sinf (a * (float) M_PI); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - &c->ctx); - c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0., - &c->ctx); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - &c->ctx); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ @@ -1125,14 +1125,13 @@ struct PaintSkew return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); - c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0., - &c->ctx); + c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ @@ -1162,22 +1161,19 @@ struct PaintSkewAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c, uint32_t varIdxBase) const + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY, - &c->ctx); - c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0., - &c->ctx); - c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY, - &c->ctx); + c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); + c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); + c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); c->recurse (this+src); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); - c->funcs->pop_transform (c->data, &c->ctx); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ @@ -1212,14 +1208,14 @@ struct PaintComposite backdrop.sanitize (c, this)); } - void paint_glyph (hb_ot_paint_context_t *c) const + void paint_glyph (hb_paint_context_t *c) const { - c->funcs->push_group (c->data, &c->ctx); + c->funcs->push_group (c->data); c->recurse (this+backdrop); - c->funcs->push_group (c->data, &c->ctx); + c->funcs->push_group (c->data); c->recurse (this+src); - c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode, &c->ctx); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER, &c->ctx); + c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } HBUINT8 format; /* format = 32 */ @@ -1974,17 +1970,17 @@ struct COLR this+varIdxMap, hb_array (font->coords, font->num_coords)); - hb_ot_paint_context_t c (this, funcs, data, font, palette, foreground, instancer); + hb_paint_context_t c (this, funcs, data, font, palette, foreground, instancer); const Paint *paint = get_base_glyph_paint (glyph); if (paint) { // COLRv1 glyph - c.funcs->push_root_transform (c.data, &c.ctx); + c.funcs->push_root_transform (c.data, font); c.recurse (*paint); - c.funcs->pop_root_transform (c.data, &c.ctx); + c.funcs->pop_root_transform (c.data); return true; } @@ -1996,9 +1992,9 @@ struct COLR for (const auto &r : (this+layersZ).as_array (numLayers) .sub_array (record->firstLayerIdx, record->numLayers)) { - c.funcs->push_clip_glyph (c.data, r.glyphId, &c.ctx); - c.funcs->color (c.data, hb_paint_get_color (&c.ctx, r.colorIdx, 1.), &c.ctx); - c.funcs->pop_clip (c.data, &c.ctx); + c.funcs->push_clip_glyph (c.data, r.glyphId, c.font); + c.funcs->color (c.data, c.get_color (r.colorIdx, 1.)); + c.funcs->pop_clip (c.data); } return true; @@ -2030,7 +2026,7 @@ struct COLR_accelerator_t : COLR::accelerator_t { }; void -hb_ot_paint_context_t::recurse (const Paint &paint) +hb_paint_context_t::recurse (const Paint &paint) { depth_left--; if (depth_left > 0) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index d1737501b..bafb45417 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -234,7 +234,6 @@ struct sbix bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { - hb_paint_context_t ctx = { font, 0, HB_COLOR (0, 0, 0, 255) }; if (!has_data ()) return false; @@ -249,7 +248,7 @@ struct sbix if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents, &ctx); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index dae4419bd..3967a1196 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -95,8 +95,6 @@ struct SVG bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { - hb_paint_context_t ctx = { font, 0, HB_COLOR (0, 0, 0, 255) }; - if (!has_data ()) return false; @@ -105,7 +103,7 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr, &ctx); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr); hb_blob_destroy (blob); return true; diff --git a/src/hb-paint.cc b/src/hb-paint.cc index ede2c8e67..75215ac48 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -47,35 +47,30 @@ hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, float dx, float dy, - const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - const hb_paint_context_t *ctx, + hb_font_t *font, void *user_data) {} static void hb_paint_push_clip_rectangle_nil (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_color_t color, - const hb_paint_context_t *ctx, void *user_data) {} static void @@ -83,7 +78,6 @@ hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, - const hb_paint_context_t *ctx, void *user_data) {} static void @@ -92,7 +86,6 @@ hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float x1, float y1, float x2, float y2, - const hb_paint_context_t *ctx, void *user_data) {} static void @@ -100,7 +93,6 @@ hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - const hb_paint_context_t *ctx, void *user_data) {} static void @@ -109,18 +101,15 @@ hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float start_angle, float end_angle, - const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) {} static void hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - const hb_paint_context_t *ctx, void *user_data) {} static bool @@ -393,7 +382,6 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix - * @ctx: the paint context * * Perform a "push-transform" paint operation. * @@ -403,27 +391,24 @@ void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, - float dx, float dy, - const hb_paint_context_t *ctx) + float dx, float dy) { - funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy, ctx); + funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); } /** * hb_paint_pop_transform: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @ctx: the paint context * * Perform a "pop-transform" paint operation. * * Since: REPLACEME */ void -hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx) +hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) { - funcs->pop_transform (paint_data, ctx); + funcs->pop_transform (paint_data); } /** @@ -431,7 +416,7 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, * @funcs: paint functions * @paint_data: associated data passed by the caller * @glyph: the glyph ID - * @ctx: the paint context + * @font: the font * * Perform a "push-clip-glyph" paint operation. * @@ -440,9 +425,9 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - const hb_paint_context_t *ctx) + hb_font_t *font) { - funcs->push_clip_glyph (paint_data, glyph, ctx); + funcs->push_clip_glyph (paint_data, glyph, font); } /** @@ -453,7 +438,6 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle - * @ctx: the paint context * * Perform a "push-clip-rect" paint operation. * @@ -461,27 +445,24 @@ hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, float xmax, float ymax, - const hb_paint_context_t *ctx) + float xmin, float ymin, float xmax, float ymax) { - funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax, ctx); + funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax); } /** * hb_paint_pop_clip: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @ctx: the paint context * * Perform a "pop-clip" paint operation. * * Since: REPLACEME */ void -hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx) +hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) { - funcs->pop_clip (paint_data, ctx); + funcs->pop_clip (paint_data); } /** @@ -489,7 +470,6 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, * @funcs: paint functions * @paint_data: associated data passed by the caller * @color: The color to use - * @ctx: the paint context * * Perform a "color" paint operation. * @@ -497,10 +477,9 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_t color, - const hb_paint_context_t *ctx) + hb_color_t color) { - funcs->color (paint_data, color, ctx); + funcs->color (paint_data, color); } /** @@ -510,7 +489,6 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, * @image: image data * @format: tag describing the image data format * @extents: (nullable): the extents of the glyph - * @ctx: the paint context * * Perform a "image" paint operation. * @@ -520,10 +498,9 @@ void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, - hb_glyph_extents_t *extents, - const hb_paint_context_t *ctx) + hb_glyph_extents_t *extents) { - funcs->image (paint_data, image, format, extents, ctx); + funcs->image (paint_data, image, format, extents); } /** @@ -537,7 +514,6 @@ hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point - * @ctx: the paint context * * Perform a "linear-gradient" paint operation. * @@ -548,10 +524,9 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, - float x2, float y2, - const hb_paint_context_t *ctx) + float x2, float y2) { - funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2, ctx); + funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); } /** @@ -565,7 +540,6 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle - * @ctx: the paint context * * Perform a "radial-gradient" paint operation. * @@ -575,10 +549,9 @@ void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, - float x1, float y1, float r1, - const hb_paint_context_t *ctx) + float x1, float y1, float r1) { - funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1, ctx); + funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); } /** @@ -590,7 +563,6 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, * @y0: Y coordinate of the circle's center * @start_angle: the start angle * @end_angle: the end angle - * @ctx: the paint context * * Perform a "sweep-gradient" paint operation. * @@ -600,27 +572,24 @@ void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, - float start_angle, float end_angle, - const hb_paint_context_t *ctx) + float start_angle, float end_angle) { - funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle, ctx); + funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); } /** * hb_paint_push_group: * @funcs: paint functions * @paint_data: associated data passed by the caller - * @ctx: the paint context * * Perform a "push-group" paint operation. * * Since: REPLACEME */ void -hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx) +hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) { - funcs->push_group (paint_data, ctx); + funcs->push_group (paint_data); } /** @@ -628,7 +597,6 @@ hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, * @funcs: paint functions * @paint_data: associated data passed by the caller * @mode: the compositing mode to use - * @ctx: the paint context * * Perform a "pop-group" paint operation. * @@ -636,10 +604,9 @@ hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, */ void hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode, - const hb_paint_context_t *ctx) + hb_paint_composite_mode_t mode) { - funcs->pop_group (paint_data, mode, ctx); + funcs->pop_group (paint_data, mode); } #endif diff --git a/src/hb-paint.h b/src/hb-paint.h index bfeaba200..4779d5f1a 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -91,29 +91,6 @@ hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs); HB_EXTERN hb_bool_t hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs); -/** - * hb_paint_context_t: - * @font: the font that is painted with - * @palette: the palette index - * @foreground: the foreground color - * - * Context information that is passed to paint functions. - */ -typedef struct hb_paint_context_t { - hb_font_t *font; - unsigned int palette; - hb_color_t foreground; - - /*< private >*/ - hb_var_num_t reserved1; - hb_var_num_t reserved2; - hb_var_num_t reserved3; - hb_var_num_t reserved4; - hb_var_num_t reserved5; - hb_var_num_t reserved6; - hb_var_num_t reserved7; -} hb_paint_context_t; - /** * hb_paint_push_transform_func_t: * @funcs: paint functions object @@ -124,7 +101,6 @@ typedef struct hb_paint_context_t { * @yy: yy component of the transform matrix * @dx: dx component of the transform matrix * @dy: dy component of the transform matrix - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_push_transform_func() * * A virtual method for the #hb_paint_funcs_t to apply @@ -141,14 +117,12 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, - const hb_paint_context_t *ctx, void *user_data); /** * hb_paint_pop_transform_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_pop_transform_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -159,7 +133,6 @@ typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs, */ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data); /** @@ -167,7 +140,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @glyph: the glyph ID - * @ctx: the paint context + * @font: the font * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_glyph_func() * * A virtual method for the #hb_paint_funcs_t to clip @@ -185,7 +158,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - const hb_paint_context_t *ctx, + hb_font_t *font, void *user_data); /** @@ -196,7 +169,6 @@ typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs, * @ymin: min Y for the rectangle * @xmax: max X for the rectangle * @ymax: max Y for the rectangle - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_rectangle_func() * * A virtual method for the #hb_paint_funcs_t to clip @@ -215,14 +187,12 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - const hb_paint_context_t *ctx, void *user_data); /** * hb_paint_pop_clip_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_pop_clip_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -233,7 +203,6 @@ typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs, */ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data); /** @@ -241,7 +210,6 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @color: The color to use - * @ctx: The paint context * @user_data: User data pointer passed to hb_paint_funcs_set_color_func() * * A virtual method for the #hb_paint_funcs_t to paint a @@ -252,7 +220,6 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_color_t color, - const hb_paint_context_t *ctx, void *user_data); /** @@ -276,7 +243,6 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @image: the image data * @format: the image format as a tag * @extents: (nullable): glyph extents - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * * A virtual method for the #hb_paint_funcs_t to paint the @@ -297,7 +263,6 @@ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, hb_blob_t *image, hb_tag_t format, hb_glyph_extents_t *extents, - const hb_paint_context_t *ctx, void *user_data); /** @@ -362,7 +327,6 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * @y1: Y coordinate of the second point * @x2: X coordinate of the third point * @y2: Y coordinate of the third point - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_linear_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a linear @@ -383,7 +347,6 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, - const hb_paint_context_t *ctx, void *user_data); /** @@ -397,7 +360,6 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * @x1: X coordinate of the second circle's center * @y1: Y coordinate of the second circle's center * @r1: radius of the second circle - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_radial_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a radial @@ -417,7 +379,6 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - const hb_paint_context_t *ctx, void *user_data); /** @@ -429,7 +390,6 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * @y0: Y coordinate of the circle's center * @start_angle: the start angle, in radians * @end_angle: the end angle, in radians - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_sweep_gradient_func() * * A virtual method for the #hb_paint_funcs_t to paint a sweep @@ -450,7 +410,6 @@ typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, float x0, float y0, float start_angle, float end_angle, - const hb_paint_context_t *ctx, void *user_data); /** @@ -498,7 +457,6 @@ typedef enum { * hb_paint_push_group_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_push_group_func() * * A virtual method for the #hb_paint_funcs_t to use @@ -512,7 +470,6 @@ typedef enum { */ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data); /** @@ -520,7 +477,6 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @mode: the compositing mode to use - * @ctx: the paint context * @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func() * * A virtual method for the #hb_paint_funcs_t to undo @@ -536,7 +492,6 @@ typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - const hb_paint_context_t *ctx, void *user_data); /** @@ -747,47 +702,40 @@ HB_EXTERN void hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xx, float yx, float xy, float yy, - float dx, float dy, - const hb_paint_context_t *ctx); + float dx, float dy); HB_EXTERN void -hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx); +hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); HB_EXTERN void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - const hb_paint_context_t *ctx); + hb_font_t *font); HB_EXTERN void hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, - float xmax, float ymax, - const hb_paint_context_t *ctx); + float xmax, float ymax); HB_EXTERN void -hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx); +hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); HB_EXTERN void hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_t color, - const hb_paint_context_t *ctx); + hb_color_t color); HB_EXTERN void hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, - hb_glyph_extents_t *extents, - const hb_paint_context_t *ctx); + hb_glyph_extents_t *extents); HB_EXTERN void hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, - float x2, float y2, - const hb_paint_context_t *ctx); + float x2, float y2); HB_EXTERN void hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, @@ -795,24 +743,20 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float r0, float x1, float y1, - float r1, - const hb_paint_context_t *ctx); + float r1); HB_EXTERN void hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_color_line_t *color_line, float x0, float y0, - float start_angle, float end_angle, - const hb_paint_context_t *ctx); + float start_angle, float end_angle); HB_EXTERN void -hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx); +hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data); HB_EXTERN void hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode, - const hb_paint_context_t *ctx); + hb_paint_composite_mode_t mode); HB_END_DECLS diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 458aca7f3..29bce0536 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -69,153 +69,107 @@ struct hb_paint_funcs_t void push_transform (void *paint_data, float xx, float yx, float xy, float yy, - float dx, float dy, - const hb_paint_context_t *ctx) + float dx, float dy) { func.push_transform (this, paint_data, xx, yx, xy, yy, dx, dy, - ctx, !user_data ? nullptr : user_data->push_transform); } - void pop_transform (void *paint_data, - const hb_paint_context_t *ctx) - { func.pop_transform (this, paint_data, ctx, + void pop_transform (void *paint_data) + { func.pop_transform (this, paint_data, !user_data ? nullptr : user_data->pop_transform); } void push_clip_glyph (void *paint_data, hb_codepoint_t glyph, - const hb_paint_context_t *ctx) + hb_font_t *font) { func.push_clip_glyph (this, paint_data, glyph, - ctx, + font, !user_data ? nullptr : user_data->push_clip_glyph); } void push_clip_rectangle (void *paint_data, - float xmin, float ymin, float xmax, float ymax, - const hb_paint_context_t *ctx) + float xmin, float ymin, float xmax, float ymax) { func.push_clip_rectangle (this, paint_data, xmin, ymin, xmax, ymax, - ctx, !user_data ? nullptr : user_data->push_clip_rectangle); } - void pop_clip (void *paint_data, - const hb_paint_context_t *ctx) - { func.pop_clip (this, paint_data, ctx, + void pop_clip (void *paint_data) + { func.pop_clip (this, paint_data, !user_data ? nullptr : user_data->pop_clip); } void color (void *paint_data, - hb_color_t color, - const hb_paint_context_t *ctx) + hb_color_t color) { func.color (this, paint_data, color, - ctx, !user_data ? nullptr : user_data->color); } void image (void *paint_data, hb_blob_t *image, hb_tag_t format, - hb_glyph_extents_t *extents, - const hb_paint_context_t *ctx) + hb_glyph_extents_t *extents) { func.image (this, paint_data, image, format, extents, - ctx, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, - float x2, float y2, - const hb_paint_context_t *ctx) + float x2, float y2) { func.linear_gradient (this, paint_data, color_line, x0, y0, x1, y1, x2, y2, - ctx, !user_data ? nullptr : user_data->linear_gradient); } void radial_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float r0, - float x1, float y1, float r1, - const hb_paint_context_t *ctx) + float x1, float y1, float r1) { func.radial_gradient (this, paint_data, color_line, x0, y0, r0, x1, y1, r1, - ctx, !user_data ? nullptr : user_data->radial_gradient); } void sweep_gradient (void *paint_data, hb_color_line_t *color_line, float x0, float y0, float start_angle, - float end_angle, - const hb_paint_context_t *ctx) + float end_angle) { func.sweep_gradient (this, paint_data, color_line, x0, y0, start_angle, end_angle, - ctx, !user_data ? nullptr : user_data->sweep_gradient); } - void push_group (void *paint_data, - const hb_paint_context_t *ctx) - { func.push_group (this, paint_data, ctx, + void push_group (void *paint_data) + { func.push_group (this, paint_data, !user_data ? nullptr : user_data->push_group); } void pop_group (void *paint_data, - hb_paint_composite_mode_t mode, - const hb_paint_context_t *ctx) + hb_paint_composite_mode_t mode) { func.pop_group (this, paint_data, mode, - ctx, !user_data ? nullptr : user_data->pop_group); } void push_root_transform (void *paint_data, - const hb_paint_context_t *ctx) + const hb_font_t *font) { - hb_font_t *font = ctx->font; int xscale = font->x_scale, yscale = font->y_scale; float upem = font->face->get_upem (); float slant = font->slant_xy; func.push_transform (this, paint_data, xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0, - ctx, !user_data ? nullptr : user_data->push_transform); } - void pop_root_transform (void *paint_data, - const hb_paint_context_t *ctx) + void pop_root_transform (void *paint_data) { - func.pop_transform (this, paint_data, ctx, + func.pop_transform (this, paint_data, !user_data ? nullptr : user_data->pop_transform); } void push_inverse_root_transform (void *paint_data, - const hb_paint_context_t *ctx) + hb_font_t *font) { - hb_font_t *font = ctx->font; int xscale = font->x_scale, yscale = font->y_scale; float upem = font->face->get_upem (); float slant = font->slant_xy; func.push_transform (this, paint_data, upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0, - ctx, !user_data ? nullptr : user_data->push_transform); } - void pop_inverse_root_transform (void *paint_data, - const hb_paint_context_t *ctx) + void pop_inverse_root_transform (void *paint_data) { - func.pop_transform (this, paint_data, ctx, + func.pop_transform (this, paint_data, !user_data ? nullptr : user_data->pop_transform); } }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); -static inline hb_color_t -hb_paint_get_color (const hb_paint_context_t *ctx, - unsigned int color_index, - float alpha) -{ - hb_color_t color = ctx->foreground; - - if (color_index != 0xffff) - { - unsigned int clen = 1; - hb_face_t *face = hb_font_get_face (ctx->font); - - hb_ot_color_palette_get_colors (face, ctx->palette, color_index, &clen, &color); - } - - return HB_COLOR (hb_color_get_blue (color), - hb_color_get_green (color), - hb_color_get_red (color), - hb_color_get_alpha (color) * alpha); -} - #endif /* HB_PAINT_HH */ diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 737a02050..a317f46fa 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -484,7 +484,6 @@ push_transform (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -496,7 +495,6 @@ push_transform (hb_paint_funcs_t *funcs, static void pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -509,7 +507,7 @@ static void push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - const hb_paint_context_t *ctx, + hb_font_t *font, void *user_data) { paint_data_t *data = user_data; @@ -522,7 +520,6 @@ static void push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -534,7 +531,6 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, static void pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -547,7 +543,6 @@ static void paint_color (hb_paint_funcs_t *funcs, void *paint_data, hb_color_t color, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -565,7 +560,6 @@ paint_image (hb_paint_funcs_t *funcs, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -606,7 +600,6 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -627,7 +620,6 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -648,7 +640,6 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, float cx, float cy, float start_angle, float end_angle, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -665,7 +656,6 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, static void push_group (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; @@ -677,7 +667,6 @@ static void pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - const hb_paint_context_t *ctx, void *user_data) { paint_data_t *data = user_data; diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 10e18e10a..8bfddde70 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -70,28 +70,6 @@ cairo_extend (hb_paint_extend_t extend) return CAIRO_EXTEND_PAD; } -void -hb_cairo_get_font_color (const hb_paint_context_t *ctx, - unsigned int color_index, - float alpha, - float *r, float *g, float *b, float *a) -{ - hb_color_t color = ctx->foreground; - - if (color_index != 0xffff) - { - unsigned int clen = 1; - hb_face_t *face = hb_font_get_face (ctx->font); - - hb_ot_color_palette_get_colors (face, ctx->palette, color_index, &clen, &color); - } - - *r = hb_color_get_red (color) / 255.f; - *g = hb_color_get_green (color) / 255.f; - *b = hb_color_get_blue (color) / 255.f; - *a = (hb_color_get_alpha (color) / 255.f) * alpha; -} - typedef struct { hb_blob_t *blob; @@ -120,7 +98,6 @@ read_blob (void *closure, void hb_cairo_paint_glyph_image (cairo_t *cr, - const hb_paint_context_t *ctx, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents) @@ -228,7 +205,6 @@ normalize_color_line (hb_color_stop_t *stops, void hb_cairo_paint_linear_gradient (cairo_t *cr, - const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, @@ -278,7 +254,6 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, void hb_cairo_paint_radial_gradient (cairo_t *cr, - const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1) @@ -469,8 +444,7 @@ add_sweep_gradient_patches1 (float cx, float cy, float radius, } static void -add_sweep_gradient_patches (const hb_paint_context_t *ctx, - hb_color_stop_t *stops, +add_sweep_gradient_patches (hb_color_stop_t *stops, unsigned int n_stops, cairo_extend_t extend, float cx, float cy, @@ -723,7 +697,6 @@ done: void hb_cairo_paint_sweep_gradient (cairo_t *cr, - const hb_paint_context_t *ctx, hb_color_line_t *color_line, float cx, float cy, float start_angle, @@ -752,7 +725,7 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr, extend = cairo_extend (hb_color_line_get_extend (color_line)); pattern = cairo_pattern_create_mesh (); - add_sweep_gradient_patches (ctx, stops, len, extend, cx, cy, + add_sweep_gradient_patches (stops, len, extend, cx, cy, radius, start_angle, end_angle, pattern); cairo_set_source (cr, pattern); diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index e372336c1..39cfa3ec4 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -70,32 +70,23 @@ hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) return CAIRO_OPERATOR_SOURCE; } -void hb_cairo_get_font_color (const hb_paint_context_t *ctx, - unsigned int color_index, - float alpha, - float *r, float *g, float *b, float *a); - void hb_cairo_paint_glyph_image (cairo_t *cr, - const hb_paint_context_t *ctx, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents); void hb_cairo_paint_linear_gradient (cairo_t *cr, - const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float x1, float y1, float x2, float y2); void hb_cairo_paint_radial_gradient (cairo_t *cr, - const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1); void hb_cairo_paint_sweep_gradient (cairo_t *cr, - const hb_paint_context_t *ctx, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle); diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index cc680f7f4..57b365b3c 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -111,7 +111,6 @@ push_transform (hb_paint_funcs_t *funcs, float xx, float yx, float xy, float yy, float dx, float dy, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -127,7 +126,6 @@ push_transform (hb_paint_funcs_t *funcs, static void pop_transform (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -139,14 +137,14 @@ static void push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, - const hb_paint_context_t *ctx, + hb_font_t *font, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; cairo_save (cr); cairo_new_path (cr); - hb_font_draw_glyph (ctx->font, glyph, get_cairo_draw_funcs (), cr); + hb_font_draw_glyph (font, glyph, get_cairo_draw_funcs (), cr); cairo_close_path (cr); cairo_clip (cr); } @@ -155,7 +153,6 @@ static void push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, float xmin, float ymin, float xmax, float ymax, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -170,7 +167,6 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, static void pop_clip (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -181,7 +177,6 @@ pop_clip (hb_paint_funcs_t *funcs, static void push_group (hb_paint_funcs_t *funcs, void *paint_data, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -194,7 +189,6 @@ static void pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_composite_mode_t mode, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -210,7 +204,6 @@ static void paint_color (hb_paint_funcs_t *funcs, void *paint_data, hb_color_t color, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; @@ -229,12 +222,11 @@ paint_image (hb_paint_funcs_t *funcs, hb_blob_t *blob, hb_tag_t format, hb_glyph_extents_t *extents, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_glyph_image (cr, ctx, blob, format, extents); + hb_cairo_paint_glyph_image (cr, blob, format, extents); } static void @@ -244,12 +236,11 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, float x0, float y0, float x1, float y1, float x2, float y2, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_linear_gradient (cr, ctx, color_line, x0, y0, x1, y1, x2, y2); + hb_cairo_paint_linear_gradient (cr, color_line, x0, y0, x1, y1, x2, y2); } static void @@ -258,12 +249,11 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float r0, float x1, float y1, float r1, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_radial_gradient (cr, ctx, color_line, x0, y0, r0, x1, y1, r1); + hb_cairo_paint_radial_gradient (cr, color_line, x0, y0, r0, x1, y1, r1); } static void @@ -272,12 +262,11 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, hb_color_line_t *color_line, float x0, float y0, float start_angle, float end_angle, - const hb_paint_context_t *ctx, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_sweep_gradient (cr, ctx, color_line, x0, y0, start_angle, end_angle); + hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle); } static hb_paint_funcs_t * From f146299a405b8338542a245b85e664de29f0c972 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 17:24:02 -0500 Subject: [PATCH 131/219] [paint] Drop unnecessary api --- docs/harfbuzz-sections.txt | 13 -- src/hb-paint.cc | 237 ------------------------------------- src/hb-paint.h | 59 --------- 3 files changed, 309 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index f758721d5..e63afdef0 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -262,19 +262,6 @@ hb_paint_push_group_func_t hb_paint_funcs_set_push_group_func hb_paint_pop_group_func_t hb_paint_funcs_set_pop_group_func - -hb_paint_push_transform -hb_paint_pop_transform -hb_paint_push_clip_glyph -hb_paint_push_clip_rectangle -hb_paint_pop_clip -hb_paint_color -hb_paint_image -hb_paint_linear_gradient -hb_paint_radial_gradient -hb_paint_sweep_gradient -hb_paint_push_group -hb_paint_pop_group
diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 75215ac48..72af14092 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -372,241 +372,4 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) return hb_object_is_immutable (funcs); } -/** - * hb_paint_push_transform: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @xx: xx component of the transform matrix - * @yx: yx component of the transform matrix - * @xy: xy component of the transform matrix - * @yy: yy component of the transform matrix - * @dx: dx component of the transform matrix - * @dy: dy component of the transform matrix - * - * Perform a "push-transform" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, - float xx, float yx, - float xy, float yy, - float dx, float dy) -{ - funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); -} - -/** - * hb_paint_pop_transform: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * - * Perform a "pop-transform" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) -{ - funcs->pop_transform (paint_data); -} - -/** - * hb_paint_push_clip_glyph: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @glyph: the glyph ID - * @font: the font - * - * Perform a "push-clip-glyph" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph, - hb_font_t *font) -{ - funcs->push_clip_glyph (paint_data, glyph, font); -} - -/** - * hb_paint_push_clip_rectangle: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @xmin: min X for the rectangle - * @ymin: min Y for the rectangle - * @xmax: max X for the rectangle - * @ymax: max Y for the rectangle - * - * Perform a "push-clip-rect" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, float xmax, float ymax) -{ - funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax); -} - -/** - * hb_paint_pop_clip: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * - * Perform a "pop-clip" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) -{ - funcs->pop_clip (paint_data); -} - -/** - * hb_paint_color: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @color: The color to use - * - * Perform a "color" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_t color) -{ - funcs->color (paint_data, color); -} - -/** - * hb_paint_image: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @image: image data - * @format: tag describing the image data format - * @extents: (nullable): the extents of the glyph - * - * Perform a "image" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, - hb_blob_t *image, - hb_tag_t format, - hb_glyph_extents_t *extents) -{ - funcs->image (paint_data, image, format, extents); -} - -/** - * hb_paint_linear_gradient: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @color_line: Color information for the gradient - * @x0: X coordinate of the first point - * @y0: Y coordinate of the first point - * @x1: X coordinate of the second point - * @y1: Y coordinate of the second point - * @x2: X coordinate of the third point - * @y2: Y coordinate of the third point - * - * Perform a "linear-gradient" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float x1, float y1, - float x2, float y2) -{ - funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); -} - -/** - * hb_paint_radial_gradient: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @color_line: Color information for the gradient - * @x0: X coordinate of the first circle's center - * @y0: Y coordinate of the first circle's center - * @r0: radius of the first circle - * @x1: X coordinate of the second circle's center - * @y1: Y coordinate of the second circle's center - * @r1: radius of the second circle - * - * Perform a "radial-gradient" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, float r0, - float x1, float y1, float r1) -{ - funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); -} - -/** - * hb_paint_sweep_gradient: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @color_line: Color information for the gradient - * @x0: X coordinate of the circle's center - * @y0: Y coordinate of the circle's center - * @start_angle: the start angle - * @end_angle: the end angle - * - * Perform a "sweep-gradient" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float start_angle, float end_angle) -{ - funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); -} - -/** - * hb_paint_push_group: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * - * Perform a "push-group" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) -{ - funcs->push_group (paint_data); -} - -/** - * hb_paint_pop_group: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @mode: the compositing mode to use - * - * Perform a "pop-group" paint operation. - * - * Since: REPLACEME - */ -void -hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode) -{ - funcs->pop_group (paint_data, mode); -} - #endif diff --git a/src/hb-paint.h b/src/hb-paint.h index 4779d5f1a..11616006d 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -698,65 +698,6 @@ hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs, void *user_data, hb_destroy_func_t destroy); -HB_EXTERN void -hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, - float xx, float yx, - float xy, float yy, - float dx, float dy); - -HB_EXTERN void -hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); - -HB_EXTERN void -hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, - hb_codepoint_t glyph, - hb_font_t *font); - -HB_EXTERN void -hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, - float xmin, float ymin, - float xmax, float ymax); - -HB_EXTERN void -hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); - -HB_EXTERN void -hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_t color); - -HB_EXTERN void -hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, - hb_blob_t *image, - hb_tag_t format, - hb_glyph_extents_t *extents); - -HB_EXTERN void -hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float x1, float y1, - float x2, float y2); - -HB_EXTERN void -hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float r0, - float x1, float y1, - float r1); - -HB_EXTERN void -hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float start_angle, float end_angle); - -HB_EXTERN void -hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data); - -HB_EXTERN void -hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, - hb_paint_composite_mode_t mode); HB_END_DECLS From c221933977bdcf272fd9f2ded5e1182de8ae1939 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 21 Dec 2022 18:39:27 -0500 Subject: [PATCH 132/219] [paint] Preserve foreground information --- src/OT/glyf/glyf.hh | 2 +- src/hb-ot-cff1-table.cc | 2 +- src/hb-ot-cff2-table.cc | 2 +- src/hb-ot-color-colr-table.hh | 23 +++++++++++++++++------ src/hb-paint.cc | 1 + src/hb-paint.h | 4 ++++ src/hb-paint.hh | 3 ++- test/api/test-ot-color.c | 1 + util/helper-cairo-user.hh | 1 + 9 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index 39ce65608..0923814d0 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -338,7 +338,7 @@ struct glyf_accelerator_t funcs->push_root_transform (data, font); funcs->push_clip_glyph (data, gid, font); - funcs->color (data, foreground); + funcs->color (data, true, foreground); funcs->pop_clip (data); funcs->pop_root_transform (data); diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index b00441fe5..da403c366 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -558,7 +558,7 @@ bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph funcs->push_root_transform (data, font); funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, foreground); + funcs->color (data, true, foreground); funcs->pop_clip (data); funcs->pop_root_transform (data); diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 6bbd5383a..6fb43cf63 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -148,7 +148,7 @@ bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph funcs->push_root_transform (data, font); funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, foreground); + funcs->color (data, true, foreground); funcs->pop_clip (data); funcs->pop_root_transform (data); diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index d5f233df7..e3893f91c 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -97,16 +97,19 @@ public: instancer (instancer_) { } - hb_color_t get_color (unsigned int color_index, float alpha) + hb_color_t get_color (unsigned int color_index, float alpha, hb_bool_t *is_foreground) { hb_color_t color = foreground; + *is_foreground = true; + if (color_index != 0xffff) { unsigned int clen = 1; hb_face_t *face = hb_font_get_face (font); hb_ot_color_palette_get_colors (face, palette, color_index, &clen, &color); + *is_foreground = false; } return HB_COLOR (hb_color_get_blue (color), @@ -360,7 +363,9 @@ struct ColorStop const VarStoreInstancer &instancer) const { out->offset = stopOffset.to_float(instancer (varIdx, 0)); - out->color = c->get_color (paletteIndex, alpha.to_float (instancer (varIdx, 1))); + out->color = c->get_color (paletteIndex, + alpha.to_float (instancer (varIdx, 1)), + &out->is_foreground); } F2DOT14 stopOffset; @@ -576,9 +581,13 @@ struct PaintSolid void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - c->funcs->color (c->data, - c->get_color (paletteIndex, - alpha.to_float (c->instancer (varIdxBase, 0)))); + hb_bool_t is_foreground; + hb_color_t color; + + color = c->get_color (paletteIndex, + alpha.to_float (c->instancer (varIdxBase, 0)), + &is_foreground); + c->funcs->color (c->data, is_foreground, color); } HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ @@ -1992,8 +2001,10 @@ struct COLR for (const auto &r : (this+layersZ).as_array (numLayers) .sub_array (record->firstLayerIdx, record->numLayers)) { + hb_bool_t is_foreground; + hb_color_t color = c.get_color (r.colorIdx, 1., &is_foreground); c.funcs->push_clip_glyph (c.data, r.glyphId, c.font); - c.funcs->color (c.data, c.get_color (r.colorIdx, 1.)); + c.funcs->color (c.data, is_foreground, color); c.funcs->pop_clip (c.data); } diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 72af14092..f59266f8a 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -70,6 +70,7 @@ hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, static void hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_bool_t is_foreground, hb_color_t color, void *user_data) {} diff --git a/src/hb-paint.h b/src/hb-paint.h index 11616006d..af36e36a0 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -209,6 +209,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * hb_paint_color_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @is_foreground: whether the color is the foreground * @color: The color to use * @user_data: User data pointer passed to hb_paint_funcs_set_color_func() * @@ -219,6 +220,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, */ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, void *paint_data, + hb_bool_t is_foreground, hb_color_t color, void *user_data); @@ -277,6 +279,7 @@ typedef struct hb_color_line_t hb_color_line_t; /** * hb_color_stop_t: * @offset: the offset of the color stop + * @is_foreground: whether the color is the foreground * @color: the color * * Information about a color stop on a color line. @@ -288,6 +291,7 @@ typedef struct hb_color_line_t hb_color_line_t; */ typedef struct { float offset; + hb_bool_t is_foreground; hb_color_t color; } hb_color_stop_t; diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 29bce0536..401c3016e 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -92,9 +92,10 @@ struct hb_paint_funcs_t { func.pop_clip (this, paint_data, !user_data ? nullptr : user_data->pop_clip); } void color (void *paint_data, + hb_bool_t is_foreground, hb_color_t color) { func.color (this, paint_data, - color, + is_foreground, color, !user_data ? nullptr : user_data->color); } void image (void *paint_data, hb_blob_t *image, diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index a317f46fa..604efbabb 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -542,6 +542,7 @@ pop_clip (hb_paint_funcs_t *funcs, static void paint_color (hb_paint_funcs_t *funcs, void *paint_data, + hb_bool_t use_foreground, hb_color_t color, void *user_data) { diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 57b365b3c..d7edea2c6 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -203,6 +203,7 @@ pop_group (hb_paint_funcs_t *funcs, static void paint_color (hb_paint_funcs_t *funcs, void *paint_data, + hb_bool_t use_foreground, hb_color_t color, void *user_data) { From 237955dffca19bc320ca1b94808b52265ef653ed Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 08:12:47 -0700 Subject: [PATCH 133/219] [paint] Add slant to image() callback And slant images in hb-view. --- src/hb-ot-color-cbdt-table.hh | 2 +- src/hb-ot-color-sbix-table.hh | 2 +- src/hb-ot-color-svg-table.hh | 2 +- src/hb-paint.cc | 1 + src/hb-paint.h | 1 + src/hb-paint.hh | 3 ++- util/hb-cairo-utils.c | 7 +++++++ util/hb-cairo-utils.h | 1 + util/helper-cairo-user.hh | 3 ++- 9 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 63536aa92..beaee108d 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -948,7 +948,7 @@ struct CBDT if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, font->slant_xy, &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index bafb45417..20f2b0444 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -248,7 +248,7 @@ struct sbix if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, &extents); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, font->slant_xy, &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 3967a1196..f9990d44b 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,7 +103,7 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, nullptr); + funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, font->slant_xy, nullptr); hb_blob_destroy (blob); return true; diff --git a/src/hb-paint.cc b/src/hb-paint.cc index f59266f8a..fdce759a1 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -78,6 +78,7 @@ static void hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, + float slant_xy, hb_glyph_extents_t *extents, void *user_data) {} diff --git a/src/hb-paint.h b/src/hb-paint.h index af36e36a0..e78462d72 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -264,6 +264,7 @@ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, hb_tag_t format, + float slant, hb_glyph_extents_t *extents, void *user_data); diff --git a/src/hb-paint.hh b/src/hb-paint.hh index 401c3016e..eaba99bce 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -100,9 +100,10 @@ struct hb_paint_funcs_t void image (void *paint_data, hb_blob_t *image, hb_tag_t format, + float slant, hb_glyph_extents_t *extents) { func.image (this, paint_data, - image, format, extents, + image, format, slant, extents, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 8bfddde70..d40b56458 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -100,6 +100,7 @@ void hb_cairo_paint_glyph_image (cairo_t *cr, hb_blob_t *blob, hb_tag_t format, + float slant, hb_glyph_extents_t *extents) { #ifdef CAIRO_HAS_PNG_FUNCTIONS @@ -119,6 +120,12 @@ hb_cairo_paint_glyph_image (cairo_t *cr, cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; cairo_pattern_set_matrix (pattern, &matrix); + /* Undo slant in the extents and apply it in the context. */ + extents->width -= extents->height * slant; + extents->x_bearing -= extents->y_bearing * slant; + cairo_matrix_t cairo_matrix = {1., 0., slant, 1., 0., 0.}; + cairo_transform (cr, &cairo_matrix); + cairo_translate (cr, extents->x_bearing, extents->y_bearing); cairo_scale (cr, extents->width, extents->height); cairo_set_source (cr, pattern); diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index 39cfa3ec4..fdc9de884 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -73,6 +73,7 @@ hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) void hb_cairo_paint_glyph_image (cairo_t *cr, hb_blob_t *blob, hb_tag_t format, + float slant, hb_glyph_extents_t *extents); void hb_cairo_paint_linear_gradient (cairo_t *cr, diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index d7edea2c6..8ad970a0b 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -222,12 +222,13 @@ paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *blob, hb_tag_t format, + float slant, hb_glyph_extents_t *extents, void *user_data) { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_glyph_image (cr, blob, format, extents); + hb_cairo_paint_glyph_image (cr, blob, format, slant, extents); } static void From f3985d948279c00518d5f3dea925a71a8e2be23f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 10:11:28 -0700 Subject: [PATCH 134/219] [paint] Fix drawing non-color glyphs --- src/OT/glyf/glyf.hh | 6 +----- src/hb-ot-cff1-table.cc | 6 +----- src/hb-ot-cff2-table.cc | 6 +----- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh index 0923814d0..58af9ead5 100644 --- a/src/OT/glyf/glyf.hh +++ b/src/OT/glyf/glyf.hh @@ -335,15 +335,11 @@ struct glyf_accelerator_t bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - funcs->push_root_transform (data, font); - funcs->push_clip_glyph (data, gid, font); funcs->color (data, true, foreground); funcs->pop_clip (data); - funcs->pop_root_transform (data); - - return false; + return true; } const glyf_impl::Glyph diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index da403c366..5040c7462 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -555,15 +555,11 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - funcs->push_root_transform (data, font); - funcs->push_clip_glyph (data, glyph, font); funcs->color (data, true, foreground); funcs->pop_clip (data); - funcs->pop_root_transform (data); - - return false; + return true; } bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 6fb43cf63..795556555 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -145,15 +145,11 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const { - funcs->push_root_transform (data, font); - funcs->push_clip_glyph (data, glyph, font); funcs->color (data, true, foreground); funcs->pop_clip (data); - funcs->pop_root_transform (data); - - return false; + return true; } struct cff2_path_param_t From c27eefec1df85d1648106c3d0ae7d2e740c5cedc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 10:41:13 -0700 Subject: [PATCH 135/219] Revert "Drop the deprecation" This reverts commit 3904e66777339a3d420ece1c2b7d550949aa3946. --- src/hb-font.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hb-font.h b/src/hb-font.h index 1978b57cd..a5859c962 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -497,6 +497,8 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * Since: 4.0.0 + * + * Deprecated: REPLACEME: Use #hb_font_draw_glyph_func_t instead **/ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -813,6 +815,8 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, * which is the same as #hb_font_draw_glyph_func_t. * * Since: 4.0.0 + * + * Deprecated: REPLACEME: Use hb_font_set_draw_glyph_func() instead **/ HB_EXTERN void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, From 91c880503e7b194c9fc15cfe43eae4c70b1b19f9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 10:42:27 -0700 Subject: [PATCH 136/219] [ft] Use new name for draw API --- src/hb-ft.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 097c52f7f..956e6c339 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -777,11 +777,11 @@ _hb_ft_cubic_to (const FT_Vector *control1, } static void -hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data HB_UNUSED) +hb_ft_draw_glyph (hb_font_t *font HB_UNUSED, + void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); @@ -844,7 +844,7 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t Date: Thu, 22 Dec 2022 10:51:26 -0700 Subject: [PATCH 137/219] [ft] Implement paint_glyph() for outline glyphs --- src/hb-ft.cc | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 956e6c339..8b297d898 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -33,12 +33,13 @@ #include "hb-ft.h" +#include "hb-cache.hh" #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" -#include "hb-cache.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-shaper-arabic-pua.hh" +#include "hb-paint.hh" #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H @@ -811,6 +812,45 @@ hb_ft_draw_glyph (hb_font_t *font HB_UNUSED, } #endif +#ifndef HB_NO_PAINT +static void +hb_ft_paint_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t gid, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) +{ + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + + FT_Glyph_Format format; + /* Release lock before calling into callbacks, such that + * eg. draw API can call back into the face.*/ + { + + hb_lock_t lock (ft_font->lock); + FT_Face ft_face = ft_font->ft_face; + + if (unlikely (FT_Load_Glyph (ft_face, gid, ft_font->load_flags))) + return; + + format = ft_face->glyph->format; + } + + if (format == FT_GLYPH_FORMAT_OUTLINE) + { + paint_funcs->push_clip_glyph (paint_data, gid, font); + paint_funcs->color (paint_data, true, foreground); + paint_funcs->pop_clip (paint_data); + + return; + } + + /* TODO Support image, COLRv0/1. */ +} +#endif + static inline void free_static_ft_funcs (); @@ -847,6 +887,10 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t Date: Thu, 22 Dec 2022 11:26:10 -0700 Subject: [PATCH 138/219] [ft] Paint COLRv0 glyphs --- src/hb-ft.cc | 73 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 8b297d898..e3e9eaec8 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -45,6 +45,7 @@ #include FT_MULTIPLE_MASTERS_H #include FT_OUTLINE_H #include FT_TRUETYPE_TABLES_H +#include FT_COLOR_H /** @@ -818,31 +819,81 @@ hb_ft_paint_glyph (hb_font_t *font, void *font_data, hb_codepoint_t gid, hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette, + unsigned int palette_index, hb_color_t foreground, void *user_data) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); + FT_Face ft_face = ft_font->ft_face; - FT_Glyph_Format format; - /* Release lock before calling into callbacks, such that + /* We release the lock before calling into callbacks, such that * eg. draw API can call back into the face.*/ + + if (unlikely (FT_Load_Glyph (ft_face, gid, ft_font->load_flags))) + return; + + if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { + /* COLRv0 */ + { + FT_Error error; + FT_Color* palette; + FT_LayerIterator iterator; - hb_lock_t lock (ft_font->lock); - FT_Face ft_face = ft_font->ft_face; + FT_Bool have_layers; + FT_UInt layer_glyph_index; + FT_UInt layer_color_index; - if (unlikely (FT_Load_Glyph (ft_face, gid, ft_font->load_flags))) - return; + error = FT_Palette_Select(ft_face, palette_index, &palette); + if ( error ) + palette = NULL; - format = ft_face->glyph->format; - } + iterator.p = NULL; + have_layers = FT_Get_Color_Glyph_Layer(ft_face, + gid, + &layer_glyph_index, + &layer_color_index, + &iterator); - if (format == FT_GLYPH_FORMAT_OUTLINE) - { + if (palette && have_layers) + { + do + { + hb_bool_t is_foreground = true; + hb_color_t color = foreground; + + if ( layer_color_index != 0xFFFF ) + { + FT_Color layer_color = palette[layer_color_index]; + color = HB_COLOR (layer_color.blue, + layer_color.green, + layer_color.red, + layer_color.alpha); + is_foreground = false; + } + + ft_font->lock.unlock (); + paint_funcs->push_clip_glyph (paint_data, layer_glyph_index, font); + paint_funcs->color (paint_data, is_foreground, color); + paint_funcs->pop_clip (paint_data); + ft_font->lock.lock (); + + } while (FT_Get_Color_Glyph_Layer(ft_face, + gid, + &layer_glyph_index, + &layer_color_index, + &iterator)); + return; + } + } + + /* Simple outline. */ + ft_font->lock.unlock (); paint_funcs->push_clip_glyph (paint_data, gid, font); paint_funcs->color (paint_data, true, foreground); paint_funcs->pop_clip (paint_data); + ft_font->lock.lock (); return; } From 3c972867b97a0fbca5bef25ebfd7cbdab008a102 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 11:40:06 -0700 Subject: [PATCH 139/219] More s/hb_font_get_glyph_shape/hb_font_draw_glyph/ --- perf/benchmark-font.cc | 2 +- src/hb-draw.h | 10 ++-- test/api/test-draw.c | 88 +++++++++++++++++----------------- test/fuzzing/hb-draw-fuzzer.cc | 2 +- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/perf/benchmark-font.cc b/perf/benchmark-font.cc index 98b6310d2..4688d6923 100644 --- a/perf/benchmark-font.cc +++ b/perf/benchmark-font.cc @@ -163,7 +163,7 @@ static void BM_Font (benchmark::State &state, hb_draw_funcs_t *draw_funcs = _draw_funcs_create (); for (auto _ : state) for (unsigned gid = 0; gid < num_glyphs; ++gid) - hb_font_get_glyph_shape (font, gid, draw_funcs, nullptr); + hb_font_draw_glyph (font, gid, draw_funcs, nullptr); break; hb_draw_funcs_destroy (draw_funcs); } diff --git a/src/hb-draw.h b/src/hb-draw.h index 47bb45d87..9ca0b4006 100644 --- a/src/hb-draw.h +++ b/src/hb-draw.h @@ -92,7 +92,7 @@ typedef struct hb_draw_funcs_t hb_draw_funcs_t; /** * hb_draw_move_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions in hb_font_get_glyph_shape() + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @to_x: X component of target point * @to_y: Y component of target point @@ -112,7 +112,7 @@ typedef void (*hb_draw_move_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data /** * hb_draw_line_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions in hb_font_get_glyph_shape() + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @to_x: X component of target point * @to_y: Y component of target point @@ -132,7 +132,7 @@ typedef void (*hb_draw_line_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data /** * hb_draw_quadratic_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions in hb_font_get_glyph_shape() + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @control_x: X component of control point * @control_y: Y component of control point @@ -155,7 +155,7 @@ typedef void (*hb_draw_quadratic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw /** * hb_draw_cubic_to_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions in hb_font_get_glyph_shape() + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @control1_x: X component of first control point * @control1_y: Y component of first control point @@ -181,7 +181,7 @@ typedef void (*hb_draw_cubic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_dat /** * hb_draw_close_path_func_t: * @dfuncs: draw functions object - * @draw_data: The data accompanying the draw functions in hb_font_get_glyph_shape() + * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph() * @st: current draw state * @user_data: User data pointer passed to hb_draw_funcs_set_close_path_func() * diff --git a/test/api/test-draw.c b/test/api/test-draw.c index 32c8e5618..ad1fd1944 100644 --- a/test/api/test-draw.c +++ b/test/api/test-draw.c @@ -182,7 +182,7 @@ static hb_draw_funcs_t *funcs2; /* this one translates quadratic calls to cubic static void test_hb_draw_empty (void) { - hb_font_get_glyph_shape (hb_font_get_empty (), 3, funcs, NULL); + hb_font_draw_glyph (hb_font_get_empty (), 3, funcs, NULL); } static void @@ -200,10 +200,10 @@ test_hb_draw_glyf (void) }; draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 4, funcs, &draw_data); + hb_font_draw_glyph (font, 4, funcs, &draw_data); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 3, funcs, &draw_data); + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected[] = "M275,442Q232,442 198,420Q164,397 145,353Q126,309 126,245" "Q126,182 147,139Q167,95 204,73Q240,50 287,50Q330,50 367,70" "Q404,90 427,128L451,116Q431,54 384,21Q336,-13 266,-13" @@ -215,7 +215,7 @@ test_hb_draw_glyf (void) /* Test translating quadratic calls to cubic by a _draw_funcs_t that doesn't set the callback */ draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 3, funcs2, &draw_data); + hb_font_draw_glyph (font, 3, funcs2, &draw_data); char expected2[] = "M275,442C246,442 221,435 198,420C175,405 158,382 145,353" "C132,324 126,288 126,245C126,203 133,168 147,139C160,110 179,88 204,73" "C228,58 256,50 287,50C316,50 342,57 367,70C392,83 412,103 427,128" @@ -233,7 +233,7 @@ test_hb_draw_glyf (void) hb_font_set_variations (font, &var, 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 3, funcs, &draw_data); + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected3[] = "M323,448Q297,448 271,430Q244,412 226,371Q209,330 209,261" "Q209,204 225,166Q242,127 272,107Q303,86 344,86Q378,86 404,101" "Q430,115 451,137L488,103Q458,42 404,13Q350,-16 279,-16" @@ -259,7 +259,7 @@ test_hb_draw_cff1 (void) .size = sizeof (str), .consumed = 0 }; - hb_font_get_glyph_shape (font, 3, funcs, &draw_data); + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367L369,267L172,267L203,367Z" "M3,0L88,0L151,200L390,200L452,0L541,0L319,656L225,656L3,0Z" "M300,653L342,694L201,861L143,806L300,653Z"; @@ -282,7 +282,7 @@ test_hb_draw_cff1_rline (void) .size = sizeof (str), .consumed = 0 }; - hb_font_get_glyph_shape (font, 1, funcs, &draw_data); + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M775,400C705,400 650,343 650,274L650,250L391,250L713,572L392,893" "L287,1000C311,942 296,869 250,823C250,823 286,858 321,823L571,572" "L150,150L750,150L750,276C750,289 761,300 775,300C789,300 800,289 800,276" @@ -307,7 +307,7 @@ test_hb_draw_cff2 (void) }; draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 3, funcs, &draw_data); + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected[] = "M275,442C303,442 337,435 371,417L325,454L350,366" "C357,341 370,321 403,321C428,321 443,333 448,358" "C435,432 361,487 272,487C153,487 43,393 43,236" @@ -321,7 +321,7 @@ test_hb_draw_cff2 (void) hb_font_set_variations (font, &var, 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 3, funcs, &draw_data); + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected2[] = "M323,448C356,448 380,441 411,427L333,469L339,401" "C343,322 379,297 420,297C458,297 480,314 492,352" "C486,433 412,501 303,501C148,501 25,406 25,241" @@ -347,19 +347,19 @@ test_hb_draw_ttf_parser_tests (void) hb_face_destroy (face); { draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 0, funcs, &draw_data); + hb_font_draw_glyph (font, 0, funcs, &draw_data); char expected[] = "M50,0L50,750L450,750L450,0L50,0Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 1, funcs, &draw_data); + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M56,416L56,487L514,487L514,416L56,416ZM56,217L56,288L514,288L514,217L56,217Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 4, funcs, &draw_data); + hb_font_draw_glyph (font, 4, funcs, &draw_data); char expected[] = "M332,468L197,468L197,0L109,0L109,468L15,468L15,509L109,539" "L109,570Q109,674 155,720Q201,765 283,765Q315,765 342,760" "Q368,754 387,747L364,678Q348,683 327,688Q306,693 284,693" @@ -371,13 +371,13 @@ test_hb_draw_ttf_parser_tests (void) } { draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 5, funcs, &draw_data); + hb_font_draw_glyph (font, 5, funcs, &draw_data); char expected[] = "M15,0Q15,0 15,0Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 6, funcs, &draw_data); + hb_font_draw_glyph (font, 6, funcs, &draw_data); char expected[] = "M346,468L211,468L211,0L123,0L123,468L29,468L29,509L123,539" "L123,570Q123,674 169,720Q215,765 297,765Q329,765 356,760" "Q382,754 401,747L378,678Q362,683 341,688Q320,693 298,693" @@ -394,7 +394,7 @@ test_hb_draw_ttf_parser_tests (void) hb_face_destroy (face); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 1, funcs, &draw_data); + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M0,0C100,0 150,-20 250,-20C350,-20 400,0 500,0C500,100 520,150 520,250" "C520,350 500,400 500,500C400,500 350,520 250,520C150,520 100,500 0,500" "C0,400 -20,350 -20,250C-20,150 0,100 0,0ZM50,50C50,130 34,170 34,250" @@ -411,7 +411,7 @@ test_hb_draw_ttf_parser_tests (void) hb_face_destroy (face); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 1, funcs, &draw_data); + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M82,0L164,0L164,486L82,486L82,0Z" "M124,586C156,586 181,608 181,639C181,671 156,692 124,692" "C92,692 67,671 67,639C67,608 92,586 124,586Z"; @@ -438,7 +438,7 @@ test_hb_draw_font_kit_glyphs_tests (void) /* should get a path for the glyph */ draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 37, funcs, &draw_data); + hb_font_draw_glyph (font, 37, funcs, &draw_data); char expected[] = "M201,1462L614,1462Q905,1462 1035,1375Q1165,1288 1165,1100" "Q1165,970 1093,886Q1020,801 881,776L881,766Q1214,709 1214,416" "Q1214,220 1082,110Q949,0 711,0L201,0L201,1462ZM371,836L651,836" @@ -449,7 +449,7 @@ test_hb_draw_font_kit_glyphs_tests (void) /* should get a path for the glyph */ draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 171, funcs, &draw_data); + hb_font_draw_glyph (font, 171, funcs, &draw_data); char expected2[] = "M639,-20Q396,-20 256,128Q115,276 115,539Q115,804 246,960Q376,1116 596,1116" "Q802,1116 922,981Q1042,845 1042,623L1042,518L287,518Q292,325 385,225" "Q477,125 645,125Q822,125 995,199L995,51Q907,13 829,-3Q750,-20 639,-20Z" @@ -475,7 +475,7 @@ test_hb_draw_font_kit_glyphs_tests (void) /* should resolve composite glyphs recursively */ draw_data.consumed = 0; - hb_font_get_glyph_shape (font, codepoint, funcs, &draw_data); + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M581,274L443,274Q409,274 384,259Q359,243 348,219Q336,194 340,166" "Q343,138 365,111L468,-13Q470,-10 473,-6Q475,-3 477,0L253,0Q225,0 203,8" "Q180,15 168,32Q155,48 155,73L155,269L50,269L50,73Q50,24 69,-10" @@ -491,7 +491,7 @@ test_hb_draw_font_kit_glyphs_tests (void) /* should transform points of a composite glyph */ draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 2, funcs, &draw_data); /* 2 == arAlef.fina */ + hb_font_draw_glyph (font, 2, funcs, &draw_data); /* 2 == arAlef.fina */ char expected2[] = "M155,624L155,84Q150,90 146,95Q141,99 136,105" "L292,105L292,0L156,0Q128,0 104,14Q79,27 65,51" "Q50,74 50,104L50,624L155,624ZM282,105L312,105" @@ -507,7 +507,7 @@ test_hb_draw_font_kit_glyphs_tests (void) hb_face_destroy (face); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 5, funcs, &draw_data); + hb_font_draw_glyph (font, 5, funcs, &draw_data); char expected[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656L90,0Z" "M173,68L173,588L248,588C401,588 478,496 478,331C478,165 401,68 248,68L173,68Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); @@ -522,7 +522,7 @@ test_hb_draw_font_kit_glyphs_tests (void) hb_face_destroy (face); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 1, funcs, &draw_data); + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M139,390C175,390 205,419 205,459C205,501 175,530 139,530C103,530 73,501 73,459" "C73,419 103,390 139,390ZM139,-13C175,-13 205,15 205,56C205,97 175,127 139,127" "C103,127 73,97 73,56C73,15 103,-13 139,-13Z"; @@ -567,7 +567,7 @@ test_hb_draw_font_kit_variations_tests (void) hb_buffer_destroy (buffer); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, codepoint, funcs, &draw_data); + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102" "Q796,-102 755,-98L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504" "L414,504L414,-102L371,-102ZM203,-94Q138,-94 86,-90L74,-52" @@ -612,7 +612,7 @@ test_hb_draw_font_kit_variations_tests (void) hb_buffer_destroy (buffer); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, codepoint, funcs, &draw_data); + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102Q796,-102 755,-98" "L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504L414,504L414,-102" "L371,-102ZM203,-94Q138,-94 86,-90L74,-52Q137,-59 188,-59Q211,-59 222,-46" @@ -656,7 +656,7 @@ test_hb_draw_font_kit_variations_tests (void) hb_buffer_destroy (buffer); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, codepoint, funcs, &draw_data); + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102Q796,-102 755,-98" "L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504L414,504L414,-102" "L371,-102ZM203,-94Q138,-94 86,-90L74,-52Q137,-59 188,-59Q211,-59 222,-46" @@ -703,7 +703,7 @@ test_hb_draw_font_kit_variations_tests (void) hb_buffer_destroy (buffer); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, codepoint, funcs, &draw_data); + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M246,15C188,15 147,27 101,68L142,23L117,117C111,143 96,149 81,149" "C65,149 56,141 52,126C71,40 137,-13 244,-13C348,-13 436,46 436,156" "C436,229 405,295 271,349L247,359C160,393 119,439 119,506" @@ -727,7 +727,7 @@ test_hb_draw_font_kit_variations_tests (void) hb_buffer_destroy (buffer); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, codepoint, funcs, &draw_data); + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M251,36C206,36 165,42 118,61L176,21L161,99C151,152 129,167 101,167" "C78,167 61,155 51,131C54,43 133,-14 247,-14C388,-14 474,64 474,171" "C474,258 430,321 294,370L257,383C188,406 150,438 150,499" @@ -752,7 +752,7 @@ test_hb_draw_font_kit_variations_tests (void) hb_buffer_destroy (buffer); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, codepoint, funcs, &draw_data); + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M258,38C197,38 167,48 118,71L192,19L183,103C177,155 155,174 115,174" "C89,174 64,161 51,125C52,36 124,-16 258,-16C417,-16 513,67 513,175" "C513,278 457,328 322,388L289,403C232,429 203,452 203,500C203,562 244,589 301,589" @@ -787,7 +787,7 @@ test_hb_draw_estedad_vf (void) hb_font_set_variations (font, &var, 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 156, funcs, &draw_data); + hb_font_draw_glyph (font, 156, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected[] = "M150,1158L182,1158Q256,1158 317,1170Q377,1182 421,1213L421,430L521,430" "L521,1490L421,1490L421,1320Q393,1279 344,1262Q294,1244 182,1244L150,1244" @@ -797,7 +797,7 @@ test_hb_draw_estedad_vf (void) g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 180, funcs, &draw_data); + hb_font_draw_glyph (font, 180, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected2[] = "M120,693Q120,545 177,414Q233,282 333,182Q433,81 567,24" "Q701,-33 856,-33Q1010,-33 1144,24Q1277,81 1377,182Q1477,282 1534,414" @@ -817,7 +817,7 @@ test_hb_draw_estedad_vf (void) g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 262, funcs, &draw_data); + hb_font_draw_glyph (font, 262, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected3[] = "M422,598Q495,598 545,548Q595,498 595,426Q595,353 545,303Q494,252 422,252" "Q350,252 300,303Q250,353 250,426Q250,499 300,549Q349,598 422,598ZM422,698" @@ -847,7 +847,7 @@ test_hb_draw_stroking (void) hb_face_destroy (face); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 6, funcs, &draw_data); + hb_font_draw_glyph (font, 6, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected[] = "M436,1522Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427Q1384,332 1626,332" "Q1868,332 2089,427Q2309,521 2468,680Q2627,839 2722,1060Q2816,1280 2816,1522" @@ -862,7 +862,7 @@ test_hb_draw_stroking (void) g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 7, funcs, &draw_data); + hb_font_draw_glyph (font, 7, funcs, &draw_data); char expected2[] = "M436,1522Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427" "Q1384,332 1626,332Q1868,332 2089,427Q2309,521 2468,680" "Q2627,839 2722,1060Q2816,1280 2816,1522Q2816,1764 2722,1985" @@ -888,14 +888,14 @@ test_hb_draw_stroking (void) hb_face_destroy (face); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 4, funcs, &draw_data); + hb_font_draw_glyph (font, 4, funcs, &draw_data); /* Skip empty path in CFF */ char expected[] = "M106,372C106,532 237,662 397,662C557,662 688,532 688,372C688,212 557,81 397,81C237,81 106,212 106,372Z" "M62,373C62,188 212,39 397,39C582,39 731,188 731,373C731,558 582,708 397,708C212,708 62,558 62,373Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 5, funcs, &draw_data); + hb_font_draw_glyph (font, 5, funcs, &draw_data); /* Fold consequent move-to commands */ char expected2[] = "M106,372C106,532 237,662 397,662C557,662 688,532 688,372" "C688,212 557,81 397,81C237,81 106,212 106,372ZM62,373" @@ -970,7 +970,7 @@ test_hb_draw_synthetic_slant (void) hb_font_set_synthetic_slant (font, 0.2f); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 37, funcs, &draw_data); + hb_font_draw_glyph (font, 37, funcs, &draw_data); char expected[] = "M493,1462L906,1462Q1197,1462 1310,1375Q1423,1288 1385,1100" "Q1359,970 1270,886Q1180,801 1036,776L1034,766Q1356,709 1297,416" "Q1258,220 1104,110Q949,0 711,0L201,0L493,1462ZM538,836L818,836" @@ -988,7 +988,7 @@ test_hb_draw_synthetic_slant (void) hb_font_set_synthetic_slant (font, 0.2f); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 5, funcs, &draw_data); + hb_font_draw_glyph (font, 5, funcs, &draw_data); char expected[] = "M90,0L258,0C456,0 588,122 630,331C672,539 587,656 385,656L221,656L90,0Z" "M187,68L291,588L366,588C519,588 577,496 544,331C511,165 415,68 262,68L187,68Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); @@ -1015,7 +1015,7 @@ test_hb_draw_subfont_scale (void) hb_font_set_scale (font2, x*2, y*2); draw_data.consumed = 0; - hb_font_get_glyph_shape (font1, 37, funcs, &draw_data); + hb_font_draw_glyph (font1, 37, funcs, &draw_data); char expected1[] = "M201,1462L614,1462Q905,1462 1035,1375Q1165,1288 1165,1100" "Q1165,970 1093,886Q1020,801 881,776L881,766Q1214,709 1214,416" "Q1214,220 1082,110Q949,0 711,0L201,0L201,1462ZM371,836L651,836" @@ -1025,7 +1025,7 @@ test_hb_draw_subfont_scale (void) g_assert_cmpmem (str, draw_data.consumed, expected1, sizeof (expected1) - 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font2, 37, funcs, &draw_data); + hb_font_draw_glyph (font2, 37, funcs, &draw_data); char expected2[] = "M402,2924L1228,2924Q1810,2924 2070,2750Q2330,2576 2330,2200" "Q2330,1940 2185,1771Q2040,1602 1762,1552L1762,1532Q2428,1418 2428,832" "Q2428,440 2163,220Q1898,0 1422,0L402,0L402,2924ZM742,1672L1302,1672" @@ -1047,13 +1047,13 @@ test_hb_draw_subfont_scale (void) hb_font_set_scale (font2, x*2, y*2); draw_data.consumed = 0; - hb_font_get_glyph_shape (font1, 5, funcs, &draw_data); + hb_font_draw_glyph (font1, 5, funcs, &draw_data); char expected1[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656L90,0Z" "M173,68L173,588L248,588C401,588 478,496 478,331C478,165 401,68 248,68L173,68Z"; g_assert_cmpmem (str, draw_data.consumed, expected1, sizeof (expected1) - 1); draw_data.consumed = 0; - hb_font_get_glyph_shape (font2, 5, funcs, &draw_data); + hb_font_draw_glyph (font2, 5, funcs, &draw_data); char expected2[] = "M180,0L516,0C912,0 1128,244 1128,662C1128,1078 912,1312 508,1312L180,1312L180,0Z" "M346,136L346,1176L496,1176C802,1176 956,992 956,662C956,330 802,136 496,136L346,136Z"; g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); @@ -1089,13 +1089,13 @@ static void test_hb_draw_ft (void) hb_face_destroy (face); { draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 0, funcs, &draw_data); + hb_font_draw_glyph (font, 0, funcs, &draw_data); char expected[] = "M50,0L50,750L450,750L450,0L50,0Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 5, funcs, &draw_data); + hb_font_draw_glyph (font, 5, funcs, &draw_data); char expected[] = "M15,0Q15,0 15,0Z"; g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } @@ -1108,7 +1108,7 @@ static void test_hb_draw_ft (void) hb_face_destroy (face); draw_data.consumed = 0; - hb_font_get_glyph_shape (font, 1, funcs, &draw_data); + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M0,0C100,0 150,-20 250,-20C350,-20 400,0 500,0C500,100 520,150 520,250" "C520,350 500,400 500,500C400,500 350,520 250,520C150,520 100,500 0,500" "C0,400 -20,350 -20,250C-20,150 0,100 0,0ZM50,50C50,130 34,170 34,250" diff --git a/test/fuzzing/hb-draw-fuzzer.cc b/test/fuzzing/hb-draw-fuzzer.cc index 5c53eb271..782db35b6 100644 --- a/test/fuzzing/hb-draw-fuzzer.cc +++ b/test/fuzzing/hb-draw-fuzzer.cc @@ -151,7 +151,7 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) hb_set_t *set = hb_set_create (); for (unsigned gid = 0; gid < glyph_count; ++gid) { - hb_font_get_glyph_shape (font, gid, funcs, &draw_data); + hb_font_draw_glyph (font, gid, funcs, &draw_data); /* Glyph extents also may practices the similar path, call it now that is related */ hb_glyph_extents_t extents; From eef47f2379a3509a2f306fb3e6207f4541b96b73 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 22 Dec 2022 14:16:02 -0500 Subject: [PATCH 140/219] [paint] Fix the docs --- src/hb-paint.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-paint.h b/src/hb-paint.h index e78462d72..85d35814c 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -244,6 +244,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @image: the image data * @format: the image format as a tag + * @slant: the synthetic slant of the font * @extents: (nullable): glyph extents * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * From c5f903872fdb9d7221acd6910a9c5c5acabf99a9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 12:16:55 -0700 Subject: [PATCH 141/219] [paint] Add bitmap width/height to paint_image callback Such that we can add raw data as well. --- src/hb-ot-color-cbdt-table.hh | 45 ++++++++++++++++++++++------------- src/hb-ot-color-sbix-table.hh | 31 ++++++++++++++---------- src/hb-ot-color-svg-table.hh | 7 +++++- src/hb-paint.cc | 2 ++ src/hb-paint.h | 8 +++++-- src/hb-paint.hh | 3 ++- util/hb-cairo-utils.c | 9 +++++-- util/hb-cairo-utils.h | 2 ++ util/helper-cairo-user.hh | 4 +++- 9 files changed, 75 insertions(+), 36 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index beaee108d..a6b906408 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -81,14 +81,15 @@ struct SmallGlyphMetrics return_trace (c->check_struct (this)); } - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const + void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scale) const { extents->x_bearing = bearingX; extents->y_bearing = bearingY; extents->width = width; extents->height = -static_cast (height); - font->scale_glyph_extents (extents); + if (scale) + font->scale_glyph_extents (extents); } HBUINT8 height; @@ -310,7 +311,7 @@ struct IndexSubtable } } - bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const + bool get_extents (hb_glyph_extents_t *extents HB_UNUSED, bool scale HB_UNUSED) const { switch (u.header.indexFormat) { @@ -507,8 +508,8 @@ struct IndexSubtableRecord return num_missing; } - bool get_extents (hb_glyph_extents_t *extents, const void *base) const - { return (base+offsetToSubtable).get_extents (extents); } + bool get_extents (hb_glyph_extents_t *extents, const void *base, bool scale) const + { return (base+offsetToSubtable).get_extents (extents, scale); } bool get_image_data (unsigned int gid, const void *base, @@ -836,7 +837,7 @@ struct CBDT } bool - get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents, bool scale = true) const { const void *base; const BitmapSizeTable &strike = this->cblc->choose_strike (font); @@ -844,7 +845,7 @@ struct CBDT if (!subtable_record || !strike.ppemX || !strike.ppemY) return false; - if (subtable_record->get_extents (extents, base)) + if (subtable_record->get_extents (extents, base, scale)) return true; unsigned int image_offset = 0, image_length = 0, image_format = 0; @@ -861,26 +862,29 @@ struct CBDT if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) return false; auto &glyphFormat17 = StructAtOffset (this->cbdt, image_offset); - glyphFormat17.glyphMetrics.get_extents (font, extents); + glyphFormat17.glyphMetrics.get_extents (font, extents, scale); break; } case 18: { if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) return false; auto &glyphFormat18 = StructAtOffset (this->cbdt, image_offset); - glyphFormat18.glyphMetrics.get_extents (font, extents); + glyphFormat18.glyphMetrics.get_extents (font, extents, scale); break; } default: return false; /* TODO: Support other image formats. */ } /* Convert to font units. */ - float x_scale = upem / (float) strike.ppemX; - float y_scale = upem / (float) strike.ppemY; - extents->x_bearing = roundf (extents->x_bearing * x_scale); - extents->y_bearing = roundf (extents->y_bearing * y_scale); - extents->width = roundf (extents->width * x_scale); - extents->height = roundf (extents->height * y_scale); + if (scale) + { + float x_scale = upem / (float) strike.ppemX; + float y_scale = upem / (float) strike.ppemY; + extents->x_bearing = roundf (extents->x_bearing * x_scale); + extents->y_bearing = roundf (extents->y_bearing * y_scale); + extents->width = roundf (extents->width * x_scale); + extents->height = roundf (extents->height * y_scale); + } return true; } @@ -940,6 +944,7 @@ struct CBDT bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { hb_glyph_extents_t extents; + hb_glyph_extents_t pixel_extents; hb_blob_t *blob = reference_png (font, glyph); if (unlikely (blob == hb_blob_get_empty ())) @@ -948,7 +953,15 @@ struct CBDT if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, font->slant_xy, &extents); + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) + return false; + + funcs->image (data, + blob, + pixel_extents.width, -pixel_extents.height, + HB_PAINT_IMAGE_FORMAT_PNG, + font->slant_xy, + &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 20f2b0444..10d4b3a85 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -214,10 +214,11 @@ struct sbix bool get_extents (hb_font_t *font, hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const + hb_glyph_extents_t *extents, + bool scale = true) const { /* We only support PNG right now, and following function checks type. */ - return get_png_extents (font, glyph, extents); + return get_png_extents (font, glyph, extents, scale); } hb_blob_t *reference_png (hb_font_t *font, @@ -241,6 +242,7 @@ struct sbix unsigned int strike_ppem = 0; hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); hb_glyph_extents_t extents; + hb_glyph_extents_t pixel_extents; if (blob == hb_blob_get_empty ()) return false; @@ -248,7 +250,15 @@ struct sbix if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, font->slant_xy, &extents); + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) + return false; + + funcs->image (data, + blob, + pixel_extents.width, -pixel_extents.height, + HB_PAINT_IMAGE_FORMAT_PNG, + font->slant_xy, + &extents); hb_blob_destroy (blob); return true; @@ -308,7 +318,8 @@ struct sbix bool get_png_extents (hb_font_t *font, hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const + hb_glyph_extents_t *extents, + bool scale = true) const { /* Following code is safe to call even without data. * But faster to short-circuit. */ @@ -333,7 +344,7 @@ struct sbix extents->height = -1 * png.IHDR.height; /* Convert to font units. */ - if (strike_ppem) + if (strike_ppem && scale) { float scale = font->face->get_upem () / (float) strike_ppem; extents->x_bearing = roundf (extents->x_bearing * scale); @@ -341,15 +352,9 @@ struct sbix extents->width = roundf (extents->width * scale); extents->height = roundf (extents->height * scale); } - else - { - extents->x_bearing = extents->x_bearing; - extents->y_bearing = extents->y_bearing; - extents->width = extents->width; - extents->height = extents->height; - } - font->scale_glyph_extents (extents); + if (scale) + font->scale_glyph_extents (extents); hb_blob_destroy (blob); diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index f9990d44b..042faa384 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,7 +103,12 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, font->slant_xy, nullptr); + funcs->image (data, + blob, + 0, 0, + HB_PAINT_IMAGE_FORMAT_SVG, + font->slant_xy, + nullptr); hb_blob_destroy (blob); return true; diff --git a/src/hb-paint.cc b/src/hb-paint.cc index fdce759a1..a22c3a25b 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -77,6 +77,8 @@ hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, static void hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, + unsigned int width, + unsigned int height, hb_tag_t format, float slant_xy, hb_glyph_extents_t *extents, diff --git a/src/hb-paint.h b/src/hb-paint.h index 85d35814c..c695891a0 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -243,9 +243,11 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @image: the image data + * @width: width of the raster image in pixels + * @height: height of the raster image in pixels * @format: the image format as a tag - * @slant: the synthetic slant of the font - * @extents: (nullable): glyph extents + * @slant: the synthetic slant ratio to be applied to the image during rendering + * @extents: (nullable): glyph extents for desired rendering * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * * A virtual method for the #hb_paint_funcs_t to paint the @@ -264,6 +266,8 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, + unsigned int width, + unsigned int height, hb_tag_t format, float slant, hb_glyph_extents_t *extents, diff --git a/src/hb-paint.hh b/src/hb-paint.hh index eaba99bce..89be4cb3d 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -99,11 +99,12 @@ struct hb_paint_funcs_t !user_data ? nullptr : user_data->color); } void image (void *paint_data, hb_blob_t *image, + unsigned width, unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents) { func.image (this, paint_data, - image, format, slant, extents, + image, width, height, format, slant, extents, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index d40b56458..36c4acd6b 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -99,6 +99,8 @@ read_blob (void *closure, void hb_cairo_paint_glyph_image (cairo_t *cr, hb_blob_t *blob, + unsigned width, + unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents) @@ -111,8 +113,11 @@ hb_cairo_paint_glyph_image (cairo_t *cr, r.blob = blob; r.offset = 0; cairo_surface_t *surface = cairo_image_surface_create_from_png_stream (read_blob, &r); - int width = cairo_image_surface_get_width (surface); - int height = cairo_image_surface_get_width (surface); + + /* For PNG, width,height can be unreliable, as is the case for NotoColorEmoji :(. + * Just pull them out of the surface. */ + width = cairo_image_surface_get_width (surface); + height = cairo_image_surface_get_width (surface); cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index fdc9de884..fdf7c01af 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -72,6 +72,8 @@ hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) void hb_cairo_paint_glyph_image (cairo_t *cr, hb_blob_t *blob, + unsigned width, + unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents); diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 8ad970a0b..2784b39bb 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -221,6 +221,8 @@ static void paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *blob, + unsigned width, + unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents, @@ -228,7 +230,7 @@ paint_image (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_glyph_image (cr, blob, format, slant, extents); + hb_cairo_paint_glyph_image (cr, blob, width, height, format, slant, extents); } static void From 63db0d2aed3cda83470bae5c2c8128d1bc54ac46 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 12:19:33 -0700 Subject: [PATCH 142/219] [util] Speculatively fix build against non-PNG builds --- util/hb-cairo-utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 36c4acd6b..0f03e40f3 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -70,6 +70,7 @@ cairo_extend (hb_paint_extend_t extend) return CAIRO_EXTEND_PAD; } +#ifdef CAIRO_HAS_PNG_FUNCTIONS typedef struct { hb_blob_t *blob; @@ -95,6 +96,7 @@ read_blob (void *closure, return CAIRO_STATUS_SUCCESS; } +#endif void hb_cairo_paint_glyph_image (cairo_t *cr, From 381d410b1eae1a292741a78920ff2e0fb436df55 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 13:21:48 -0700 Subject: [PATCH 143/219] [paint] Add HB_PAINT_IMAGE_FORMAT_BGRA and use it in hb-ft Now hb-ft can render color emoji as well. Just left COLRv2. --- docs/harfbuzz-sections.txt | 4 ++ src/hb-ft.cc | 39 ++++++++++++++++++- src/hb-paint.h | 18 ++++++++- util/hb-cairo-utils.c | 78 ++++++++++++++++++++++++++++++++------ 4 files changed, 125 insertions(+), 14 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index e63afdef0..d9ad80b3a 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -244,6 +244,7 @@ hb_paint_color_func_t hb_paint_funcs_set_color_func HB_PAINT_IMAGE_FORMAT_PNG HB_PAINT_IMAGE_FORMAT_SVG +HB_PAINT_IMAGE_FORMAT_BGRA hb_paint_image_func_t hb_paint_funcs_set_image_func hb_color_line_t @@ -373,6 +374,7 @@ hb_font_get_glyph_v_origin hb_font_get_glyph_origin_for_direction hb_font_get_glyph_name hb_font_get_glyph_shape +hb_font_draw_glyph hb_font_paint_glyph hb_font_get_nominal_glyph hb_font_get_nominal_glyphs @@ -436,6 +438,8 @@ hb_font_get_glyph_name_func_t hb_font_funcs_set_glyph_name_func hb_font_get_glyph_shape_func_t hb_font_funcs_set_glyph_shape_func +hb_font_draw_glyph_func_t +hb_font_funcs_set_draw_glyph_func hb_font_paint_glyph_func_t hb_font_funcs_set_paint_glyph_func hb_font_get_nominal_glyph_func_t diff --git a/src/hb-ft.cc b/src/hb-ft.cc index e3e9eaec8..c495cb629 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -830,7 +830,8 @@ hb_ft_paint_glyph (hb_font_t *font, /* We release the lock before calling into callbacks, such that * eg. draw API can call back into the face.*/ - if (unlikely (FT_Load_Glyph (ft_face, gid, ft_font->load_flags))) + if (unlikely (FT_Load_Glyph (ft_face, gid, + ft_font->load_flags | FT_LOAD_COLOR))) return; if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) @@ -898,6 +899,42 @@ hb_ft_paint_glyph (hb_font_t *font, return; } + auto *glyph = ft_face->glyph; + if (glyph->format == FT_GLYPH_FORMAT_BITMAP) + { + auto &bitmap = glyph->bitmap; + if (bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) + { + if (bitmap.pitch != (signed) bitmap.width * 4) + return; + + ft_font->lock.unlock (); + + hb_blob_t *blob = hb_blob_create ((const char *) bitmap.buffer, + bitmap.pitch * bitmap.rows, + HB_MEMORY_MODE_DUPLICATE, + nullptr, nullptr); + + hb_glyph_extents_t extents; + if (!hb_font_get_glyph_extents (font, gid, &extents)) + goto out; + + paint_funcs->image (paint_data, + blob, + bitmap.width, + bitmap.rows, + HB_PAINT_IMAGE_FORMAT_BGRA, + font->slant_xy, + &extents); + + out: + hb_blob_destroy (blob); + ft_font->lock.lock (); + } + + return; + } + /* TODO Support image, COLRv0/1. */ } #endif diff --git a/src/hb-paint.h b/src/hb-paint.h index c695891a0..ac9aaf020 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -227,17 +227,31 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, /** * HB_PAINT_IMAGE_FORMAT_PNG: * - * Tag identifying png images in #hb_paint_image_func_t callbacks. + * Tag identifying PNG images in #hb_paint_image_func_t callbacks. + * + * Since: REPLACEME */ #define HB_PAINT_IMAGE_FORMAT_PNG HB_TAG('p','n','g',' ') /** * HB_PAINT_IMAGE_FORMAT_SVG: * - * Tag identifying svg images in #hb_paint_image_func_t callbacks. + * Tag identifying SVG images in #hb_paint_image_func_t callbacks. + * + * Since: REPLACEME */ #define HB_PAINT_IMAGE_FORMAT_SVG HB_TAG('s','v','g',' ') +/** + * HB_PAINT_IMAGE_FORMAT_BGRA: + * + * Tag identifying raw pixel-data images in #hb_paint_image_func_t callbacks. + * The data is in BGRA pre-multiplied sRGBA color-space format. + * + * Since: REPLACEME + */ +#define HB_PAINT_IMAGE_FORMAT_BGRA HB_TAG('B','G','R','A') + /** * hb_paint_image_func_t: * @funcs: paint functions object diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 0f03e40f3..614d96eda 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -98,6 +98,14 @@ read_blob (void *closure, } #endif +static const cairo_user_data_key_t *_hb_cairo_surface_blob_user_data_key = {0}; + +static void +_hb_cairo_destroy_blob (void *p) +{ + hb_blob_destroy ((hb_blob_t *) p); +} + void hb_cairo_paint_glyph_image (cairo_t *cr, hb_blob_t *blob, @@ -107,19 +115,68 @@ hb_cairo_paint_glyph_image (cairo_t *cr, float slant, hb_glyph_extents_t *extents) { -#ifdef CAIRO_HAS_PNG_FUNCTIONS - if (format != HB_PAINT_IMAGE_FORMAT_PNG || !extents) + if (!extents) /* SVG currently. */ return; - read_blob_data_t r; - r.blob = blob; - r.offset = 0; - cairo_surface_t *surface = cairo_image_surface_create_from_png_stream (read_blob, &r); + cairo_surface_t *surface = NULL; - /* For PNG, width,height can be unreliable, as is the case for NotoColorEmoji :(. - * Just pull them out of the surface. */ - width = cairo_image_surface_get_width (surface); - height = cairo_image_surface_get_width (surface); +#ifdef CAIRO_HAS_PNG_FUNCTIONS + if (format == HB_PAINT_IMAGE_FORMAT_PNG) + { + read_blob_data_t r; + r.blob = blob; + r.offset = 0; + surface = cairo_image_surface_create_from_png_stream (read_blob, &r); + + /* For PNG, width,height can be unreliable, as is the case for NotoColorEmoji :(. + * Just pull them out of the surface. */ + width = cairo_image_surface_get_width (surface); + height = cairo_image_surface_get_width (surface); + } + else +#endif + if (format == HB_PAINT_IMAGE_FORMAT_BGRA) + { + /* Byte-endian conversion. */ + unsigned data_size = hb_blob_get_length (blob); + if (data_size < width * height * 4) + return; + + unsigned char *data; + if (__BYTE_ORDER == __BIG_ENDIAN) + { + data = (unsigned char *) hb_blob_get_data_writable (blob, NULL); + if (!data) + return; + + unsigned count = width * height * 4; + for (unsigned i = 0; i < count; i += 4) + { + unsigned char b; + b = data[i]; + data[i] = data[i+3]; + data[i+3] = b; + b = data[i+1]; + data[i+1] = data[i+2]; + data[i+2] = b; + } + } + else + data = (unsigned char *) hb_blob_get_data (blob, NULL); + + surface = cairo_image_surface_create_for_data (data, + CAIRO_FORMAT_ARGB32, + width, height, + width * 4); + + cairo_surface_set_user_data (surface, + _hb_cairo_surface_blob_user_data_key, + hb_blob_reference (blob), + _hb_cairo_destroy_blob); + } + + if (!surface) + return; cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); @@ -141,7 +198,6 @@ hb_cairo_paint_glyph_image (cairo_t *cr, cairo_pattern_destroy (pattern); cairo_surface_destroy (surface); -#endif } static void From 6909701b36e989a9bd0f581bf4959f8c706116a7 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 22 Dec 2022 15:32:09 -0500 Subject: [PATCH 144/219] [paint] Update docs --- src/hb-paint.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index ac9aaf020..91683718e 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -257,8 +257,8 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @image: the image data - * @width: width of the raster image in pixels - * @height: height of the raster image in pixels + * @width: width of the raster image in pixels, or 0 + * @height: height of the raster image in pixels, or 0 * @format: the image format as a tag * @slant: the synthetic slant ratio to be applied to the image during rendering * @extents: (nullable): glyph extents for desired rendering @@ -270,10 +270,10 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * This method is intended for glyphs with image blobs in the CBDT, * sbix or SVG tables. The @format identifies the kind of data that * is contained in @image. Possible values include #HB_PAINT_IMAGE_FORMAT_PNG - * and HB_PAINT_IMAGE_FORMAT_SVG. + * #HB_PAINT_IMAGE_FORMAT_SVG and #HB_PAINT_IMAGE_FORMAT_BGRA. * - * The glyph extents are provided if available, and should be used - * to size and position the image. + * The image dimensions and glyph extents are provided if available, + * and should be used to size and position the image. * * Since: REPLACEME */ From 47dbebff393dcb121f058b43977bf8d931b19b1e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 22 Dec 2022 16:06:51 -0500 Subject: [PATCH 145/219] [paint] Add COLRv0 tests --- test/api/fonts/RocherColorGX.abc.ttf | Bin 0 -> 7588 bytes test/api/results/rocher-20-0-2 | 12 +++++++++ test/api/results/rocher-20-0-3 | 12 +++++++++ test/api/results/rocher-20-0.3-1 | 12 +++++++++ test/api/test-ot-color.c | 35 ++++++++++++++++++--------- 5 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 test/api/fonts/RocherColorGX.abc.ttf create mode 100644 test/api/results/rocher-20-0-2 create mode 100644 test/api/results/rocher-20-0-3 create mode 100644 test/api/results/rocher-20-0.3-1 diff --git a/test/api/fonts/RocherColorGX.abc.ttf b/test/api/fonts/RocherColorGX.abc.ttf new file mode 100644 index 0000000000000000000000000000000000000000..35fce09234ba77f802bc58639b6ba1c89517162c GIT binary patch literal 7588 zcmZ`;3wTpiw%+?ZlQgd;Z9+>+(~>5o6zDT4rO>2L&_IP!Kv1CeK`DinJ}3wX_FdY9 zDzpe9N@w&#z{faNs-WViFv8q%hRY0B9cP%i_o5E!z2YD!^z2#tBrO#1r2Cw`_G9g} z{#Zr-EN`4^zi73AjSBNL27I05Jh z1rHP!?RkIClhCgR`ga9I#o0qQhyDru=YftZESi?w)YASHLd->=R~9XFFWhsa>uu=o z0oq!+wxkxRQ9ty@0i9a0p`>pA``sVG`iFq7TvffP;uk^l3l$In+i))1b zn?T2}E!kL$_A?rwJwRL5m8>m~R?j+#5D)Y5;o6$|1~P;I4_r;p>}SKW-oH4mv7QT9h@13SWy-`Ey9g50Q`f z9`ch+*PJVCM%Im5^QS1%cDXOWi38LVfMX044kS_oh9PJiiU8YLQC#xO`6Tzv ztHkNMNEV&BN}fuePo8f7k+iJ+lDu-@CYircOPaoFAl0AEBOTYCAo+{_gM9MiKgg&5 z9F(6=m8O#)|F47m_?sd!{KK!v#@YpB)uk(B>+6GL?+=8u&aNWY_6(4#o$ch>EANqK zikFddmnz8V57v;2-?b9HaxaKuxbZ9wPpC>*Tp z=Oe&Qq4L*Zuc022jmpsmDAi~IszIfw66$p*2kO;O>d+KuFGs6TBhV#4FOvJ~(Q4>j z2iPW}sVE74iDTwlZsTCNgTt*EGtg{Ue<5(0F=qD9uRd0m+aWaGj#>};l|u_fW3{Z|RG{3Tb2U6~@u`=oa#Symp}3WS z{{C2?K8nz+z>b~|^^t2jnvPbWR&*I%#tz(szs6rPNlYVijycDw*%>G0aVODsniDF) ztKFo5)a~++I#Pe{Uwgrw?JaJ!6M1)ekPmt9{cA6{v%ST?Vm2)AB2`Q`zabZOqh3hU zeWaS<{-0o`;#c zo3qIyfYGGpJd!}FQ9eMv3-z%}KHb;tCTq#^4i{O9U!LbiZKxM-TeBk%x+jxLGM_9X zwZNngN1=9LvK|y|Y(`JqN1Dh|vVxS5jieDkUrW}IDzdsG2U;EiQ*6M;N?ho`4%yde zX3HUyNEAsX3BY7IDJDys@tTHguuM04z9k!G=a3mp$Dx0@q2W($F0`AOIJDPIR*^@# z+^|9p-v0#5Tuq)KCC$0$0D4AtnZA|+Qj6vSn>N%bJJqhXY}5|@d-2*K7g^usxAH}> z@-53YlDZuuHeXNby>q~>bt85jv03vxs5RW#I?_w(JMwOy(^de~mRr5xFJtVyW5fe` zkk32kF55yZHP3_Ao)LTA{p_IpM*G`nl(pYJD&PT+%N}qH9Ye3-=+|4(K{wezW;dhq z9N56$LhnG~TDYvYf@d!EK;*rPK0s&CS@b!&hJHYQ1;;sw2GK5D;pxu>{tLjot4URB zHdz9Wu(X-qI)&-=wzPoPg1&1Y(l)4{|A%x#Ynzs3QHLd!yFsMBe%b2VKob0VZ#H>= zWP$zm{@#U-wdax9WDb;kGMB8!zj&)1b4PQaC6j=&vM>DRN>(T9ai0cv+=9Iaceuf+ z8n}1AxG{gD3$?d{lX7qV;o4^}xB=_BcD|+cw@lQs9Mnaf8TmSM;Jybv2`=n;%0-s= zz3)}9y+0Dc%DzI7o5u6KBN;rSZO-jh92vXg?pC@djK-hOAG@RWx!p2y-PbnfuC|@X zx8v?s@P&Xa*8qa~83ylx1>hgjdMmpm@i+U|xxUBR|KbK2>KxEbnjql4&KZoTz~a}Wki0C5S#?`E%T zwPIM)g|@R5io@PK@+eshhM7e&NC|%aY!7Rhl9<*43*hE17kR8B7n02`SiT>1@mm&7 zRQ+YAo2(?udveea`V}m45VpY0WE-L6j;;@vF6Xx`7g|Nf{L z>CnaKah$>zG6{c*_c9uvK4Rg!DZy&2oX=~0nlPzRDr5w&QlI#EMtoe7G7{^(`tZ$4 z>57BHxY=iDKE-K_?!zX+RPqs- zBCO;;L>aKp&qZtD%<&lD2s%>);SPUksm?S?0pWBwtv&RL9eDr2{UIpAUAc)?_LI2q#v#*CfL7;$1K@TF`7k!PgsaZzrE zFU}P#@R(T`zEcJW{5Jq)H`>8#cH3zIOk-33ZED}1(x4iXo@i;mBufh zx;ix^I;8luUYmvynJEHRFpQv$7}7`P$J&+{w2X8<*s}B2^D{S>Me5@opH+CICx(j{ zm;1WQsFZ@F)9LFLg|f9mG>(fs!!wa(Q)jr8@5Lg6WuL4JvjuxC zv*KAcwo`iYgbCNSVXHHu{Q8D@s1pv@#l_);~5beqkU_7a?I)vOXI_=30d!4-Zm)x_Ch?o^PyBp z&z})G;Jqpdb|C7#3}cjGaMC*fNjC+PL3UftYB!o3P6NZ5Z8lM43`WdqeOfj`&|qbd zr7StvV*VOmcspD}8$-0Ad{UFNK)UbIPnZ7vVU04(yZHCZR4S~OCh5J}Nc;%fiaSiv zhUAJEwUW_^79Qq}zdF2XxZ+x>YMeo-!`}(K7VDS+Z1<|LQYHOzc&~Jc%3ULU!ehY$ zZ-G(p!N@N%2utMzDXms2B*+M61u2^px~O%jm+<#*f>5R!sYLR0;e9x%DmW;j>}sPn zTvW4$h3qDL$XOF*P*|=ER}PomFdG&6|5k!`3ue`d2(5H#c)Ii%UH?gWeJi~4 z$HIpK69-$Ofw4PB1aJmWgfErONvA6NYWxWCN5XiWF+WCn;^tqa;~R15Euc0@ zuik8x_8WqE^(O5IRDjM%#&M%Lw`Uu(jXD@49)FyTW*j^0Yt+l`$T>Eo_{#0;KwREG^sFU(0#4P;O)$J=D;FF^m1%7#zyLb3vOw|4N=g!3Vu-mBN zPBj~RLwsa7Q-r@26a|9`ss&QQ@L4^cfR!h-s&DDn1U?{v6W;pu@NG99-h&Z_?a%}s z2rFWSg>;W)%9xm#1hFmu=@?nYSfHTQX_6(!<<5qL%kTD48JL{O)w@@@Z~XJ%&I`o@ zuT6?*{H7`2n?LaRUuD6$q{Q;HH6ea=@X#0dxG!X4uPl@_4Xd37sFswKtIS=tHI$?{)1~@zb zLF*89)>sf;ltE@PUC+)u-|b_rjMKhg)Zr(`r-VQ9{OrVWQffi`iHDoMY5ddC%-Wc! zKIwg_^gsY}?#qvdJEY4s6yf15Z|r#XRPz7^%=#3tdcCwtdQZWF;JcKJ0Fd`)=yu9h zKh~kZ0ydeN1)SYxhfKwSa&p}!h67>O;%|PzR>6|G1vcUN?3@^H%^^gjqk|iM=yC5D$#h4 zY@Svb?~O_JjZNrrL8_@{linL@Qm0ih&nPBOu*Z5$O3XYQl|{cZ^W+=;DZU5x>3Eb1 zAM+uvGGIIa#A>BU7_3Mi^k5W=Wc49%OlG4$1B*f^ezDA>3sM(XgO|ZkM>{ybzdmYw zeLi+K6>GFjM<4u3dL2*kPAd@gd5O|lj=Q$dt}B|lZYyJ0v@RV_$5)j`*Xz0CBDk2I zBZadbkJCq%ZO)wk>z$ThJr36zme^wRBlSZMF=6f*Q_CV5{tW!%fkW}K+@0{%R|j9% zT;PeRMk@ppl?aY*f{4JXX|ZOIRZKDk4sS_dJ~&M{@6ZeH7qRv;4~Qf=_OuKYSL2W8 zs1^7!N5##$`gZ2}xk}@ru4T*n%pvnvJ3aT%ka_L^{$&W;PsPIndesX`n-4=?N+5OL8`qh4TS))pUKGX*}5&zfl0Z~`czqka4 zVdLV$B30V^v&AfXiZ9bssWjyH7tIRoc7##hwF&t5{m;9r;JmF#&FOBr(mY?b@BSNIDd$TDhq|hR40UeXE#!>g10b4{zAZqz zoxM48@OW-+eW50(>CJU%yT^d1sk^Z`4e)x&nr>(Y47oGowGmOt{clxtTs{;x5Pv&- WH-0fK1s?>=*yzbCQho_QBJ^(nBp&hr literal 0 HcmV?d00001 diff --git a/test/api/results/rocher-20-0-2 b/test/api/results/rocher-20-0-2 new file mode 100644 index 000000000..d26bb572b --- /dev/null +++ b/test/api/results/rocher-20-0-2 @@ -0,0 +1,12 @@ +start clip glyph 12 + solid 81 61 50 255 +end clip +start clip glyph 13 + solid 245 185 68 255 +end clip +start clip glyph 14 + solid 224 142 55 255 +end clip +start clip glyph 15 + solid 245 202 86 255 +end clip diff --git a/test/api/results/rocher-20-0-3 b/test/api/results/rocher-20-0-3 new file mode 100644 index 000000000..326fdc4f9 --- /dev/null +++ b/test/api/results/rocher-20-0-3 @@ -0,0 +1,12 @@ +start clip glyph 16 + solid 81 61 50 255 +end clip +start clip glyph 17 + solid 245 185 68 255 +end clip +start clip glyph 18 + solid 224 142 55 255 +end clip +start clip glyph 19 + solid 245 202 86 255 +end clip diff --git a/test/api/results/rocher-20-0.3-1 b/test/api/results/rocher-20-0.3-1 new file mode 100644 index 000000000..9cb0e66e6 --- /dev/null +++ b/test/api/results/rocher-20-0.3-1 @@ -0,0 +1,12 @@ +start clip glyph 8 + solid 81 61 50 255 +end clip +start clip glyph 9 + solid 245 185 68 255 +end clip +start clip glyph 10 + solid 224 142 55 255 +end clip +start clip glyph 11 + solid 245 202 86 255 +end clip diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 604efbabb..cd292d12e 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -559,7 +559,10 @@ static void paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *blob, + unsigned int width, + unsigned int height, hb_tag_t format, + float slant, hb_glyph_extents_t *extents, void *user_data) { @@ -567,8 +570,9 @@ paint_image (hb_paint_funcs_t *funcs, char buf[5] = { 0, }; hb_tag_to_string (format, buf); - print (data, "image type %s extents %d %d %d %d\n", - buf, extents->x_bearing, extents->y_bearing, extents->width, extents->height); + print (data, "image type %s size %u %u slant %f extents %d %d %d %d\n", + buf, width, height, slant, + extents->x_bearing, extents->y_bearing, extents->width, extents->height); } static void @@ -680,23 +684,30 @@ typedef struct { int scale; float slant; hb_codepoint_t glyph; + unsigned int palette; const char *output; } colrv1_test_t; #define NOTO_HAND "fonts/noto_handwriting-cff2_colr_1.otf" #define TEST_GLYPHS "fonts/test_glyphs-glyf_colr_1.ttf" +#define ROCHER_ABC "fonts/RocherColorGX.abc.ttf" static colrv1_test_t colrv1_tests[] = { - { NOTO_HAND, 20, 0., 10, "hand-20-0-10" }, - { NOTO_HAND, 20, 0.2, 10, "hand-20-0.2-10" }, - { TEST_GLYPHS, 20, 0, 6, "test-20-0-6" }, - { TEST_GLYPHS, 20, 0, 10, "test-20-0-10" }, - { TEST_GLYPHS, 20, 0, 92, "test-20-0-92" }, - { TEST_GLYPHS, 20, 0, 106, "test-20-0-106" }, - { TEST_GLYPHS, 20, 0, 116, "test-20-0-116" }, - { TEST_GLYPHS, 20, 0, 123, "test-20-0-123" }, - { TEST_GLYPHS, 20, 0, 165, "test-20-0-165" }, - { TEST_GLYPHS, 20, 0, 175, "test-20-0-175" }, + /* COLRv1 */ + { NOTO_HAND, 20, 0., 10, 0, "hand-20-0-10" }, + { NOTO_HAND, 20, 0.2, 10, 0, "hand-20-0.2-10" }, + { TEST_GLYPHS, 20, 0, 6, 0, "test-20-0-6" }, + { TEST_GLYPHS, 20, 0, 10, 0, "test-20-0-10" }, + { TEST_GLYPHS, 20, 0, 92, 0, "test-20-0-92" }, + { TEST_GLYPHS, 20, 0, 106, 0, "test-20-0-106" }, + { TEST_GLYPHS, 20, 0, 116, 0, "test-20-0-116" }, + { TEST_GLYPHS, 20, 0, 123, 0, "test-20-0-123" }, + { TEST_GLYPHS, 20, 0, 165, 0, "test-20-0-165" }, + { TEST_GLYPHS, 20, 0, 175, 0, "test-20-0-175" }, + /* COLRv0 */ + { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-20-0.3-1" }, + { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-20-0-2" }, + { ROCHER_ABC, 120, 0, 3, 200, "rocher-20-0-3" }, }; static void From 5bd3c07b5475dac69e33403f8c33b137cf9281d2 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 22 Dec 2022 16:23:50 -0500 Subject: [PATCH 146/219] [colr] Don't access baseGlyphList unless v1 This was showing up sporadic crashes due to invalid reads. --- src/hb-ot-color-colr-table.hh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index e3893f91c..9fbdd2c29 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1976,22 +1976,24 @@ struct COLR paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette, hb_color_t foreground) const { VarStoreInstancer instancer (this+varStore, - this+varIdxMap, - hb_array (font->coords, font->num_coords)); - + this+varIdxMap, + hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette, foreground, instancer); - const Paint *paint = get_base_glyph_paint (glyph); - if (paint) + if (version == 1) { - // COLRv1 glyph - c.funcs->push_root_transform (c.data, font); + const Paint *paint = get_base_glyph_paint (glyph); + if (paint) + { + // COLRv1 glyph + c.funcs->push_root_transform (c.data, font); - c.recurse (*paint); + c.recurse (*paint); - c.funcs->pop_root_transform (c.data); + c.funcs->pop_root_transform (c.data); - return true; + return true; + } } const BaseGlyphRecord *record = get_base_glyph_record (glyph); From e2546f5ab0fa440206ef501b382c19e8409ada61 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 15:50:43 -0700 Subject: [PATCH 147/219] [ft] Add hb-ft-colr.hh --- src/Makefile.sources | 2 +- src/hb-ft-colr.hh | 102 +++++++++++++++++++++++++++++++++++++++++++ src/hb-ft.cc | 60 ++++--------------------- src/meson.build | 2 +- 4 files changed, 112 insertions(+), 54 deletions(-) create mode 100644 src/hb-ft-colr.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index 5988ff575..edfbed164 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -305,7 +305,7 @@ HB_BASE_headers = \ # Optional Sources and Headers with external deps -HB_FT_sources = hb-ft.cc +HB_FT_sources = hb-ft.cc hb-ft-colr.hh HB_FT_headers = hb-ft.h HB_GLIB_sources = hb-glib.cc diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh new file mode 100644 index 000000000..cd480c0d4 --- /dev/null +++ b/src/hb-ft-colr.hh @@ -0,0 +1,102 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * 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. + */ + +#ifndef HB_FT_COLR_HH +#define HB_FT_COLR_HH + +#include "hb.hh" + + +#ifndef HB_NO_PAINT +static bool +hb_ft_paint_glyph_colr (hb_font_t *font, + void *font_data, + hb_codepoint_t gid, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data) +{ + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + FT_Face ft_face = ft_font->ft_face; + + /* Face is locked. */ + + /* COLRv0 */ + FT_Error error; + FT_Color* palette; + FT_LayerIterator iterator; + + FT_Bool have_layers; + FT_UInt layer_glyph_index; + FT_UInt layer_color_index; + + error = FT_Palette_Select(ft_face, palette_index, &palette); + if ( error ) + palette = NULL; + + iterator.p = NULL; + have_layers = FT_Get_Color_Glyph_Layer(ft_face, + gid, + &layer_glyph_index, + &layer_color_index, + &iterator); + + if (palette && have_layers) + { + do + { + hb_bool_t is_foreground = true; + hb_color_t color = foreground; + + if ( layer_color_index != 0xFFFF ) + { + FT_Color layer_color = palette[layer_color_index]; + color = HB_COLOR (layer_color.blue, + layer_color.green, + layer_color.red, + layer_color.alpha); + is_foreground = false; + } + + ft_font->lock.unlock (); + paint_funcs->push_clip_glyph (paint_data, layer_glyph_index, font); + paint_funcs->color (paint_data, is_foreground, color); + paint_funcs->pop_clip (paint_data); + ft_font->lock.lock (); + + } while (FT_Get_Color_Glyph_Layer(ft_face, + gid, + &layer_glyph_index, + &layer_color_index, + &iterator)); + return true; + } + + return false; +} +#endif + + +#endif /* HB_FT_COLR_HH */ diff --git a/src/hb-ft.cc b/src/hb-ft.cc index c495cb629..6d4c64d6f 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -814,6 +814,9 @@ hb_ft_draw_glyph (hb_font_t *font HB_UNUSED, #endif #ifndef HB_NO_PAINT + +#include "hb-ft-colr.hh" + static void hb_ft_paint_glyph (hb_font_t *font, void *font_data, @@ -836,58 +839,11 @@ hb_ft_paint_glyph (hb_font_t *font, if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { - /* COLRv0 */ - { - FT_Error error; - FT_Color* palette; - FT_LayerIterator iterator; - - FT_Bool have_layers; - FT_UInt layer_glyph_index; - FT_UInt layer_color_index; - - error = FT_Palette_Select(ft_face, palette_index, &palette); - if ( error ) - palette = NULL; - - iterator.p = NULL; - have_layers = FT_Get_Color_Glyph_Layer(ft_face, - gid, - &layer_glyph_index, - &layer_color_index, - &iterator); - - if (palette && have_layers) - { - do - { - hb_bool_t is_foreground = true; - hb_color_t color = foreground; - - if ( layer_color_index != 0xFFFF ) - { - FT_Color layer_color = palette[layer_color_index]; - color = HB_COLOR (layer_color.blue, - layer_color.green, - layer_color.red, - layer_color.alpha); - is_foreground = false; - } - - ft_font->lock.unlock (); - paint_funcs->push_clip_glyph (paint_data, layer_glyph_index, font); - paint_funcs->color (paint_data, is_foreground, color); - paint_funcs->pop_clip (paint_data); - ft_font->lock.lock (); - - } while (FT_Get_Color_Glyph_Layer(ft_face, - gid, - &layer_glyph_index, - &layer_color_index, - &iterator)); - return; - } - } + if (hb_ft_paint_glyph_colr (font, font_data, gid, + paint_funcs, paint_data, + palette_index, foreground, + user_data)) + return; /* Simple outline. */ ft_font->lock.unlock (); diff --git a/src/meson.build b/src/meson.build index 164bb17f0..89bb4ffa3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -305,7 +305,7 @@ hb_base_headers += hb_version_h # Optional Sources and Headers with external deps -hb_ft_sources = files('hb-ft.cc') +hb_ft_sources = files('hb-ft.cc', 'hb-ft-colr.hh') hb_ft_headers = files('hb-ft.h') hb_glib_sources = files('hb-glib.cc') From ac2682c610e64d47d9de0f5c742779a3b8f48f80 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 17:36:54 -0700 Subject: [PATCH 148/219] [ft] Start of a COLRv1 renderer --- src/hb-ft-colr.hh | 164 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 3 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index cd480c0d4..663de8594 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -29,6 +29,127 @@ #ifndef HB_NO_PAINT + +static void +_hb_ft_paint (FT_OpaquePaint opaque_paint, + const hb_ft_font_t *ft_font, + hb_font_t *font, + hb_paint_funcs_t *paint_funcs, void *paint_data, + FT_Color *palette, + hb_color_t foreground) +{ + FT_Face ft_face = ft_font->ft_face; + FT_COLR_Paint paint; + if (!FT_Get_Paint (ft_face, opaque_paint, &paint)) + return; + +#define RECURSE(other_paint) \ + _hb_ft_paint (other_paint, ft_font, font, paint_funcs, paint_data, palette, foreground) + + switch (paint.format) + { + case FT_COLR_PAINTFORMAT_COLR_LAYERS: + { + FT_OpaquePaint other_paint = {0}; + while (FT_Get_Paint_Layers (ft_face, + &paint.u.colr_layers.layer_iterator, + &other_paint)) + { + paint_funcs->push_group (paint_data); + RECURSE (other_paint); + paint_funcs->pop_group (paint_data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + } + } + break; + case FT_COLR_PAINTFORMAT_SOLID: + { + bool is_foreground = paint.u.solid.color.palette_index == 0xFFFF; + hb_color_t color; + if (is_foreground) + color = HB_COLOR (hb_color_get_blue (foreground), + hb_color_get_green (foreground), + hb_color_get_red (foreground), + (hb_color_get_alpha (foreground) * paint.u.solid.color.alpha) >> 14); + else + { + FT_Color ft_color = palette[paint.u.solid.color.palette_index]; + color = HB_COLOR (ft_color.blue, + ft_color.green, + ft_color.red, + ft_color.alpha); + } + paint_funcs->color (paint_data, is_foreground, color); + } + break; + case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT: break; + case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: break; + case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: break; + case FT_COLR_PAINTFORMAT_GLYPH: + { + //paint_funcs->push_inverse_root_transform (paint_data, font); + ft_font->lock.unlock (); + paint_funcs->push_clip_glyph (paint_data, paint.u.glyph.glyphID, font); + ft_font->lock.lock (); + RECURSE (paint.u.glyph.paint); + paint_funcs->pop_clip (paint_data); + //paint_funcs->pop_inverse_root_transform (paint_data); + } + break; + case FT_COLR_PAINTFORMAT_COLR_GLYPH: break; + case FT_COLR_PAINTFORMAT_TRANSFORM: + { + paint_funcs->push_transform (paint_data, + paint.u.transform.affine.xx / 65536.f, + paint.u.transform.affine.yx / 65536.f, + paint.u.transform.affine.xy / 65536.f, + paint.u.transform.affine.yy / 65536.f, + paint.u.transform.affine.dx / 65536.f, + paint.u.transform.affine.dy / 65536.f); + RECURSE (paint.u.transform.paint); + paint_funcs->pop_transform (paint_data); + } + break; + case FT_COLR_PAINTFORMAT_TRANSLATE: + { + paint_funcs->push_transform (paint_data, + 0.f, 0.f, 0.f, 0.f, + paint.u.translate.dx / 65536.f, + paint.u.translate.dy / 65536.f); + RECURSE (paint.u.translate.paint); + paint_funcs->pop_transform (paint_data); + } + break; + case FT_COLR_PAINTFORMAT_SCALE: + { + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + -paint.u.scale.center_x / 65536.f, + -paint.u.scale.center_y / 65536.f); + paint_funcs->push_transform (paint_data, + paint.u.scale.scale_y / 65536.f, + 0.f, 0.f, + paint.u.scale.scale_x / 65536.f, + 0.f, 0.f); + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + +paint.u.scale.center_x / 65536.f, + +paint.u.scale.center_y / 65536.f); + RECURSE (paint.u.scale.paint); + paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data); + } + break; + case FT_COLR_PAINTFORMAT_ROTATE: break; + case FT_COLR_PAINTFORMAT_SKEW: break; + case FT_COLR_PAINTFORMAT_COMPOSITE: break; + + case FT_COLR_PAINT_FORMAT_MAX: break; + case FT_COLR_PAINTFORMAT_UNSUPPORTED: break; + } +#undef RECURSE +} + static bool hb_ft_paint_glyph_colr (hb_font_t *font, void *font_data, @@ -43,7 +164,6 @@ hb_ft_paint_glyph_colr (hb_font_t *font, /* Face is locked. */ - /* COLRv0 */ FT_Error error; FT_Color* palette; FT_LayerIterator iterator; @@ -53,9 +173,47 @@ hb_ft_paint_glyph_colr (hb_font_t *font, FT_UInt layer_color_index; error = FT_Palette_Select(ft_face, palette_index, &palette); - if ( error ) + if (error) palette = NULL; + /* COLRv1 */ + FT_OpaquePaint paint = {0}; + if (FT_Get_Color_Glyph_Paint (ft_face, gid, + FT_COLOR_NO_ROOT_TRANSFORM, + &paint)) + { + FT_ClipBox clip_box; + bool pop_clip = false; + if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, + &clip_box)) + { + /* TODO mult's like hb-ft. */ + paint_funcs->push_clip_rectangle (paint_data, + clip_box.bottom_left.x, + clip_box.bottom_left.y, + clip_box.top_right.x, + clip_box.top_right.y); +#if 0 + FT_Vector bottom_left; + FT_Vector top_left; + FT_Vector top_right; + FT_Vector bottom_right; +#endif + } + + _hb_ft_paint (paint, + ft_font, + font, + paint_funcs, paint_data, + palette, foreground); + + if (pop_clip) + paint_funcs->pop_clip (paint_data); + + return true; + } + + /* COLRv0 */ iterator.p = NULL; have_layers = FT_Get_Color_Glyph_Layer(ft_face, gid, @@ -82,9 +240,9 @@ hb_ft_paint_glyph_colr (hb_font_t *font, ft_font->lock.unlock (); paint_funcs->push_clip_glyph (paint_data, layer_glyph_index, font); + ft_font->lock.lock (); paint_funcs->color (paint_data, is_foreground, color); paint_funcs->pop_clip (paint_data); - ft_font->lock.lock (); } while (FT_Get_Color_Glyph_Layer(ft_face, gid, From 0ec201446bf0f8b776a8820e97d76b4357036e2f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 17:40:53 -0700 Subject: [PATCH 149/219] [ft] Implement FT_COLR_PAINTFORMAT_COLR_GLYPH --- src/hb-ft-colr.hh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 663de8594..8fa2ae542 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -95,7 +95,16 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, //paint_funcs->pop_inverse_root_transform (paint_data); } break; - case FT_COLR_PAINTFORMAT_COLR_GLYPH: break; + case FT_COLR_PAINTFORMAT_COLR_GLYPH: + { + /* TODO Depth counter. */ + FT_OpaquePaint other_paint = {0}; + if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID, + FT_COLOR_NO_ROOT_TRANSFORM, + &other_paint)) + RECURSE (other_paint); + } + break; case FT_COLR_PAINTFORMAT_TRANSFORM: { paint_funcs->push_transform (paint_data, From a0f7f9e61cca50dfbf6969c1dfd088301ac89318 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 17:50:35 -0700 Subject: [PATCH 150/219] [ft-paint] Implement FT_COLR_PAINTFORMAT_COMPOSITE --- src/hb-ft-colr.hh | 67 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 8fa2ae542..a60e09ce3 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -30,6 +30,45 @@ #ifndef HB_NO_PAINT +static hb_paint_composite_mode_t +_hb_ft_paint_composite_mode (FT_Composite_Mode mode) +{ + switch (mode) + { + case FT_COLR_COMPOSITE_CLEAR: return HB_PAINT_COMPOSITE_MODE_CLEAR; + case FT_COLR_COMPOSITE_SRC: return HB_PAINT_COMPOSITE_MODE_SRC; + case FT_COLR_COMPOSITE_DEST: return HB_PAINT_COMPOSITE_MODE_DEST; + case FT_COLR_COMPOSITE_SRC_OVER: return HB_PAINT_COMPOSITE_MODE_SRC_OVER; + case FT_COLR_COMPOSITE_DEST_OVER: return HB_PAINT_COMPOSITE_MODE_DEST_OVER; + case FT_COLR_COMPOSITE_SRC_IN: return HB_PAINT_COMPOSITE_MODE_SRC_IN; + case FT_COLR_COMPOSITE_DEST_IN: return HB_PAINT_COMPOSITE_MODE_DEST_IN; + case FT_COLR_COMPOSITE_SRC_OUT: return HB_PAINT_COMPOSITE_MODE_SRC_OUT; + case FT_COLR_COMPOSITE_DEST_OUT: return HB_PAINT_COMPOSITE_MODE_DEST_OUT; + case FT_COLR_COMPOSITE_SRC_ATOP: return HB_PAINT_COMPOSITE_MODE_SRC_ATOP; + case FT_COLR_COMPOSITE_DEST_ATOP: return HB_PAINT_COMPOSITE_MODE_DEST_ATOP; + case FT_COLR_COMPOSITE_XOR: return HB_PAINT_COMPOSITE_MODE_XOR; + case FT_COLR_COMPOSITE_PLUS: return HB_PAINT_COMPOSITE_MODE_PLUS; + case FT_COLR_COMPOSITE_SCREEN: return HB_PAINT_COMPOSITE_MODE_SCREEN; + case FT_COLR_COMPOSITE_OVERLAY: return HB_PAINT_COMPOSITE_MODE_OVERLAY; + case FT_COLR_COMPOSITE_DARKEN: return HB_PAINT_COMPOSITE_MODE_DARKEN; + case FT_COLR_COMPOSITE_LIGHTEN: return HB_PAINT_COMPOSITE_MODE_LIGHTEN; + case FT_COLR_COMPOSITE_COLOR_DODGE: return HB_PAINT_COMPOSITE_MODE_COLOR_DODGE; + case FT_COLR_COMPOSITE_COLOR_BURN: return HB_PAINT_COMPOSITE_MODE_COLOR_BURN; + case FT_COLR_COMPOSITE_HARD_LIGHT: return HB_PAINT_COMPOSITE_MODE_HARD_LIGHT; + case FT_COLR_COMPOSITE_SOFT_LIGHT: return HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT; + case FT_COLR_COMPOSITE_DIFFERENCE: return HB_PAINT_COMPOSITE_MODE_DIFFERENCE; + case FT_COLR_COMPOSITE_EXCLUSION: return HB_PAINT_COMPOSITE_MODE_EXCLUSION; + case FT_COLR_COMPOSITE_MULTIPLY: return HB_PAINT_COMPOSITE_MODE_MULTIPLY; + case FT_COLR_COMPOSITE_HSL_HUE: return HB_PAINT_COMPOSITE_MODE_HSL_HUE; + case FT_COLR_COMPOSITE_HSL_SATURATION: return HB_PAINT_COMPOSITE_MODE_HSL_SATURATION; + case FT_COLR_COMPOSITE_HSL_COLOR: return HB_PAINT_COMPOSITE_MODE_HSL_COLOR; + case FT_COLR_COMPOSITE_HSL_LUMINOSITY: return HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY; + + case FT_COLR_COMPOSITE_MAX: HB_FALLTHROUGH; + default: return HB_PAINT_COMPOSITE_MODE_CLEAR; + } +} + static void _hb_ft_paint (FT_OpaquePaint opaque_paint, const hb_ft_font_t *ft_font, @@ -43,7 +82,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, if (!FT_Get_Paint (ft_face, opaque_paint, &paint)) return; -#define RECURSE(other_paint) \ +#define paint_recurse(other_paint) \ _hb_ft_paint (other_paint, ft_font, font, paint_funcs, paint_data, palette, foreground) switch (paint.format) @@ -56,7 +95,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, &other_paint)) { paint_funcs->push_group (paint_data); - RECURSE (other_paint); + paint_recurse (other_paint); paint_funcs->pop_group (paint_data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } } @@ -90,7 +129,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, ft_font->lock.unlock (); paint_funcs->push_clip_glyph (paint_data, paint.u.glyph.glyphID, font); ft_font->lock.lock (); - RECURSE (paint.u.glyph.paint); + paint_recurse (paint.u.glyph.paint); paint_funcs->pop_clip (paint_data); //paint_funcs->pop_inverse_root_transform (paint_data); } @@ -102,7 +141,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID, FT_COLOR_NO_ROOT_TRANSFORM, &other_paint)) - RECURSE (other_paint); + paint_recurse (other_paint); } break; case FT_COLR_PAINTFORMAT_TRANSFORM: @@ -114,7 +153,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, paint.u.transform.affine.yy / 65536.f, paint.u.transform.affine.dx / 65536.f, paint.u.transform.affine.dy / 65536.f); - RECURSE (paint.u.transform.paint); + paint_recurse (paint.u.transform.paint); paint_funcs->pop_transform (paint_data); } break; @@ -124,7 +163,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, 0.f, 0.f, 0.f, 0.f, paint.u.translate.dx / 65536.f, paint.u.translate.dy / 65536.f); - RECURSE (paint.u.translate.paint); + paint_recurse (paint.u.translate.paint); paint_funcs->pop_transform (paint_data); } break; @@ -143,7 +182,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, 1.f, 0.f, 0.f, 1.f, +paint.u.scale.center_x / 65536.f, +paint.u.scale.center_y / 65536.f); - RECURSE (paint.u.scale.paint); + paint_recurse (paint.u.scale.paint); paint_funcs->pop_transform (paint_data); paint_funcs->pop_transform (paint_data); paint_funcs->pop_transform (paint_data); @@ -151,12 +190,20 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, break; case FT_COLR_PAINTFORMAT_ROTATE: break; case FT_COLR_PAINTFORMAT_SKEW: break; - case FT_COLR_PAINTFORMAT_COMPOSITE: break; - + case FT_COLR_PAINTFORMAT_COMPOSITE: + { + paint_funcs->push_group (paint_data); + paint_recurse (paint.u.composite.backdrop_paint); + paint_funcs->push_group (paint_data); + paint_recurse (paint.u.composite.source_paint); + paint_funcs->pop_group (paint_data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode)); + paint_funcs->pop_group (paint_data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + } + break; case FT_COLR_PAINT_FORMAT_MAX: break; case FT_COLR_PAINTFORMAT_UNSUPPORTED: break; } -#undef RECURSE +#undef paint_recurse } static bool From 16598e024bd79796878650b9e723b02269e8f9d4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 17:51:35 -0700 Subject: [PATCH 151/219] [ft-paint] Default --- src/hb-ft-colr.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index a60e09ce3..039743147 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -200,7 +200,9 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, paint_funcs->pop_group (paint_data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } break; + case FT_COLR_PAINT_FORMAT_MAX: break; + default: HB_FALLTHROUGH; case FT_COLR_PAINTFORMAT_UNSUPPORTED: break; } #undef paint_recurse From ddbe4e52ec05bca0c284192af41df7479edd2ecd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 17:54:01 -0700 Subject: [PATCH 152/219] [ft-paint] Implement FT_COLR_PAINTFORMAT_ROTATE --- src/hb-ft-colr.hh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 039743147..4d3c2f467 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -188,7 +188,25 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, paint_funcs->pop_transform (paint_data); } break; - case FT_COLR_PAINTFORMAT_ROTATE: break; + case FT_COLR_PAINTFORMAT_ROTATE: + { + float a = paint.u.rotate.angle / 65536.f; + float cc = cosf (a * (float) M_PI); + float ss = sinf (a * (float) M_PI); + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + -paint.u.rotate.center_x / 65536.f, + -paint.u.rotate.center_y / 65536.f); + paint_funcs->push_transform (paint_data, cc, ss, -ss, cc, 0., 0.); + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + +paint.u.rotate.center_x / 65536.f, + +paint.u.rotate.center_y / 65536.f); + paint_recurse (paint.u.rotate.paint); + paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data); + } case FT_COLR_PAINTFORMAT_SKEW: break; case FT_COLR_PAINTFORMAT_COMPOSITE: { From 64cf17ec8b616dcf0a6254c56498b3b53cd4b933 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 17:55:25 -0700 Subject: [PATCH 153/219] [ft-paint] Fix center translation --- src/hb-ft-colr.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 4d3c2f467..5cdd98306 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -171,8 +171,8 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, { paint_funcs->push_transform (paint_data, 1.f, 0.f, 0.f, 1.f, - -paint.u.scale.center_x / 65536.f, - -paint.u.scale.center_y / 65536.f); + +paint.u.scale.center_x / 65536.f, + +paint.u.scale.center_y / 65536.f); paint_funcs->push_transform (paint_data, paint.u.scale.scale_y / 65536.f, 0.f, 0.f, @@ -180,8 +180,8 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, 0.f, 0.f); paint_funcs->push_transform (paint_data, 1.f, 0.f, 0.f, 1.f, - +paint.u.scale.center_x / 65536.f, - +paint.u.scale.center_y / 65536.f); + -paint.u.scale.center_x / 65536.f, + -paint.u.scale.center_y / 65536.f); paint_recurse (paint.u.scale.paint); paint_funcs->pop_transform (paint_data); paint_funcs->pop_transform (paint_data); @@ -195,13 +195,13 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, float ss = sinf (a * (float) M_PI); paint_funcs->push_transform (paint_data, 1.f, 0.f, 0.f, 1.f, - -paint.u.rotate.center_x / 65536.f, - -paint.u.rotate.center_y / 65536.f); + +paint.u.rotate.center_x / 65536.f, + +paint.u.rotate.center_y / 65536.f); paint_funcs->push_transform (paint_data, cc, ss, -ss, cc, 0., 0.); paint_funcs->push_transform (paint_data, 1.f, 0.f, 0.f, 1.f, - +paint.u.rotate.center_x / 65536.f, - +paint.u.rotate.center_y / 65536.f); + -paint.u.rotate.center_x / 65536.f, + -paint.u.rotate.center_y / 65536.f); paint_recurse (paint.u.rotate.paint); paint_funcs->pop_transform (paint_data); paint_funcs->pop_transform (paint_data); From cfdc34b44d97bedfe482612f885f52641452390f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 17:58:36 -0700 Subject: [PATCH 154/219] [ft-paint] Implement FT_COLR_PAINTFORMAT_SKEW --- src/hb-ft-colr.hh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 5cdd98306..a4c807fd5 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -207,7 +207,26 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, paint_funcs->pop_transform (paint_data); paint_funcs->pop_transform (paint_data); } - case FT_COLR_PAINTFORMAT_SKEW: break; + break; + case FT_COLR_PAINTFORMAT_SKEW: + { + float x = +tanf (paint.u.skew.x_skew_angle / 65536.f * (float) M_PI); + float y = -tanf (paint.u.skew.y_skew_angle / 65536.f * (float) M_PI); + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + +paint.u.skew.center_x / 65536.f, + +paint.u.skew.center_y / 65536.f); + paint_funcs->push_transform (paint_data, 1., y, x, 1., 0., 0.); + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + -paint.u.skew.center_x / 65536.f, + -paint.u.skew.center_y / 65536.f); + paint_recurse (paint.u.skew.paint); + paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data); + } + break; case FT_COLR_PAINTFORMAT_COMPOSITE: { paint_funcs->push_group (paint_data); From 569d5b436cff95fbd7753aebb443ecc682d248c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 18:00:02 -0700 Subject: [PATCH 155/219] [ft-paint] Remove dead code --- src/hb-ft-colr.hh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index a4c807fd5..66a6f18a8 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -288,12 +288,6 @@ hb_ft_paint_glyph_colr (hb_font_t *font, clip_box.bottom_left.y, clip_box.top_right.x, clip_box.top_right.y); -#if 0 - FT_Vector bottom_left; - FT_Vector top_left; - FT_Vector top_right; - FT_Vector bottom_right; -#endif } _hb_ft_paint (paint, From 7c9e42ed924d7e286b666e9206532cf1dac76955 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 19:49:06 -0700 Subject: [PATCH 156/219] [colr] Fix transform hell --- src/hb-ot-color-colr-table.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 9fbdd2c29..6f9dce82e 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -762,7 +762,9 @@ struct PaintGlyph { c->funcs->push_inverse_root_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); + c->funcs->push_root_transform (c->data, c->font); c->recurse (this+paint); + c->funcs->pop_root_transform (c->data); c->funcs->pop_clip (c->data); c->funcs->pop_inverse_root_transform (c->data); } From fe4e9bd93070daa2b8ac3bb8201e3736faab752b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 20:14:19 -0700 Subject: [PATCH 157/219] [colr] Add public vtable for hb_color_line_t --- src/hb-ot-color-colr-table.cc | 47 --------------------------- src/hb-ot-color-colr-table.hh | 44 +++++++++++++++++++------ src/hb-paint.cc | 49 ++++++++++++++++++++++++++++ src/hb-paint.h | 60 ++++++++++++++++++++++++++--------- 4 files changed, 129 insertions(+), 71 deletions(-) diff --git a/src/hb-ot-color-colr-table.cc b/src/hb-ot-color-colr-table.cc index 449da1691..f7cf00712 100644 --- a/src/hb-ot-color-colr-table.cc +++ b/src/hb-ot-color-colr-table.cc @@ -25,50 +25,3 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const } } - -/** - * hb_color_line_get_color_stops: - * @color_line: a #hb_color_line_t object - * @start: the index of the first color stop to return - * @count: (inout) (optional): Input = the maximum number of feature tags to return; - * Output = the actual number of feature tags returned (may be zero) - * @color_stops: (out) (array length=count) (optional): Array of #hb_color_stop_t to populate - * - * Fetches a list of color stops from the given color line object. - * - * Note that due to variations being applied, the returned color stops - * may be out of order. It is the callers responsibility to ensure that - * color stops are sorted by their offset before they are used. - * - * Return value: the total number of color stops in @cl - * - * Since: REPLACEME - */ -unsigned int -hb_color_line_get_color_stops (hb_color_line_t *color_line, - unsigned int start, - unsigned int *count, - hb_color_stop_t *color_stops) -{ - if (color_line->is_variable) - return reinterpret_cast *>(color_line->base)->get_color_stops (color_line->c, start, count, color_stops, color_line->c->instancer); - else - return reinterpret_cast *>(color_line->base)->get_color_stops (color_line->c, start, count, color_stops, color_line->c->instancer); -} - -/** - * hb_color_line_get_extend: - * @color_line: a #hb_color_line_t object - * - * Fetches the extend mode of the color line object. - * - * Since: REPLACEME - */ -hb_paint_extend_t -hb_color_line_get_extend (hb_color_line_t *color_line) -{ - if (color_line->is_variable) - return reinterpret_cast *>(color_line->base)->get_extend (); - else - return reinterpret_cast *>(color_line->base)->get_extend (); -} diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 6f9dce82e..0194e100b 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -49,12 +49,6 @@ namespace OT { struct hb_paint_context_t; } -struct hb_color_line_t { - struct OT::hb_paint_context_t *c; - const void *base; - bool is_variable; -}; - namespace OT { struct COLR; @@ -440,11 +434,31 @@ struct ColorLine return len; } + HB_INTERNAL static unsigned int static_get_color_stops (hb_color_line_t *color_line, + void *color_line_data, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops, + void *user_data) + { + const ColorLine *thiz = (const ColorLine *) color_line_data; + hb_paint_context_t *c = (hb_paint_context_t *) user_data; + return thiz->get_color_stops (c, start, count, color_stops, c->instancer); + } + hb_paint_extend_t get_extend () const { return (hb_paint_extend_t) (unsigned int) extend; } + HB_INTERNAL static hb_paint_extend_t static_get_extend (hb_color_line_t *color_line, + void *color_line_data, + void *user_data) + { + const ColorLine *thiz = (const ColorLine *) color_line_data; + return thiz->get_extend (); + } + Extend extend; Array16Of> stops; public: @@ -620,7 +634,11 @@ struct PaintLinearGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; + hb_color_line_t cl = { + (void *) &(this+colorLine), + (this+colorLine).static_get_color_stops, c, + (this+colorLine).static_get_extend, nullptr + }; c->funcs->linear_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -667,7 +685,11 @@ struct PaintRadialGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; + hb_color_line_t cl = { + (void *) &(this+colorLine), + (this+colorLine).static_get_color_stops, c, + (this+colorLine).static_get_extend, nullptr + }; c->funcs->radial_gradient (c->data, &cl, x0 + c->instancer (varIdxBase, 0), @@ -714,7 +736,11 @@ struct PaintSweepGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { - hb_color_line_t cl = { c, &(this+colorLine), Var::is_variable }; + hb_color_line_t cl = { + (void *) &(this+colorLine), + (this+colorLine).static_get_color_stops, c, + (this+colorLine).static_get_extend, nullptr + }; c->funcs->sweep_gradient (c->data, &cl, centerX + c->instancer (varIdxBase, 0), diff --git a/src/hb-paint.cc b/src/hb-paint.cc index a22c3a25b..209ca98f6 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -376,4 +376,53 @@ hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) return hb_object_is_immutable (funcs); } + +/** + * hb_color_line_get_color_stops: + * @color_line: a #hb_color_line_t object + * @start: the index of the first color stop to return + * @count: (inout) (optional): Input = the maximum number of feature tags to return; + * Output = the actual number of feature tags returned (may be zero) + * @color_stops: (out) (array length=count) (optional): Array of #hb_color_stop_t to populate + * + * Fetches a list of color stops from the given color line object. + * + * Note that due to variations being applied, the returned color stops + * may be out of order. It is the callers responsibility to ensure that + * color stops are sorted by their offset before they are used. + * + * Return value: the total number of color stops in @cl + * + * Since: REPLACEME + */ +unsigned int +hb_color_line_get_color_stops (hb_color_line_t *color_line, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops) +{ + return color_line->get_color_stops (color_line, + color_line->data, + start, count, + color_stops, + color_line->get_color_stops_user_data); +} + +/** + * hb_color_line_get_extend: + * @color_line: a #hb_color_line_t object + * + * Fetches the extend mode of the color line object. + * + * Since: REPLACEME + */ +hb_paint_extend_t +hb_color_line_get_extend (hb_color_line_t *color_line) +{ + return color_line->get_extend (color_line, + color_line->data, + color_line->get_extend_user_data); +} + + #endif diff --git a/src/hb-paint.h b/src/hb-paint.h index 91683718e..630cd89d8 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -287,15 +287,6 @@ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, hb_glyph_extents_t *extents, void *user_data); -/** - * hb_color_line_t: - * - * An opaque struct containing color information for a gradient. - * - * Since: REPLACEME - */ -typedef struct hb_color_line_t hb_color_line_t; - /** * hb_color_stop_t: * @offset: the offset of the color stop @@ -315,12 +306,6 @@ typedef struct { hb_color_t color; } hb_color_stop_t; -HB_EXTERN unsigned int -hb_color_line_get_color_stops (hb_color_line_t *color_line, - unsigned int start, - unsigned int *count, - hb_color_stop_t *color_stops); - /** * hb_paint_extend_t: * @@ -337,6 +322,51 @@ typedef enum { HB_PAINT_EXTEND_REFLECT } hb_paint_extend_t; +typedef struct hb_color_line_t hb_color_line_t; + +typedef unsigned int (*hb_color_line_get_color_stops_func_t) (hb_color_line_t *color_line, + void *color_line_data, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops, + void *user_data); + +typedef hb_paint_extend_t (*hb_color_line_get_extend_func_t) (hb_color_line_t *color_line, + void *color_line_data, + void *user_data); + +/** + * hb_color_line_t: + * + * A struct containing color information for a gradient. + * + * Since: REPLACEME + */ +struct hb_color_line_t { + void *data; + + hb_color_line_get_color_stops_func_t get_color_stops; + void *get_color_stops_user_data; + + hb_color_line_get_extend_func_t get_extend; + void *get_extend_user_data; + + void *reserved0; + void *reserved1; + void *reserved2; + void *reserved3; + void *reserved5; + void *reserved6; + void *reserved7; + void *reserved8; +}; + +HB_EXTERN unsigned int +hb_color_line_get_color_stops (hb_color_line_t *color_line, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops); + HB_EXTERN hb_paint_extend_t hb_color_line_get_extend (hb_color_line_t *color_line); From 6ebcc9d2e16ca4d7eaad2002ea8209dce5e9ed90 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 21:23:45 -0700 Subject: [PATCH 158/219] [ft-paint] Hook up gradients --- src/hb-ft-colr.hh | 125 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 3 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 66a6f18a8..2eb5916f1 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -69,6 +69,76 @@ _hb_ft_paint_composite_mode (FT_Composite_Mode mode) } } +typedef struct +{ + FT_Face face; + FT_Color *palette; + hb_color_t foreground; +} _hb_ft_get_color_stops_data_t; + +static unsigned +_hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, + void *color_line_data, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops, + void *user_data) +{ + FT_ColorLine *c = (FT_ColorLine *) color_line_data; + _hb_ft_get_color_stops_data_t *data = (_hb_ft_get_color_stops_data_t *) user_data; + + if (count) + { + FT_ColorStop stop; + unsigned wrote = 0; + + c->color_stop_iterator.current_color_stop = start; + + while (count && *count && + FT_Get_Colorline_Stops(data->face, + &stop, + &c->color_stop_iterator)) + { + color_stops->offset = stop.stop_offset / 65536.f; + color_stops->is_foreground = stop.color.palette_index == 0xFFFF; + if (color_stops->is_foreground) + color_stops->color = HB_COLOR (hb_color_get_blue (data->foreground), + hb_color_get_green (data->foreground), + hb_color_get_red (data->foreground), + (hb_color_get_alpha (data->foreground) * stop.color.alpha) >> 14); + else + { + FT_Color ft_color = data->palette[stop.color.palette_index]; + color_stops->color = HB_COLOR (ft_color.blue, + ft_color.green, + ft_color.red, + ft_color.alpha); + } + + color_stops++; + wrote++; + } + *count = wrote; + } + + return c->color_stop_iterator.num_color_stops; +} + +static hb_paint_extend_t +_hb_ft_color_line_get_extend (hb_color_line_t *color_line, + void *color_line_data, + void *user_data) +{ + FT_ColorLine *c = (FT_ColorLine *) color_line_data; + switch (c->extend) + { + default: + case FT_COLR_PAINT_EXTEND_PAD: return HB_PAINT_EXTEND_PAD; + case FT_COLR_PAINT_EXTEND_REPEAT: return HB_PAINT_EXTEND_REPEAT; + case FT_COLR_PAINT_EXTEND_REFLECT: return HB_PAINT_EXTEND_REFLECT; + } +} + static void _hb_ft_paint (FT_OpaquePaint opaque_paint, const hb_ft_font_t *ft_font, @@ -120,9 +190,58 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, paint_funcs->color (paint_data, is_foreground, color); } break; - case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT: break; - case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: break; - case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: break; + case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT: + { + _hb_ft_get_color_stops_data_t data = {ft_face, palette, foreground}; + hb_color_line_t cl = { + &paint.u.linear_gradient.colorline, + _hb_ft_color_line_get_color_stops, &data, + _hb_ft_color_line_get_extend, nullptr + }; + + paint_funcs->linear_gradient (paint_data, &cl, + paint.u.linear_gradient.p0.x, + paint.u.linear_gradient.p0.y, + paint.u.linear_gradient.p1.x, + paint.u.linear_gradient.p1.y, + paint.u.linear_gradient.p2.x, + paint.u.linear_gradient.p2.y); + } + break; + case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: + { + _hb_ft_get_color_stops_data_t data = {ft_face, palette, foreground}; + hb_color_line_t cl = { + &paint.u.linear_gradient.colorline, + _hb_ft_color_line_get_color_stops, &data, + _hb_ft_color_line_get_extend, nullptr + }; + + paint_funcs->radial_gradient (paint_data, &cl, + paint.u.radial_gradient.c0.x, + paint.u.radial_gradient.c0.y, + paint.u.radial_gradient.r0, + paint.u.radial_gradient.c1.x, + paint.u.radial_gradient.c1.y, + paint.u.radial_gradient.r1); + } + break; + case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: + { + _hb_ft_get_color_stops_data_t data = {ft_face, palette, foreground}; + hb_color_line_t cl = { + &paint.u.linear_gradient.colorline, + _hb_ft_color_line_get_color_stops, &data, + _hb_ft_color_line_get_extend, nullptr + }; + + paint_funcs->sweep_gradient (paint_data, &cl, + paint.u.sweep_gradient.center.x, + paint.u.sweep_gradient.center.y, + (paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI, + (paint.u.sweep_gradient.end_angle / 65536.f + 1) * (float) M_PI); + } + break; case FT_COLR_PAINTFORMAT_GLYPH: { //paint_funcs->push_inverse_root_transform (paint_data, font); From 3993a407037477e384650a1394c27c15596c9a45 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 22 Dec 2022 23:55:27 -0500 Subject: [PATCH 159/219] test: Add some verification hints --- test/api/test-ot-color.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index cd292d12e..1bf287c58 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -692,10 +692,16 @@ typedef struct { #define TEST_GLYPHS "fonts/test_glyphs-glyf_colr_1.ttf" #define ROCHER_ABC "fonts/RocherColorGX.abc.ttf" +/* To verify the rendering visually, use + * + * hb-view --font-size SCALE --font-slant SLANT --font-palette PALETTE FONT TEXT + * + * where TEXT is as mentioned below. + */ static colrv1_test_t colrv1_tests[] = { /* COLRv1 */ - { NOTO_HAND, 20, 0., 10, 0, "hand-20-0-10" }, - { NOTO_HAND, 20, 0.2, 10, 0, "hand-20-0.2-10" }, + { NOTO_HAND, 20, 0., 10, 0, "hand-20-0-10" }, // ✍️ + { NOTO_HAND, 20, 0.2, 10, 0, "hand-20-0.2-10" }, // ✍️ { TEST_GLYPHS, 20, 0, 6, 0, "test-20-0-6" }, { TEST_GLYPHS, 20, 0, 10, 0, "test-20-0-10" }, { TEST_GLYPHS, 20, 0, 92, 0, "test-20-0-92" }, @@ -705,9 +711,9 @@ static colrv1_test_t colrv1_tests[] = { { TEST_GLYPHS, 20, 0, 165, 0, "test-20-0-165" }, { TEST_GLYPHS, 20, 0, 175, 0, "test-20-0-175" }, /* COLRv0 */ - { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-20-0.3-1" }, - { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-20-0-2" }, - { ROCHER_ABC, 120, 0, 3, 200, "rocher-20-0-3" }, + { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-20-0.3-1" }, // A + { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-20-0-2" }, // B + { ROCHER_ABC, 120, 0, 3, 200, "rocher-20-0-3" }, // C }; static void From ee7bbdf372833a5705a0ba9e012d9665f5731726 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 00:01:20 -0500 Subject: [PATCH 160/219] tests: Update expected results These were changed by fixes for glyph transforms. --- test/api/results/hand-20-0-10 | 162 +++++++++++++++++-------------- test/api/results/hand-20-0.2-10 | 162 +++++++++++++++++-------------- test/api/results/rocher-20-0-2 | 12 --- test/api/results/rocher-20-0-3 | 12 --- test/api/results/rocher-20-0.3-1 | 12 --- test/api/results/test-20-0-10 | 18 ++-- test/api/results/test-20-0-106 | 8 +- test/api/results/test-20-0-116 | 8 +- test/api/results/test-20-0-123 | 12 ++- test/api/results/test-20-0-165 | 18 ++-- test/api/results/test-20-0-175 | 20 ++-- test/api/results/test-20-0-6 | 16 +-- test/api/results/test-20-0-92 | 16 +-- test/api/test-ot-color.c | 6 +- 14 files changed, 254 insertions(+), 228 deletions(-) delete mode 100644 test/api/results/rocher-20-0-2 delete mode 100644 test/api/results/rocher-20-0-3 delete mode 100644 test/api/results/rocher-20-0.3-1 diff --git a/test/api/results/hand-20-0-10 b/test/api/results/hand-20-0-10 index e6e82f49b..081f31606 100644 --- a/test/api/results/hand-20-0-10 +++ b/test/api/results/hand-20-0-10 @@ -2,15 +2,17 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 13 - start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 - radial gradient - p0 280.000000 440.000000 radius 0.000000 - p1 280.000000 440.000000 radius 467.000000 - colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 - 1.000000 164 123 98 255 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform end transform end clip end transform @@ -18,79 +20,95 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 14 - linear gradient - p0 231.000000 -27.000000 - p1 1019.000000 -27.000000 - p2 231.000000 -815.000000 - colors - 0.000000 164 123 98 255 - 1.000000 164 123 98 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 15 - solid 145 103 77 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 16 - solid 30 136 229 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 21 - solid 145 103 77 255 - end clip - end transform - pop group mode 3 - push group - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 16 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 linear gradient - p0 669.000000 776.000000 - p1 180.000000 -106.000000 - p2 -212.000000 1265.000000 + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 colors - 0.000000 100 181 246 255 - 1.000000 33 150 243 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 18 - solid 66 66 66 51 - end clip - end transform - pop group mode 3 - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 19 - start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 - radial gradient - p0 588.000000 198.000000 radius 0.000000 - p1 588.000000 198.000000 radius 342.000000 - colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 + 0.000000 164 123 98 255 1.000000 164 123 98 255 end transform end clip end transform pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 15 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 16 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 30 136 229 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 21 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 + push group + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 16 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 100 181 246 255 + 1.000000 33 150 243 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 18 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 66 66 66 51 + end transform + end clip + end transform + pop group mode 3 + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 19 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform + end transform + end clip + end transform + pop group mode 3 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 20 - solid 145 103 77 255 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform end clip end transform pop group mode 3 diff --git a/test/api/results/hand-20-0.2-10 b/test/api/results/hand-20-0.2-10 index a285dedcd..86cb6031a 100644 --- a/test/api/results/hand-20-0.2-10 +++ b/test/api/results/hand-20-0.2-10 @@ -2,15 +2,17 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 13 - start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 - radial gradient - p0 280.000000 440.000000 radius 0.000000 - p1 280.000000 440.000000 radius 467.000000 - colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 - 1.000000 164 123 98 255 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform end transform end clip end transform @@ -18,79 +20,95 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 14 - linear gradient - p0 231.000000 -27.000000 - p1 1019.000000 -27.000000 - p2 231.000000 -815.000000 - colors - 0.000000 164 123 98 255 - 1.000000 164 123 98 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 15 - solid 145 103 77 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 16 - solid 30 136 229 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 21 - solid 145 103 77 255 - end clip - end transform - pop group mode 3 - push group - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 16 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 linear gradient - p0 669.000000 776.000000 - p1 180.000000 -106.000000 - p2 -212.000000 1265.000000 + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 colors - 0.000000 100 181 246 255 - 1.000000 33 150 243 255 - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 18 - solid 66 66 66 51 - end clip - end transform - pop group mode 3 - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 19 - start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 - radial gradient - p0 588.000000 198.000000 radius 0.000000 - p1 588.000000 198.000000 radius 342.000000 - colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 + 0.000000 164 123 98 255 1.000000 164 123 98 255 end transform end clip end transform pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 15 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 16 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 30 136 229 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 21 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 + push group + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 16 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 100 181 246 255 + 1.000000 33 150 243 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 18 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 66 66 66 51 + end transform + end clip + end transform + pop group mode 3 + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 19 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform + end transform + end clip + end transform + pop group mode 3 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 20 - solid 145 103 77 255 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform end clip end transform pop group mode 3 diff --git a/test/api/results/rocher-20-0-2 b/test/api/results/rocher-20-0-2 deleted file mode 100644 index d26bb572b..000000000 --- a/test/api/results/rocher-20-0-2 +++ /dev/null @@ -1,12 +0,0 @@ -start clip glyph 12 - solid 81 61 50 255 -end clip -start clip glyph 13 - solid 245 185 68 255 -end clip -start clip glyph 14 - solid 224 142 55 255 -end clip -start clip glyph 15 - solid 245 202 86 255 -end clip diff --git a/test/api/results/rocher-20-0-3 b/test/api/results/rocher-20-0-3 deleted file mode 100644 index 326fdc4f9..000000000 --- a/test/api/results/rocher-20-0-3 +++ /dev/null @@ -1,12 +0,0 @@ -start clip glyph 16 - solid 81 61 50 255 -end clip -start clip glyph 17 - solid 245 185 68 255 -end clip -start clip glyph 18 - solid 224 142 55 255 -end clip -start clip glyph 19 - solid 245 202 86 255 -end clip diff --git a/test/api/results/rocher-20-0.3-1 b/test/api/results/rocher-20-0.3-1 deleted file mode 100644 index 9cb0e66e6..000000000 --- a/test/api/results/rocher-20-0.3-1 +++ /dev/null @@ -1,12 +0,0 @@ -start clip glyph 8 - solid 81 61 50 255 -end clip -start clip glyph 9 - solid 245 185 68 255 -end clip -start clip glyph 10 - solid 224 142 55 255 -end clip -start clip glyph 11 - solid 245 202 86 255 -end clip diff --git a/test/api/results/test-20-0-10 b/test/api/results/test-20-0-10 index 332c00a48..8bb19a3bf 100644 --- a/test/api/results/test-20-0-10 +++ b/test/api/results/test-20-0-10 @@ -1,14 +1,16 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 174 - sweep gradient - center 500.000000 600.000000 - angles 0.000000 6.283185 - colors - 0.250000 250 240 230 255 - 0.416687 0 0 255 255 - 0.583313 255 0 0 255 - 0.750000 47 79 79 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + sweep gradient + center 500.000000 600.000000 + angles 0.000000 6.283185 + colors + 0.250000 250 240 230 255 + 0.416687 0 0 255 255 + 0.583313 255 0 0 255 + 0.750000 47 79 79 255 + end transform end clip end transform end transform diff --git a/test/api/results/test-20-0-106 b/test/api/results/test-20-0-106 index 9f59e4c06..8e09c8726 100644 --- a/test/api/results/test-20-0-106 +++ b/test/api/results/test-20-0-106 @@ -2,7 +2,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 0 0 255 127 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 0 255 127 + end transform end clip end transform push group @@ -11,7 +13,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 255 165 0 178 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 255 165 0 178 + end transform end clip end transform end transform diff --git a/test/api/results/test-20-0-116 b/test/api/results/test-20-0-116 index fdc4f9951..128dff31b 100644 --- a/test/api/results/test-20-0-116 +++ b/test/api/results/test-20-0-116 @@ -2,14 +2,18 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 0 0 255 127 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 0 255 127 + end transform end clip end transform push group start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 255 165 0 178 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 255 165 0 178 + end transform end clip end transform end transform diff --git a/test/api/results/test-20-0-123 b/test/api/results/test-20-0-123 index 40d40f843..f29e2ebcd 100644 --- a/test/api/results/test-20-0-123 +++ b/test/api/results/test-20-0-123 @@ -2,7 +2,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 3 - solid 0 0 0 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 0 0 255 + end transform end clip end transform pop group mode 3 @@ -13,7 +15,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 - solid 255 220 1 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 255 220 1 255 + end transform end clip end transform end transform @@ -25,7 +29,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 - solid 104 199 232 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 104 199 232 255 + end transform end clip end transform end transform diff --git a/test/api/results/test-20-0-165 b/test/api/results/test-20-0-165 index 8ce13633b..f67bfdd44 100644 --- a/test/api/results/test-20-0-165 +++ b/test/api/results/test-20-0-165 @@ -1,14 +1,16 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 165 - linear gradient - p0 100.000000 950.000000 - p1 2300.000000 950.000000 - p2 -1000.000000 250.000000 - colors - 0.000000 255 0 0 255 - 0.500000 0 0 255 255 - 1.000000 255 255 0 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + linear gradient + p0 100.000000 950.000000 + p1 2300.000000 950.000000 + p2 -1000.000000 250.000000 + colors + 0.000000 255 0 0 255 + 0.500000 0 0 255 255 + 1.000000 255 255 0 255 + end transform end clip end transform end transform diff --git a/test/api/results/test-20-0-175 b/test/api/results/test-20-0-175 index 4488375f9..4f9d775f2 100644 --- a/test/api/results/test-20-0-175 +++ b/test/api/results/test-20-0-175 @@ -3,7 +3,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 174 - solid 0 128 0 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 128 0 255 + end transform end clip end transform end transform @@ -12,13 +14,15 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 1.000000 0.000000 0.000000 1.000000 -150.000000 0.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 174 - linear gradient - p0 500.000000 250.000000 - p1 500.000000 950.000000 - p2 600.000000 250.000000 - colors - 0.000000 255 0 0 255 - 1.000000 0 0 255 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + linear gradient + p0 500.000000 250.000000 + p1 500.000000 950.000000 + p2 600.000000 250.000000 + colors + 0.000000 255 0 0 255 + 1.000000 0 0 255 255 + end transform end clip end transform end transform diff --git a/test/api/results/test-20-0-6 b/test/api/results/test-20-0-6 index 8fe765ac9..58bbfdc29 100644 --- a/test/api/results/test-20-0-6 +++ b/test/api/results/test-20-0-6 @@ -1,13 +1,15 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 6 - linear gradient - p0 100.000000 250.000000 - p1 900.000000 250.000000 - p2 100.000000 300.000000 - colors - 0.000000 255 0 0 255 - 1.000000 0 0 255 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + linear gradient + p0 100.000000 250.000000 + p1 900.000000 250.000000 + p2 100.000000 300.000000 + colors + 0.000000 255 0 0 255 + 1.000000 0 0 255 255 + end transform end clip end transform end transform diff --git a/test/api/results/test-20-0-92 b/test/api/results/test-20-0-92 index 7c7916dac..e130ab088 100644 --- a/test/api/results/test-20-0-92 +++ b/test/api/results/test-20-0-92 @@ -1,13 +1,15 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 - radial gradient - p0 166.000000 768.000000 radius 0.000000 - p1 166.000000 768.000000 radius 256.000000 - colors - 0.000000 0 128 0 255 - 0.500000 255 255 255 255 - 1.000000 255 0 0 255 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + radial gradient + p0 166.000000 768.000000 radius 0.000000 + p1 166.000000 768.000000 radius 256.000000 + colors + 0.000000 0 128 0 255 + 0.500000 255 255 255 255 + 1.000000 255 0 0 255 + end transform end clip end transform end transform diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 1bf287c58..061b6cedb 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -711,9 +711,9 @@ static colrv1_test_t colrv1_tests[] = { { TEST_GLYPHS, 20, 0, 165, 0, "test-20-0-165" }, { TEST_GLYPHS, 20, 0, 175, 0, "test-20-0-175" }, /* COLRv0 */ - { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-20-0.3-1" }, // A - { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-20-0-2" }, // B - { ROCHER_ABC, 120, 0, 3, 200, "rocher-20-0-3" }, // C + { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-120-0.3-1" }, // A + { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-120-0.3-2" }, // B + { ROCHER_ABC, 120, 0, 3, 200, "rocher-120-0-3" }, // C }; static void From a02c2a911cc59985db00b86b09ed77b755238291 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 22:05:09 -0700 Subject: [PATCH 161/219] [ft-paint] Apply alpha correctly --- src/hb-ft-colr.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 2eb5916f1..260225083 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -112,7 +112,7 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, color_stops->color = HB_COLOR (ft_color.blue, ft_color.green, ft_color.red, - ft_color.alpha); + (ft_color.alpha * stop.color.alpha) >> 14); } color_stops++; @@ -185,7 +185,7 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, color = HB_COLOR (ft_color.blue, ft_color.green, ft_color.red, - ft_color.alpha); + (ft_color.alpha * paint.u.solid.color.alpha) >> 14); } paint_funcs->color (paint_data, is_foreground, color); } From a634f6b48699b72b3f5bc57aad0c88c713e138f8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 00:18:40 -0500 Subject: [PATCH 162/219] [colr] Add more docs State explicitly that palette entries are unpremultipled, and link to the spec. --- src/hb-ot-color.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 734ac1022..4a2707e5a 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -167,6 +167,10 @@ hb_ot_color_palette_get_flags (hb_face_t *face, * for allocating a buffer of suitable size before calling * hb_ot_color_palette_get_colors() a second time. * + * The RGBA values in the palette are unpremultiplied. See the + * OpenType spec [CPAL](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal) + * section for details. + * * Return value: the total number of colors in the palette * * Since: 2.1.0 From 7a2dc5cf5b41058c6d598cd89f714d81ea325632 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Dec 2022 22:29:52 -0700 Subject: [PATCH 163/219] [docs] Hook up a couple --- docs/harfbuzz-sections.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index d9ad80b3a..e4f89d264 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -249,8 +249,10 @@ hb_paint_image_func_t hb_paint_funcs_set_image_func hb_color_line_t hb_color_stop_t +hb_color_line_get_color_stops_func_t hb_color_line_get_color_stops hb_paint_extend_t +hb_color_line_get_extend_func_t hb_color_line_get_extend hb_paint_linear_gradient_func_t hb_paint_funcs_set_linear_gradient_func From b6e98cf758b8f38c14dee28b57d63514ace1a97d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 00:18:40 -0500 Subject: [PATCH 164/219] [colr] Add more docs State explicitly that palette entries are unpremultipled, and link to the spec. --- src/hb-font.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index 903af6d98..28d3a4b2c 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1429,17 +1429,18 @@ hb_font_draw_glyph (hb_font_t *font, * @glyph: The glyph ID * @pfuncs: #hb_paint_funcs_t to paint with * @paint_data: User data to pass to paint callbacks - * @palette: The palette index to use - * @foreground: The foreground color + * @palette: The index of the font's color palette to use + * @foreground: The foreground color, unpremultipled * * Paints the glyph. * - * The painting instructions are returned by way of - * calls to the callbacks of the @funcs objects, - * with @paint_data passed to them. + * The painting instructions are returned by way of calls to + * the callbacks of the @funcs object, with @paint_data passed + * to them. * - * Note that this function applies the the scale and synthetic - * slant of the font as outermost transform. + * If the font has color palettes (see hb_ot_color_has_palettes()), + * then @palette selects the palette to use. If the font doesn't + * have palettes, passing 0 is fine. * * Since: REPLACEME */ From 21f78c87744c8a119f999f4b02c50009f681db33 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 00:30:40 -0500 Subject: [PATCH 165/219] [paint] Document that colors are unpremultiplied And mention that gradient interpolation must happen in premultiplied space. --- src/hb-paint.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hb-paint.h b/src/hb-paint.h index 630cd89d8..782d29b94 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -210,7 +210,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @is_foreground: whether the color is the foreground - * @color: The color to use + * @color: The color to use, unpremultiplied * @user_data: User data pointer passed to hb_paint_funcs_set_color_func() * * A virtual method for the #hb_paint_funcs_t to paint a @@ -291,13 +291,18 @@ typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, * hb_color_stop_t: * @offset: the offset of the color stop * @is_foreground: whether the color is the foreground - * @color: the color + * @color: the color, unpremultiplied * * Information about a color stop on a color line. * * Color lines typically have offsets ranging between 0 and 1, * but that is not required. * + * Note: despite @color being unpremultiplied here, interpolation in + * gradients shall happen in premultiplied space. See the OpenType spec + * [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr) + * section for details. + * * Since: REPLACEME */ typedef struct { From 13e0cb64f47f54c54651a239c8633f6d836ea9eb Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 00:54:05 -0500 Subject: [PATCH 166/219] hb-view: Interpolate gradients premultiplied This is what the specs demand. --- util/hb-cairo-utils.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 614d96eda..316f5480b 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -382,13 +382,37 @@ interpolate (float f0, float f1, float f) return f0 + f * (f1 - f0); } +static inline void +premultiply (color_t *c) +{ + c->r *= c->a; + c->g *= c->a; + c->b *= c->a; +} + +static inline void +unpremultiply (color_t *c) +{ + if (c->a != 0.) + { + c->r /= c->a; + c->g /= c->a; + c->b /= c->a; + } +} + static void interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) { + // According to the COLR specification, gradients + // should be interpolated in premultiplied form + premultiply (c0); + premultiply (c1); c->r = c0->r + k * (c1->r - c0->r); c->g = c0->g + k * (c1->g - c0->g); c->b = c0->b + k * (c1->b - c0->b); c->a = c0->a + k * (c1->a - c0->a); + unpremultiply (c); } static inline float From 07ba5be393f43ea8584074c61a463717ef33d72f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 01:10:35 -0500 Subject: [PATCH 167/219] [paint] Documentation tweaks --- src/hb-paint.cc | 9 +++++---- src/hb-paint.h | 15 +++++---------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 209ca98f6..9ae01a235 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -36,10 +36,11 @@ * * Functions for painting glyphs. * - * The main purpose of these functions is to paint - * (extract) color glyph layers from the COLRv1 table, - * but the API works for drawing ordinary outlines - * and images as well. + * The main purpose of these functions is to paint (extract) color glyph layers + * from the COLRv1 table, but the API works for drawing ordinary outlines and + * images as well. + * + * The #hb_paint_funcs_t struct can be used with hb_font_paint_glyph(). **/ static void diff --git a/src/hb-paint.h b/src/hb-paint.h index 782d29b94..673b9723f 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -44,15 +44,11 @@ HB_BEGIN_DECLS * push/pop calls will be properly nested, so it is fine * to store the different kinds of object on a single stack. * - * The callbacks also assume that the caller uses - * hb_ot_color_palette_get_colors() to obtain colors - * from the color palette that is selected. If the font does - * not have color palettes, the color index will always - * be 0xFFFF, indicating the use of the foreground color. - * * Not all callbacks are required for all kinds of glyphs. * For rendering COLRv0 or non-color outline glyphs, the - * gradient and composite callbacks are not needed. + * gradient callbacks are not needed, and the composite + * callback only needs to handle simple alpha compositing + * (#HB_PAINT_COMPOSITE_MODE_SRC_OVER). * * The paint-image callback is only needed for glyphs * with image blobs in the CBDT, sbix or SVG tables. @@ -264,10 +260,9 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @extents: (nullable): glyph extents for desired rendering * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * - * A virtual method for the #hb_paint_funcs_t to paint the - * glyph image. + * A virtual method for the #hb_paint_funcs_t to paint a glyph image. * - * This method is intended for glyphs with image blobs in the CBDT, + * This method is called for glyphs with image blobs in the CBDT, * sbix or SVG tables. The @format identifies the kind of data that * is contained in @image. Possible values include #HB_PAINT_IMAGE_FORMAT_PNG * #HB_PAINT_IMAGE_FORMAT_SVG and #HB_PAINT_IMAGE_FORMAT_BGRA. From 0d5256e5a729552a6c9b292c42928fc3734a95a7 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 02:41:08 -0500 Subject: [PATCH 168/219] [ft-paint] Fix some fixed->float conversions --- src/hb-ft-colr.hh | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 260225083..fcf0e4f33 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -99,7 +99,7 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, &stop, &c->color_stop_iterator)) { - color_stops->offset = stop.stop_offset / 65536.f; + color_stops->offset = stop.stop_offset / 16384.f; color_stops->is_foreground = stop.color.palette_index == 0xFFFF; if (color_stops->is_foreground) color_stops->color = HB_COLOR (hb_color_get_blue (data->foreground), @@ -200,12 +200,12 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, }; paint_funcs->linear_gradient (paint_data, &cl, - paint.u.linear_gradient.p0.x, - paint.u.linear_gradient.p0.y, - paint.u.linear_gradient.p1.x, - paint.u.linear_gradient.p1.y, - paint.u.linear_gradient.p2.x, - paint.u.linear_gradient.p2.y); + paint.u.linear_gradient.p0.x / 65535.f, + paint.u.linear_gradient.p0.y / 65535.f, + paint.u.linear_gradient.p1.x / 65535.f, + paint.u.linear_gradient.p1.y / 65535.f, + paint.u.linear_gradient.p2.x / 65535.f, + paint.u.linear_gradient.p2.y / 65535.f); } break; case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: @@ -218,12 +218,12 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, }; paint_funcs->radial_gradient (paint_data, &cl, - paint.u.radial_gradient.c0.x, - paint.u.radial_gradient.c0.y, - paint.u.radial_gradient.r0, - paint.u.radial_gradient.c1.x, - paint.u.radial_gradient.c1.y, - paint.u.radial_gradient.r1); + paint.u.radial_gradient.c0.x / 65535.f, + paint.u.radial_gradient.c0.y / 65535.f, + (paint.u.radial_gradient.r0 / 65535.f), + paint.u.radial_gradient.c1.x / 65535.f, + paint.u.radial_gradient.c1.y / 65535.f, + (paint.u.radial_gradient.r1 / 65535.f)); } break; case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: @@ -236,8 +236,8 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, }; paint_funcs->sweep_gradient (paint_data, &cl, - paint.u.sweep_gradient.center.x, - paint.u.sweep_gradient.center.y, + paint.u.sweep_gradient.center.x / 65535.f, + paint.u.sweep_gradient.center.y / 65535.f, (paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI, (paint.u.sweep_gradient.end_angle / 65536.f + 1) * (float) M_PI); } From fe08e956e0eb89ca26547b00d0a3191db9011af9 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 09:08:10 -0500 Subject: [PATCH 169/219] [ft-paint] Fix a case of x/y confusion --- src/hb-ft-colr.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index fcf0e4f33..7c39bb9e3 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -293,9 +293,9 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, +paint.u.scale.center_x / 65536.f, +paint.u.scale.center_y / 65536.f); paint_funcs->push_transform (paint_data, - paint.u.scale.scale_y / 65536.f, - 0.f, 0.f, paint.u.scale.scale_x / 65536.f, + 0.f, 0.f, + paint.u.scale.scale_y / 65536.f, 0.f, 0.f); paint_funcs->push_transform (paint_data, 1.f, 0.f, 0.f, 1.f, From 092637f94c60bc56ba135bbce1905275bde0925d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 09:14:11 -0500 Subject: [PATCH 170/219] [ft-paint] Fix rounding --- src/hb-ft-colr.hh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 7c39bb9e3..abb5ff4c3 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -200,12 +200,12 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, }; paint_funcs->linear_gradient (paint_data, &cl, - paint.u.linear_gradient.p0.x / 65535.f, - paint.u.linear_gradient.p0.y / 65535.f, - paint.u.linear_gradient.p1.x / 65535.f, - paint.u.linear_gradient.p1.y / 65535.f, - paint.u.linear_gradient.p2.x / 65535.f, - paint.u.linear_gradient.p2.y / 65535.f); + paint.u.linear_gradient.p0.x / 65536.f, + paint.u.linear_gradient.p0.y / 65536.f, + paint.u.linear_gradient.p1.x / 65536.f, + paint.u.linear_gradient.p1.y / 65536.f, + paint.u.linear_gradient.p2.x / 65536.f, + paint.u.linear_gradient.p2.y / 65536.f); } break; case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: @@ -218,12 +218,12 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, }; paint_funcs->radial_gradient (paint_data, &cl, - paint.u.radial_gradient.c0.x / 65535.f, - paint.u.radial_gradient.c0.y / 65535.f, - (paint.u.radial_gradient.r0 / 65535.f), - paint.u.radial_gradient.c1.x / 65535.f, - paint.u.radial_gradient.c1.y / 65535.f, - (paint.u.radial_gradient.r1 / 65535.f)); + paint.u.radial_gradient.c0.x / 65536.f, + paint.u.radial_gradient.c0.y / 65536.f, + (paint.u.radial_gradient.r0 / 65536.f), + paint.u.radial_gradient.c1.x / 65536.f, + paint.u.radial_gradient.c1.y / 65536.f, + (paint.u.radial_gradient.r1 / 65536.f)); } break; case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: @@ -236,8 +236,8 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, }; paint_funcs->sweep_gradient (paint_data, &cl, - paint.u.sweep_gradient.center.x / 65535.f, - paint.u.sweep_gradient.center.y / 65535.f, + paint.u.sweep_gradient.center.x / 65536.f, + paint.u.sweep_gradient.center.y / 65536.f, (paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI, (paint.u.sweep_gradient.end_angle / 65536.f + 1) * (float) M_PI); } From 586d1758c1aecf995de85020cb608f3fe5d859cf Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 09:21:14 -0500 Subject: [PATCH 171/219] [ft-paint] Fix an oversight --- src/hb-ft-colr.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index abb5ff4c3..9034585c7 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -407,6 +407,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, clip_box.bottom_left.y, clip_box.top_right.x, clip_box.top_right.y); + pop_clip = true; } _hb_ft_paint (paint, From 7fc3fdac761670d9c223768c128f5225a87b47df Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 09:16:26 -0500 Subject: [PATCH 172/219] [ft-paint] Optimize away some transforms --- src/hb-ft-colr.hh | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 9034585c7..fa215e38f 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -288,23 +288,29 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, break; case FT_COLR_PAINTFORMAT_SCALE: { - paint_funcs->push_transform (paint_data, - 1.f, 0.f, 0.f, 1.f, - +paint.u.scale.center_x / 65536.f, - +paint.u.scale.center_y / 65536.f); + bool has_translate = paint.u.scale.center_x != 0 || paint.u.scale.center_y != 0; + if (has_translate) + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + +paint.u.scale.center_x / 65536.f, + +paint.u.scale.center_y / 65536.f); paint_funcs->push_transform (paint_data, paint.u.scale.scale_x / 65536.f, 0.f, 0.f, paint.u.scale.scale_y / 65536.f, 0.f, 0.f); - paint_funcs->push_transform (paint_data, - 1.f, 0.f, 0.f, 1.f, - -paint.u.scale.center_x / 65536.f, - -paint.u.scale.center_y / 65536.f); + if (has_translate) + paint_funcs->push_transform (paint_data, + 1.f, 0.f, 0.f, 1.f, + -paint.u.scale.center_x / 65536.f, + -paint.u.scale.center_y / 65536.f); paint_recurse (paint.u.scale.paint); paint_funcs->pop_transform (paint_data); - paint_funcs->pop_transform (paint_data); - paint_funcs->pop_transform (paint_data); + if (has_translate) + { + paint_funcs->pop_transform (paint_data); + paint_funcs->pop_transform (paint_data); + } } break; case FT_COLR_PAINTFORMAT_ROTATE: From c11ae85cbfa7b7a13577a058544a39146fc81bbf Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 09:20:45 -0500 Subject: [PATCH 173/219] [ft-paint] Apply root transform --- src/hb-ft-colr.hh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index fa215e38f..3ad664cf3 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -244,13 +244,15 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, break; case FT_COLR_PAINTFORMAT_GLYPH: { - //paint_funcs->push_inverse_root_transform (paint_data, font); + paint_funcs->push_inverse_root_transform (paint_data, font); ft_font->lock.unlock (); paint_funcs->push_clip_glyph (paint_data, paint.u.glyph.glyphID, font); ft_font->lock.lock (); + paint_funcs->push_root_transform (paint_data, font); paint_recurse (paint.u.glyph.paint); + paint_funcs->pop_root_transform (paint_data); paint_funcs->pop_clip (paint_data); - //paint_funcs->pop_inverse_root_transform (paint_data); + paint_funcs->pop_inverse_root_transform (paint_data); } break; case FT_COLR_PAINTFORMAT_COLR_GLYPH: @@ -416,11 +418,13 @@ hb_ft_paint_glyph_colr (hb_font_t *font, pop_clip = true; } + paint_funcs->push_root_transform (paint_data, font); _hb_ft_paint (paint, ft_font, font, paint_funcs, paint_data, palette, foreground); + paint_funcs->pop_root_transform (paint_data); if (pop_clip) paint_funcs->pop_clip (paint_data); From 393bab4ba1e5938843f83cc824e4a4142b42ff56 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 11:02:38 -0500 Subject: [PATCH 174/219] [ft-paint] Apply ClipBox to all glyphs --- src/hb-ft-colr.hh | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 3ad664cf3..4d8e24124 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -262,7 +262,22 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID, FT_COLOR_NO_ROOT_TRANSFORM, &other_paint)) + { + bool has_clip_box; + FT_ClipBox clip_box; + has_clip_box = FT_Get_Color_Glyph_ClipBox (ft_face, paint.u.colr_glyph.glyphID, &clip_box); + has_clip_box = 0; + + if (has_clip_box) + paint_funcs->push_clip_rectangle (paint_data, + clip_box.bottom_left.x / 64.f, + clip_box.bottom_left.y / 64.f, + clip_box.top_right.x / 64.f, + clip_box.top_right.y / 64.f); paint_recurse (other_paint); + if (has_clip_box) + paint_funcs->pop_clip (paint_data); + } } break; case FT_COLR_PAINTFORMAT_TRANSFORM: @@ -405,28 +420,26 @@ hb_ft_paint_glyph_colr (hb_font_t *font, &paint)) { FT_ClipBox clip_box; - bool pop_clip = false; - if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, - &clip_box)) - { - /* TODO mult's like hb-ft. */ + bool has_clip; + + has_clip = FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box); + if (has_clip) paint_funcs->push_clip_rectangle (paint_data, - clip_box.bottom_left.x, - clip_box.bottom_left.y, - clip_box.top_right.x, - clip_box.top_right.y); - pop_clip = true; - } + clip_box.bottom_left.x, + clip_box.bottom_left.y, + clip_box.top_right.x, + clip_box.top_right.y); paint_funcs->push_root_transform (paint_data, font); + _hb_ft_paint (paint, ft_font, font, paint_funcs, paint_data, - palette, foreground); - paint_funcs->pop_root_transform (paint_data); + palette, foreground); - if (pop_clip) + paint_funcs->pop_root_transform (paint_data); + if (has_clip) paint_funcs->pop_clip (paint_data); return true; From 7abd5dcf10ea06fb5ba48077734222e7acc41065 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 11:49:06 -0500 Subject: [PATCH 175/219] [ft-paint] Fix handling of colorstop iters --- src/hb-ft-colr.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 4d8e24124..be8e940d2 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -91,6 +91,7 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, { FT_ColorStop stop; unsigned wrote = 0; + FT_ColorStopIterator iter = c->color_stop_iterator; c->color_stop_iterator.current_color_stop = start; @@ -118,7 +119,11 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, color_stops++; wrote++; } + *count = wrote; + + // reset the iterator for next time + c->color_stop_iterator = iter; } return c->color_stop_iterator.num_color_stops; From 15582d5fc164f8e0a4b5f2df5ef246e213cd85d2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 11:14:16 -0700 Subject: [PATCH 176/219] [ft-colr] Apply slant to clipbox --- src/hb-ft-colr.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index be8e940d2..c0e29ebfe 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -430,9 +430,9 @@ hb_ft_paint_glyph_colr (hb_font_t *font, has_clip = FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box); if (has_clip) paint_funcs->push_clip_rectangle (paint_data, - clip_box.bottom_left.x, + clip_box.bottom_left.x - font->slant_xy * clip_box.bottom_left.y, clip_box.bottom_left.y, - clip_box.top_right.x, + clip_box.top_right.x - font->slant_xy * clip_box.top_right.y, clip_box.top_right.y); paint_funcs->push_root_transform (paint_data, font); From bbb89e62aa5f876dc0b9348f11ce6a24ab032e47 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 13:30:26 -0500 Subject: [PATCH 177/219] [paint] Document color lines as transient Just so people don't get ideas. --- src/hb-paint.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hb-paint.h b/src/hb-paint.h index 673b9723f..a76d5392b 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -386,6 +386,9 @@ hb_color_line_get_extend (hb_color_line_t *color_line); * A virtual method for the #hb_paint_funcs_t to paint a linear * gradient everywhere within the current clip. * + * The @color_line object contains information about the colors of the gradients. + * It is only valid for the duration of the callback, you cannot keep it around. + * * The coordinates of the points are interpreted according * to the current transform. * @@ -419,6 +422,9 @@ typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, * A virtual method for the #hb_paint_funcs_t to paint a radial * gradient everywhere within the current clip. * + * The @color_line object contains information about the colors of the gradients. + * It is only valid for the duration of the callback, you cannot keep it around. + * * The coordinates of the points are interpreted according * to the current transform. * @@ -449,6 +455,9 @@ typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, * A virtual method for the #hb_paint_funcs_t to paint a sweep * gradient everywhere within the current clip. * + * The @color_line object contains information about the colors of the gradients. + * It is only valid for the duration of the callback, you cannot keep it around. + * * The coordinates of the points are interpreted according * to the current transform. * From c453c2fce990b066155ccb72d8a39eba55e42a2d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 11:33:23 -0700 Subject: [PATCH 178/219] [ft-colr] Fix color-stop iteration --- src/hb-ft-colr.hh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index c0e29ebfe..db52d8d0b 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -93,7 +93,16 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, unsigned wrote = 0; FT_ColorStopIterator iter = c->color_stop_iterator; - c->color_stop_iterator.current_color_stop = start; + if (start >= c->color_stop_iterator.num_color_stops) + { + *count = 0; + return c->color_stop_iterator.num_color_stops; + } + + while (c->color_stop_iterator.current_color_stop < start) + FT_Get_Colorline_Stops(data->face, + &stop, + &c->color_stop_iterator); while (count && *count && FT_Get_Colorline_Stops(data->face, From 7a4b4c64f2f71e3b66833222a153a3f7b56300b3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 11:36:04 -0700 Subject: [PATCH 179/219] [ft-colr] Minor macro --- src/hb-ft-colr.hh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index db52d8d0b..ad5be26d2 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -398,7 +398,6 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, default: HB_FALLTHROUGH; case FT_COLR_PAINTFORMAT_UNSUPPORTED: break; } -#undef paint_recurse } static bool @@ -446,11 +445,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, paint_funcs->push_root_transform (paint_data, font); - _hb_ft_paint (paint, - ft_font, - font, - paint_funcs, paint_data, - palette, foreground); + paint_recurse (paint); paint_funcs->pop_root_transform (paint_data); if (has_clip) @@ -500,6 +495,8 @@ hb_ft_paint_glyph_colr (hb_font_t *font, return false; } +#undef paint_recurse + #endif From 882c2bca2dcc898b6aa884605013c2609dd775ba Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 11:48:41 -0700 Subject: [PATCH 180/219] [ft-colr] Add a paint context --- src/hb-ft-colr.hh | 167 ++++++++++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 72 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index ad5be26d2..0502bb8ed 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -153,22 +153,43 @@ _hb_ft_color_line_get_extend (hb_color_line_t *color_line, } } +typedef struct hb_ft_paint_context_t hb_ft_paint_context_t; + static void -_hb_ft_paint (FT_OpaquePaint opaque_paint, - const hb_ft_font_t *ft_font, - hb_font_t *font, - hb_paint_funcs_t *paint_funcs, void *paint_data, - FT_Color *palette, - hb_color_t foreground) +_hb_ft_paint (hb_ft_paint_context_t *c, + FT_OpaquePaint opaque_paint); + +struct hb_ft_paint_context_t { - FT_Face ft_face = ft_font->ft_face; + hb_ft_paint_context_t (const hb_ft_font_t *ft_font, + hb_font_t *font, + hb_paint_funcs_t *paint_funcs, void *paint_data, + FT_Color *palette, + hb_color_t foreground) : + ft_font (ft_font), font(font), + funcs (paint_funcs), data (paint_data), + palette (palette), foreground (foreground) {} + + void recurse (FT_OpaquePaint paint) { _hb_ft_paint (this, paint); + } + + const hb_ft_font_t *ft_font; + hb_font_t *font; + hb_paint_funcs_t *funcs; + void *data; + FT_Color *palette; + hb_color_t foreground; +}; + +void +_hb_ft_paint (hb_ft_paint_context_t *c, + FT_OpaquePaint opaque_paint) +{ + FT_Face ft_face = c->ft_font->ft_face; FT_COLR_Paint paint; if (!FT_Get_Paint (ft_face, opaque_paint, &paint)) return; -#define paint_recurse(other_paint) \ - _hb_ft_paint (other_paint, ft_font, font, paint_funcs, paint_data, palette, foreground) - switch (paint.format) { case FT_COLR_PAINTFORMAT_COLR_LAYERS: @@ -178,9 +199,9 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, &paint.u.colr_layers.layer_iterator, &other_paint)) { - paint_funcs->push_group (paint_data); - paint_recurse (other_paint); - paint_funcs->pop_group (paint_data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + c->funcs->push_group (c->data); + c->recurse (other_paint); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } } break; @@ -189,31 +210,31 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, bool is_foreground = paint.u.solid.color.palette_index == 0xFFFF; hb_color_t color; if (is_foreground) - color = HB_COLOR (hb_color_get_blue (foreground), - hb_color_get_green (foreground), - hb_color_get_red (foreground), - (hb_color_get_alpha (foreground) * paint.u.solid.color.alpha) >> 14); + color = HB_COLOR (hb_color_get_blue (c->foreground), + hb_color_get_green (c->foreground), + hb_color_get_red (c->foreground), + (hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14); else { - FT_Color ft_color = palette[paint.u.solid.color.palette_index]; + FT_Color ft_color = c->palette[paint.u.solid.color.palette_index]; color = HB_COLOR (ft_color.blue, ft_color.green, ft_color.red, (ft_color.alpha * paint.u.solid.color.alpha) >> 14); } - paint_funcs->color (paint_data, is_foreground, color); + c->funcs->color (c->data, is_foreground, color); } break; case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT: { - _hb_ft_get_color_stops_data_t data = {ft_face, palette, foreground}; + _hb_ft_get_color_stops_data_t data = {ft_face, c->palette, c->foreground}; hb_color_line_t cl = { &paint.u.linear_gradient.colorline, _hb_ft_color_line_get_color_stops, &data, _hb_ft_color_line_get_extend, nullptr }; - paint_funcs->linear_gradient (paint_data, &cl, + c->funcs->linear_gradient (c->data, &cl, paint.u.linear_gradient.p0.x / 65536.f, paint.u.linear_gradient.p0.y / 65536.f, paint.u.linear_gradient.p1.x / 65536.f, @@ -224,14 +245,14 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, break; case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: { - _hb_ft_get_color_stops_data_t data = {ft_face, palette, foreground}; + _hb_ft_get_color_stops_data_t data = {ft_face, c->palette, c->foreground}; hb_color_line_t cl = { &paint.u.linear_gradient.colorline, _hb_ft_color_line_get_color_stops, &data, _hb_ft_color_line_get_extend, nullptr }; - paint_funcs->radial_gradient (paint_data, &cl, + c->funcs->radial_gradient (c->data, &cl, paint.u.radial_gradient.c0.x / 65536.f, paint.u.radial_gradient.c0.y / 65536.f, (paint.u.radial_gradient.r0 / 65536.f), @@ -242,14 +263,14 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, break; case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: { - _hb_ft_get_color_stops_data_t data = {ft_face, palette, foreground}; + _hb_ft_get_color_stops_data_t data = {ft_face, c->palette, c->foreground}; hb_color_line_t cl = { &paint.u.linear_gradient.colorline, _hb_ft_color_line_get_color_stops, &data, _hb_ft_color_line_get_extend, nullptr }; - paint_funcs->sweep_gradient (paint_data, &cl, + c->funcs->sweep_gradient (c->data, &cl, paint.u.sweep_gradient.center.x / 65536.f, paint.u.sweep_gradient.center.y / 65536.f, (paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI, @@ -258,15 +279,15 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, break; case FT_COLR_PAINTFORMAT_GLYPH: { - paint_funcs->push_inverse_root_transform (paint_data, font); - ft_font->lock.unlock (); - paint_funcs->push_clip_glyph (paint_data, paint.u.glyph.glyphID, font); - ft_font->lock.lock (); - paint_funcs->push_root_transform (paint_data, font); - paint_recurse (paint.u.glyph.paint); - paint_funcs->pop_root_transform (paint_data); - paint_funcs->pop_clip (paint_data); - paint_funcs->pop_inverse_root_transform (paint_data); + c->funcs->push_inverse_root_transform (c->data, c->font); + c->ft_font->lock.unlock (); + c->funcs->push_clip_glyph (c->data, paint.u.glyph.glyphID, c->font); + c->ft_font->lock.lock (); + c->funcs->push_root_transform (c->data, c->font); + c->recurse (paint.u.glyph.paint); + c->funcs->pop_root_transform (c->data); + c->funcs->pop_clip (c->data); + c->funcs->pop_inverse_root_transform (c->data); } break; case FT_COLR_PAINTFORMAT_COLR_GLYPH: @@ -283,64 +304,64 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, has_clip_box = 0; if (has_clip_box) - paint_funcs->push_clip_rectangle (paint_data, + c->funcs->push_clip_rectangle (c->data, clip_box.bottom_left.x / 64.f, clip_box.bottom_left.y / 64.f, clip_box.top_right.x / 64.f, clip_box.top_right.y / 64.f); - paint_recurse (other_paint); + c->recurse (other_paint); if (has_clip_box) - paint_funcs->pop_clip (paint_data); + c->funcs->pop_clip (c->data); } } break; case FT_COLR_PAINTFORMAT_TRANSFORM: { - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, paint.u.transform.affine.xx / 65536.f, paint.u.transform.affine.yx / 65536.f, paint.u.transform.affine.xy / 65536.f, paint.u.transform.affine.yy / 65536.f, paint.u.transform.affine.dx / 65536.f, paint.u.transform.affine.dy / 65536.f); - paint_recurse (paint.u.transform.paint); - paint_funcs->pop_transform (paint_data); + c->recurse (paint.u.transform.paint); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_TRANSLATE: { - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, 0.f, 0.f, 0.f, 0.f, paint.u.translate.dx / 65536.f, paint.u.translate.dy / 65536.f); - paint_recurse (paint.u.translate.paint); - paint_funcs->pop_transform (paint_data); + c->recurse (paint.u.translate.paint); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_SCALE: { bool has_translate = paint.u.scale.center_x != 0 || paint.u.scale.center_y != 0; if (has_translate) - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, 1.f, 0.f, 0.f, 1.f, +paint.u.scale.center_x / 65536.f, +paint.u.scale.center_y / 65536.f); - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, paint.u.scale.scale_x / 65536.f, 0.f, 0.f, paint.u.scale.scale_y / 65536.f, 0.f, 0.f); if (has_translate) - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, 1.f, 0.f, 0.f, 1.f, -paint.u.scale.center_x / 65536.f, -paint.u.scale.center_y / 65536.f); - paint_recurse (paint.u.scale.paint); - paint_funcs->pop_transform (paint_data); + c->recurse (paint.u.scale.paint); + c->funcs->pop_transform (c->data); if (has_translate) { - paint_funcs->pop_transform (paint_data); - paint_funcs->pop_transform (paint_data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } } break; @@ -349,48 +370,48 @@ _hb_ft_paint (FT_OpaquePaint opaque_paint, float a = paint.u.rotate.angle / 65536.f; float cc = cosf (a * (float) M_PI); float ss = sinf (a * (float) M_PI); - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, 1.f, 0.f, 0.f, 1.f, +paint.u.rotate.center_x / 65536.f, +paint.u.rotate.center_y / 65536.f); - paint_funcs->push_transform (paint_data, cc, ss, -ss, cc, 0., 0.); - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); + c->funcs->push_transform (c->data, 1.f, 0.f, 0.f, 1.f, -paint.u.rotate.center_x / 65536.f, -paint.u.rotate.center_y / 65536.f); - paint_recurse (paint.u.rotate.paint); - paint_funcs->pop_transform (paint_data); - paint_funcs->pop_transform (paint_data); - paint_funcs->pop_transform (paint_data); + c->recurse (paint.u.rotate.paint); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_SKEW: { float x = +tanf (paint.u.skew.x_skew_angle / 65536.f * (float) M_PI); float y = -tanf (paint.u.skew.y_skew_angle / 65536.f * (float) M_PI); - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, 1.f, 0.f, 0.f, 1.f, +paint.u.skew.center_x / 65536.f, +paint.u.skew.center_y / 65536.f); - paint_funcs->push_transform (paint_data, 1., y, x, 1., 0., 0.); - paint_funcs->push_transform (paint_data, + c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); + c->funcs->push_transform (c->data, 1.f, 0.f, 0.f, 1.f, -paint.u.skew.center_x / 65536.f, -paint.u.skew.center_y / 65536.f); - paint_recurse (paint.u.skew.paint); - paint_funcs->pop_transform (paint_data); - paint_funcs->pop_transform (paint_data); - paint_funcs->pop_transform (paint_data); + c->recurse (paint.u.skew.paint); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_COMPOSITE: { - paint_funcs->push_group (paint_data); - paint_recurse (paint.u.composite.backdrop_paint); - paint_funcs->push_group (paint_data); - paint_recurse (paint.u.composite.source_paint); - paint_funcs->pop_group (paint_data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode)); - paint_funcs->pop_group (paint_data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + c->funcs->push_group (c->data); + c->recurse (paint.u.composite.backdrop_paint); + c->funcs->push_group (c->data); + c->recurse (paint.u.composite.source_paint); + c->funcs->pop_group (c->data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode)); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } break; @@ -445,7 +466,10 @@ hb_ft_paint_glyph_colr (hb_font_t *font, paint_funcs->push_root_transform (paint_data, font); - paint_recurse (paint); + hb_ft_paint_context_t c (ft_font, font, + paint_funcs, paint_data, + palette, foreground); + _hb_ft_paint (&c, paint); paint_funcs->pop_root_transform (paint_data); if (has_clip) @@ -495,7 +519,6 @@ hb_ft_paint_glyph_colr (hb_font_t *font, return false; } -#undef paint_recurse #endif From 1cc3b10008a2ae52b83466bb0039e2b8d99f7a28 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 11:55:55 -0700 Subject: [PATCH 181/219] [ft-colr] Ifdef build for older freetype --- src/hb-ft-colr.hh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 0502bb8ed..c5124a48c 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -27,9 +27,12 @@ #include "hb.hh" +#include FT_COLOR_H #ifndef HB_NO_PAINT +#ifdef TT_SUPPORT_COLRV1 + static hb_paint_composite_mode_t _hb_ft_paint_composite_mode (FT_Composite_Mode mode) { @@ -421,6 +424,8 @@ _hb_ft_paint (hb_ft_paint_context_t *c, } } +#endif + static bool hb_ft_paint_glyph_colr (hb_font_t *font, void *font_data, @@ -447,6 +452,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, if (error) palette = NULL; +#ifdef TT_SUPPORT_COLRV1 /* COLRv1 */ FT_OpaquePaint paint = {0}; if (FT_Get_Color_Glyph_Paint (ft_face, gid, @@ -477,6 +483,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, return true; } +#endif /* COLRv0 */ iterator.p = NULL; From 3a1385f019082575e93bb92be870e1b5d9c76134 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 12:06:18 -0700 Subject: [PATCH 182/219] [ft-colr] Simplify color-stop callback --- src/hb-ft-colr.hh | 170 ++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 90 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index c5124a48c..1eb1e1ff5 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -72,90 +72,6 @@ _hb_ft_paint_composite_mode (FT_Composite_Mode mode) } } -typedef struct -{ - FT_Face face; - FT_Color *palette; - hb_color_t foreground; -} _hb_ft_get_color_stops_data_t; - -static unsigned -_hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, - void *color_line_data, - unsigned int start, - unsigned int *count, - hb_color_stop_t *color_stops, - void *user_data) -{ - FT_ColorLine *c = (FT_ColorLine *) color_line_data; - _hb_ft_get_color_stops_data_t *data = (_hb_ft_get_color_stops_data_t *) user_data; - - if (count) - { - FT_ColorStop stop; - unsigned wrote = 0; - FT_ColorStopIterator iter = c->color_stop_iterator; - - if (start >= c->color_stop_iterator.num_color_stops) - { - *count = 0; - return c->color_stop_iterator.num_color_stops; - } - - while (c->color_stop_iterator.current_color_stop < start) - FT_Get_Colorline_Stops(data->face, - &stop, - &c->color_stop_iterator); - - while (count && *count && - FT_Get_Colorline_Stops(data->face, - &stop, - &c->color_stop_iterator)) - { - color_stops->offset = stop.stop_offset / 16384.f; - color_stops->is_foreground = stop.color.palette_index == 0xFFFF; - if (color_stops->is_foreground) - color_stops->color = HB_COLOR (hb_color_get_blue (data->foreground), - hb_color_get_green (data->foreground), - hb_color_get_red (data->foreground), - (hb_color_get_alpha (data->foreground) * stop.color.alpha) >> 14); - else - { - FT_Color ft_color = data->palette[stop.color.palette_index]; - color_stops->color = HB_COLOR (ft_color.blue, - ft_color.green, - ft_color.red, - (ft_color.alpha * stop.color.alpha) >> 14); - } - - color_stops++; - wrote++; - } - - *count = wrote; - - // reset the iterator for next time - c->color_stop_iterator = iter; - } - - return c->color_stop_iterator.num_color_stops; -} - -static hb_paint_extend_t -_hb_ft_color_line_get_extend (hb_color_line_t *color_line, - void *color_line_data, - void *user_data) -{ - FT_ColorLine *c = (FT_ColorLine *) color_line_data; - switch (c->extend) - { - default: - case FT_COLR_PAINT_EXTEND_PAD: return HB_PAINT_EXTEND_PAD; - case FT_COLR_PAINT_EXTEND_REPEAT: return HB_PAINT_EXTEND_REPEAT; - case FT_COLR_PAINT_EXTEND_REFLECT: return HB_PAINT_EXTEND_REFLECT; - } -} - typedef struct hb_ft_paint_context_t hb_ft_paint_context_t; static void @@ -184,6 +100,83 @@ struct hb_ft_paint_context_t hb_color_t foreground; }; +static unsigned +_hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, + void *color_line_data, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops, + void *user_data) +{ + FT_ColorLine *cl = (FT_ColorLine *) color_line_data; + hb_ft_paint_context_t *c = (hb_ft_paint_context_t *) user_data; + + if (count) + { + FT_ColorStop stop; + unsigned wrote = 0; + FT_ColorStopIterator iter = cl->color_stop_iterator; + + if (start >= cl->color_stop_iterator.num_color_stops) + { + *count = 0; + return cl->color_stop_iterator.num_color_stops; + } + + while (cl->color_stop_iterator.current_color_stop < start) + FT_Get_Colorline_Stops(c->ft_font->ft_face, + &stop, + &cl->color_stop_iterator); + + while (count && *count && + FT_Get_Colorline_Stops(c->ft_font->ft_face, + &stop, + &cl->color_stop_iterator)) + { + color_stops->offset = stop.stop_offset / 16384.f; + color_stops->is_foreground = stop.color.palette_index == 0xFFFF; + if (color_stops->is_foreground) + color_stops->color = HB_COLOR (hb_color_get_blue (c->foreground), + hb_color_get_green (c->foreground), + hb_color_get_red (c->foreground), + (hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14); + else + { + FT_Color ft_color = c->palette[stop.color.palette_index]; + color_stops->color = HB_COLOR (ft_color.blue, + ft_color.green, + ft_color.red, + (ft_color.alpha * stop.color.alpha) >> 14); + } + + color_stops++; + wrote++; + } + + *count = wrote; + + // reset the iterator for next time + cl->color_stop_iterator = iter; + } + + return cl->color_stop_iterator.num_color_stops; +} + +static hb_paint_extend_t +_hb_ft_color_line_get_extend (hb_color_line_t *color_line, + void *color_line_data, + void *user_data) +{ + FT_ColorLine *c = (FT_ColorLine *) color_line_data; + switch (c->extend) + { + default: + case FT_COLR_PAINT_EXTEND_PAD: return HB_PAINT_EXTEND_PAD; + case FT_COLR_PAINT_EXTEND_REPEAT: return HB_PAINT_EXTEND_REPEAT; + case FT_COLR_PAINT_EXTEND_REFLECT: return HB_PAINT_EXTEND_REFLECT; + } +} + void _hb_ft_paint (hb_ft_paint_context_t *c, FT_OpaquePaint opaque_paint) @@ -230,10 +223,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT: { - _hb_ft_get_color_stops_data_t data = {ft_face, c->palette, c->foreground}; hb_color_line_t cl = { &paint.u.linear_gradient.colorline, - _hb_ft_color_line_get_color_stops, &data, + _hb_ft_color_line_get_color_stops, c, _hb_ft_color_line_get_extend, nullptr }; @@ -248,10 +240,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: { - _hb_ft_get_color_stops_data_t data = {ft_face, c->palette, c->foreground}; hb_color_line_t cl = { &paint.u.linear_gradient.colorline, - _hb_ft_color_line_get_color_stops, &data, + _hb_ft_color_line_get_color_stops, c, _hb_ft_color_line_get_extend, nullptr }; @@ -266,10 +257,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: { - _hb_ft_get_color_stops_data_t data = {ft_face, c->palette, c->foreground}; hb_color_line_t cl = { &paint.u.linear_gradient.colorline, - _hb_ft_color_line_get_color_stops, &data, + _hb_ft_color_line_get_color_stops, c, _hb_ft_color_line_get_extend, nullptr }; From 276290390952d0ad26f77247675ad023e0651856 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 12:09:17 -0700 Subject: [PATCH 183/219] [ft-colr] Minor --- src/hb-ft-colr.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 1eb1e1ff5..070c43e61 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -249,10 +249,10 @@ _hb_ft_paint (hb_ft_paint_context_t *c, c->funcs->radial_gradient (c->data, &cl, paint.u.radial_gradient.c0.x / 65536.f, paint.u.radial_gradient.c0.y / 65536.f, - (paint.u.radial_gradient.r0 / 65536.f), + paint.u.radial_gradient.r0 / 65536.f, paint.u.radial_gradient.c1.x / 65536.f, paint.u.radial_gradient.c1.y / 65536.f, - (paint.u.radial_gradient.r1 / 65536.f)); + paint.u.radial_gradient.r1 / 65536.f); } break; case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: From 583f010b0506cec061e5a6849da649fe3d2cb22e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 12:10:22 -0700 Subject: [PATCH 184/219] [ft] Move lock only around clip_glyph --- src/hb-ft.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 6d4c64d6f..70cdcbe81 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -848,9 +848,9 @@ hb_ft_paint_glyph (hb_font_t *font, /* Simple outline. */ ft_font->lock.unlock (); paint_funcs->push_clip_glyph (paint_data, gid, font); + ft_font->lock.lock (); paint_funcs->color (paint_data, true, foreground); paint_funcs->pop_clip (paint_data); - ft_font->lock.lock (); return; } From ecd7420456619dcfffd51b943468ed828c07d5a1 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 13:32:31 -0500 Subject: [PATCH 185/219] Debug spew To get a dump of the hb-paint callbacks, set HB_PAINT_DEBUG=1 when running hb-view. For now, leave this code in place, since it comes in handy for various debugging. --- util/helper-cairo-user.hh | 131 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 126 insertions(+), 5 deletions(-) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 2784b39bb..03dbb8727 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -37,6 +37,27 @@ #include "hb-blob.hh" #include "hb-cairo-utils.h" +static bool debug = false; +static int level = 0; + +static void +print (const char *format, + ...) +{ + va_list args; + + if (!debug) + return; + + printf ("%*s", 2 * level, ""); + + va_start (args, format); + vprintf (format, args); + va_end (args); + + printf ("\n"); +} + static const cairo_user_data_key_t _hb_font_cairo_user_data_key = {0}; static void @@ -46,6 +67,8 @@ move_to (hb_draw_funcs_t *dfuncs, float to_x, float to_y, void *) { + print ("move to %f %f", + (double) to_x, (double) to_y); cairo_move_to (cr, (double) to_x, (double) to_y); } @@ -57,6 +80,8 @@ line_to (hb_draw_funcs_t *dfuncs, float to_x, float to_y, void *) { + print ("line to %f %f", + (double) to_x, (double) to_y); cairo_line_to (cr, (double) to_x, (double) to_y); } @@ -70,6 +95,10 @@ cubic_to (hb_draw_funcs_t *dfuncs, float to_x, float to_y, void *) { + print ("cubic to %f %f", + (double) control1_x, (double) control1_y, + (double) control2_x, (double) control2_y, + (double) to_x, (double) to_y); cairo_curve_to (cr, (double) control1_x, (double) control1_y, (double) control2_x, (double) control2_y, @@ -82,6 +111,7 @@ close_path (hb_draw_funcs_t *dfuncs, hb_draw_state_t *st, void *) { + print ("close path"); cairo_close_path (cr); } @@ -116,10 +146,16 @@ push_transform (hb_paint_funcs_t *funcs, cairo_t *cr = (cairo_t *)paint_data; cairo_matrix_t m; + print ("start transform %f %f %f %f %f %f", + (double) xx, (double) yx, + (double) xy, (double) yy, + (double) dx, (double) dy); + level++; + cairo_save (cr); - cairo_matrix_init (&m, (double)xx, (double)yx, - (double)xy, (double)yy, - (double)dx, (double)dy); + cairo_matrix_init (&m, (double) xx, (double) yx, + (double) xy, (double) yy, + (double) dx, (double) dy); cairo_transform (cr, &m); } @@ -131,6 +167,9 @@ pop_transform (hb_paint_funcs_t *funcs, cairo_t *cr = (cairo_t *)paint_data; cairo_restore (cr); + + level--; + print ("end transform"); } static void @@ -142,6 +181,9 @@ push_clip_glyph (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + print ("start clip glyph %u", glyph); + level++; + cairo_save (cr); cairo_new_path (cr); hb_font_draw_glyph (font, glyph, get_cairo_draw_funcs (), cr); @@ -157,10 +199,15 @@ push_clip_rectangle (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + print ("start clip rectangle %f %f %f %f", + (double) xmin, (double) ymin, + (double) xmax, (double) ymax); + level++; + cairo_save (cr); cairo_rectangle (cr, - (double)xmin, (double)ymin, - (double)(xmax - xmin), (double)(ymax - ymin)); + (double) xmin, (double) ymin, + (double) (xmax - xmin), (double) (ymax - ymin)); cairo_clip (cr); } @@ -172,6 +219,9 @@ pop_clip (hb_paint_funcs_t *funcs, cairo_t *cr = (cairo_t *)paint_data; cairo_restore (cr); + + level--; + print ("end clip"); } static void @@ -181,6 +231,9 @@ push_group (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + print ("push group"); + level++; + cairo_save (cr); cairo_push_group (cr); } @@ -198,6 +251,9 @@ pop_group (hb_paint_funcs_t *funcs, cairo_paint (cr); cairo_restore (cr); + + level--; + print ("pop group mode %d", mode); } static void @@ -209,6 +265,13 @@ paint_color (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + print ("solid (fg %d) %d %d %d %d", + use_foreground, + hb_color_get_red (color), + hb_color_get_green (color), + hb_color_get_blue (color), + hb_color_get_alpha (color)); + cairo_set_source_rgba (cr, hb_color_get_red (color) / 255., hb_color_get_green (color) / 255., @@ -230,9 +293,39 @@ paint_image (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + char buf[5] = { 0, }; + + hb_tag_to_string (format, buf); + print ("image type %s size %u %u slant %f extents %d %d %d %d\n", + buf, width, height, (double) slant, + extents->x_bearing, extents->y_bearing, extents->width, extents->height); + hb_cairo_paint_glyph_image (cr, blob, width, height, format, slant, extents); } +static void +print_color_line (hb_color_line_t *color_line) +{ + hb_color_stop_t *stops; + unsigned int len; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = (hb_color_stop_t *)alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + + print ("colors extend %d", hb_color_line_get_extend (color_line)); + level += 1; + for (unsigned int i = 0; i < len; i++) + print ("%f (fg %d) %d %d %d %d", + (double) stops[i].offset, + stops[i].is_foreground, + hb_color_get_red (stops[i].color), + hb_color_get_green (stops[i].color), + hb_color_get_blue (stops[i].color), + hb_color_get_alpha (stops[i].color)); + level -= 1; +} + static void paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, @@ -244,6 +337,15 @@ paint_linear_gradient (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + print ("linear gradient"); + level += 1; + print ("p0 %f %f", (double) x0, (double) y0); + print ("p1 %f %f", (double) x1, (double) y1); + print ("p2 %f %f", (double) x2, (double) y2); + + print_color_line (color_line); + level -= 1; + hb_cairo_paint_linear_gradient (cr, color_line, x0, y0, x1, y1, x2, y2); } @@ -257,6 +359,14 @@ paint_radial_gradient (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + print ("radial gradient"); + level += 1; + print ("p0 %f %f radius %f", (double) x0, (double) y0, (double) r0); + print ("p1 %f %f radius %f", (double) x1, (double) y1, (double) r1); + + print_color_line (color_line); + level -= 1; + hb_cairo_paint_radial_gradient (cr, color_line, x0, y0, r0, x1, y1, r1); } @@ -270,6 +380,14 @@ paint_sweep_gradient (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; + print ("sweep gradient"); + level++; + print ("center %f %f", (double) x0, (double) y0); + print ("angles %f %f", (double) start_angle, (double) end_angle); + + print_color_line (color_line); + level--; + hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle); } @@ -366,6 +484,9 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, hb_font_get_scale (font, &x_scale, &y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale); + if (getenv ("HB_PAINT_DEBUG")) + debug = atoi (getenv ("HB_PAINT_DEBUG")); + hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, palette, color); hb_glyph_extents_t hb_extents; From ca190aaba4878b00bfeda39ae4f8ba6b669e90d3 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 14:03:03 -0500 Subject: [PATCH 186/219] Split off the hb-paint tests They belong in their own file. --- test/api/meson.build | 1 + test/api/test-ot-color.c | 370 ------------------------------------ test/api/test-paint.c | 400 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 401 insertions(+), 370 deletions(-) create mode 100644 test/api/test-paint.c diff --git a/test/api/meson.build b/test/api/meson.build index f5cdce805..2bdd1bbac 100644 --- a/test/api/meson.build +++ b/test/api/meson.build @@ -32,6 +32,7 @@ tests = [ 'test-ot-tag.c', 'test-ot-extents-cff.c', 'test-ot-metrics-tt-var.c', + 'test-paint.c', 'test-subset-repacker.c', 'test-set.c', 'test-shape.c', diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 061b6cedb..d5b387699 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -103,9 +103,6 @@ static hb_face_t *sbix = NULL; static hb_face_t *svg = NULL; static hb_face_t *empty = NULL; -static hb_face_t *colr_v1 = NULL; -static hb_face_t *colr_v1_2 = NULL; - #define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START { \ const hb_color_t *_colors = (colors); \ const size_t _i = (i); \ @@ -455,367 +452,6 @@ test_hb_ot_color_png (void) hb_font_destroy (cbdt_font); } -/* ---- */ - -typedef struct { - int level; - GString *string; -} paint_data_t; - -static void -print (paint_data_t *data, - const char *format, - ...) -{ - va_list args; - - g_string_append_printf (data->string, "%*s", 2 * data->level, ""); - - va_start (args, format); - g_string_append_vprintf (data->string, format, args); - va_end (args); - - g_string_append (data->string, "\n"); -} - -static void -push_transform (hb_paint_funcs_t *funcs, - void *paint_data, - float xx, float yx, - float xy, float yy, - float dx, float dy, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "start transform %f %f %f %f %f %f", xx, yx, xy, yy, dx, dy); - data->level++; -} - -static void -pop_transform (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data) -{ - paint_data_t *data = user_data; - - data->level--; - print (data, "end transform"); -} - -static void -push_clip_glyph (hb_paint_funcs_t *funcs, - void *paint_data, - hb_codepoint_t glyph, - hb_font_t *font, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "start clip glyph %u", glyph); - data->level++; -} - -static void -push_clip_rectangle (hb_paint_funcs_t *funcs, - void *paint_data, - float xmin, float ymin, float xmax, float ymax, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "start clip rectangle %f %f %f %f", xmin, ymin, xmax, ymax); - data->level++; -} - -static void -pop_clip (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data) -{ - paint_data_t *data = user_data; - - data->level--; - print (data, "end clip"); -} - -static void -paint_color (hb_paint_funcs_t *funcs, - void *paint_data, - hb_bool_t use_foreground, - hb_color_t color, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "solid %d %d %d %d", - hb_color_get_red (color), - hb_color_get_green (color), - hb_color_get_blue (color), - hb_color_get_alpha (color)); -} - -static void -paint_image (hb_paint_funcs_t *funcs, - void *paint_data, - hb_blob_t *blob, - unsigned int width, - unsigned int height, - hb_tag_t format, - float slant, - hb_glyph_extents_t *extents, - void *user_data) -{ - paint_data_t *data = user_data; - char buf[5] = { 0, }; - - hb_tag_to_string (format, buf); - print (data, "image type %s size %u %u slant %f extents %d %d %d %d\n", - buf, width, height, slant, - extents->x_bearing, extents->y_bearing, extents->width, extents->height); -} - -static void -print_color_line (paint_data_t *data, - hb_color_line_t *color_line) -{ - hb_color_stop_t *stops; - unsigned int len; - - len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = alloca (len * sizeof (hb_color_stop_t)); - hb_color_line_get_color_stops (color_line, 0, &len, stops); - - print (data, "colors"); - data->level += 1; - for (unsigned int i = 0; i < len; i++) - print (data, "%f %d %d %d %d", - stops[i].offset, - hb_color_get_red (stops[i].color), - hb_color_get_green (stops[i].color), - hb_color_get_blue (stops[i].color), - hb_color_get_alpha (stops[i].color)); - data->level -= 1; -} - -static void -paint_linear_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, - float x1, float y1, - float x2, float y2, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "linear gradient"); - data->level += 1; - print (data, "p0 %f %f", x0, y0); - print (data, "p1 %f %f", x1, y1); - print (data, "p2 %f %f", x2, y2); - - print_color_line (data, color_line); - data->level -= 1; -} - -static void -paint_radial_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float x0, float y0, float r0, - float x1, float y1, float r1, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "radial gradient"); - data->level += 1; - print (data, "p0 %f %f radius %f", x0, y0, r0); - print (data, "p1 %f %f radius %f", x1, y1, r1); - - print_color_line (data, color_line); - data->level -= 1; -} - -static void -paint_sweep_gradient (hb_paint_funcs_t *funcs, - void *paint_data, - hb_color_line_t *color_line, - float cx, float cy, - float start_angle, - float end_angle, - void *user_data) -{ - paint_data_t *data = user_data; - - print (data, "sweep gradient"); - data->level++; - print (data, "center %f %f", cx, cy); - print (data, "angles %f %f", start_angle, end_angle); - - print_color_line (data, color_line); - data->level -= 1; -} - -static void -push_group (hb_paint_funcs_t *funcs, - void *paint_data, - void *user_data) -{ - paint_data_t *data = user_data; - print (data, "push group"); - data->level++; -} - -static void -pop_group (hb_paint_funcs_t *funcs, - void *paint_data, - hb_paint_composite_mode_t mode, - void *user_data) -{ - paint_data_t *data = user_data; - data->level--; - print (data, "pop group mode %d", mode); -} - -typedef struct { - const char *font_file; - int scale; - float slant; - hb_codepoint_t glyph; - unsigned int palette; - const char *output; -} colrv1_test_t; - -#define NOTO_HAND "fonts/noto_handwriting-cff2_colr_1.otf" -#define TEST_GLYPHS "fonts/test_glyphs-glyf_colr_1.ttf" -#define ROCHER_ABC "fonts/RocherColorGX.abc.ttf" - -/* To verify the rendering visually, use - * - * hb-view --font-size SCALE --font-slant SLANT --font-palette PALETTE FONT TEXT - * - * where TEXT is as mentioned below. - */ -static colrv1_test_t colrv1_tests[] = { - /* COLRv1 */ - { NOTO_HAND, 20, 0., 10, 0, "hand-20-0-10" }, // ✍️ - { NOTO_HAND, 20, 0.2, 10, 0, "hand-20-0.2-10" }, // ✍️ - { TEST_GLYPHS, 20, 0, 6, 0, "test-20-0-6" }, - { TEST_GLYPHS, 20, 0, 10, 0, "test-20-0-10" }, - { TEST_GLYPHS, 20, 0, 92, 0, "test-20-0-92" }, - { TEST_GLYPHS, 20, 0, 106, 0, "test-20-0-106" }, - { TEST_GLYPHS, 20, 0, 116, 0, "test-20-0-116" }, - { TEST_GLYPHS, 20, 0, 123, 0, "test-20-0-123" }, - { TEST_GLYPHS, 20, 0, 165, 0, "test-20-0-165" }, - { TEST_GLYPHS, 20, 0, 175, 0, "test-20-0-175" }, - /* COLRv0 */ - { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-120-0.3-1" }, // A - { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-120-0.3-2" }, // B - { ROCHER_ABC, 120, 0, 3, 200, "rocher-120-0-3" }, // C -}; - -static void -test_hb_ot_color_colr_v1 (gconstpointer d) -{ - const colrv1_test_t *test = d; - hb_face_t *face; - hb_font_t *font; - hb_paint_funcs_t *funcs; - paint_data_t data; - char *file; - char *buffer; - gsize len; - GError *error = NULL; - - face = hb_test_open_font_file (test->font_file); - font = hb_font_create (face); - hb_font_set_scale (font, test->scale, test->scale); - hb_font_set_synthetic_slant (font, test->slant); - - funcs = hb_paint_funcs_create (); - hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); - hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); - hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, &data, NULL); - hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, &data, NULL); - hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); - hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); - hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); - hb_paint_funcs_set_color_func (funcs, paint_color, &data, NULL); - hb_paint_funcs_set_image_func (funcs, paint_image, &data, NULL); - hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, &data, NULL); - hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, &data, NULL); - hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, &data, NULL); - - data.string = g_string_new (""); - data.level = 0; - - hb_font_paint_glyph (font, test->glyph, funcs, &data, 0, HB_COLOR (0, 0, 0, 255)); - - /* Run - * - * GENERATE_DATA=1 G_TEST_SRCDIR=./test/api ./build/test/api/test-ot-color -p TESTCASE > test/api/results/OUTPUT - * - * to produce the expected results file. - */ - if (getenv ("GENERATE_DATA")) - { - g_print ("%s", data.string->str); - exit (0); - } - - file = g_test_build_filename (G_TEST_DIST, "results", test->output, NULL); - if (!g_file_get_contents (file, &buffer, &len, &error)) - { - g_test_message ("File %s not found.", file); - g_test_fail (); - return; - } - - char **lines = g_strsplit (data.string->str, "\n", 0); - char **expected; - if (strstr (buffer, "\r\n")) - expected = g_strsplit (buffer, "\r\n", 0); - else - expected = g_strsplit (buffer, "\n", 0); - - if (g_strv_length (lines) != g_strv_length (expected)) - { - g_test_message ("Unexpected number of lines in output (%d instead of %d)", g_strv_length (lines), g_strv_length (expected)); - g_test_fail (); - } - else - { - unsigned int length = g_strv_length (lines); - for (unsigned int i = 0; i < length; i++) - { - if (strcmp (lines[i], expected[i]) != 0) - { - int pos; - for (pos = 0; lines[i][pos]; pos++) - if (lines[i][pos] != expected[i][pos]) - break; - - g_test_message ("Unxpected output at %d:%d (%#x instead of %#x):\n%s", i, pos, (unsigned int)lines[i][pos], (unsigned int)expected[i][pos], data.string->str); - g_test_fail (); - } - } - } - - g_strfreev (lines); - g_strfreev (expected); - - g_free (buffer); - g_free (file); - - g_string_free (data.string, TRUE); - - hb_paint_funcs_destroy (funcs); - hb_font_destroy (font); - hb_face_destroy (face); -} - int main (int argc, char **argv) { @@ -828,8 +464,6 @@ 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"); - colr_v1 = hb_test_open_font_file ("fonts/noto_handwriting-cff2_colr_1.otf"); - colr_v1_2 = hb_test_open_font_file ("fonts/test_glyphs-glyf_colr_1.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); @@ -846,8 +480,6 @@ main (int argc, char **argv) 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); - for (unsigned int i = 0; i < G_N_ELEMENTS (colrv1_tests); i++) - hb_test_add_data_flavor (&colrv1_tests[i], colrv1_tests[i].output, test_hb_ot_color_colr_v1); status = hb_test_run(); hb_face_destroy (cpal_v0); @@ -856,7 +488,5 @@ main (int argc, char **argv) hb_face_destroy (cbdt); hb_face_destroy (sbix); hb_face_destroy (svg); - hb_face_destroy (colr_v1); - hb_face_destroy (colr_v1_2); return status; } diff --git a/test/api/test-paint.c b/test/api/test-paint.c new file mode 100644 index 000000000..3c24ffbc2 --- /dev/null +++ b/test/api/test-paint.c @@ -0,0 +1,400 @@ +/* + * Copyright © 2022 Matthias Clasen + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb-test.h" + +#include + +/* Unit tests for hb-paint.h */ + +/* ---- */ + +typedef struct { + int level; + GString *string; +} paint_data_t; + +static void +print (paint_data_t *data, + const char *format, + ...) +{ + va_list args; + + g_string_append_printf (data->string, "%*s", 2 * data->level, ""); + + va_start (args, format); + g_string_append_vprintf (data->string, format, args); + va_end (args); + + g_string_append (data->string, "\n"); +} + +static void +push_transform (hb_paint_funcs_t *funcs, + void *paint_data, + float xx, float yx, + float xy, float yy, + float dx, float dy, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "start transform %f %f %f %f %f %f", xx, yx, xy, yy, dx, dy); + data->level++; +} + +static void +pop_transform (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + + data->level--; + print (data, "end transform"); +} + +static void +push_clip_glyph (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "start clip glyph %u", glyph); + data->level++; +} + +static void +push_clip_rectangle (hb_paint_funcs_t *funcs, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "start clip rectangle %f %f %f %f", xmin, ymin, xmax, ymax); + data->level++; +} + +static void +pop_clip (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + + data->level--; + print (data, "end clip"); +} + +static void +paint_color (hb_paint_funcs_t *funcs, + void *paint_data, + hb_bool_t use_foreground, + hb_color_t color, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "solid %d %d %d %d", + hb_color_get_red (color), + hb_color_get_green (color), + hb_color_get_blue (color), + hb_color_get_alpha (color)); +} + +static void +paint_image (hb_paint_funcs_t *funcs, + void *paint_data, + hb_blob_t *blob, + unsigned int width, + unsigned int height, + hb_tag_t format, + float slant, + hb_glyph_extents_t *extents, + void *user_data) +{ + paint_data_t *data = user_data; + char buf[5] = { 0, }; + + hb_tag_to_string (format, buf); + print (data, "image type %s size %u %u slant %f extents %d %d %d %d\n", + buf, width, height, slant, + extents->x_bearing, extents->y_bearing, extents->width, extents->height); +} + +static void +print_color_line (paint_data_t *data, + hb_color_line_t *color_line) +{ + hb_color_stop_t *stops; + unsigned int len; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + stops = alloca (len * sizeof (hb_color_stop_t)); + hb_color_line_get_color_stops (color_line, 0, &len, stops); + + print (data, "colors"); + data->level += 1; + for (unsigned int i = 0; i < len; i++) + print (data, "%f %d %d %d %d", + stops[i].offset, + hb_color_get_red (stops[i].color), + hb_color_get_green (stops[i].color), + hb_color_get_blue (stops[i].color), + hb_color_get_alpha (stops[i].color)); + data->level -= 1; +} + +static void +paint_linear_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "linear gradient"); + data->level += 1; + print (data, "p0 %f %f", x0, y0); + print (data, "p1 %f %f", x1, y1); + print (data, "p2 %f %f", x2, y2); + + print_color_line (data, color_line); + data->level -= 1; +} + +static void +paint_radial_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "radial gradient"); + data->level += 1; + print (data, "p0 %f %f radius %f", x0, y0, r0); + print (data, "p1 %f %f radius %f", x1, y1, r1); + + print_color_line (data, color_line); + data->level -= 1; +} + +static void +paint_sweep_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float cx, float cy, + float start_angle, + float end_angle, + void *user_data) +{ + paint_data_t *data = user_data; + + print (data, "sweep gradient"); + data->level++; + print (data, "center %f %f", cx, cy); + print (data, "angles %f %f", start_angle, end_angle); + + print_color_line (data, color_line); + data->level -= 1; +} + +static void +push_group (hb_paint_funcs_t *funcs, + void *paint_data, + void *user_data) +{ + paint_data_t *data = user_data; + print (data, "push group"); + data->level++; +} + +static void +pop_group (hb_paint_funcs_t *funcs, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data) +{ + paint_data_t *data = user_data; + data->level--; + print (data, "pop group mode %d", mode); +} + +typedef struct { + const char *font_file; + int scale; + float slant; + hb_codepoint_t glyph; + unsigned int palette; + const char *output; +} paint_test_t; + +#define NOTO_HAND "fonts/noto_handwriting-cff2_colr_1.otf" +#define TEST_GLYPHS "fonts/test_glyphs-glyf_colr_1.ttf" +#define ROCHER_ABC "fonts/RocherColorGX.abc.ttf" + +/* To verify the rendering visually, use + * + * hb-view --font-size SCALE --font-slant SLANT --font-palette PALETTE FONT TEXT + * + * where TEXT is as mentioned below. + */ +static paint_test_t paint_tests[] = { + /* COLRv1 */ + { NOTO_HAND, 20, 0., 10, 0, "hand-20-0-10" }, // ✍️ + { NOTO_HAND, 20, 0.2, 10, 0, "hand-20-0.2-10" }, // ✍️ + { TEST_GLYPHS, 20, 0, 6, 0, "test-20-0-6" }, + { TEST_GLYPHS, 20, 0, 10, 0, "test-20-0-10" }, + { TEST_GLYPHS, 20, 0, 92, 0, "test-20-0-92" }, + { TEST_GLYPHS, 20, 0, 106, 0, "test-20-0-106" }, + { TEST_GLYPHS, 20, 0, 116, 0, "test-20-0-116" }, + { TEST_GLYPHS, 20, 0, 123, 0, "test-20-0-123" }, + { TEST_GLYPHS, 20, 0, 165, 0, "test-20-0-165" }, + { TEST_GLYPHS, 20, 0, 175, 0, "test-20-0-175" }, + /* COLRv0 */ + { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-120-0.3-1" }, // A + { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-120-0.3-2" }, // B + { ROCHER_ABC, 120, 0, 3, 200, "rocher-120-0-3" }, // C +}; + +static void +test_hb_paint (gconstpointer d) +{ + const paint_test_t *test = d; + hb_face_t *face; + hb_font_t *font; + hb_paint_funcs_t *funcs; + paint_data_t data; + char *file; + char *buffer; + gsize len; + GError *error = NULL; + + face = hb_test_open_font_file (test->font_file); + font = hb_font_create (face); + hb_font_set_scale (font, test->scale, test->scale); + hb_font_set_synthetic_slant (font, test->slant); + + funcs = hb_paint_funcs_create (); + hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); + hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); + hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, &data, NULL); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, &data, NULL); + hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); + hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); + hb_paint_funcs_set_pop_group_func (funcs, pop_group, &data, NULL); + hb_paint_funcs_set_color_func (funcs, paint_color, &data, NULL); + hb_paint_funcs_set_image_func (funcs, paint_image, &data, NULL); + hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, &data, NULL); + hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, &data, NULL); + hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, &data, NULL); + + data.string = g_string_new (""); + data.level = 0; + + hb_font_paint_glyph (font, test->glyph, funcs, &data, 0, HB_COLOR (0, 0, 0, 255)); + + /* Run + * + * GENERATE_DATA=1 G_TEST_SRCDIR=./test/api ./build/test/api/test-ot-color -p TESTCASE > test/api/results/OUTPUT + * + * to produce the expected results file. + */ + if (getenv ("GENERATE_DATA")) + { + g_print ("%s", data.string->str); + exit (0); + } + + file = g_test_build_filename (G_TEST_DIST, "results", test->output, NULL); + if (!g_file_get_contents (file, &buffer, &len, &error)) + { + g_test_message ("File %s not found.", file); + g_test_fail (); + return; + } + + char **lines = g_strsplit (data.string->str, "\n", 0); + char **expected; + if (strstr (buffer, "\r\n")) + expected = g_strsplit (buffer, "\r\n", 0); + else + expected = g_strsplit (buffer, "\n", 0); + + if (g_strv_length (lines) != g_strv_length (expected)) + { + g_test_message ("Unexpected number of lines in output (%d instead of %d)", g_strv_length (lines), g_strv_length (expected)); + g_test_fail (); + } + else + { + unsigned int length = g_strv_length (lines); + for (unsigned int i = 0; i < length; i++) + { + if (strcmp (lines[i], expected[i]) != 0) + { + int pos; + for (pos = 0; lines[i][pos]; pos++) + if (lines[i][pos] != expected[i][pos]) + break; + + g_test_message ("Unxpected output at %d:%d (%#x instead of %#x):\n%s", i, pos, (unsigned int)lines[i][pos], (unsigned int)expected[i][pos], data.string->str); + g_test_fail (); + } + } + } + + g_strfreev (lines); + g_strfreev (expected); + + g_free (buffer); + g_free (file); + + g_string_free (data.string, TRUE); + + hb_paint_funcs_destroy (funcs); + hb_font_destroy (font); + hb_face_destroy (face); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + for (unsigned int i = 0; i < G_N_ELEMENTS (paint_tests); i++) + hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint); + + return hb_test_run(); +} From 3b021c5568bf8fe26b9691075211dad2408ae3b9 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 14:30:29 -0500 Subject: [PATCH 187/219] Run paint tests with ft font funcs --- test/api/test-paint.c | 59 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/test/api/test-paint.c b/test/api/test-paint.c index 3c24ffbc2..d18345855 100644 --- a/test/api/test-paint.c +++ b/test/api/test-paint.c @@ -24,8 +24,13 @@ #include "hb-test.h" +#include #include +#ifdef HB_HAS_FREETYPE +#include +#endif + /* Unit tests for hb-paint.h */ /* ---- */ @@ -289,8 +294,11 @@ static paint_test_t paint_tests[] = { { ROCHER_ABC, 120, 0, 3, 200, "rocher-120-0-3" }, // C }; +static FT_Library library; + static void -test_hb_paint (gconstpointer d) +test_hb_paint (gconstpointer d, + hb_bool_t use_ft) { const paint_test_t *test = d; hb_face_t *face; @@ -302,7 +310,29 @@ test_hb_paint (gconstpointer d) gsize len; GError *error = NULL; - face = hb_test_open_font_file (test->font_file); +#ifdef HB_HAS_FREETYPE + if (use_ft) + { + FT_Face ft_face; + char *path; + + path = g_test_build_filename (G_TEST_DIST, test->font_file, NULL); + if (FT_New_Face (library, path, 0, &ft_face) != 0) + { + g_test_fail_printf ("Failed to create FT_Face for %s", path); + g_free (path); + return; + } + face = hb_ft_face_create_referenced (ft_face); + FT_Done_Face (ft_face); + g_free (path); + } + else +#endif + { + face = hb_test_open_font_file (test->font_file); + } + font = hb_font_create (face); hb_font_set_scale (font, test->scale, test->scale); hb_font_set_synthetic_slant (font, test->slant); @@ -389,12 +419,35 @@ test_hb_paint (gconstpointer d) hb_face_destroy (face); } +static void +test_hb_paint_ot (gconstpointer data) +{ + test_hb_paint (data, 0); +} + +static void +test_hb_paint_ft (gconstpointer data) +{ +#ifdef HB_HAS_FREETYPE + test_hb_paint (data, 1); +#else + g_test_skip_printf ("freetype support not present"); +#endif +} + int main (int argc, char **argv) { +#ifdef HB_HAS_FREETYPE + FT_Init_FreeType (&library); +#endif + hb_test_init (&argc, &argv); for (unsigned int i = 0; i < G_N_ELEMENTS (paint_tests); i++) - hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint); + { + hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint_ot); + hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint_ft); + } return hb_test_run(); } From d9875ddc9d7a6b7078906929d98e0606a49f5da4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 12:37:42 -0700 Subject: [PATCH 188/219] [ft-colr] Add depth counter --- src/hb-ft-colr.hh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 070c43e61..51f14f6c0 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -89,7 +89,12 @@ struct hb_ft_paint_context_t funcs (paint_funcs), data (paint_data), palette (palette), foreground (foreground) {} - void recurse (FT_OpaquePaint paint) { _hb_ft_paint (this, paint); + void recurse (FT_OpaquePaint paint) + { + if (depth_left <= 0) return; + depth_left--; + _hb_ft_paint (this, paint); + depth_left++; } const hb_ft_font_t *ft_font; @@ -98,6 +103,7 @@ struct hb_ft_paint_context_t void *data; FT_Color *palette; hb_color_t foreground; + int depth_left = 128; }; static unsigned @@ -285,7 +291,6 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_COLR_GLYPH: { - /* TODO Depth counter. */ FT_OpaquePaint other_paint = {0}; if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID, FT_COLOR_NO_ROOT_TRANSFORM, From 8e197f50daf6d89a1e6f14cbd9836160d5d3d8c7 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 15:31:16 -0500 Subject: [PATCH 189/219] Add missing paint test results --- test/api/results/rocher-120-0-3 | 12 ++++++++++++ test/api/results/rocher-120-0.3-1 | 12 ++++++++++++ test/api/results/rocher-120-0.3-2 | 12 ++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 test/api/results/rocher-120-0-3 create mode 100644 test/api/results/rocher-120-0.3-1 create mode 100644 test/api/results/rocher-120-0.3-2 diff --git a/test/api/results/rocher-120-0-3 b/test/api/results/rocher-120-0-3 new file mode 100644 index 000000000..326fdc4f9 --- /dev/null +++ b/test/api/results/rocher-120-0-3 @@ -0,0 +1,12 @@ +start clip glyph 16 + solid 81 61 50 255 +end clip +start clip glyph 17 + solid 245 185 68 255 +end clip +start clip glyph 18 + solid 224 142 55 255 +end clip +start clip glyph 19 + solid 245 202 86 255 +end clip diff --git a/test/api/results/rocher-120-0.3-1 b/test/api/results/rocher-120-0.3-1 new file mode 100644 index 000000000..9cb0e66e6 --- /dev/null +++ b/test/api/results/rocher-120-0.3-1 @@ -0,0 +1,12 @@ +start clip glyph 8 + solid 81 61 50 255 +end clip +start clip glyph 9 + solid 245 185 68 255 +end clip +start clip glyph 10 + solid 224 142 55 255 +end clip +start clip glyph 11 + solid 245 202 86 255 +end clip diff --git a/test/api/results/rocher-120-0.3-2 b/test/api/results/rocher-120-0.3-2 new file mode 100644 index 000000000..d26bb572b --- /dev/null +++ b/test/api/results/rocher-120-0.3-2 @@ -0,0 +1,12 @@ +start clip glyph 12 + solid 81 61 50 255 +end clip +start clip glyph 13 + solid 245 185 68 255 +end clip +start clip glyph 14 + solid 224 142 55 255 +end clip +start clip glyph 15 + solid 245 202 86 255 +end clip From dcab5679889ff47db6765e1ea853963cf9ee4286 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 13:47:37 -0700 Subject: [PATCH 190/219] [test-paint] Don't use g_test_fail_print() for older glib --- test/api/test-paint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api/test-paint.c b/test/api/test-paint.c index d18345855..672329fd4 100644 --- a/test/api/test-paint.c +++ b/test/api/test-paint.c @@ -319,7 +319,7 @@ test_hb_paint (gconstpointer d, path = g_test_build_filename (G_TEST_DIST, test->font_file, NULL); if (FT_New_Face (library, path, 0, &ft_face) != 0) { - g_test_fail_printf ("Failed to create FT_Face for %s", path); + g_test_fail ();//_printf ("Failed to create FT_Face for %s", path); g_free (path); return; } From a4a86c0ec281e0e5ce0cd90822d6b6d633457342 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 13:52:22 -0700 Subject: [PATCH 191/219] [test-paint] g_test_message --- test/api/test-paint.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/api/test-paint.c b/test/api/test-paint.c index 672329fd4..70f9356f6 100644 --- a/test/api/test-paint.c +++ b/test/api/test-paint.c @@ -319,7 +319,8 @@ test_hb_paint (gconstpointer d, path = g_test_build_filename (G_TEST_DIST, test->font_file, NULL); if (FT_New_Face (library, path, 0, &ft_face) != 0) { - g_test_fail ();//_printf ("Failed to create FT_Face for %s", path); + g_test_message ("Failed to create FT_Face for %s", path); + g_test_fail (); g_free (path); return; } From 44b48845b7200a74f4ea01711f30a7c3ebe6fee4 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 16:26:05 -0500 Subject: [PATCH 192/219] Add tests for hb_color_line_t Test a few things that were broken with the ft implementation before. --- test/api/test-paint.c | 108 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/test/api/test-paint.c b/test/api/test-paint.c index 70f9356f6..6583544fd 100644 --- a/test/api/test-paint.c +++ b/test/api/test-paint.c @@ -436,6 +436,112 @@ test_hb_paint_ft (gconstpointer data) #endif } +static void +scrutinize_linear_gradient (hb_paint_funcs_t *funcs, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *user_data) +{ + hb_bool_t *result = paint_data; + hb_color_stop_t *stops; + unsigned int len; + hb_color_stop_t *stops2; + unsigned int len2; + + *result = FALSE; + + len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); + if (len == 0) + return; + + stops = malloc (len * sizeof (hb_color_stop_t)); + stops2 = malloc (len * sizeof (hb_color_stop_t)); + + hb_color_line_get_color_stops (color_line, 0, &len, stops); + hb_color_line_get_color_stops (color_line, 0, &len, stops2); + + // check that we can get stops twice + if (memcmp (stops, stops2, len * sizeof (hb_color_stop_t)) != 0) + { + free (stops); + free (stops2); + return; + } + + // check that we can get a single stop in the middle + len2 = 1; + hb_color_line_get_color_stops (color_line, len - 1, &len2, stops2); + if (memcmp (&stops[len - 1], stops2, sizeof (hb_color_stop_t)) != 0) + { + free (stops); + free (stops2); + return; + } + + free (stops); + free (stops2); + + *result = TRUE; +} + +static void +test_color_stops (hb_bool_t use_ft) +{ + hb_face_t *face; + hb_font_t *font; + hb_paint_funcs_t *funcs; + hb_bool_t result = FALSE; + +#ifdef HB_HAS_FREETYPE + if (use_ft) + { + FT_Face ft_face; + char *path; + + path = g_test_build_filename (G_TEST_DIST, NOTO_HAND, NULL); + if (FT_New_Face (library, path, 0, &ft_face) != 0) + { + g_test_message ("Failed to create FT_Face for %s", path); + g_test_fail (); + g_free (path); + return; + } + face = hb_ft_face_create_referenced (ft_face); + FT_Done_Face (ft_face); + g_free (path); + } + else +#endif + face = hb_test_open_font_file (NOTO_HAND); + + font = hb_font_create (face); + + funcs = hb_paint_funcs_create (); + hb_paint_funcs_set_linear_gradient_func (funcs, scrutinize_linear_gradient, NULL, NULL); + + hb_font_paint_glyph (font, 10, funcs, &result, 0, HB_COLOR (0, 0, 0, 255)); + + g_assert_true (result); + + hb_font_destroy (font); + hb_face_destroy (face); +} + +static void +test_color_stops_ot (void) +{ + test_color_stops (0); +} + +static void +test_color_stops_ft (void) +{ + test_color_stops (1); +} + int main (int argc, char **argv) { @@ -449,6 +555,8 @@ main (int argc, char **argv) hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint_ot); hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint_ft); } + hb_test_add (test_color_stops_ot); + hb_test_add (test_color_stops_ft); return hb_test_run(); } From 268d8b7dedf35b8c097075c2726753fb1462a04d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 14:45:56 -0700 Subject: [PATCH 193/219] [paint-extents] Start out --- src/Makefile.sources | 1 + src/hb-ft-colr.hh | 2 + src/hb-paint-extents.hh | 288 ++++++++++++++++++++++++++++++++++++++++ src/meson.build | 1 + 4 files changed, 292 insertions(+) create mode 100644 src/hb-paint-extents.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index edfbed164..d49e6a716 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -91,6 +91,7 @@ HB_BASE_sources = \ hb-ot-layout-gpos-table.hh \ hb-paint.cc \ hb-paint.hh \ + hb-paint-extents.hh \ hb-ot-layout-gsub-table.hh \ OT/glyf/glyf.hh \ OT/glyf/glyf-helpers.hh \ diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 51f14f6c0..f87a347fa 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -27,6 +27,8 @@ #include "hb.hh" +#include "hb-paint-extents.hh" + #include FT_COLOR_H #ifndef HB_NO_PAINT diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh new file mode 100644 index 000000000..a362d4f87 --- /dev/null +++ b/src/hb-paint-extents.hh @@ -0,0 +1,288 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * 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. + */ + +#ifndef HB_PAINT_EXTENTS_HH +#define HB_PAINT_EXTENTS_HH + +#include "hb.hh" +#include "hb-paint.hh" + + +typedef struct hb_transform_t +{ + hb_transform_t () {} + hb_transform_t (float xx, float yx, + float xy, float yy, + float x0, float y0) : + xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} + + void multiply (const hb_transform_t &o) + { + /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ + hb_transform_t r; + + r.xx = o.xx * xx + o.yx * xy; + r.yx = o.xx * yx + o.yx * yy; + + r.xy = o.xy * xx + o.yy * xy; + r.yy = o.xy * yx + o.yy * yy; + + r.x0 = o.x0 * xx + o.y0 * xy + x0; + r.y0 = o.x0 * yx + o.y0 * yy + y0; + + *this = r; + } + + float xx = 1.f; + float yx = 0.f; + float xy = 0.f; + float yy = 1.f; + float x0 = 0.f; + float y0 = 0.f; +} hb_transform_t; + +typedef struct hb_bounds_t +{ + hb_bounds_t () {} + hb_bounds_t (const hb_glyph_extents_t &extents) : + bounded (true), extents (extents) {} + + bool bounded = false; + hb_glyph_extents_t extents = {0, 0, 0, 0}; +} hb_bounds_t; + +typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; + +struct hb_paint_extents_context_t { + + hb_paint_extents_context_t () + { + clips.push (hb_bounds_t{}); + bounds.push (hb_bounds_t{}); + transforms.push (hb_transform_t{}); + } + + void push_transform (const hb_transform_t &trans) + { + hb_transform_t r = transforms.tail (); + r.multiply (trans); + transforms.push (r); + } + + void pop_transform () + { + transforms.pop (); + } + + void push_clip (const hb_glyph_extents_t &extents) + { + hb_bounds_t b {extents}; + clips.push (b); + } + + void pop_clip () + { + clips.pop (); + } + + void push_group () + { + bounds.push (hb_bounds_t{}); + } + + hb_bounds_t pop_group () + { + return bounds.pop (); + } + + void add_extents (const hb_glyph_extents_t &extents) + { + // TODO + + //hb_transform_t &r = transforms.tail (); + } + + hb_vector_t clips; + hb_vector_t bounds; + hb_vector_t transforms; +}; + +static void +hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + float xx, float yx, + float xy, float yy, + float dx, float dy, + void *user_data HB_UNUSED) +{ + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy}); +} + +static void +hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->pop_transform (); +} + +static void +hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data HB_UNUSED) +{ + //hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + // TODO +} + +static void +hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) +{ + // TODO +} + +static void +hb_paint_extents_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->pop_clip (); +} + +static void +hb_paint_extents_push_group (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->push_group (); +} + +static void +hb_paint_extents_pop_group (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data HB_UNUSED) +{ + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + hb_bounds_t bounds = c->pop_group (); + + // TODO +} + +static void +hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_blob_t *blob HB_UNUSED, + unsigned int width HB_UNUSED, + unsigned int height HB_UNUSED, + hb_tag_t format HB_UNUSED, + float slant HB_UNUSED, + hb_glyph_extents_t *extents, + void *user_data HB_UNUSED) +{ + // TODO +} + +static void +hb_paint_extents_paint_color (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_bool_t use_foreground HB_UNUSED, + hb_color_t color HB_UNUSED, + void *user_data HB_UNUSED) +{ + // TODO +} + +static void +hb_paint_extents_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float x0 HB_UNUSED, float y0 HB_UNUSED, + float x1 HB_UNUSED, float y1 HB_UNUSED, + float x2 HB_UNUSED, float y2 HB_UNUSED, + void *user_data HB_UNUSED) +{ + // TODO +} + +static void +hb_paint_extents_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float x0 HB_UNUSED, float y0 HB_UNUSED, float r0 HB_UNUSED, + float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED, + void *user_data HB_UNUSED) +{ + // TODO +} + +static void +hb_paint_extents_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float cx HB_UNUSED, float cy HB_UNUSED, + float start_angle HB_UNUSED, + float end_angle HB_UNUSED, + void *user_data HB_UNUSED) +{ + // TODO +} + +static inline hb_paint_funcs_t * +hb_paint_extents_get_funcs () +{ + hb_paint_funcs_t *funcs = hb_paint_funcs_create (); + + hb_paint_funcs_set_push_transform_func (funcs, hb_paint_extents_push_transform, nullptr, nullptr); + hb_paint_funcs_set_pop_transform_func (funcs, hb_paint_extents_pop_transform, nullptr, nullptr); + hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_paint_extents_push_clip_glyph, nullptr, nullptr); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_paint_extents_push_clip_rectangle, nullptr, nullptr); + hb_paint_funcs_set_pop_clip_func (funcs, hb_paint_extents_pop_clip, nullptr, nullptr); + hb_paint_funcs_set_push_group_func (funcs, hb_paint_extents_push_group, nullptr, nullptr); + hb_paint_funcs_set_pop_group_func (funcs, hb_paint_extents_pop_group, nullptr, nullptr); + hb_paint_funcs_set_color_func (funcs, hb_paint_extents_paint_color, nullptr, nullptr); + hb_paint_funcs_set_image_func (funcs, hb_paint_extents_paint_image, nullptr, nullptr); + hb_paint_funcs_set_linear_gradient_func (funcs, hb_paint_extents_paint_linear_gradient, nullptr, nullptr); + hb_paint_funcs_set_radial_gradient_func (funcs, hb_paint_extents_paint_radial_gradient, nullptr, nullptr); + hb_paint_funcs_set_sweep_gradient_func (funcs, hb_paint_extents_paint_sweep_gradient, nullptr, nullptr); + + return funcs; +} + +#endif /* HB_PAINT_EXTENTS_HH */ diff --git a/src/meson.build b/src/meson.build index 89bb4ffa3..3b09a3441 100644 --- a/src/meson.build +++ b/src/meson.build @@ -46,6 +46,7 @@ hb_base_sources = files( 'hb-draw.hh', 'hb-paint.cc', 'hb-paint.hh', + 'hb-paint-extents.hh', 'hb-face.cc', 'hb-face.hh', 'hb-fallback-shape.cc', From c37a1eadef4c99d7c95cefb8341c40c7b3159246 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 14:57:12 -0700 Subject: [PATCH 194/219] [paint-extents] Flesh out some more --- src/hb-paint-extents.hh | 64 ++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index a362d4f87..b053bca0e 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -62,14 +62,20 @@ typedef struct hb_transform_t float y0 = 0.f; } hb_transform_t; +typedef struct hb_extents_t +{ + float xmin, ymin, xmax, ymax; +} hb_extents_t; + typedef struct hb_bounds_t { hb_bounds_t () {} - hb_bounds_t (const hb_glyph_extents_t &extents) : + hb_bounds_t (const hb_extents_t &extents) : bounded (true), extents (extents) {} bool bounded = false; - hb_glyph_extents_t extents = {0, 0, 0, 0}; + bool empty = true; + hb_extents_t extents = {0, 0, 0, 0}; } hb_bounds_t; typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; @@ -95,8 +101,11 @@ struct hb_paint_extents_context_t { transforms.pop (); } - void push_clip (const hb_glyph_extents_t &extents) + void push_clip (hb_extents_t extents) { + /* Transform extents and push a new clip. */ + //hb_transform_t &r = transforms.tail (); + hb_bounds_t b {extents}; clips.push (b); } @@ -116,11 +125,9 @@ struct hb_paint_extents_context_t { return bounds.pop (); } - void add_extents (const hb_glyph_extents_t &extents) + void paint () { - // TODO - - //hb_transform_t &r = transforms.tail (); + /* Union current clip bounds with current bounds. */ } hb_vector_t clips; @@ -158,9 +165,15 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, hb_font_t *font, void *user_data HB_UNUSED) { - //hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - // TODO + hb_glyph_extents_t glyph_extents; + hb_font_get_glyph_extents (font, glyph, &glyph_extents); + hb_extents_t extents = {(float) glyph_extents.x_bearing, + (float) glyph_extents.y_bearing + glyph_extents.height, + (float) glyph_extents.x_bearing + glyph_extents.width, + (float) glyph_extents.y_bearing}; + c->push_clip (extents); } static void @@ -169,7 +182,10 @@ hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, float xmin, float ymin, float xmax, float ymax, void *user_data) { - // TODO + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + hb_extents_t extents = {xmin, ymin, xmax, ymax}; + c->push_clip (extents); } static void @@ -213,10 +229,18 @@ hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, unsigned int height HB_UNUSED, hb_tag_t format HB_UNUSED, float slant HB_UNUSED, - hb_glyph_extents_t *extents, + hb_glyph_extents_t *glyph_extents, void *user_data HB_UNUSED) { - // TODO + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + hb_extents_t extents = {(float) glyph_extents->x_bearing, + (float) glyph_extents->y_bearing + glyph_extents->height, + (float) glyph_extents->x_bearing + glyph_extents->width, + (float) glyph_extents->y_bearing}; + c->push_clip (extents); + c->paint (); + c->pop_clip (); } static void @@ -226,7 +250,9 @@ hb_paint_extents_paint_color (hb_paint_funcs_t *funcs HB_UNUSED, hb_color_t color HB_UNUSED, void *user_data HB_UNUSED) { - // TODO + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->paint (); } static void @@ -238,7 +264,9 @@ hb_paint_extents_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED, float x2 HB_UNUSED, float y2 HB_UNUSED, void *user_data HB_UNUSED) { - // TODO + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->paint (); } static void @@ -249,7 +277,9 @@ hb_paint_extents_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED, float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED, void *user_data HB_UNUSED) { - // TODO + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->paint (); } static void @@ -261,7 +291,9 @@ hb_paint_extents_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED, float end_angle HB_UNUSED, void *user_data HB_UNUSED) { - // TODO + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + + c->paint (); } static inline hb_paint_funcs_t * From d7435b10095bf035f41539de5e1ddd39c14719ce Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 15:05:30 -0700 Subject: [PATCH 195/219] [paint-extents] Flesh out more --- src/hb-paint-extents.hh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index b053bca0e..1a17e4491 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -69,12 +69,17 @@ typedef struct hb_extents_t typedef struct hb_bounds_t { - hb_bounds_t () {} - hb_bounds_t (const hb_extents_t &extents) : - bounded (true), extents (extents) {} + enum status_t { + EMPTY, + BOUNDED, + UNBOUNDED, + }; - bool bounded = false; - bool empty = true; + hb_bounds_t (status_t status) : status (status) {} + hb_bounds_t (const hb_extents_t &extents) : + status (BOUNDED), extents (extents) {} + + status_t status; hb_extents_t extents = {0, 0, 0, 0}; } hb_bounds_t; @@ -84,8 +89,8 @@ struct hb_paint_extents_context_t { hb_paint_extents_context_t () { - clips.push (hb_bounds_t{}); - bounds.push (hb_bounds_t{}); + clips.push (hb_bounds_t{hb_bounds_t::status_t::UNBOUNDED}); + groups.push (hb_bounds_t{hb_bounds_t::status_t::EMPTY}); transforms.push (hb_transform_t{}); } @@ -117,12 +122,12 @@ struct hb_paint_extents_context_t { void push_group () { - bounds.push (hb_bounds_t{}); + groups.push (hb_bounds_t{hb_bounds_t::status_t::EMPTY}); } hb_bounds_t pop_group () { - return bounds.pop (); + return groups.pop (); } void paint () @@ -131,7 +136,7 @@ struct hb_paint_extents_context_t { } hb_vector_t clips; - hb_vector_t bounds; + hb_vector_t groups; hb_vector_t transforms; }; From 23a2d4dbabf812c75dec6bfe7ceb3a4fbf0b039e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 15:10:26 -0700 Subject: [PATCH 196/219] [paint-extents] More --- src/hb-paint-extents.hh | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index 1a17e4491..ae9ba7ba7 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -132,7 +132,35 @@ struct hb_paint_extents_context_t { void paint () { - /* Union current clip bounds with current bounds. */ + /* Union current clip bounds with current group bounds. */ + const hb_bounds_t &clip = clips.tail (); + hb_bounds_t &group = groups.tail (); + + if (clip.status == hb_bounds_t::status_t::EMPTY) + return; // Shouldn't happen + + if (group.status == hb_bounds_t::status_t::UNBOUNDED) + return; + + if (group.status == hb_bounds_t::status_t::EMPTY) + { + group = clip; + return; + } + + /* Group is bounded now. Clip is not empty. */ + + if (clip.status == hb_bounds_t::status_t::UNBOUNDED) + { + group.status = hb_bounds_t::status_t::UNBOUNDED; + return; + } + + /* Both are bounded. Union. */ + group.extents.xmin = hb_min (group.extents.xmin, clip.extents.xmin); + group.extents.ymin = hb_min (group.extents.ymin, clip.extents.ymin); + group.extents.xmax = hb_max (group.extents.xmax, clip.extents.xmax); + group.extents.ymax = hb_max (group.extents.ymax, clip.extents.ymax); } hb_vector_t clips; From 8ca78d1520cf9c4ee1720ed80abc3167cdf6f963 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 15:21:48 -0700 Subject: [PATCH 197/219] [paint-extend] More --- src/hb-paint-extents.hh | 56 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index ae9ba7ba7..1f1bf0d9b 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -29,6 +29,11 @@ #include "hb-paint.hh" +typedef struct hb_extents_t +{ + float xmin, ymin, xmax, ymax; +} hb_extents_t; + typedef struct hb_transform_t { hb_transform_t () {} @@ -54,6 +59,49 @@ typedef struct hb_transform_t *this = r; } + void transform_distance (float &dx, float &dy) + { + float new_x = xx * dx + xy * dy; + float new_y = yx * dx + yy * dy; + dx = new_x; + dy = new_y; + } + + void transform_point (float &x, float &y) + { + transform_distance (x, y); + x += x0; + y += y0; + } + + void transform_extents (hb_extents_t extents) + { + float quad_x[4], quad_y[4]; + + quad_x[0] = extents.xmin; + quad_y[0] = extents.ymin; + quad_x[1] = extents.xmin; + quad_y[1] = extents.ymax; + quad_x[2] = extents.xmax; + quad_y[2] = extents.ymin; + quad_x[3] = extents.xmax; + quad_y[3] = extents.ymax; + + for (unsigned i = 0; i < 4; i++) + transform_point (quad_x[i], quad_y[i]); + + extents.xmin = extents.xmax = quad_x[0]; + extents.ymin = extents.ymax = quad_y[0]; + + for (unsigned i = 1; i < 4; i++) + { + extents.xmin = hb_min (extents.xmin, quad_x[i]); + extents.ymin = hb_min (extents.ymin, quad_y[i]); + extents.xmax = hb_max (extents.xmax, quad_x[i]); + extents.ymax = hb_max (extents.ymax, quad_y[i]); + } + } + float xx = 1.f; float yx = 0.f; float xy = 0.f; @@ -62,11 +110,6 @@ typedef struct hb_transform_t float y0 = 0.f; } hb_transform_t; -typedef struct hb_extents_t -{ - float xmin, ymin, xmax, ymax; -} hb_extents_t; - typedef struct hb_bounds_t { enum status_t { @@ -109,7 +152,8 @@ struct hb_paint_extents_context_t { void push_clip (hb_extents_t extents) { /* Transform extents and push a new clip. */ - //hb_transform_t &r = transforms.tail (); + hb_transform_t &r = transforms.tail (); + r.transform_extents (extents); hb_bounds_t b {extents}; clips.push (b); From 7fbaaebe8bf61523f1c69ba50c4c29c5e5230fa1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 15:37:16 -0700 Subject: [PATCH 198/219] [paint-extents] Finish off Untested and unused. --- src/hb-paint-extents.hh | 61 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index 1f1bf0d9b..a2701f29c 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -169,9 +169,62 @@ struct hb_paint_extents_context_t { groups.push (hb_bounds_t{hb_bounds_t::status_t::EMPTY}); } - hb_bounds_t pop_group () + void pop_group (hb_paint_composite_mode_t mode) { - return groups.pop (); + const hb_bounds_t src_bounds = groups.pop (); + hb_bounds_t &backdrop_bounds = groups.tail (); + + switch ((int) mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: + backdrop_bounds.status = hb_bounds_t::status_t::EMPTY; + break; + case HB_PAINT_COMPOSITE_MODE_SRC: + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: + backdrop_bounds = src_bounds; + break; + case HB_PAINT_COMPOSITE_MODE_DEST: + case HB_PAINT_COMPOSITE_MODE_DEST_OUT: + break; + case HB_PAINT_COMPOSITE_MODE_SRC_IN: + case HB_PAINT_COMPOSITE_MODE_DEST_IN: + // Intersect + if (src_bounds.status == hb_bounds_t::status_t::EMPTY) + backdrop_bounds.status = hb_bounds_t::status_t::EMPTY; + else if (src_bounds.status == hb_bounds_t::status_t::BOUNDED) + { + if (backdrop_bounds.status == hb_bounds_t::status_t::UNBOUNDED) + backdrop_bounds = src_bounds; + else if (backdrop_bounds.status == hb_bounds_t::status_t::BOUNDED) + { + backdrop_bounds.extents.xmin = hb_max (backdrop_bounds.extents.xmin, src_bounds.extents.xmin); + backdrop_bounds.extents.ymin = hb_max (backdrop_bounds.extents.ymin, src_bounds.extents.ymin); + backdrop_bounds.extents.xmax = hb_min (backdrop_bounds.extents.xmax, src_bounds.extents.xmax); + backdrop_bounds.extents.ymax = hb_min (backdrop_bounds.extents.ymax, src_bounds.extents.ymax); + if (backdrop_bounds.extents.xmin >= backdrop_bounds.extents.xmax || + backdrop_bounds.extents.ymin >= backdrop_bounds.extents.ymax) + backdrop_bounds.status = hb_bounds_t::status_t::EMPTY; + } + } + break; + default: + // Union + if (src_bounds.status == hb_bounds_t::status_t::UNBOUNDED) + backdrop_bounds.status = hb_bounds_t::status_t::UNBOUNDED; + else if (src_bounds.status == hb_bounds_t::status_t::BOUNDED) + { + if (backdrop_bounds.status == hb_bounds_t::status_t::EMPTY) + backdrop_bounds = src_bounds; + else if (backdrop_bounds.status == hb_bounds_t::status_t::BOUNDED) + { + backdrop_bounds.extents.xmin = hb_min (backdrop_bounds.extents.xmin, src_bounds.extents.xmin); + backdrop_bounds.extents.ymin = hb_min (backdrop_bounds.extents.ymin, src_bounds.extents.ymin); + backdrop_bounds.extents.xmax = hb_max (backdrop_bounds.extents.xmax, src_bounds.extents.xmax); + backdrop_bounds.extents.ymax = hb_max (backdrop_bounds.extents.ymax, src_bounds.extents.ymax); + } + } + break; + } } void paint () @@ -293,9 +346,7 @@ hb_paint_extents_pop_group (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_bounds_t bounds = c->pop_group (); - - // TODO + c->pop_group (mode); } static void From 47c896f0040c4fd6b6c91cdbc0f4f0fa2e9f6582 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 16:20:44 -0700 Subject: [PATCH 199/219] [paint-extents] Hook it up, kinda --- src/hb-ft-colr.hh | 25 +++++++++++++++++++------ src/hb-ot-color-colr-table.hh | 16 ++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index f87a347fa..0efd7e7d0 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -457,15 +457,29 @@ hb_ft_paint_glyph_colr (hb_font_t *font, &paint)) { FT_ClipBox clip_box; - bool has_clip; - - has_clip = FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box); - if (has_clip) + if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box)) paint_funcs->push_clip_rectangle (paint_data, clip_box.bottom_left.x - font->slant_xy * clip_box.bottom_left.y, clip_box.bottom_left.y, clip_box.top_right.x - font->slant_xy * clip_box.top_right.y, clip_box.top_right.y); + else + { + /* XXX Untested. */ + auto *extents_funcs = hb_paint_extents_get_funcs (); + hb_paint_extents_context_t extents_data; + hb_ft_paint_context_t c (ft_font, font, + extents_funcs, &extents_data, + palette, foreground); + _hb_ft_paint (&c, paint); + paint_funcs->push_clip_rectangle (paint_data, + extents_data.groups.tail().extents.xmin, + extents_data.groups.tail().extents.ymin, + extents_data.groups.tail().extents.xmax, + extents_data.groups.tail().extents.ymax); + + hb_paint_funcs_destroy (extents_funcs); + } paint_funcs->push_root_transform (paint_data, font); @@ -475,8 +489,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, _hb_ft_paint (&c, paint); paint_funcs->pop_root_transform (paint_data); - if (has_clip) - paint_funcs->pop_clip (paint_data); + paint_funcs->pop_clip (paint_data); return true; } diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 0194e100b..c9d1f563c 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -33,6 +33,7 @@ #include "hb-ot-layout-common.hh" #include "hb-ot-var-common.hh" #include "hb-paint.hh" +#include "hb-paint-extents.hh" /* * COLR -- Color @@ -1997,6 +1998,21 @@ struct COLR return true; } +#if 0 + /* This currently goes into infinite recursion. */ + + auto *extents_funcs = hb_paint_extents_get_funcs (); + hb_paint_extents_context_t extents_data; + paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0)); + + extents_data.groups.tail().extents.xmin, + extents_data.groups.tail().extents.ymin, + extents_data.groups.tail().extents.xmax, + extents_data.groups.tail().extents.ymax; + + hb_paint_funcs_destroy (extents_funcs); +#endif + return false; } From 55b7af6b621daf2b02d49d4b43d54c67298865fd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 18:01:45 -0500 Subject: [PATCH 200/219] Tweak paint-tests --- test/api/test-paint.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/api/test-paint.c b/test/api/test-paint.c index 6583544fd..1e48b97c5 100644 --- a/test/api/test-paint.c +++ b/test/api/test-paint.c @@ -272,26 +272,26 @@ typedef struct { /* To verify the rendering visually, use * - * hb-view --font-size SCALE --font-slant SLANT --font-palette PALETTE FONT TEXT + * hb-view --font-size SCALE --font-slant SLANT --font-palette PALETTE FONT --glyphs [gidGID=0+1000] * - * where TEXT is as mentioned below. + * where GID is the glyph value of the test. */ static paint_test_t paint_tests[] = { /* COLRv1 */ - { NOTO_HAND, 20, 0., 10, 0, "hand-20-0-10" }, // ✍️ - { NOTO_HAND, 20, 0.2, 10, 0, "hand-20-0.2-10" }, // ✍️ - { TEST_GLYPHS, 20, 0, 6, 0, "test-20-0-6" }, - { TEST_GLYPHS, 20, 0, 10, 0, "test-20-0-10" }, - { TEST_GLYPHS, 20, 0, 92, 0, "test-20-0-92" }, + { NOTO_HAND, 20, 0., 10, 0, "hand-20-0-10" }, + { NOTO_HAND, 20, 0.2, 10, 0, "hand-20-0.2-10" }, + { TEST_GLYPHS, 20, 0, 6, 0, "test-20-0-6" }, // linear gradient + { TEST_GLYPHS, 20, 0, 10, 0, "test-20-0-10" }, // sweep gradient + { TEST_GLYPHS, 20, 0, 92, 0, "test-20-0-92" }, // radial gradient { TEST_GLYPHS, 20, 0, 106, 0, "test-20-0-106" }, - { TEST_GLYPHS, 20, 0, 116, 0, "test-20-0-116" }, + { TEST_GLYPHS, 20, 0, 116, 0, "test-20-0-116" }, // compositing { TEST_GLYPHS, 20, 0, 123, 0, "test-20-0-123" }, - { TEST_GLYPHS, 20, 0, 165, 0, "test-20-0-165" }, - { TEST_GLYPHS, 20, 0, 175, 0, "test-20-0-175" }, + { TEST_GLYPHS, 20, 0, 165, 0, "test-20-0-165" }, // linear gradient + { TEST_GLYPHS, 20, 0, 175, 0, "test-20-0-175" }, // layers /* COLRv0 */ - { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-120-0.3-1" }, // A - { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-120-0.3-2" }, // B - { ROCHER_ABC, 120, 0, 3, 200, "rocher-120-0-3" }, // C + { ROCHER_ABC, 120, 0.3, 1, 0, "rocher-120-0.3-1" }, + { ROCHER_ABC, 120, 0.3, 2, 2, "rocher-120-0.3-2" }, + { ROCHER_ABC, 120, 0, 3, 200, "rocher-120-0-3" }, }; static FT_Library library; From 79229cea1743acaf12c5736f8d7d0e2a8308a961 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 18:33:53 -0500 Subject: [PATCH 201/219] Get outline extents manually --- src/hb-paint-extents.hh | 96 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index a2701f29c..84854f23b 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -27,8 +27,17 @@ #include "hb.hh" #include "hb-paint.hh" +#include "hb-draw.h" +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif + typedef struct hb_extents_t { float xmin, ymin, xmax, ymax; @@ -224,7 +233,7 @@ struct hb_paint_extents_context_t { } } break; - } + } } void paint () @@ -288,6 +297,80 @@ hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED, c->pop_transform (); } +static void +add_point (hb_extents_t *extents, + float x, float y) +{ + if (extents->xmax < extents->xmin) + { + extents->xmin = extents->xmax = x; + extents->ymin = extents->ymax = y; + } + else + { + extents->xmin = MIN (extents->xmin, x); + extents->ymin = MIN (extents->ymin, y); + extents->xmax = MAX (extents->xmax, x); + extents->ymax = MAX (extents->ymax, y); + } +} + +static void +move_to (hb_draw_funcs_t *dfuncs, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *) +{ + hb_extents_t *extents = (hb_extents_t *)data; + add_point (extents, to_x, to_y); +} + +static void +line_to (hb_draw_funcs_t *dfuncs, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *) +{ + hb_extents_t *extents = (hb_extents_t *)data; + add_point (extents, to_x, to_y); +} + +static void +cubic_to (hb_draw_funcs_t *dfuncs, + void *data, + hb_draw_state_t *st, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *) +{ + hb_extents_t *extents = (hb_extents_t *)data; + add_point (extents, control1_x, control1_y); + add_point (extents, control2_x, control2_y); + add_point (extents, to_x, to_y); +} + +static void +close_path (hb_draw_funcs_t *dfuncs, + void *data, + hb_draw_state_t *st, + void *) +{ +} + +static hb_draw_funcs_t * +hb_draw_extent_get_funcs () +{ + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + hb_draw_funcs_set_move_to_func (funcs, move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, line_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, cubic_to, nullptr, nullptr); + hb_draw_funcs_set_close_path_func (funcs, close_path, nullptr, nullptr); + return funcs; +} + static void hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data, @@ -297,12 +380,11 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_glyph_extents_t glyph_extents; - hb_font_get_glyph_extents (font, glyph, &glyph_extents); - hb_extents_t extents = {(float) glyph_extents.x_bearing, - (float) glyph_extents.y_bearing + glyph_extents.height, - (float) glyph_extents.x_bearing + glyph_extents.width, - (float) glyph_extents.y_bearing}; + hb_extents_t extents = { 0, 0, -1, -1 }; + hb_draw_funcs_t *draw_extent_funcs = hb_draw_extent_get_funcs (); + hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); + hb_draw_funcs_destroy (draw_extent_funcs); + c->push_clip (extents); } From 56a48f8b0a881dd0c211f76668a36b477f22e100 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 16:44:06 -0700 Subject: [PATCH 202/219] [paint] Don't use extents in hb-view Let the clipbox do its magic. Currently works for ft backend only. --- src/hb-ft-colr.hh | 1 - util/helper-cairo-user.hh | 7 ------- 2 files changed, 8 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index 0efd7e7d0..a54ee0dcc 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -465,7 +465,6 @@ hb_ft_paint_glyph_colr (hb_font_t *font, clip_box.top_right.y); else { - /* XXX Untested. */ auto *extents_funcs = hb_paint_extents_get_funcs (); hb_paint_extents_context_t extents_data; hb_ft_paint_context_t c (ft_font, font, diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 03dbb8727..9b8428ee7 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -489,13 +489,6 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, palette, color); - hb_glyph_extents_t hb_extents; - hb_font_get_glyph_extents (font, glyph, &hb_extents); - extents->x_bearing = (double) hb_extents.x_bearing / x_scale; - extents->y_bearing = (double)-hb_extents.y_bearing / y_scale; - extents->width = (double) hb_extents.width / x_scale; - extents->height = (double)-hb_extents.height / y_scale; - return CAIRO_STATUS_SUCCESS; } From bd61e645ffea3fdc421f7dc17c0ac0c5fb0d2357 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 16:59:12 -0700 Subject: [PATCH 203/219] [paint-extents] Use hb_min/hb_max --- src/hb-paint-extents.hh | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index 84854f23b..bc9f05c22 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -30,14 +30,6 @@ #include "hb-draw.h" -#ifndef MIN -#define MIN(x,y) ((x) < (y) ? (x) : (y)) -#endif - -#ifndef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#endif - typedef struct hb_extents_t { float xmin, ymin, xmax, ymax; @@ -308,10 +300,10 @@ add_point (hb_extents_t *extents, } else { - extents->xmin = MIN (extents->xmin, x); - extents->ymin = MIN (extents->ymin, y); - extents->xmax = MAX (extents->xmax, x); - extents->ymax = MAX (extents->ymax, y); + extents->xmin = hb_min (extents->xmin, x); + extents->ymin = hb_min (extents->ymin, y); + extents->xmax = hb_max (extents->xmax, x); + extents->ymax = hb_max (extents->ymax, y); } } From 885dbcfba0e1bbc22255ab54f8f76096cb35fdeb Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 19:07:32 -0500 Subject: [PATCH 204/219] Skip empty outlines --- src/hb-paint-extents.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index bc9f05c22..cd95af682 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -376,8 +376,8 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, hb_draw_funcs_t *draw_extent_funcs = hb_draw_extent_get_funcs (); hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); hb_draw_funcs_destroy (draw_extent_funcs); - - c->push_clip (extents); + if (extents.xmin < extents.xmax) + c->push_clip (extents); } static void From f9c2e30e0173f29ce5c05b3163561b1dab3889f7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 17:13:35 -0700 Subject: [PATCH 205/219] [paint-extents] Better handle empty glyphs --- src/hb-paint-extents.hh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index cd95af682..69484d97e 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -121,7 +121,7 @@ typedef struct hb_bounds_t hb_bounds_t (status_t status) : status (status) {} hb_bounds_t (const hb_extents_t &extents) : - status (BOUNDED), extents (extents) {} + status (extents.xmin <= extents.xmax ? BOUNDED : EMPTY), extents (extents) {} status_t status; hb_extents_t extents = {0, 0, 0, 0}; @@ -376,8 +376,7 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, hb_draw_funcs_t *draw_extent_funcs = hb_draw_extent_get_funcs (); hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); hb_draw_funcs_destroy (draw_extent_funcs); - if (extents.xmin < extents.xmax) - c->push_clip (extents); + c->push_clip (extents); } static void From dbea503a38878d8cab0d2106d5b7e44d6550ff5b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 17:28:46 -0700 Subject: [PATCH 206/219] [colr] Return true extents --- src/hb-ot-color-colr-table.hh | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index c9d1f563c..6f1b23d30 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -1998,22 +1998,18 @@ struct COLR return true; } -#if 0 - /* This currently goes into infinite recursion. */ - auto *extents_funcs = hb_paint_extents_get_funcs (); hb_paint_extents_context_t extents_data; paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0)); - extents_data.groups.tail().extents.xmin, - extents_data.groups.tail().extents.ymin, - extents_data.groups.tail().extents.xmax, - extents_data.groups.tail().extents.ymax; + extents->x_bearing = extents_data.groups.tail().extents.xmin; + extents->y_bearing = extents_data.groups.tail().extents.ymax; + extents->width = extents_data.groups.tail().extents.xmax - extents_data.groups.tail().extents.xmin, + extents->height = extents_data.groups.tail().extents.ymin - extents_data.groups.tail().extents.ymax; hb_paint_funcs_destroy (extents_funcs); -#endif - return false; + return true; } bool From 02684751bd6c4f76e6377862136611cf12f66762 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 17:33:13 -0700 Subject: [PATCH 207/219] [paint-extents] Clean up --- src/hb-ft-colr.hh | 15 ++++++++++----- src/hb-ot-color-colr-table.hh | 9 +++++---- src/hb-paint-extents.hh | 10 ++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index a54ee0dcc..3fb40e109 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -456,6 +456,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, FT_COLOR_NO_ROOT_TRANSFORM, &paint)) { + bool is_bounded = true; FT_ClipBox clip_box; if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box)) paint_funcs->push_clip_rectangle (paint_data, @@ -471,11 +472,13 @@ hb_ft_paint_glyph_colr (hb_font_t *font, extents_funcs, &extents_data, palette, foreground); _hb_ft_paint (&c, paint); + hb_extents_t extents = extents_data.get_extents (); + is_bounded = extents_data.is_bounded (); paint_funcs->push_clip_rectangle (paint_data, - extents_data.groups.tail().extents.xmin, - extents_data.groups.tail().extents.ymin, - extents_data.groups.tail().extents.xmax, - extents_data.groups.tail().extents.ymax); + extents.xmin, + extents.ymin, + extents.xmax, + extents.ymax); hb_paint_funcs_destroy (extents_funcs); } @@ -485,7 +488,9 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_ft_paint_context_t c (ft_font, font, paint_funcs, paint_data, palette, foreground); - _hb_ft_paint (&c, paint); + + if (is_bounded) + _hb_ft_paint (&c, paint); paint_funcs->pop_root_transform (paint_data); paint_funcs->pop_clip (paint_data); diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 6f1b23d30..1cdde5adb 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -2002,10 +2002,11 @@ struct COLR hb_paint_extents_context_t extents_data; paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0)); - extents->x_bearing = extents_data.groups.tail().extents.xmin; - extents->y_bearing = extents_data.groups.tail().extents.ymax; - extents->width = extents_data.groups.tail().extents.xmax - extents_data.groups.tail().extents.xmin, - extents->height = extents_data.groups.tail().extents.ymin - extents_data.groups.tail().extents.ymax; + hb_extents_t e = extents_data.get_extents (); + extents->x_bearing = e.xmin; + extents->y_bearing = e.ymax; + extents->width = e.xmax - e.xmin, + extents->height = e.ymin - e.ymax; hb_paint_funcs_destroy (extents_funcs); diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index 69484d97e..01f91d243 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -138,6 +138,16 @@ struct hb_paint_extents_context_t { transforms.push (hb_transform_t{}); } + hb_extents_t get_extents () + { + return groups.tail().extents; + } + + bool is_bounded () + { + return groups.tail().status != hb_bounds_t::status_t::UNBOUNDED; + } + void push_transform (const hb_transform_t &trans) { hb_transform_t r = transforms.tail (); From 73e48b9357ae8efb1526d64f6978efa8f22d80e3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 17:55:09 -0700 Subject: [PATCH 208/219] [colr] Push clipbox or computed clip --- src/hb-ot-color-colr-table.hh | 59 +++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 1cdde5adb..c189c721b 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -2014,7 +2014,7 @@ struct COLR } bool - paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette, hb_color_t foreground) const + paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette, hb_color_t foreground, bool clip = true) const { VarStoreInstancer instancer (this+varStore, this+varIdxMap, @@ -2027,12 +2027,65 @@ struct COLR if (paint) { // COLRv1 glyph - c.funcs->push_root_transform (c.data, font); - c.recurse (*paint); + VarStoreInstancer instancer (this+varStore, + this+varIdxMap, + hb_array (font->coords, font->num_coords)); + + bool is_bounded = true; + bool pop_clip_first = true; + if (clip) + { + hb_glyph_extents_t extents; + if ((this+clipList).get_extents (glyph, + &extents, + instancer)) + { + c.funcs->push_root_transform (c.data, font); + + c.funcs->push_clip_rectangle (c.data, + extents.x_bearing, + extents.y_bearing + extents.height, + extents.x_bearing + extents.width, + extents.y_bearing); + } + else + { + auto *extents_funcs = hb_paint_extents_get_funcs (); + hb_paint_extents_context_t extents_data; + + paint_glyph (font, glyph, + extents_funcs, &extents_data, + palette, foreground, + false); + + hb_extents_t extents = extents_data.get_extents (); + is_bounded = extents_data.is_bounded (); + c.funcs->push_clip_rectangle (c.data, + extents.xmin, + extents.ymin, + extents.xmax, + extents.ymax); + + hb_paint_funcs_destroy (extents_funcs); + + c.funcs->push_root_transform (c.data, font); + + pop_clip_first = false; + } + } + + if (is_bounded) + c.recurse (*paint); + + if (clip && pop_clip_first) + c.funcs->pop_clip (c.data); c.funcs->pop_root_transform (c.data); + if (clip && !pop_clip_first) + c.funcs->pop_clip (c.data); + return true; } } From 0d129ae308d7ac8d0d676b302118229e5add655d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 18:00:38 -0700 Subject: [PATCH 209/219] Fix warning --- src/hb-ot-color-colr-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index c189c721b..c14033233 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -2005,7 +2005,7 @@ struct COLR hb_extents_t e = extents_data.get_extents (); extents->x_bearing = e.xmin; extents->y_bearing = e.ymax; - extents->width = e.xmax - e.xmin, + extents->width = e.xmax - e.xmin; extents->height = e.ymin - e.ymax; hb_paint_funcs_destroy (extents_funcs); From 9f3e050b990e7006a34648faa62a1fd912b8e3c1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 18:15:21 -0700 Subject: [PATCH 210/219] [paint-extents] Streamline extents_t --- src/hb-paint-extents.hh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index 01f91d243..e91bb6486 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -32,7 +32,14 @@ typedef struct hb_extents_t { - float xmin, ymin, xmax, ymax; + hb_extents_t () {} + hb_extents_t (float xmin, float ymin, float xmax, float ymax) : + xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} + + float xmin = 0.f; + float ymin = 0.f; + float xmax = -1.f; + float ymax = -1.f; } hb_extents_t; typedef struct hb_transform_t @@ -124,7 +131,7 @@ typedef struct hb_bounds_t status (extents.xmin <= extents.xmax ? BOUNDED : EMPTY), extents (extents) {} status_t status; - hb_extents_t extents = {0, 0, 0, 0}; + hb_extents_t extents; } hb_bounds_t; typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; @@ -382,7 +389,7 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents = { 0, 0, -1, -1 }; + hb_extents_t extents; hb_draw_funcs_t *draw_extent_funcs = hb_draw_extent_get_funcs (); hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); hb_draw_funcs_destroy (draw_extent_funcs); From 0110bdb3eaa46a6a60f2d5bc0f9cd2f782c6d446 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 18:17:05 -0700 Subject: [PATCH 211/219] [paint-extents] Streamline extents_t more --- src/hb-paint-extents.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index e91bb6486..49456c1eb 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -36,6 +36,8 @@ typedef struct hb_extents_t hb_extents_t (float xmin, float ymin, float xmax, float ymax) : xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} + bool is_empty () const { return xmin > xmax; } + float xmin = 0.f; float ymin = 0.f; float xmax = -1.f; @@ -128,7 +130,7 @@ typedef struct hb_bounds_t hb_bounds_t (status_t status) : status (status) {} hb_bounds_t (const hb_extents_t &extents) : - status (extents.xmin <= extents.xmax ? BOUNDED : EMPTY), extents (extents) {} + status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} status_t status; hb_extents_t extents; From f7eebc397c87d4e8c14c5c0e9f892c0dc8b2e269 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Dec 2022 18:52:46 -0700 Subject: [PATCH 212/219] [paint-extents] Shorten enum addressing --- src/hb-paint-extents.hh | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/hb-paint-extents.hh b/src/hb-paint-extents.hh index 49456c1eb..8e89a8e64 100644 --- a/src/hb-paint-extents.hh +++ b/src/hb-paint-extents.hh @@ -142,8 +142,8 @@ struct hb_paint_extents_context_t { hb_paint_extents_context_t () { - clips.push (hb_bounds_t{hb_bounds_t::status_t::UNBOUNDED}); - groups.push (hb_bounds_t{hb_bounds_t::status_t::EMPTY}); + clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED}); + groups.push (hb_bounds_t{hb_bounds_t::EMPTY}); transforms.push (hb_transform_t{}); } @@ -154,7 +154,7 @@ struct hb_paint_extents_context_t { bool is_bounded () { - return groups.tail().status != hb_bounds_t::status_t::UNBOUNDED; + return groups.tail().status != hb_bounds_t::UNBOUNDED; } void push_transform (const hb_transform_t &trans) @@ -186,7 +186,7 @@ struct hb_paint_extents_context_t { void push_group () { - groups.push (hb_bounds_t{hb_bounds_t::status_t::EMPTY}); + groups.push (hb_bounds_t{hb_bounds_t::EMPTY}); } void pop_group (hb_paint_composite_mode_t mode) @@ -197,7 +197,7 @@ struct hb_paint_extents_context_t { switch ((int) mode) { case HB_PAINT_COMPOSITE_MODE_CLEAR: - backdrop_bounds.status = hb_bounds_t::status_t::EMPTY; + backdrop_bounds.status = hb_bounds_t::EMPTY; break; case HB_PAINT_COMPOSITE_MODE_SRC: case HB_PAINT_COMPOSITE_MODE_SRC_OUT: @@ -209,13 +209,13 @@ struct hb_paint_extents_context_t { case HB_PAINT_COMPOSITE_MODE_SRC_IN: case HB_PAINT_COMPOSITE_MODE_DEST_IN: // Intersect - if (src_bounds.status == hb_bounds_t::status_t::EMPTY) - backdrop_bounds.status = hb_bounds_t::status_t::EMPTY; - else if (src_bounds.status == hb_bounds_t::status_t::BOUNDED) + if (src_bounds.status == hb_bounds_t::EMPTY) + backdrop_bounds.status = hb_bounds_t::EMPTY; + else if (src_bounds.status == hb_bounds_t::BOUNDED) { - if (backdrop_bounds.status == hb_bounds_t::status_t::UNBOUNDED) + if (backdrop_bounds.status == hb_bounds_t::UNBOUNDED) backdrop_bounds = src_bounds; - else if (backdrop_bounds.status == hb_bounds_t::status_t::BOUNDED) + else if (backdrop_bounds.status == hb_bounds_t::BOUNDED) { backdrop_bounds.extents.xmin = hb_max (backdrop_bounds.extents.xmin, src_bounds.extents.xmin); backdrop_bounds.extents.ymin = hb_max (backdrop_bounds.extents.ymin, src_bounds.extents.ymin); @@ -223,19 +223,19 @@ struct hb_paint_extents_context_t { backdrop_bounds.extents.ymax = hb_min (backdrop_bounds.extents.ymax, src_bounds.extents.ymax); if (backdrop_bounds.extents.xmin >= backdrop_bounds.extents.xmax || backdrop_bounds.extents.ymin >= backdrop_bounds.extents.ymax) - backdrop_bounds.status = hb_bounds_t::status_t::EMPTY; + backdrop_bounds.status = hb_bounds_t::EMPTY; } } break; default: // Union - if (src_bounds.status == hb_bounds_t::status_t::UNBOUNDED) - backdrop_bounds.status = hb_bounds_t::status_t::UNBOUNDED; - else if (src_bounds.status == hb_bounds_t::status_t::BOUNDED) + if (src_bounds.status == hb_bounds_t::UNBOUNDED) + backdrop_bounds.status = hb_bounds_t::UNBOUNDED; + else if (src_bounds.status == hb_bounds_t::BOUNDED) { - if (backdrop_bounds.status == hb_bounds_t::status_t::EMPTY) + if (backdrop_bounds.status == hb_bounds_t::EMPTY) backdrop_bounds = src_bounds; - else if (backdrop_bounds.status == hb_bounds_t::status_t::BOUNDED) + else if (backdrop_bounds.status == hb_bounds_t::BOUNDED) { backdrop_bounds.extents.xmin = hb_min (backdrop_bounds.extents.xmin, src_bounds.extents.xmin); backdrop_bounds.extents.ymin = hb_min (backdrop_bounds.extents.ymin, src_bounds.extents.ymin); @@ -253,13 +253,13 @@ struct hb_paint_extents_context_t { const hb_bounds_t &clip = clips.tail (); hb_bounds_t &group = groups.tail (); - if (clip.status == hb_bounds_t::status_t::EMPTY) + if (clip.status == hb_bounds_t::EMPTY) return; // Shouldn't happen - if (group.status == hb_bounds_t::status_t::UNBOUNDED) + if (group.status == hb_bounds_t::UNBOUNDED) return; - if (group.status == hb_bounds_t::status_t::EMPTY) + if (group.status == hb_bounds_t::EMPTY) { group = clip; return; @@ -267,9 +267,9 @@ struct hb_paint_extents_context_t { /* Group is bounded now. Clip is not empty. */ - if (clip.status == hb_bounds_t::status_t::UNBOUNDED) + if (clip.status == hb_bounds_t::UNBOUNDED) { - group.status = hb_bounds_t::status_t::UNBOUNDED; + group.status = hb_bounds_t::UNBOUNDED; return; } From f9c865a8998d6d41b756526f1053b7f55e3c2218 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Dec 2022 20:20:33 -0500 Subject: [PATCH 213/219] Update test results These were changed by the introduction of clip boxes. --- test/api/results/hand-20-0-10 | 190 ++++++++++++++++---------------- test/api/results/hand-20-0.2-10 | 190 ++++++++++++++++---------------- test/api/results/test-20-0-10 | 30 ++--- test/api/results/test-20-0-106 | 46 ++++---- test/api/results/test-20-0-116 | 42 +++---- test/api/results/test-20-0-123 | 54 ++++----- test/api/results/test-20-0-165 | 30 ++--- test/api/results/test-20-0-175 | 54 ++++----- test/api/results/test-20-0-6 | 28 ++--- test/api/results/test-20-0-92 | 28 ++--- 10 files changed, 356 insertions(+), 336 deletions(-) diff --git a/test/api/results/hand-20-0-10 b/test/api/results/hand-20-0-10 index 081f31606..def53eebb 100644 --- a/test/api/results/hand-20-0-10 +++ b/test/api/results/hand-20-0-10 @@ -1,115 +1,117 @@ start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 13 - start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 - radial gradient - p0 280.000000 440.000000 radius 0.000000 - p1 280.000000 440.000000 radius 467.000000 + start clip rectangle 64.000000 -224.000000 1216.000000 928.000000 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 13 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 14 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + linear gradient + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 + 0.000000 164 123 98 255 1.000000 164 123 98 255 end transform - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 14 - start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - linear gradient - p0 231.000000 -27.000000 - p1 1019.000000 -27.000000 - p2 231.000000 -815.000000 - colors - 0.000000 164 123 98 255 - 1.000000 164 123 98 255 - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 15 - start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - solid 145 103 77 255 - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 16 - start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - solid 30 136 229 255 - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 21 - start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - solid 145 103 77 255 - end transform - end clip - end transform - pop group mode 3 - push group + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 15 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 start clip glyph 16 start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - linear gradient - p0 669.000000 776.000000 - p1 180.000000 -106.000000 - p2 -212.000000 1265.000000 - colors - 0.000000 100 181 246 255 - 1.000000 33 150 243 255 + solid 30 136 229 255 end transform end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 18 + start clip glyph 21 start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - solid 66 66 66 51 + solid 145 103 77 255 end transform end clip end transform pop group mode 3 - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 19 - start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 - radial gradient - p0 588.000000 198.000000 radius 0.000000 - p1 588.000000 198.000000 radius 342.000000 - colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 - 1.000000 164 123 98 255 + push group + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 16 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 100 181 246 255 + 1.000000 33 150 243 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 18 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 66 66 66 51 + end transform + end clip + end transform + pop group mode 3 + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 19 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform end transform - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 - start clip glyph 20 - start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 - solid 145 103 77 255 - end transform - end clip - end transform - pop group mode 3 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -0.000000 51.200001 0.000000 0.000000 + start clip glyph 20 + start transform 0.019531 0.000000 0.000000 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 + end clip end transform diff --git a/test/api/results/hand-20-0.2-10 b/test/api/results/hand-20-0.2-10 index 86cb6031a..708cf2c11 100644 --- a/test/api/results/hand-20-0.2-10 +++ b/test/api/results/hand-20-0.2-10 @@ -1,115 +1,117 @@ start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 13 - start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 - radial gradient - p0 280.000000 440.000000 radius 0.000000 - p1 280.000000 440.000000 radius 467.000000 + start clip rectangle 64.000000 -224.000000 1216.000000 928.000000 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 13 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.976807 0.000000 0.000000 + radial gradient + p0 280.000000 440.000000 radius 0.000000 + p1 280.000000 440.000000 radius 467.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 14 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + linear gradient + p0 231.000000 -27.000000 + p1 1019.000000 -27.000000 + p2 231.000000 -815.000000 colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 + 0.000000 164 123 98 255 1.000000 164 123 98 255 end transform - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 14 - start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - linear gradient - p0 231.000000 -27.000000 - p1 1019.000000 -27.000000 - p2 231.000000 -815.000000 - colors - 0.000000 164 123 98 255 - 1.000000 164 123 98 255 - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 15 - start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - solid 145 103 77 255 - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 16 - start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - solid 30 136 229 255 - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 21 - start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - solid 145 103 77 255 - end transform - end clip - end transform - pop group mode 3 - push group + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 15 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 start clip glyph 16 start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - linear gradient - p0 669.000000 776.000000 - p1 180.000000 -106.000000 - p2 -212.000000 1265.000000 - colors - 0.000000 100 181 246 255 - 1.000000 33 150 243 255 + solid 30 136 229 255 end transform end clip end transform pop group mode 3 push group start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 18 + start clip glyph 21 start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - solid 66 66 66 51 + solid 145 103 77 255 end transform end clip end transform pop group mode 3 - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 19 - start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 - radial gradient - p0 588.000000 198.000000 radius 0.000000 - p1 588.000000 198.000000 radius 342.000000 - colors - 0.000000 186 141 104 255 - 0.448792 183 138 103 255 - 0.808594 173 130 100 255 - 1.000000 164 123 98 255 + push group + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 16 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + linear gradient + p0 669.000000 776.000000 + p1 180.000000 -106.000000 + p2 -212.000000 1265.000000 + colors + 0.000000 100 181 246 255 + 1.000000 33 150 243 255 + end transform + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 18 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 66 66 66 51 + end transform + end clip + end transform + pop group mode 3 + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 19 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + start transform 1.000000 0.000000 0.000000 0.969116 0.000000 0.000000 + radial gradient + p0 588.000000 198.000000 radius 0.000000 + p1 588.000000 198.000000 radius 342.000000 + colors + 0.000000 186 141 104 255 + 0.448792 183 138 103 255 + 0.808594 173 130 100 255 + 1.000000 164 123 98 255 + end transform end transform - end transform - end clip - end transform - pop group mode 3 - push group - start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 - start clip glyph 20 - start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 - solid 145 103 77 255 - end transform - end clip - end transform - pop group mode 3 + end clip + end transform + pop group mode 3 + push group + start transform 51.200001 0.000000 -10.240000 51.200001 0.000000 0.000000 + start clip glyph 20 + start transform 0.019531 0.000000 0.003906 0.019531 0.000000 0.000000 + solid 145 103 77 255 + end transform + end clip + end transform + pop group mode 3 + end clip end transform diff --git a/test/api/results/test-20-0-10 b/test/api/results/test-20-0-10 index 8bb19a3bf..27772487c 100644 --- a/test/api/results/test-20-0-10 +++ b/test/api/results/test-20-0-10 @@ -1,16 +1,18 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 174 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - sweep gradient - center 500.000000 600.000000 - angles 0.000000 6.283185 - colors - 0.250000 250 240 230 255 - 0.416687 0 0 255 255 - 0.583313 255 0 0 255 - 0.750000 47 79 79 255 - end transform - end clip - end transform + start clip rectangle 0.000000 0.000000 1000.000000 1000.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 174 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + sweep gradient + center 500.000000 600.000000 + angles 0.000000 6.283185 + colors + 0.250000 250 240 230 255 + 0.416687 0 0 255 255 + 0.583313 255 0 0 255 + 0.750000 47 79 79 255 + end transform + end clip + end transform + end clip end transform diff --git a/test/api/results/test-20-0-106 b/test/api/results/test-20-0-106 index 8e09c8726..6803913f9 100644 --- a/test/api/results/test-20-0-106 +++ b/test/api/results/test-20-0-106 @@ -1,26 +1,28 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - push group - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 3 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 0 0 255 127 - end transform - end clip - end transform +start clip rectangle 5.000000 5.000000 15.000000 15.000000 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group - start transform 0.000000 0.000000 0.000000 0.000000 1000.000000 1000.000000 - start transform 1.000000 -0.363874 -0.176283 1.000000 0.000000 0.000000 - start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 3 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 255 165 0 178 - end transform - end clip + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 0 255 127 + end transform + end clip + end transform + push group + start transform 0.000000 0.000000 0.000000 0.000000 1000.000000 1000.000000 + start transform 1.000000 -0.363874 -0.176283 1.000000 0.000000 0.000000 + start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 255 165 0 178 + end transform + end clip + end transform end transform end transform end transform - end transform - pop group mode 4 - pop group mode 3 -end transform + pop group mode 4 + pop group mode 3 + end transform +end clip diff --git a/test/api/results/test-20-0-116 b/test/api/results/test-20-0-116 index 128dff31b..d07157120 100644 --- a/test/api/results/test-20-0-116 +++ b/test/api/results/test-20-0-116 @@ -1,22 +1,24 @@ -start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - push group - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 3 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 0 0 255 127 - end transform - end clip - end transform +start clip rectangle 5.000000 5.000000 15.000000 15.000000 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 push group - start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 3 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 255 165 0 178 - end transform - end clip - end transform + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 0 255 127 + end transform + end clip end transform - pop group mode 4 - pop group mode 3 -end transform + push group + start transform 1.000000 0.000000 0.000000 1.000000 200.000000 200.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 255 165 0 178 + end transform + end clip + end transform + end transform + pop group mode 4 + pop group mode 3 + end transform +end clip diff --git a/test/api/results/test-20-0-123 b/test/api/results/test-20-0-123 index f29e2ebcd..9d3fa7475 100644 --- a/test/api/results/test-20-0-123 +++ b/test/api/results/test-20-0-123 @@ -1,43 +1,45 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - push group - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 3 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 0 0 0 255 - end transform - end clip - end transform - pop group mode 3 - push group + start clip rectangle 0.000000 0.000000 1000.000000 1000.000000 push group - start transform 0.000000 0.000000 0.000000 0.000000 333.000000 667.000000 - start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 - start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 2 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 255 220 1 255 - end transform - end clip - end transform + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 3 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 0 0 255 end transform - end transform + end clip end transform + pop group mode 3 + push group push group - start transform 0.000000 0.000000 0.000000 0.000000 667.000000 333.000000 + start transform 0.000000 0.000000 0.000000 0.000000 333.000000 667.000000 start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 - start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000 + start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000 start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 start clip glyph 2 start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 104 199 232 255 + solid 255 220 1 255 end transform end clip end transform end transform end transform end transform - pop group mode 5 + push group + start transform 0.000000 0.000000 0.000000 0.000000 667.000000 333.000000 + start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000 + start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 2 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 104 199 232 255 + end transform + end clip + end transform + end transform + end transform + end transform + pop group mode 5 + pop group mode 3 pop group mode 3 - pop group mode 3 + end clip end transform diff --git a/test/api/results/test-20-0-165 b/test/api/results/test-20-0-165 index f67bfdd44..ad5554d80 100644 --- a/test/api/results/test-20-0-165 +++ b/test/api/results/test-20-0-165 @@ -1,16 +1,18 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 165 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - linear gradient - p0 100.000000 950.000000 - p1 2300.000000 950.000000 - p2 -1000.000000 250.000000 - colors - 0.000000 255 0 0 255 - 0.500000 0 0 255 255 - 1.000000 255 255 0 255 - end transform - end clip - end transform + start clip rectangle 100.000000 250.000000 1200.000000 950.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 165 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + linear gradient + p0 100.000000 950.000000 + p1 2300.000000 950.000000 + p2 -1000.000000 250.000000 + colors + 0.000000 255 0 0 255 + 0.500000 0 0 255 255 + 1.000000 255 255 0 255 + end transform + end clip + end transform + end clip end transform diff --git a/test/api/results/test-20-0-175 b/test/api/results/test-20-0-175 index 4f9d775f2..ed4903f53 100644 --- a/test/api/results/test-20-0-175 +++ b/test/api/results/test-20-0-175 @@ -1,30 +1,32 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - push group - start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 174 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - solid 0 128 0 255 - end transform - end clip + start clip rectangle 0.000000 0.000000 1000.000000 1000.000000 + push group + start transform 1.000000 0.000000 0.000000 1.000000 150.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 174 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + solid 0 128 0 255 + end transform + end clip + end transform end transform - end transform - pop group mode 3 - push group - start transform 1.000000 0.000000 0.000000 1.000000 -150.000000 0.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 174 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - linear gradient - p0 500.000000 250.000000 - p1 500.000000 950.000000 - p2 600.000000 250.000000 - colors - 0.000000 255 0 0 255 - 1.000000 0 0 255 255 - end transform - end clip + pop group mode 3 + push group + start transform 1.000000 0.000000 0.000000 1.000000 -150.000000 0.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 174 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + linear gradient + p0 500.000000 250.000000 + p1 500.000000 950.000000 + p2 600.000000 250.000000 + colors + 0.000000 255 0 0 255 + 1.000000 0 0 255 255 + end transform + end clip + end transform end transform - end transform - pop group mode 3 + pop group mode 3 + end clip end transform diff --git a/test/api/results/test-20-0-6 b/test/api/results/test-20-0-6 index 58bbfdc29..8d4c45c55 100644 --- a/test/api/results/test-20-0-6 +++ b/test/api/results/test-20-0-6 @@ -1,15 +1,17 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 6 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - linear gradient - p0 100.000000 250.000000 - p1 900.000000 250.000000 - p2 100.000000 300.000000 - colors - 0.000000 255 0 0 255 - 1.000000 0 0 255 255 - end transform - end clip - end transform + start clip rectangle 100.000000 250.000000 900.000000 950.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 6 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + linear gradient + p0 100.000000 250.000000 + p1 900.000000 250.000000 + p2 100.000000 300.000000 + colors + 0.000000 255 0 0 255 + 1.000000 0 0 255 255 + end transform + end clip + end transform + end clip end transform diff --git a/test/api/results/test-20-0-92 b/test/api/results/test-20-0-92 index e130ab088..463818616 100644 --- a/test/api/results/test-20-0-92 +++ b/test/api/results/test-20-0-92 @@ -1,15 +1,17 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 - start clip glyph 2 - start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 - radial gradient - p0 166.000000 768.000000 radius 0.000000 - p1 166.000000 768.000000 radius 256.000000 - colors - 0.000000 0 128 0 255 - 0.500000 255 255 255 255 - 1.000000 255 0 0 255 - end transform - end clip - end transform + start clip rectangle 0.000000 0.000000 1000.000000 1000.000000 + start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000 + start clip glyph 2 + start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000 + radial gradient + p0 166.000000 768.000000 radius 0.000000 + p1 166.000000 768.000000 radius 256.000000 + colors + 0.000000 0 128 0 255 + 0.500000 255 255 255 255 + 1.000000 255 0 0 255 + end transform + end clip + end transform + end clip end transform From 76c16095fa9a15d719ce78e3adc6d890439e62e1 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 24 Dec 2022 05:30:11 -0500 Subject: [PATCH 214/219] Fix the build on Windows No __BYTE_ORDER there. --- util/hb-cairo-utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 316f5480b..3613e09b6 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -143,6 +143,7 @@ hb_cairo_paint_glyph_image (cairo_t *cr, return; unsigned char *data; +#ifdef __BYTE_ORDER if (__BYTE_ORDER == __BIG_ENDIAN) { data = (unsigned char *) hb_blob_get_data_writable (blob, NULL); @@ -162,6 +163,7 @@ hb_cairo_paint_glyph_image (cairo_t *cr, } } else +#endif data = (unsigned char *) hb_blob_get_data (blob, NULL); surface = cairo_image_surface_create_for_data (data, From 9b9d7c7b8eac99116eeb9cead68c9f926881841c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 24 Dec 2022 05:34:47 -0500 Subject: [PATCH 215/219] Plug a memory lek in paint tests --- test/api/test-paint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/api/test-paint.c b/test/api/test-paint.c index 1e48b97c5..508fff604 100644 --- a/test/api/test-paint.c +++ b/test/api/test-paint.c @@ -526,6 +526,7 @@ test_color_stops (hb_bool_t use_ft) g_assert_true (result); + hb_paint_funcs_destroy (funcs); hb_font_destroy (font); hb_face_destroy (face); } From 4816be9ab5c0afdc7019728620c6761838236bd3 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 24 Dec 2022 07:37:04 -0500 Subject: [PATCH 216/219] Work around cairo limitations If we just draw an image, cairos recording surface complains that it is unbounded. Its not true of course. To make things work, clip to the extents. --- src/hb-ot-color-cbdt-table.hh | 7 +++++++ util/hb-cairo-utils.c | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index a6b906408..c326770a8 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -956,6 +956,11 @@ struct CBDT if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) return false; + funcs->push_clip_rectangle (data, + extents.x_bearing, extents.y_bearing, + extents.x_bearing + extents.width, + extents.y_bearing + extents.height); + funcs->image (data, blob, pixel_extents.width, -pixel_extents.height, @@ -963,6 +968,8 @@ struct CBDT font->slant_xy, &extents); + funcs->pop_clip (data); + hb_blob_destroy (blob); return true; } diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 3613e09b6..27dda47e5 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -180,6 +180,15 @@ hb_cairo_paint_glyph_image (cairo_t *cr, if (!surface) return; + cairo_save (cr); + /* this clip is here to work around recording surface limitations */ + cairo_rectangle (cr, + extents->x_bearing, + extents->y_bearing, + extents->width, + extents->height); + cairo_clip (cr); + cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); @@ -200,6 +209,8 @@ hb_cairo_paint_glyph_image (cairo_t *cr, cairo_pattern_destroy (pattern); cairo_surface_destroy (surface); + + cairo_restore (cr); } static void From 3478728edb32787bcc52cf262563c140a958031e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 24 Dec 2022 08:51:23 -0500 Subject: [PATCH 217/219] Fix test-paint build without freetype --- test/api/test-paint.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/api/test-paint.c b/test/api/test-paint.c index 508fff604..e1331ca0d 100644 --- a/test/api/test-paint.c +++ b/test/api/test-paint.c @@ -294,7 +294,9 @@ static paint_test_t paint_tests[] = { { ROCHER_ABC, 120, 0, 3, 200, "rocher-120-0-3" }, }; +#ifdef HB_HAS_FREETYPE static FT_Library library; +#endif static void test_hb_paint (gconstpointer d, @@ -546,6 +548,8 @@ test_color_stops_ft (void) int main (int argc, char **argv) { + int status = 0; + #ifdef HB_HAS_FREETYPE FT_Init_FreeType (&library); #endif @@ -559,5 +563,7 @@ main (int argc, char **argv) hb_test_add (test_color_stops_ot); hb_test_add (test_color_stops_ft); - return hb_test_run(); + status = hb_test_run(); + + return status; } From d00e97f16cb72ce12ef8c93ccc34fb1be2023a10 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 24 Dec 2022 06:58:44 -0500 Subject: [PATCH 218/219] Add test-paint to the autotools build --- test/api/Makefile.am | 7 + test/api/fonts/RocherColorGX.abc.ttx | 2714 +++++++ test/api/fonts/test_glyphs-glyf_colr_1.ttx | 8458 ++++++++++++++++++++ 3 files changed, 11179 insertions(+) create mode 100644 test/api/fonts/RocherColorGX.abc.ttx create mode 100644 test/api/fonts/test_glyphs-glyf_colr_1.ttx diff --git a/test/api/Makefile.am b/test/api/Makefile.am index e10773e9c..16c4c0913 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -59,6 +59,7 @@ TEST_PROGS = \ test-ot-tag \ test-ot-extents-cff \ test-ot-metrics-tt-var \ + test-paint \ test-set \ test-shape \ test-style \ @@ -90,6 +91,9 @@ TEST_PROGS = \ test_draw_CPPFLAGS = $(AM_CPPFLAGS) test_draw_LDADD = $(LDADD) +test_paint_CPPFLAGS = $(AM_CPPFLAGS) +test_paint_LDADD = $(LDADD) + test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_cmap_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_drop_tables_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la @@ -136,6 +140,9 @@ if HAVE_FREETYPE test_draw_CPPFLAGS += $(FREETYPE_CFLAGS) test_draw_LDADD += $(FREETYPE_LIBS) +test_paint_CPPFLAGS += $(FREETYPE_CFLAGS) +test_paint_LDADD += $(FREETYPE_LIBS) + TEST_PROGS += \ test-ot-math \ $(NULL) diff --git a/test/api/fonts/RocherColorGX.abc.ttx b/test/api/fonts/RocherColorGX.abc.ttx new file mode 100644 index 000000000..a9236f86d --- /dev/null +++ b/test/api/fonts/RocherColorGX.abc.ttx @@ -0,0 +1,2714 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Copyright © 2018 by Henrique Beier. All rights reserved. + + + Rocher Color + + + Regular + + + 0.110;HBT ;RocherColor-Regular + + + Rocher Color Regular + + + Version 0.110 + + + RocherColor-Regular + + + Bevel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BVEL + 0x0 + 0.0 + 100.0 + 100.0 + 257 + + + SHDW + 0x0 + 0.0 + 100.0 + 100.0 + 259 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/api/fonts/test_glyphs-glyf_colr_1.ttx b/test/api/fonts/test_glyphs-glyf_colr_1.ttx new file mode 100644 index 000000000..fc79abe74 --- /dev/null +++ b/test/api/fonts/test_glyphs-glyf_colr_1.ttx @@ -0,0 +1,8458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + COLRv1 Static Test Glyphs + + + Regular + + + COLRv1 Static Test Glyphs 2022-08-16T17:28:26.463214 + + + COLRv1 Static Test Glyphs Regular + + + 2022-08-16T17:28:26.463214 + + + COLRv1StaticTestGlyphs-Regular + + + COLRv1 Static Test Glyphs + + + Regular + + + COLRv1 Static Test Glyphs 2022-08-16T17:28:26.463214 + + + COLRv1 Static Test Glyphs Regular + + + 2022-08-16T17:28:26.463214 + + + COLRv1StaticTestGlyphs-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From dfd371e97653b704326e04c2436ee3edab6c9d64 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 24 Dec 2022 09:57:48 -0500 Subject: [PATCH 219/219] Cosmetics --- util/helper-cairo-user.hh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 9b8428ee7..3c54036bc 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -40,6 +40,8 @@ static bool debug = false; static int level = 0; +static void print (const char *format, ...) __attribute__((format (printf, 1, 2))); + static void print (const char *format, ...) @@ -95,7 +97,7 @@ cubic_to (hb_draw_funcs_t *dfuncs, float to_x, float to_y, void *) { - print ("cubic to %f %f", + print ("cubic to %f %f %f %f %f %f", (double) control1_x, (double) control1_y, (double) control2_x, (double) control2_y, (double) to_x, (double) to_y); @@ -296,7 +298,7 @@ paint_image (hb_paint_funcs_t *funcs, char buf[5] = { 0, }; hb_tag_to_string (format, buf); - print ("image type %s size %u %u slant %f extents %d %d %d %d\n", + print ("image type '%s' size %u %u slant %f extents %d %d %d %d", buf, width, height, (double) slant, extents->x_bearing, extents->y_bearing, extents->width, extents->height); @@ -485,7 +487,10 @@ render_color_glyph (cairo_scaled_font_t *scaled_font, cairo_scale (cr, +1./x_scale, -1./y_scale); if (getenv ("HB_PAINT_DEBUG")) + { debug = atoi (getenv ("HB_PAINT_DEBUG")); + level = 0; + } hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, palette, color);