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 #include "hb-test.h"
26*2d1272b8SAndroid Build Coastguard Worker
27*2d1272b8SAndroid Build Coastguard Worker #include <hb-features.h>
28*2d1272b8SAndroid Build Coastguard Worker #include <hb-ot.h>
29*2d1272b8SAndroid Build Coastguard Worker
30*2d1272b8SAndroid Build Coastguard Worker #ifdef HB_HAS_FREETYPE
31*2d1272b8SAndroid Build Coastguard Worker #include <hb-ft.h>
32*2d1272b8SAndroid Build Coastguard Worker
33*2d1272b8SAndroid Build Coastguard Worker #if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
34*2d1272b8SAndroid Build Coastguard Worker #include FT_COLOR_H
35*2d1272b8SAndroid Build Coastguard Worker #endif
36*2d1272b8SAndroid Build Coastguard Worker #endif
37*2d1272b8SAndroid Build Coastguard Worker
38*2d1272b8SAndroid Build Coastguard Worker static inline hb_bool_t
have_ft_colrv1(void)39*2d1272b8SAndroid Build Coastguard Worker have_ft_colrv1 (void)
40*2d1272b8SAndroid Build Coastguard Worker {
41*2d1272b8SAndroid Build Coastguard Worker #if defined(HB_HAS_FREETYPE) && (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
42*2d1272b8SAndroid Build Coastguard Worker return TRUE;
43*2d1272b8SAndroid Build Coastguard Worker #else
44*2d1272b8SAndroid Build Coastguard Worker return FALSE;
45*2d1272b8SAndroid Build Coastguard Worker #endif
46*2d1272b8SAndroid Build Coastguard Worker }
47*2d1272b8SAndroid Build Coastguard Worker
48*2d1272b8SAndroid Build Coastguard Worker /* Unit tests for hb-paint.h */
49*2d1272b8SAndroid Build Coastguard Worker
50*2d1272b8SAndroid Build Coastguard Worker /* ---- */
51*2d1272b8SAndroid Build Coastguard Worker
52*2d1272b8SAndroid Build Coastguard Worker typedef struct {
53*2d1272b8SAndroid Build Coastguard Worker int level;
54*2d1272b8SAndroid Build Coastguard Worker GString *string;
55*2d1272b8SAndroid Build Coastguard Worker } paint_data_t;
56*2d1272b8SAndroid Build Coastguard Worker
57*2d1272b8SAndroid Build Coastguard Worker static void print (paint_data_t *data, const char *format, ...) G_GNUC_PRINTF (2, 3);
58*2d1272b8SAndroid Build Coastguard Worker
59*2d1272b8SAndroid Build Coastguard Worker static void
print(paint_data_t * data,const char * format,...)60*2d1272b8SAndroid Build Coastguard Worker print (paint_data_t *data,
61*2d1272b8SAndroid Build Coastguard Worker const char *format,
62*2d1272b8SAndroid Build Coastguard Worker ...)
63*2d1272b8SAndroid Build Coastguard Worker {
64*2d1272b8SAndroid Build Coastguard Worker va_list args;
65*2d1272b8SAndroid Build Coastguard Worker
66*2d1272b8SAndroid Build Coastguard Worker g_string_append_printf (data->string, "%*s", 2 * data->level, "");
67*2d1272b8SAndroid Build Coastguard Worker
68*2d1272b8SAndroid Build Coastguard Worker va_start (args, format);
69*2d1272b8SAndroid Build Coastguard Worker g_string_append_vprintf (data->string, format, args);
70*2d1272b8SAndroid Build Coastguard Worker va_end (args);
71*2d1272b8SAndroid Build Coastguard Worker
72*2d1272b8SAndroid Build Coastguard Worker g_string_append (data->string, "\n");
73*2d1272b8SAndroid Build Coastguard Worker }
74*2d1272b8SAndroid Build Coastguard Worker
75*2d1272b8SAndroid Build Coastguard Worker static void
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)76*2d1272b8SAndroid Build Coastguard Worker push_transform (hb_paint_funcs_t *funcs HB_UNUSED,
77*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
78*2d1272b8SAndroid Build Coastguard Worker float xx, float yx,
79*2d1272b8SAndroid Build Coastguard Worker float xy, float yy,
80*2d1272b8SAndroid Build Coastguard Worker float dx, float dy,
81*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
82*2d1272b8SAndroid Build Coastguard Worker {
83*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
84*2d1272b8SAndroid Build Coastguard Worker
85*2d1272b8SAndroid Build Coastguard Worker print (data, "start transform %.3g %.3g %.3g %.3g %.3g %.3g", xx, yx, xy, yy, dx, dy);
86*2d1272b8SAndroid Build Coastguard Worker data->level++;
87*2d1272b8SAndroid Build Coastguard Worker }
88*2d1272b8SAndroid Build Coastguard Worker
89*2d1272b8SAndroid Build Coastguard Worker static void
pop_transform(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,void * user_data HB_UNUSED)90*2d1272b8SAndroid Build Coastguard Worker pop_transform (hb_paint_funcs_t *funcs HB_UNUSED,
91*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
92*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
93*2d1272b8SAndroid Build Coastguard Worker {
94*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
95*2d1272b8SAndroid Build Coastguard Worker
96*2d1272b8SAndroid Build Coastguard Worker data->level--;
97*2d1272b8SAndroid Build Coastguard Worker print (data, "end transform");
98*2d1272b8SAndroid Build Coastguard Worker }
99*2d1272b8SAndroid Build Coastguard Worker
100*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
paint_color_glyph(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_codepoint_t glyph,hb_font_t * font HB_UNUSED,void * user_data HB_UNUSED)101*2d1272b8SAndroid Build Coastguard Worker paint_color_glyph (hb_paint_funcs_t *funcs HB_UNUSED,
102*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
103*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t glyph,
104*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font HB_UNUSED,
105*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
106*2d1272b8SAndroid Build Coastguard Worker {
107*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
108*2d1272b8SAndroid Build Coastguard Worker
109*2d1272b8SAndroid Build Coastguard Worker print (data, "paint color glyph %u; acting as failed", glyph);
110*2d1272b8SAndroid Build Coastguard Worker
111*2d1272b8SAndroid Build Coastguard Worker return FALSE;
112*2d1272b8SAndroid Build Coastguard Worker }
113*2d1272b8SAndroid Build Coastguard Worker
114*2d1272b8SAndroid Build Coastguard Worker static void
push_clip_glyph(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_codepoint_t glyph,hb_font_t * font HB_UNUSED,void * user_data HB_UNUSED)115*2d1272b8SAndroid Build Coastguard Worker push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED,
116*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
117*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t glyph,
118*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font HB_UNUSED,
119*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
120*2d1272b8SAndroid Build Coastguard Worker {
121*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
122*2d1272b8SAndroid Build Coastguard Worker
123*2d1272b8SAndroid Build Coastguard Worker print (data, "start clip glyph %u", glyph);
124*2d1272b8SAndroid Build Coastguard Worker data->level++;
125*2d1272b8SAndroid Build Coastguard Worker }
126*2d1272b8SAndroid Build Coastguard Worker
127*2d1272b8SAndroid Build Coastguard Worker static void
push_clip_rectangle(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,float xmin,float ymin,float xmax,float ymax,void * user_data HB_UNUSED)128*2d1272b8SAndroid Build Coastguard Worker push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED,
129*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
130*2d1272b8SAndroid Build Coastguard Worker float xmin, float ymin, float xmax, float ymax,
131*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
132*2d1272b8SAndroid Build Coastguard Worker {
133*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
134*2d1272b8SAndroid Build Coastguard Worker
135*2d1272b8SAndroid Build Coastguard Worker print (data, "start clip rectangle %.3g %.3g %.3g %.3g", xmin, ymin, xmax, ymax);
136*2d1272b8SAndroid Build Coastguard Worker data->level++;
137*2d1272b8SAndroid Build Coastguard Worker }
138*2d1272b8SAndroid Build Coastguard Worker
139*2d1272b8SAndroid Build Coastguard Worker static void
pop_clip(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,void * user_data HB_UNUSED)140*2d1272b8SAndroid Build Coastguard Worker pop_clip (hb_paint_funcs_t *funcs HB_UNUSED,
141*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
142*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
143*2d1272b8SAndroid Build Coastguard Worker {
144*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
145*2d1272b8SAndroid Build Coastguard Worker
146*2d1272b8SAndroid Build Coastguard Worker data->level--;
147*2d1272b8SAndroid Build Coastguard Worker print (data, "end clip");
148*2d1272b8SAndroid Build Coastguard Worker }
149*2d1272b8SAndroid Build Coastguard Worker
150*2d1272b8SAndroid Build Coastguard Worker static void
paint_color(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_bool_t use_foreground HB_UNUSED,hb_color_t color,void * user_data HB_UNUSED)151*2d1272b8SAndroid Build Coastguard Worker paint_color (hb_paint_funcs_t *funcs HB_UNUSED,
152*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
153*2d1272b8SAndroid Build Coastguard Worker hb_bool_t use_foreground HB_UNUSED,
154*2d1272b8SAndroid Build Coastguard Worker hb_color_t color,
155*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
156*2d1272b8SAndroid Build Coastguard Worker {
157*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
158*2d1272b8SAndroid Build Coastguard Worker
159*2d1272b8SAndroid Build Coastguard Worker print (data, "solid %d %d %d %d",
160*2d1272b8SAndroid Build Coastguard Worker hb_color_get_red (color),
161*2d1272b8SAndroid Build Coastguard Worker hb_color_get_green (color),
162*2d1272b8SAndroid Build Coastguard Worker hb_color_get_blue (color),
163*2d1272b8SAndroid Build Coastguard Worker hb_color_get_alpha (color));
164*2d1272b8SAndroid Build Coastguard Worker }
165*2d1272b8SAndroid Build Coastguard Worker
166*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
paint_image(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_blob_t * blob HB_UNUSED,unsigned int width,unsigned int height,hb_tag_t format,float slant,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)167*2d1272b8SAndroid Build Coastguard Worker paint_image (hb_paint_funcs_t *funcs HB_UNUSED,
168*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
169*2d1272b8SAndroid Build Coastguard Worker hb_blob_t *blob HB_UNUSED,
170*2d1272b8SAndroid Build Coastguard Worker unsigned int width,
171*2d1272b8SAndroid Build Coastguard Worker unsigned int height,
172*2d1272b8SAndroid Build Coastguard Worker hb_tag_t format,
173*2d1272b8SAndroid Build Coastguard Worker float slant,
174*2d1272b8SAndroid Build Coastguard Worker hb_glyph_extents_t *extents,
175*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
176*2d1272b8SAndroid Build Coastguard Worker {
177*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
178*2d1272b8SAndroid Build Coastguard Worker char buf[5] = { 0, };
179*2d1272b8SAndroid Build Coastguard Worker
180*2d1272b8SAndroid Build Coastguard Worker hb_tag_to_string (format, buf);
181*2d1272b8SAndroid Build Coastguard Worker print (data, "image type %s size %u %u slant %.3g extents %d %d %d %d\n",
182*2d1272b8SAndroid Build Coastguard Worker buf, width, height, slant,
183*2d1272b8SAndroid Build Coastguard Worker extents->x_bearing, extents->y_bearing, extents->width, extents->height);
184*2d1272b8SAndroid Build Coastguard Worker
185*2d1272b8SAndroid Build Coastguard Worker return TRUE;
186*2d1272b8SAndroid Build Coastguard Worker }
187*2d1272b8SAndroid Build Coastguard Worker
188*2d1272b8SAndroid Build Coastguard Worker static void
print_color_line(paint_data_t * data,hb_color_line_t * color_line)189*2d1272b8SAndroid Build Coastguard Worker print_color_line (paint_data_t *data,
190*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line)
191*2d1272b8SAndroid Build Coastguard Worker {
192*2d1272b8SAndroid Build Coastguard Worker hb_color_stop_t *stops;
193*2d1272b8SAndroid Build Coastguard Worker unsigned int len;
194*2d1272b8SAndroid Build Coastguard Worker
195*2d1272b8SAndroid Build Coastguard Worker len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL);
196*2d1272b8SAndroid Build Coastguard Worker stops = alloca (len * sizeof (hb_color_stop_t));
197*2d1272b8SAndroid Build Coastguard Worker hb_color_line_get_color_stops (color_line, 0, &len, stops);
198*2d1272b8SAndroid Build Coastguard Worker
199*2d1272b8SAndroid Build Coastguard Worker print (data, "colors %d", hb_color_line_get_extend (color_line));
200*2d1272b8SAndroid Build Coastguard Worker data->level += 1;
201*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 0; i < len; i++)
202*2d1272b8SAndroid Build Coastguard Worker print (data, "%.3g %d %d %d %d",
203*2d1272b8SAndroid Build Coastguard Worker stops[i].offset,
204*2d1272b8SAndroid Build Coastguard Worker hb_color_get_red (stops[i].color),
205*2d1272b8SAndroid Build Coastguard Worker hb_color_get_green (stops[i].color),
206*2d1272b8SAndroid Build Coastguard Worker hb_color_get_blue (stops[i].color),
207*2d1272b8SAndroid Build Coastguard Worker hb_color_get_alpha (stops[i].color));
208*2d1272b8SAndroid Build Coastguard Worker data->level -= 1;
209*2d1272b8SAndroid Build Coastguard Worker }
210*2d1272b8SAndroid Build Coastguard Worker
211*2d1272b8SAndroid Build Coastguard Worker static void
paint_linear_gradient(hb_paint_funcs_t * funcs HB_UNUSED,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_UNUSED)212*2d1272b8SAndroid Build Coastguard Worker paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
213*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
214*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line,
215*2d1272b8SAndroid Build Coastguard Worker float x0, float y0,
216*2d1272b8SAndroid Build Coastguard Worker float x1, float y1,
217*2d1272b8SAndroid Build Coastguard Worker float x2, float y2,
218*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
219*2d1272b8SAndroid Build Coastguard Worker {
220*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
221*2d1272b8SAndroid Build Coastguard Worker
222*2d1272b8SAndroid Build Coastguard Worker print (data, "linear gradient");
223*2d1272b8SAndroid Build Coastguard Worker data->level += 1;
224*2d1272b8SAndroid Build Coastguard Worker print (data, "p0 %.3g %.3g", x0, y0);
225*2d1272b8SAndroid Build Coastguard Worker print (data, "p1 %.3g %.3g", x1, y1);
226*2d1272b8SAndroid Build Coastguard Worker print (data, "p2 %.3g %.3g", x2, y2);
227*2d1272b8SAndroid Build Coastguard Worker
228*2d1272b8SAndroid Build Coastguard Worker print_color_line (data, color_line);
229*2d1272b8SAndroid Build Coastguard Worker data->level -= 1;
230*2d1272b8SAndroid Build Coastguard Worker }
231*2d1272b8SAndroid Build Coastguard Worker
232*2d1272b8SAndroid Build Coastguard Worker static void
paint_radial_gradient(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_color_line_t * color_line,float x0,float y0,float r0,float x1,float y1,float r1,void * user_data HB_UNUSED)233*2d1272b8SAndroid Build Coastguard Worker paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
234*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
235*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line,
236*2d1272b8SAndroid Build Coastguard Worker float x0, float y0, float r0,
237*2d1272b8SAndroid Build Coastguard Worker float x1, float y1, float r1,
238*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
239*2d1272b8SAndroid Build Coastguard Worker {
240*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
241*2d1272b8SAndroid Build Coastguard Worker
242*2d1272b8SAndroid Build Coastguard Worker print (data, "radial gradient");
243*2d1272b8SAndroid Build Coastguard Worker data->level += 1;
244*2d1272b8SAndroid Build Coastguard Worker print (data, "p0 %.3g %.3g radius %.3g", x0, y0, r0);
245*2d1272b8SAndroid Build Coastguard Worker print (data, "p1 %.3g %.3g radius %.3g", x1, y1, r1);
246*2d1272b8SAndroid Build Coastguard Worker
247*2d1272b8SAndroid Build Coastguard Worker print_color_line (data, color_line);
248*2d1272b8SAndroid Build Coastguard Worker data->level -= 1;
249*2d1272b8SAndroid Build Coastguard Worker }
250*2d1272b8SAndroid Build Coastguard Worker
251*2d1272b8SAndroid Build Coastguard Worker static void
paint_sweep_gradient(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_color_line_t * color_line,float cx,float cy,float start_angle,float end_angle,void * user_data HB_UNUSED)252*2d1272b8SAndroid Build Coastguard Worker paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
253*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
254*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line,
255*2d1272b8SAndroid Build Coastguard Worker float cx, float cy,
256*2d1272b8SAndroid Build Coastguard Worker float start_angle,
257*2d1272b8SAndroid Build Coastguard Worker float end_angle,
258*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
259*2d1272b8SAndroid Build Coastguard Worker {
260*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
261*2d1272b8SAndroid Build Coastguard Worker
262*2d1272b8SAndroid Build Coastguard Worker print (data, "sweep gradient");
263*2d1272b8SAndroid Build Coastguard Worker data->level++;
264*2d1272b8SAndroid Build Coastguard Worker print (data, "center %.3g %.3g", cx, cy);
265*2d1272b8SAndroid Build Coastguard Worker print (data, "angles %.3g %.3g", start_angle, end_angle);
266*2d1272b8SAndroid Build Coastguard Worker
267*2d1272b8SAndroid Build Coastguard Worker print_color_line (data, color_line);
268*2d1272b8SAndroid Build Coastguard Worker data->level -= 1;
269*2d1272b8SAndroid Build Coastguard Worker }
270*2d1272b8SAndroid Build Coastguard Worker
271*2d1272b8SAndroid Build Coastguard Worker static void
push_group(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,void * user_data HB_UNUSED)272*2d1272b8SAndroid Build Coastguard Worker push_group (hb_paint_funcs_t *funcs HB_UNUSED,
273*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
274*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
275*2d1272b8SAndroid Build Coastguard Worker {
276*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
277*2d1272b8SAndroid Build Coastguard Worker print (data, "push group");
278*2d1272b8SAndroid Build Coastguard Worker data->level++;
279*2d1272b8SAndroid Build Coastguard Worker }
280*2d1272b8SAndroid Build Coastguard Worker
281*2d1272b8SAndroid Build Coastguard Worker static void
pop_group(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_paint_composite_mode_t mode,void * user_data HB_UNUSED)282*2d1272b8SAndroid Build Coastguard Worker pop_group (hb_paint_funcs_t *funcs HB_UNUSED,
283*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
284*2d1272b8SAndroid Build Coastguard Worker hb_paint_composite_mode_t mode,
285*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
286*2d1272b8SAndroid Build Coastguard Worker {
287*2d1272b8SAndroid Build Coastguard Worker paint_data_t *data = paint_data;
288*2d1272b8SAndroid Build Coastguard Worker data->level--;
289*2d1272b8SAndroid Build Coastguard Worker print (data, "pop group mode %d", mode);
290*2d1272b8SAndroid Build Coastguard Worker }
291*2d1272b8SAndroid Build Coastguard Worker
292*2d1272b8SAndroid Build Coastguard Worker static hb_paint_funcs_t *
get_test_paint_funcs(void)293*2d1272b8SAndroid Build Coastguard Worker get_test_paint_funcs (void)
294*2d1272b8SAndroid Build Coastguard Worker {
295*2d1272b8SAndroid Build Coastguard Worker static hb_paint_funcs_t *funcs = NULL;
296*2d1272b8SAndroid Build Coastguard Worker
297*2d1272b8SAndroid Build Coastguard Worker if (!funcs)
298*2d1272b8SAndroid Build Coastguard Worker {
299*2d1272b8SAndroid Build Coastguard Worker funcs = hb_paint_funcs_create ();
300*2d1272b8SAndroid Build Coastguard Worker
301*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_transform_func (funcs, push_transform, NULL, NULL);
302*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, NULL, NULL);
303*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_color_glyph_func (funcs, paint_color_glyph, NULL, NULL);
304*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, NULL, NULL);
305*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, NULL, NULL);
306*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, NULL, NULL);
307*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_group_func (funcs, push_group, NULL, NULL);
308*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_pop_group_func (funcs, pop_group, NULL, NULL);
309*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_color_func (funcs, paint_color, NULL, NULL);
310*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_image_func (funcs, paint_image, NULL, NULL);
311*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_linear_gradient_func (funcs, paint_linear_gradient, NULL, NULL);
312*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_radial_gradient_func (funcs, paint_radial_gradient, NULL, NULL);
313*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_sweep_gradient_func (funcs, paint_sweep_gradient, NULL, NULL);
314*2d1272b8SAndroid Build Coastguard Worker
315*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_make_immutable (funcs);
316*2d1272b8SAndroid Build Coastguard Worker }
317*2d1272b8SAndroid Build Coastguard Worker
318*2d1272b8SAndroid Build Coastguard Worker return funcs;
319*2d1272b8SAndroid Build Coastguard Worker }
320*2d1272b8SAndroid Build Coastguard Worker
321*2d1272b8SAndroid Build Coastguard Worker typedef struct {
322*2d1272b8SAndroid Build Coastguard Worker const char *font_file;
323*2d1272b8SAndroid Build Coastguard Worker float slant;
324*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t glyph;
325*2d1272b8SAndroid Build Coastguard Worker unsigned int palette;
326*2d1272b8SAndroid Build Coastguard Worker const char *output;
327*2d1272b8SAndroid Build Coastguard Worker } paint_test_t;
328*2d1272b8SAndroid Build Coastguard Worker
329*2d1272b8SAndroid Build Coastguard Worker #define NOTO_HAND "fonts/noto_handwriting-cff2_colr_1.otf"
330*2d1272b8SAndroid Build Coastguard Worker #define TEST_GLYPHS "fonts/test_glyphs-glyf_colr_1.ttf"
331*2d1272b8SAndroid Build Coastguard Worker #define TEST_GLYPHS_VF "fonts/test_glyphs-glyf_colr_1_variable.ttf"
332*2d1272b8SAndroid Build Coastguard Worker #define BAD_COLRV1 "fonts/bad_colrv1.ttf"
333*2d1272b8SAndroid Build Coastguard Worker #define ROCHER_ABC "fonts/RocherColorGX.abc.ttf"
334*2d1272b8SAndroid Build Coastguard Worker
335*2d1272b8SAndroid Build Coastguard Worker /* To verify the rendering visually, use
336*2d1272b8SAndroid Build Coastguard Worker *
337*2d1272b8SAndroid Build Coastguard Worker * hb-view --font-slant SLANT --font-palette PALETTE FONT --glyphs [gidGID=0+1000]
338*2d1272b8SAndroid Build Coastguard Worker *
339*2d1272b8SAndroid Build Coastguard Worker * where GID is the glyph value of the test.
340*2d1272b8SAndroid Build Coastguard Worker */
341*2d1272b8SAndroid Build Coastguard Worker static paint_test_t paint_tests[] = {
342*2d1272b8SAndroid Build Coastguard Worker /* COLRv1 */
343*2d1272b8SAndroid Build Coastguard Worker { NOTO_HAND, 0., 10, 0, "hand-10" },
344*2d1272b8SAndroid Build Coastguard Worker { NOTO_HAND, 0.2f,10, 0, "hand-10.2" },
345*2d1272b8SAndroid Build Coastguard Worker
346*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 6, 0, "test-6" }, // linear gradient
347*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 10, 0, "test-10" }, // sweep gradient
348*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 92, 0, "test-92" }, // radial gradient
349*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 106, 0, "test-106" },
350*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 116, 0, "test-116" }, // compositing
351*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 123, 0, "test-123" },
352*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 154, 0, "test-154" },
353*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 165, 0, "test-165" }, // linear gradient
354*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS, 0, 175, 0, "test-175" }, // layers
355*2d1272b8SAndroid Build Coastguard Worker
356*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 6, 0, "testvf-6" },
357*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 10, 0, "testvf-10" },
358*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 92, 0, "testvf-92" },
359*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 106, 0, "testvf-106" },
360*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 116, 0, "testvf-116" },
361*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 123, 0, "testvf-123" },
362*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 154, 0, "testvf-154" },
363*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 165, 0, "testvf-165" },
364*2d1272b8SAndroid Build Coastguard Worker { TEST_GLYPHS_VF, 0, 175, 0, "testvf-175" },
365*2d1272b8SAndroid Build Coastguard Worker
366*2d1272b8SAndroid Build Coastguard Worker { BAD_COLRV1, 0, 154, 0, "bad-154" }, // recursion
367*2d1272b8SAndroid Build Coastguard Worker
368*2d1272b8SAndroid Build Coastguard Worker /* COLRv0 */
369*2d1272b8SAndroid Build Coastguard Worker { ROCHER_ABC, 0.3f, 1, 0, "rocher-1" },
370*2d1272b8SAndroid Build Coastguard Worker { ROCHER_ABC, 0.3f, 2, 2, "rocher-2" },
371*2d1272b8SAndroid Build Coastguard Worker { ROCHER_ABC, 0, 3, 200, "rocher-3" },
372*2d1272b8SAndroid Build Coastguard Worker };
373*2d1272b8SAndroid Build Coastguard Worker
374*2d1272b8SAndroid Build Coastguard Worker static void
test_hb_paint(gconstpointer d,hb_bool_t use_ft HB_UNUSED)375*2d1272b8SAndroid Build Coastguard Worker test_hb_paint (gconstpointer d,
376*2d1272b8SAndroid Build Coastguard Worker hb_bool_t use_ft HB_UNUSED)
377*2d1272b8SAndroid Build Coastguard Worker {
378*2d1272b8SAndroid Build Coastguard Worker const paint_test_t *test = d;
379*2d1272b8SAndroid Build Coastguard Worker hb_face_t *face;
380*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font;
381*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_t *funcs;
382*2d1272b8SAndroid Build Coastguard Worker paint_data_t data;
383*2d1272b8SAndroid Build Coastguard Worker char *file;
384*2d1272b8SAndroid Build Coastguard Worker char *buffer;
385*2d1272b8SAndroid Build Coastguard Worker gsize len;
386*2d1272b8SAndroid Build Coastguard Worker GError *error = NULL;
387*2d1272b8SAndroid Build Coastguard Worker
388*2d1272b8SAndroid Build Coastguard Worker face = hb_test_open_font_file (test->font_file);
389*2d1272b8SAndroid Build Coastguard Worker font = hb_font_create (face);
390*2d1272b8SAndroid Build Coastguard Worker
391*2d1272b8SAndroid Build Coastguard Worker hb_font_set_synthetic_slant (font, test->slant);
392*2d1272b8SAndroid Build Coastguard Worker
393*2d1272b8SAndroid Build Coastguard Worker #ifdef HB_HAS_FREETYPE
394*2d1272b8SAndroid Build Coastguard Worker if (use_ft)
395*2d1272b8SAndroid Build Coastguard Worker hb_ft_font_set_funcs (font);
396*2d1272b8SAndroid Build Coastguard Worker #endif
397*2d1272b8SAndroid Build Coastguard Worker
398*2d1272b8SAndroid Build Coastguard Worker funcs = get_test_paint_funcs ();
399*2d1272b8SAndroid Build Coastguard Worker
400*2d1272b8SAndroid Build Coastguard Worker data.string = g_string_new ("");
401*2d1272b8SAndroid Build Coastguard Worker data.level = 0;
402*2d1272b8SAndroid Build Coastguard Worker
403*2d1272b8SAndroid Build Coastguard Worker hb_font_paint_glyph (font, test->glyph, funcs, &data, 0, HB_COLOR (0, 0, 0, 255));
404*2d1272b8SAndroid Build Coastguard Worker
405*2d1272b8SAndroid Build Coastguard Worker /* Run
406*2d1272b8SAndroid Build Coastguard Worker *
407*2d1272b8SAndroid Build Coastguard Worker * GENERATE_DATA=1 G_TEST_SRCDIR=./test/api ./build/test/api/test-paint -p TESTCASE > test/api/results/OUTPUT
408*2d1272b8SAndroid Build Coastguard Worker *
409*2d1272b8SAndroid Build Coastguard Worker * to produce the expected results file.
410*2d1272b8SAndroid Build Coastguard Worker */
411*2d1272b8SAndroid Build Coastguard Worker if (getenv ("GENERATE_DATA"))
412*2d1272b8SAndroid Build Coastguard Worker {
413*2d1272b8SAndroid Build Coastguard Worker g_print ("%s", data.string->str);
414*2d1272b8SAndroid Build Coastguard Worker exit (0);
415*2d1272b8SAndroid Build Coastguard Worker }
416*2d1272b8SAndroid Build Coastguard Worker
417*2d1272b8SAndroid Build Coastguard Worker file = g_test_build_filename (G_TEST_DIST, "results", test->output, NULL);
418*2d1272b8SAndroid Build Coastguard Worker if (!g_file_get_contents (file, &buffer, &len, &error))
419*2d1272b8SAndroid Build Coastguard Worker {
420*2d1272b8SAndroid Build Coastguard Worker g_test_message ("File %s not found.", file);
421*2d1272b8SAndroid Build Coastguard Worker g_test_fail ();
422*2d1272b8SAndroid Build Coastguard Worker return;
423*2d1272b8SAndroid Build Coastguard Worker }
424*2d1272b8SAndroid Build Coastguard Worker
425*2d1272b8SAndroid Build Coastguard Worker char **lines = g_strsplit (data.string->str, "\n", 0);
426*2d1272b8SAndroid Build Coastguard Worker char **expected;
427*2d1272b8SAndroid Build Coastguard Worker if (strstr (buffer, "\r\n"))
428*2d1272b8SAndroid Build Coastguard Worker expected = g_strsplit (buffer, "\r\n", 0);
429*2d1272b8SAndroid Build Coastguard Worker else
430*2d1272b8SAndroid Build Coastguard Worker expected = g_strsplit (buffer, "\n", 0);
431*2d1272b8SAndroid Build Coastguard Worker
432*2d1272b8SAndroid Build Coastguard Worker /* Strip initial comments */
433*2d1272b8SAndroid Build Coastguard Worker int i;
434*2d1272b8SAndroid Build Coastguard Worker for (i = 0; expected[i]; i++)
435*2d1272b8SAndroid Build Coastguard Worker {
436*2d1272b8SAndroid Build Coastguard Worker if (expected[i][0] != '#')
437*2d1272b8SAndroid Build Coastguard Worker {
438*2d1272b8SAndroid Build Coastguard Worker if (i > 0)
439*2d1272b8SAndroid Build Coastguard Worker {
440*2d1272b8SAndroid Build Coastguard Worker char **tmp = g_strdupv (expected + i);
441*2d1272b8SAndroid Build Coastguard Worker g_strfreev (expected);
442*2d1272b8SAndroid Build Coastguard Worker expected = tmp;
443*2d1272b8SAndroid Build Coastguard Worker }
444*2d1272b8SAndroid Build Coastguard Worker break;
445*2d1272b8SAndroid Build Coastguard Worker }
446*2d1272b8SAndroid Build Coastguard Worker }
447*2d1272b8SAndroid Build Coastguard Worker
448*2d1272b8SAndroid Build Coastguard Worker if (g_strv_length (lines) != g_strv_length (expected))
449*2d1272b8SAndroid Build Coastguard Worker {
450*2d1272b8SAndroid Build Coastguard Worker g_test_message ("Unexpected number of lines in output (%d instead of %d):\n%s", g_strv_length (lines), g_strv_length (expected), data.string->str);
451*2d1272b8SAndroid Build Coastguard Worker g_test_fail ();
452*2d1272b8SAndroid Build Coastguard Worker }
453*2d1272b8SAndroid Build Coastguard Worker else
454*2d1272b8SAndroid Build Coastguard Worker {
455*2d1272b8SAndroid Build Coastguard Worker unsigned int length = g_strv_length (lines);
456*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 0; i < length; i++)
457*2d1272b8SAndroid Build Coastguard Worker {
458*2d1272b8SAndroid Build Coastguard Worker if (strcmp (lines[i], expected[i]) != 0)
459*2d1272b8SAndroid Build Coastguard Worker {
460*2d1272b8SAndroid Build Coastguard Worker int pos;
461*2d1272b8SAndroid Build Coastguard Worker for (pos = 0; lines[i][pos]; pos++)
462*2d1272b8SAndroid Build Coastguard Worker if (lines[i][pos] != expected[i][pos])
463*2d1272b8SAndroid Build Coastguard Worker break;
464*2d1272b8SAndroid Build Coastguard Worker
465*2d1272b8SAndroid Build Coastguard Worker g_test_message ("Unexpected output at %d:%d (%c instead of %c):\n%s", i, pos, lines[i][pos], expected[i][pos], data.string->str);
466*2d1272b8SAndroid Build Coastguard Worker g_test_fail ();
467*2d1272b8SAndroid Build Coastguard Worker }
468*2d1272b8SAndroid Build Coastguard Worker }
469*2d1272b8SAndroid Build Coastguard Worker }
470*2d1272b8SAndroid Build Coastguard Worker
471*2d1272b8SAndroid Build Coastguard Worker g_strfreev (lines);
472*2d1272b8SAndroid Build Coastguard Worker g_strfreev (expected);
473*2d1272b8SAndroid Build Coastguard Worker
474*2d1272b8SAndroid Build Coastguard Worker g_free (buffer);
475*2d1272b8SAndroid Build Coastguard Worker g_free (file);
476*2d1272b8SAndroid Build Coastguard Worker
477*2d1272b8SAndroid Build Coastguard Worker g_string_free (data.string, TRUE);
478*2d1272b8SAndroid Build Coastguard Worker
479*2d1272b8SAndroid Build Coastguard Worker hb_font_destroy (font);
480*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
481*2d1272b8SAndroid Build Coastguard Worker }
482*2d1272b8SAndroid Build Coastguard Worker
483*2d1272b8SAndroid Build Coastguard Worker static void
test_compare_ot_ft(const char * file,hb_codepoint_t glyph)484*2d1272b8SAndroid Build Coastguard Worker test_compare_ot_ft (const char *file, hb_codepoint_t glyph)
485*2d1272b8SAndroid Build Coastguard Worker {
486*2d1272b8SAndroid Build Coastguard Worker hb_face_t *face;
487*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font;
488*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_t *funcs;
489*2d1272b8SAndroid Build Coastguard Worker GString *ot_str;
490*2d1272b8SAndroid Build Coastguard Worker paint_data_t data;
491*2d1272b8SAndroid Build Coastguard Worker
492*2d1272b8SAndroid Build Coastguard Worker face = hb_test_open_font_file (file);
493*2d1272b8SAndroid Build Coastguard Worker font = hb_font_create (face);
494*2d1272b8SAndroid Build Coastguard Worker
495*2d1272b8SAndroid Build Coastguard Worker funcs = get_test_paint_funcs ();
496*2d1272b8SAndroid Build Coastguard Worker
497*2d1272b8SAndroid Build Coastguard Worker data.string = g_string_new ("");
498*2d1272b8SAndroid Build Coastguard Worker data.level = 0;
499*2d1272b8SAndroid Build Coastguard Worker
500*2d1272b8SAndroid Build Coastguard Worker hb_font_paint_glyph (font, glyph, funcs, &data, 0, HB_COLOR (0, 0, 0, 255));
501*2d1272b8SAndroid Build Coastguard Worker
502*2d1272b8SAndroid Build Coastguard Worker g_assert_true (data.level == 0);
503*2d1272b8SAndroid Build Coastguard Worker
504*2d1272b8SAndroid Build Coastguard Worker ot_str = data.string;
505*2d1272b8SAndroid Build Coastguard Worker
506*2d1272b8SAndroid Build Coastguard Worker #ifdef HB_HAS_FREETYPE
507*2d1272b8SAndroid Build Coastguard Worker hb_ft_font_set_funcs (font);
508*2d1272b8SAndroid Build Coastguard Worker #endif
509*2d1272b8SAndroid Build Coastguard Worker
510*2d1272b8SAndroid Build Coastguard Worker data.string = g_string_new ("");
511*2d1272b8SAndroid Build Coastguard Worker data.level = 0;
512*2d1272b8SAndroid Build Coastguard Worker
513*2d1272b8SAndroid Build Coastguard Worker hb_font_paint_glyph (font, glyph, funcs, &data, 0, HB_COLOR (0, 0, 0, 255));
514*2d1272b8SAndroid Build Coastguard Worker
515*2d1272b8SAndroid Build Coastguard Worker g_assert_true (data.level == 0);
516*2d1272b8SAndroid Build Coastguard Worker
517*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpstr (ot_str->str, ==, data.string->str);
518*2d1272b8SAndroid Build Coastguard Worker
519*2d1272b8SAndroid Build Coastguard Worker g_string_free (data.string, TRUE);
520*2d1272b8SAndroid Build Coastguard Worker hb_font_destroy (font);
521*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
522*2d1272b8SAndroid Build Coastguard Worker
523*2d1272b8SAndroid Build Coastguard Worker g_string_free (ot_str, TRUE);
524*2d1272b8SAndroid Build Coastguard Worker }
525*2d1272b8SAndroid Build Coastguard Worker
526*2d1272b8SAndroid Build Coastguard Worker static void
test_hb_paint_ot(gconstpointer data)527*2d1272b8SAndroid Build Coastguard Worker test_hb_paint_ot (gconstpointer data)
528*2d1272b8SAndroid Build Coastguard Worker {
529*2d1272b8SAndroid Build Coastguard Worker test_hb_paint (data, 0);
530*2d1272b8SAndroid Build Coastguard Worker }
531*2d1272b8SAndroid Build Coastguard Worker
532*2d1272b8SAndroid Build Coastguard Worker static void
test_hb_paint_ft(gconstpointer data)533*2d1272b8SAndroid Build Coastguard Worker test_hb_paint_ft (gconstpointer data)
534*2d1272b8SAndroid Build Coastguard Worker {
535*2d1272b8SAndroid Build Coastguard Worker if (have_ft_colrv1 ())
536*2d1272b8SAndroid Build Coastguard Worker test_hb_paint (data, 1);
537*2d1272b8SAndroid Build Coastguard Worker else
538*2d1272b8SAndroid Build Coastguard Worker g_test_skip ("FreeType COLRv1 support not present");
539*2d1272b8SAndroid Build Coastguard Worker }
540*2d1272b8SAndroid Build Coastguard Worker
541*2d1272b8SAndroid Build Coastguard Worker static void
test_compare_ot_ft_novf(gconstpointer d)542*2d1272b8SAndroid Build Coastguard Worker test_compare_ot_ft_novf (gconstpointer d)
543*2d1272b8SAndroid Build Coastguard Worker {
544*2d1272b8SAndroid Build Coastguard Worker if (have_ft_colrv1 ())
545*2d1272b8SAndroid Build Coastguard Worker test_compare_ot_ft (TEST_GLYPHS, GPOINTER_TO_UINT (d));
546*2d1272b8SAndroid Build Coastguard Worker else
547*2d1272b8SAndroid Build Coastguard Worker g_test_skip ("FreeType COLRv1 support not present");
548*2d1272b8SAndroid Build Coastguard Worker }
549*2d1272b8SAndroid Build Coastguard Worker
550*2d1272b8SAndroid Build Coastguard Worker static void
test_compare_ot_ft_vf(gconstpointer d)551*2d1272b8SAndroid Build Coastguard Worker test_compare_ot_ft_vf (gconstpointer d)
552*2d1272b8SAndroid Build Coastguard Worker {
553*2d1272b8SAndroid Build Coastguard Worker if (have_ft_colrv1 ())
554*2d1272b8SAndroid Build Coastguard Worker test_compare_ot_ft (TEST_GLYPHS_VF, GPOINTER_TO_UINT (d));
555*2d1272b8SAndroid Build Coastguard Worker else
556*2d1272b8SAndroid Build Coastguard Worker g_test_skip ("FreeType COLRv1 support not present");
557*2d1272b8SAndroid Build Coastguard Worker }
558*2d1272b8SAndroid Build Coastguard Worker
559*2d1272b8SAndroid Build Coastguard Worker static void
scrutinize_linear_gradient(hb_paint_funcs_t * funcs HB_UNUSED,void * paint_data,hb_color_line_t * color_line,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)560*2d1272b8SAndroid Build Coastguard Worker scrutinize_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
561*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
562*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line,
563*2d1272b8SAndroid Build Coastguard Worker float x0 HB_UNUSED, float y0 HB_UNUSED,
564*2d1272b8SAndroid Build Coastguard Worker float x1 HB_UNUSED, float y1 HB_UNUSED,
565*2d1272b8SAndroid Build Coastguard Worker float x2 HB_UNUSED, float y2 HB_UNUSED,
566*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
567*2d1272b8SAndroid Build Coastguard Worker {
568*2d1272b8SAndroid Build Coastguard Worker hb_bool_t *result = paint_data;
569*2d1272b8SAndroid Build Coastguard Worker hb_color_stop_t *stops;
570*2d1272b8SAndroid Build Coastguard Worker unsigned int len;
571*2d1272b8SAndroid Build Coastguard Worker hb_color_stop_t *stops2;
572*2d1272b8SAndroid Build Coastguard Worker unsigned int len2;
573*2d1272b8SAndroid Build Coastguard Worker
574*2d1272b8SAndroid Build Coastguard Worker *result = FALSE;
575*2d1272b8SAndroid Build Coastguard Worker
576*2d1272b8SAndroid Build Coastguard Worker len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL);
577*2d1272b8SAndroid Build Coastguard Worker if (len == 0)
578*2d1272b8SAndroid Build Coastguard Worker return;
579*2d1272b8SAndroid Build Coastguard Worker
580*2d1272b8SAndroid Build Coastguard Worker stops = malloc (len * sizeof (hb_color_stop_t));
581*2d1272b8SAndroid Build Coastguard Worker stops2 = malloc (len * sizeof (hb_color_stop_t));
582*2d1272b8SAndroid Build Coastguard Worker
583*2d1272b8SAndroid Build Coastguard Worker hb_color_line_get_color_stops (color_line, 0, &len, stops);
584*2d1272b8SAndroid Build Coastguard Worker hb_color_line_get_color_stops (color_line, 0, &len, stops2);
585*2d1272b8SAndroid Build Coastguard Worker
586*2d1272b8SAndroid Build Coastguard Worker // check that we can get stops twice
587*2d1272b8SAndroid Build Coastguard Worker if (memcmp (stops, stops2, len * sizeof (hb_color_stop_t)) != 0)
588*2d1272b8SAndroid Build Coastguard Worker {
589*2d1272b8SAndroid Build Coastguard Worker free (stops);
590*2d1272b8SAndroid Build Coastguard Worker free (stops2);
591*2d1272b8SAndroid Build Coastguard Worker return;
592*2d1272b8SAndroid Build Coastguard Worker }
593*2d1272b8SAndroid Build Coastguard Worker
594*2d1272b8SAndroid Build Coastguard Worker // check that we can get a single stop in the middle
595*2d1272b8SAndroid Build Coastguard Worker len2 = 1;
596*2d1272b8SAndroid Build Coastguard Worker hb_color_line_get_color_stops (color_line, len - 1, &len2, stops2);
597*2d1272b8SAndroid Build Coastguard Worker if (memcmp (&stops[len - 1], stops2, sizeof (hb_color_stop_t)) != 0)
598*2d1272b8SAndroid Build Coastguard Worker {
599*2d1272b8SAndroid Build Coastguard Worker free (stops);
600*2d1272b8SAndroid Build Coastguard Worker free (stops2);
601*2d1272b8SAndroid Build Coastguard Worker return;
602*2d1272b8SAndroid Build Coastguard Worker }
603*2d1272b8SAndroid Build Coastguard Worker
604*2d1272b8SAndroid Build Coastguard Worker free (stops);
605*2d1272b8SAndroid Build Coastguard Worker free (stops2);
606*2d1272b8SAndroid Build Coastguard Worker
607*2d1272b8SAndroid Build Coastguard Worker *result = TRUE;
608*2d1272b8SAndroid Build Coastguard Worker }
609*2d1272b8SAndroid Build Coastguard Worker
610*2d1272b8SAndroid Build Coastguard Worker static void
test_color_stops(hb_bool_t use_ft HB_UNUSED)611*2d1272b8SAndroid Build Coastguard Worker test_color_stops (hb_bool_t use_ft HB_UNUSED)
612*2d1272b8SAndroid Build Coastguard Worker {
613*2d1272b8SAndroid Build Coastguard Worker hb_face_t *face;
614*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font;
615*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_t *funcs;
616*2d1272b8SAndroid Build Coastguard Worker hb_bool_t result = FALSE;
617*2d1272b8SAndroid Build Coastguard Worker
618*2d1272b8SAndroid Build Coastguard Worker face = hb_test_open_font_file (NOTO_HAND);
619*2d1272b8SAndroid Build Coastguard Worker font = hb_font_create (face);
620*2d1272b8SAndroid Build Coastguard Worker
621*2d1272b8SAndroid Build Coastguard Worker #ifdef HB_HAS_FREETYPE
622*2d1272b8SAndroid Build Coastguard Worker if (use_ft)
623*2d1272b8SAndroid Build Coastguard Worker hb_ft_font_set_funcs (font);
624*2d1272b8SAndroid Build Coastguard Worker #endif
625*2d1272b8SAndroid Build Coastguard Worker
626*2d1272b8SAndroid Build Coastguard Worker funcs = hb_paint_funcs_create ();
627*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_linear_gradient_func (funcs, scrutinize_linear_gradient, NULL, NULL);
628*2d1272b8SAndroid Build Coastguard Worker
629*2d1272b8SAndroid Build Coastguard Worker hb_font_paint_glyph (font, 10, funcs, &result, 0, HB_COLOR (0, 0, 0, 255));
630*2d1272b8SAndroid Build Coastguard Worker
631*2d1272b8SAndroid Build Coastguard Worker g_assert_true (result);
632*2d1272b8SAndroid Build Coastguard Worker
633*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_destroy (funcs);
634*2d1272b8SAndroid Build Coastguard Worker hb_font_destroy (font);
635*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
636*2d1272b8SAndroid Build Coastguard Worker }
637*2d1272b8SAndroid Build Coastguard Worker
638*2d1272b8SAndroid Build Coastguard Worker static void
test_color_stops_ot(void)639*2d1272b8SAndroid Build Coastguard Worker test_color_stops_ot (void)
640*2d1272b8SAndroid Build Coastguard Worker {
641*2d1272b8SAndroid Build Coastguard Worker test_color_stops (0);
642*2d1272b8SAndroid Build Coastguard Worker }
643*2d1272b8SAndroid Build Coastguard Worker
644*2d1272b8SAndroid Build Coastguard Worker static void
test_color_stops_ft(void)645*2d1272b8SAndroid Build Coastguard Worker test_color_stops_ft (void)
646*2d1272b8SAndroid Build Coastguard Worker {
647*2d1272b8SAndroid Build Coastguard Worker if (have_ft_colrv1 ())
648*2d1272b8SAndroid Build Coastguard Worker test_color_stops (1);
649*2d1272b8SAndroid Build Coastguard Worker else
650*2d1272b8SAndroid Build Coastguard Worker g_test_skip ("FreeType COLRv1 support not present");
651*2d1272b8SAndroid Build Coastguard Worker }
652*2d1272b8SAndroid Build Coastguard Worker
653*2d1272b8SAndroid Build Coastguard Worker int
main(int argc,char ** argv)654*2d1272b8SAndroid Build Coastguard Worker main (int argc, char **argv)
655*2d1272b8SAndroid Build Coastguard Worker {
656*2d1272b8SAndroid Build Coastguard Worker int status = 0;
657*2d1272b8SAndroid Build Coastguard Worker
658*2d1272b8SAndroid Build Coastguard Worker hb_test_init (&argc, &argv);
659*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 0; i < G_N_ELEMENTS (paint_tests); i++)
660*2d1272b8SAndroid Build Coastguard Worker {
661*2d1272b8SAndroid Build Coastguard Worker hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint_ot);
662*2d1272b8SAndroid Build Coastguard Worker hb_test_add_data_flavor (&paint_tests[i], paint_tests[i].output, test_hb_paint_ft);
663*2d1272b8SAndroid Build Coastguard Worker }
664*2d1272b8SAndroid Build Coastguard Worker
665*2d1272b8SAndroid Build Coastguard Worker hb_face_t *face = hb_test_open_font_file (TEST_GLYPHS);
666*2d1272b8SAndroid Build Coastguard Worker unsigned glyph_count = hb_face_get_glyph_count (face);
667*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 1; i < glyph_count; i++)
668*2d1272b8SAndroid Build Coastguard Worker {
669*2d1272b8SAndroid Build Coastguard Worker char buf[20];
670*2d1272b8SAndroid Build Coastguard Worker snprintf (buf, 20, "test-%u", i);
671*2d1272b8SAndroid Build Coastguard Worker hb_test_add_data_flavor (GUINT_TO_POINTER (i), buf, test_compare_ot_ft_novf);
672*2d1272b8SAndroid Build Coastguard Worker hb_test_add_data_flavor (GUINT_TO_POINTER (i), buf, test_compare_ot_ft_vf);
673*2d1272b8SAndroid Build Coastguard Worker }
674*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
675*2d1272b8SAndroid Build Coastguard Worker
676*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_color_stops_ot);
677*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_color_stops_ft);
678*2d1272b8SAndroid Build Coastguard Worker
679*2d1272b8SAndroid Build Coastguard Worker status = hb_test_run();
680*2d1272b8SAndroid Build Coastguard Worker
681*2d1272b8SAndroid Build Coastguard Worker return status;
682*2d1272b8SAndroid Build Coastguard Worker }
683