xref: /aosp_15_r20/external/harfbuzz_ng/src/hb-paint.hh (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker  * Copyright © 2022 Matthias Clasen
3*2d1272b8SAndroid Build Coastguard Worker  *
4*2d1272b8SAndroid Build Coastguard Worker  *  This is part of HarfBuzz, a text shaping library.
5*2d1272b8SAndroid Build Coastguard Worker  *
6*2d1272b8SAndroid Build Coastguard Worker  * Permission is hereby granted, without written agreement and without
7*2d1272b8SAndroid Build Coastguard Worker  * license or royalty fees, to use, copy, modify, and distribute this
8*2d1272b8SAndroid Build Coastguard Worker  * software and its documentation for any purpose, provided that the
9*2d1272b8SAndroid Build Coastguard Worker  * above copyright notice and the following two paragraphs appear in
10*2d1272b8SAndroid Build Coastguard Worker  * all copies of this software.
11*2d1272b8SAndroid Build Coastguard Worker  *
12*2d1272b8SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13*2d1272b8SAndroid Build Coastguard Worker  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14*2d1272b8SAndroid Build Coastguard Worker  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15*2d1272b8SAndroid Build Coastguard Worker  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16*2d1272b8SAndroid Build Coastguard Worker  * DAMAGE.
17*2d1272b8SAndroid Build Coastguard Worker  *
18*2d1272b8SAndroid Build Coastguard Worker  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19*2d1272b8SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20*2d1272b8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21*2d1272b8SAndroid Build Coastguard Worker  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22*2d1272b8SAndroid Build Coastguard Worker  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23*2d1272b8SAndroid Build Coastguard Worker  */
24*2d1272b8SAndroid Build Coastguard Worker 
25*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_PAINT_HH
26*2d1272b8SAndroid Build Coastguard Worker #define HB_PAINT_HH
27*2d1272b8SAndroid Build Coastguard Worker 
28*2d1272b8SAndroid Build Coastguard Worker #include "hb.hh"
29*2d1272b8SAndroid Build Coastguard Worker #include "hb-face.hh"
30*2d1272b8SAndroid Build Coastguard Worker #include "hb-font.hh"
31*2d1272b8SAndroid Build Coastguard Worker 
32*2d1272b8SAndroid Build Coastguard Worker #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \
33*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (push_transform) \
34*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (pop_transform) \
35*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (color_glyph) \
36*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \
37*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \
38*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (pop_clip) \
39*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (color) \
40*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (image) \
41*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \
42*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (radial_gradient) \
43*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \
44*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (push_group) \
45*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (pop_group) \
46*2d1272b8SAndroid Build Coastguard Worker   HB_PAINT_FUNC_IMPLEMENT (custom_palette_color) \
47*2d1272b8SAndroid Build Coastguard Worker   /* ^--- Add new callbacks here */
48*2d1272b8SAndroid Build Coastguard Worker 
49*2d1272b8SAndroid Build Coastguard Worker struct hb_paint_funcs_t
50*2d1272b8SAndroid Build Coastguard Worker {
51*2d1272b8SAndroid Build Coastguard Worker   hb_object_header_t header;
52*2d1272b8SAndroid Build Coastguard Worker 
53*2d1272b8SAndroid Build Coastguard Worker   struct {
54*2d1272b8SAndroid Build Coastguard Worker #define HB_PAINT_FUNC_IMPLEMENT(name) hb_paint_##name##_func_t name;
55*2d1272b8SAndroid Build Coastguard Worker     HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
56*2d1272b8SAndroid Build Coastguard Worker #undef HB_PAINT_FUNC_IMPLEMENT
57*2d1272b8SAndroid Build Coastguard Worker   } func;
58*2d1272b8SAndroid Build Coastguard Worker 
59*2d1272b8SAndroid Build Coastguard Worker   struct {
60*2d1272b8SAndroid Build Coastguard Worker #define HB_PAINT_FUNC_IMPLEMENT(name) void *name;
61*2d1272b8SAndroid Build Coastguard Worker     HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
62*2d1272b8SAndroid Build Coastguard Worker #undef HB_PAINT_FUNC_IMPLEMENT
63*2d1272b8SAndroid Build Coastguard Worker   } *user_data;
64*2d1272b8SAndroid Build Coastguard Worker 
65*2d1272b8SAndroid Build Coastguard Worker   struct {
66*2d1272b8SAndroid Build Coastguard Worker #define HB_PAINT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
67*2d1272b8SAndroid Build Coastguard Worker     HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
68*2d1272b8SAndroid Build Coastguard Worker #undef HB_PAINT_FUNC_IMPLEMENT
69*2d1272b8SAndroid Build Coastguard Worker   } *destroy;
70*2d1272b8SAndroid Build Coastguard Worker 
push_transformhb_paint_funcs_t71*2d1272b8SAndroid Build Coastguard Worker   void push_transform (void *paint_data,
72*2d1272b8SAndroid Build Coastguard Worker                        float xx, float yx,
73*2d1272b8SAndroid Build Coastguard Worker                        float xy, float yy,
74*2d1272b8SAndroid Build Coastguard Worker                        float dx, float dy)
75*2d1272b8SAndroid Build Coastguard Worker   { func.push_transform (this, paint_data,
76*2d1272b8SAndroid Build Coastguard Worker                          xx, yx, xy, yy, dx, dy,
77*2d1272b8SAndroid Build Coastguard Worker                          !user_data ? nullptr : user_data->push_transform); }
pop_transformhb_paint_funcs_t78*2d1272b8SAndroid Build Coastguard Worker   void pop_transform (void *paint_data)
79*2d1272b8SAndroid Build Coastguard Worker   { func.pop_transform (this, paint_data,
80*2d1272b8SAndroid Build Coastguard Worker                         !user_data ? nullptr : user_data->pop_transform); }
color_glyphhb_paint_funcs_t81*2d1272b8SAndroid Build Coastguard Worker   bool color_glyph (void *paint_data,
82*2d1272b8SAndroid Build Coastguard Worker                     hb_codepoint_t glyph,
83*2d1272b8SAndroid Build Coastguard Worker                     hb_font_t *font)
84*2d1272b8SAndroid Build Coastguard Worker   { return func.color_glyph (this, paint_data,
85*2d1272b8SAndroid Build Coastguard Worker                              glyph,
86*2d1272b8SAndroid Build Coastguard Worker                              font,
87*2d1272b8SAndroid Build Coastguard Worker                              !user_data ? nullptr : user_data->push_clip_glyph); }
push_clip_glyphhb_paint_funcs_t88*2d1272b8SAndroid Build Coastguard Worker   void push_clip_glyph (void *paint_data,
89*2d1272b8SAndroid Build Coastguard Worker                         hb_codepoint_t glyph,
90*2d1272b8SAndroid Build Coastguard Worker                         hb_font_t *font)
91*2d1272b8SAndroid Build Coastguard Worker   { func.push_clip_glyph (this, paint_data,
92*2d1272b8SAndroid Build Coastguard Worker                           glyph,
93*2d1272b8SAndroid Build Coastguard Worker                           font,
94*2d1272b8SAndroid Build Coastguard Worker                           !user_data ? nullptr : user_data->push_clip_glyph); }
push_clip_rectanglehb_paint_funcs_t95*2d1272b8SAndroid Build Coastguard Worker   void push_clip_rectangle (void *paint_data,
96*2d1272b8SAndroid Build Coastguard Worker                            float xmin, float ymin, float xmax, float ymax)
97*2d1272b8SAndroid Build Coastguard Worker   { func.push_clip_rectangle (this, paint_data,
98*2d1272b8SAndroid Build Coastguard Worker                               xmin, ymin, xmax, ymax,
99*2d1272b8SAndroid Build Coastguard Worker                               !user_data ? nullptr : user_data->push_clip_rectangle); }
pop_cliphb_paint_funcs_t100*2d1272b8SAndroid Build Coastguard Worker   void pop_clip (void *paint_data)
101*2d1272b8SAndroid Build Coastguard Worker   { func.pop_clip (this, paint_data,
102*2d1272b8SAndroid Build Coastguard Worker                    !user_data ? nullptr : user_data->pop_clip); }
colorhb_paint_funcs_t103*2d1272b8SAndroid Build Coastguard Worker   void color (void *paint_data,
104*2d1272b8SAndroid Build Coastguard Worker               hb_bool_t is_foreground,
105*2d1272b8SAndroid Build Coastguard Worker               hb_color_t color)
106*2d1272b8SAndroid Build Coastguard Worker   { func.color (this, paint_data,
107*2d1272b8SAndroid Build Coastguard Worker                 is_foreground, color,
108*2d1272b8SAndroid Build Coastguard Worker                 !user_data ? nullptr : user_data->color); }
imagehb_paint_funcs_t109*2d1272b8SAndroid Build Coastguard Worker   bool image (void *paint_data,
110*2d1272b8SAndroid Build Coastguard Worker               hb_blob_t *image,
111*2d1272b8SAndroid Build Coastguard Worker               unsigned width, unsigned height,
112*2d1272b8SAndroid Build Coastguard Worker               hb_tag_t format,
113*2d1272b8SAndroid Build Coastguard Worker               float slant,
114*2d1272b8SAndroid Build Coastguard Worker               hb_glyph_extents_t *extents)
115*2d1272b8SAndroid Build Coastguard Worker   { return func.image (this, paint_data,
116*2d1272b8SAndroid Build Coastguard Worker                        image, width, height, format, slant, extents,
117*2d1272b8SAndroid Build Coastguard Worker                        !user_data ? nullptr : user_data->image); }
linear_gradienthb_paint_funcs_t118*2d1272b8SAndroid Build Coastguard Worker   void linear_gradient (void *paint_data,
119*2d1272b8SAndroid Build Coastguard Worker                         hb_color_line_t *color_line,
120*2d1272b8SAndroid Build Coastguard Worker                         float x0, float y0,
121*2d1272b8SAndroid Build Coastguard Worker                         float x1, float y1,
122*2d1272b8SAndroid Build Coastguard Worker                         float x2, float y2)
123*2d1272b8SAndroid Build Coastguard Worker   { func.linear_gradient (this, paint_data,
124*2d1272b8SAndroid Build Coastguard Worker                           color_line, x0, y0, x1, y1, x2, y2,
125*2d1272b8SAndroid Build Coastguard Worker                           !user_data ? nullptr : user_data->linear_gradient); }
radial_gradienthb_paint_funcs_t126*2d1272b8SAndroid Build Coastguard Worker   void radial_gradient (void *paint_data,
127*2d1272b8SAndroid Build Coastguard Worker                         hb_color_line_t *color_line,
128*2d1272b8SAndroid Build Coastguard Worker                         float x0, float y0, float r0,
129*2d1272b8SAndroid Build Coastguard Worker                         float x1, float y1, float r1)
130*2d1272b8SAndroid Build Coastguard Worker   { func.radial_gradient (this, paint_data,
131*2d1272b8SAndroid Build Coastguard Worker                           color_line, x0, y0, r0, x1, y1, r1,
132*2d1272b8SAndroid Build Coastguard Worker                           !user_data ? nullptr : user_data->radial_gradient); }
sweep_gradienthb_paint_funcs_t133*2d1272b8SAndroid Build Coastguard Worker   void sweep_gradient (void *paint_data,
134*2d1272b8SAndroid Build Coastguard Worker                        hb_color_line_t *color_line,
135*2d1272b8SAndroid Build Coastguard Worker                        float x0, float y0,
136*2d1272b8SAndroid Build Coastguard Worker                        float start_angle,
137*2d1272b8SAndroid Build Coastguard Worker                        float end_angle)
138*2d1272b8SAndroid Build Coastguard Worker   { func.sweep_gradient (this, paint_data,
139*2d1272b8SAndroid Build Coastguard Worker                          color_line, x0, y0, start_angle, end_angle,
140*2d1272b8SAndroid Build Coastguard Worker                          !user_data ? nullptr : user_data->sweep_gradient); }
push_grouphb_paint_funcs_t141*2d1272b8SAndroid Build Coastguard Worker   void push_group (void *paint_data)
142*2d1272b8SAndroid Build Coastguard Worker   { func.push_group (this, paint_data,
143*2d1272b8SAndroid Build Coastguard Worker                      !user_data ? nullptr : user_data->push_group); }
pop_grouphb_paint_funcs_t144*2d1272b8SAndroid Build Coastguard Worker   void pop_group (void *paint_data,
145*2d1272b8SAndroid Build Coastguard Worker                   hb_paint_composite_mode_t mode)
146*2d1272b8SAndroid Build Coastguard Worker   { func.pop_group (this, paint_data,
147*2d1272b8SAndroid Build Coastguard Worker                     mode,
148*2d1272b8SAndroid Build Coastguard Worker                     !user_data ? nullptr : user_data->pop_group); }
custom_palette_colorhb_paint_funcs_t149*2d1272b8SAndroid Build Coastguard Worker   bool custom_palette_color (void *paint_data,
150*2d1272b8SAndroid Build Coastguard Worker                              unsigned int color_index,
151*2d1272b8SAndroid Build Coastguard Worker                              hb_color_t *color)
152*2d1272b8SAndroid Build Coastguard Worker   { return func.custom_palette_color (this, paint_data,
153*2d1272b8SAndroid Build Coastguard Worker                                       color_index,
154*2d1272b8SAndroid Build Coastguard Worker                                       color,
155*2d1272b8SAndroid Build Coastguard Worker                                       !user_data ? nullptr : user_data->custom_palette_color); }
156*2d1272b8SAndroid Build Coastguard Worker 
157*2d1272b8SAndroid Build Coastguard Worker 
158*2d1272b8SAndroid Build Coastguard Worker   /* Internal specializations. */
159*2d1272b8SAndroid Build Coastguard Worker 
push_root_transformhb_paint_funcs_t160*2d1272b8SAndroid Build Coastguard Worker   void push_root_transform (void *paint_data,
161*2d1272b8SAndroid Build Coastguard Worker                             const hb_font_t *font)
162*2d1272b8SAndroid Build Coastguard Worker   {
163*2d1272b8SAndroid Build Coastguard Worker     float upem = font->face->get_upem ();
164*2d1272b8SAndroid Build Coastguard Worker     int xscale = font->x_scale, yscale = font->y_scale;
165*2d1272b8SAndroid Build Coastguard Worker     float slant = font->slant_xy;
166*2d1272b8SAndroid Build Coastguard Worker 
167*2d1272b8SAndroid Build Coastguard Worker     push_transform (paint_data,
168*2d1272b8SAndroid Build Coastguard Worker 		    xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0);
169*2d1272b8SAndroid Build Coastguard Worker   }
170*2d1272b8SAndroid Build Coastguard Worker 
push_inverse_root_transformhb_paint_funcs_t171*2d1272b8SAndroid Build Coastguard Worker   void push_inverse_root_transform (void *paint_data,
172*2d1272b8SAndroid Build Coastguard Worker                                     hb_font_t *font)
173*2d1272b8SAndroid Build Coastguard Worker   {
174*2d1272b8SAndroid Build Coastguard Worker     float upem = font->face->get_upem ();
175*2d1272b8SAndroid Build Coastguard Worker     int xscale = font->x_scale ? font->x_scale : upem;
176*2d1272b8SAndroid Build Coastguard Worker     int yscale = font->y_scale ? font->y_scale : upem;
177*2d1272b8SAndroid Build Coastguard Worker     float slant = font->slant_xy;
178*2d1272b8SAndroid Build Coastguard Worker 
179*2d1272b8SAndroid Build Coastguard Worker     push_transform (paint_data,
180*2d1272b8SAndroid Build Coastguard Worker 		    upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0);
181*2d1272b8SAndroid Build Coastguard Worker   }
182*2d1272b8SAndroid Build Coastguard Worker 
183*2d1272b8SAndroid Build Coastguard Worker   HB_NODISCARD
push_translatehb_paint_funcs_t184*2d1272b8SAndroid Build Coastguard Worker   bool push_translate (void *paint_data,
185*2d1272b8SAndroid Build Coastguard Worker                        float dx, float dy)
186*2d1272b8SAndroid Build Coastguard Worker   {
187*2d1272b8SAndroid Build Coastguard Worker     if (!dx && !dy)
188*2d1272b8SAndroid Build Coastguard Worker       return false;
189*2d1272b8SAndroid Build Coastguard Worker 
190*2d1272b8SAndroid Build Coastguard Worker     push_transform (paint_data,
191*2d1272b8SAndroid Build Coastguard Worker 		    1.f, 0.f, 0.f, 1.f, dx, dy);
192*2d1272b8SAndroid Build Coastguard Worker     return true;
193*2d1272b8SAndroid Build Coastguard Worker   }
194*2d1272b8SAndroid Build Coastguard Worker 
195*2d1272b8SAndroid Build Coastguard Worker   HB_NODISCARD
push_scalehb_paint_funcs_t196*2d1272b8SAndroid Build Coastguard Worker   bool push_scale (void *paint_data,
197*2d1272b8SAndroid Build Coastguard Worker                    float sx, float sy)
198*2d1272b8SAndroid Build Coastguard Worker   {
199*2d1272b8SAndroid Build Coastguard Worker     if (sx == 1.f && sy == 1.f)
200*2d1272b8SAndroid Build Coastguard Worker       return false;
201*2d1272b8SAndroid Build Coastguard Worker 
202*2d1272b8SAndroid Build Coastguard Worker     push_transform (paint_data,
203*2d1272b8SAndroid Build Coastguard Worker 		    sx, 0.f, 0.f, sy, 0.f, 0.f);
204*2d1272b8SAndroid Build Coastguard Worker     return true;
205*2d1272b8SAndroid Build Coastguard Worker   }
206*2d1272b8SAndroid Build Coastguard Worker 
207*2d1272b8SAndroid Build Coastguard Worker   HB_NODISCARD
push_rotatehb_paint_funcs_t208*2d1272b8SAndroid Build Coastguard Worker   bool push_rotate (void *paint_data,
209*2d1272b8SAndroid Build Coastguard Worker                     float a)
210*2d1272b8SAndroid Build Coastguard Worker   {
211*2d1272b8SAndroid Build Coastguard Worker     if (!a)
212*2d1272b8SAndroid Build Coastguard Worker       return false;
213*2d1272b8SAndroid Build Coastguard Worker 
214*2d1272b8SAndroid Build Coastguard Worker     float cc = cosf (a * HB_PI);
215*2d1272b8SAndroid Build Coastguard Worker     float ss = sinf (a * HB_PI);
216*2d1272b8SAndroid Build Coastguard Worker     push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f);
217*2d1272b8SAndroid Build Coastguard Worker     return true;
218*2d1272b8SAndroid Build Coastguard Worker   }
219*2d1272b8SAndroid Build Coastguard Worker 
220*2d1272b8SAndroid Build Coastguard Worker   HB_NODISCARD
push_skewhb_paint_funcs_t221*2d1272b8SAndroid Build Coastguard Worker   bool push_skew (void *paint_data,
222*2d1272b8SAndroid Build Coastguard Worker                   float sx, float sy)
223*2d1272b8SAndroid Build Coastguard Worker   {
224*2d1272b8SAndroid Build Coastguard Worker     if (!sx && !sy)
225*2d1272b8SAndroid Build Coastguard Worker       return false;
226*2d1272b8SAndroid Build Coastguard Worker 
227*2d1272b8SAndroid Build Coastguard Worker     float x = tanf (-sx * HB_PI);
228*2d1272b8SAndroid Build Coastguard Worker     float y = tanf (+sy * HB_PI);
229*2d1272b8SAndroid Build Coastguard Worker     push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f);
230*2d1272b8SAndroid Build Coastguard Worker     return true;
231*2d1272b8SAndroid Build Coastguard Worker   }
232*2d1272b8SAndroid Build Coastguard Worker };
233*2d1272b8SAndroid Build Coastguard Worker DECLARE_NULL_INSTANCE (hb_paint_funcs_t);
234*2d1272b8SAndroid Build Coastguard Worker 
235*2d1272b8SAndroid Build Coastguard Worker 
236*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_PAINT_HH */
237