From 83d0a49f7100008937fcf7e69e31fe9625365259 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 13 Dec 2022 21:14:25 -0500 Subject: [PATCH] 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',