1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2022 Red Hat, Inc.
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 * Red Hat Author(s): Matthias Clasen
25*2d1272b8SAndroid Build Coastguard Worker */
26*2d1272b8SAndroid Build Coastguard Worker
27*2d1272b8SAndroid Build Coastguard Worker #include "hb.hh"
28*2d1272b8SAndroid Build Coastguard Worker
29*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CAIRO
30*2d1272b8SAndroid Build Coastguard Worker
31*2d1272b8SAndroid Build Coastguard Worker #include "hb-cairo.h"
32*2d1272b8SAndroid Build Coastguard Worker
33*2d1272b8SAndroid Build Coastguard Worker #include "hb-cairo-utils.hh"
34*2d1272b8SAndroid Build Coastguard Worker
35*2d1272b8SAndroid Build Coastguard Worker #include "hb-machinery.hh"
36*2d1272b8SAndroid Build Coastguard Worker #include "hb-utf.hh"
37*2d1272b8SAndroid Build Coastguard Worker
38*2d1272b8SAndroid Build Coastguard Worker
39*2d1272b8SAndroid Build Coastguard Worker /**
40*2d1272b8SAndroid Build Coastguard Worker * SECTION:hb-cairo
41*2d1272b8SAndroid Build Coastguard Worker * @title: hb-cairo
42*2d1272b8SAndroid Build Coastguard Worker * @short_description: Cairo integration
43*2d1272b8SAndroid Build Coastguard Worker * @include: hb-cairo.h
44*2d1272b8SAndroid Build Coastguard Worker *
45*2d1272b8SAndroid Build Coastguard Worker * Functions for using HarfBuzz with the cairo library.
46*2d1272b8SAndroid Build Coastguard Worker *
47*2d1272b8SAndroid Build Coastguard Worker * HarfBuzz supports using cairo for rendering.
48*2d1272b8SAndroid Build Coastguard Worker **/
49*2d1272b8SAndroid Build Coastguard Worker
50*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_move_to(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st HB_UNUSED,float to_x,float to_y,void * user_data HB_UNUSED)51*2d1272b8SAndroid Build Coastguard Worker hb_cairo_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
52*2d1272b8SAndroid Build Coastguard Worker void *draw_data,
53*2d1272b8SAndroid Build Coastguard Worker hb_draw_state_t *st HB_UNUSED,
54*2d1272b8SAndroid Build Coastguard Worker float to_x, float to_y,
55*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
56*2d1272b8SAndroid Build Coastguard Worker {
57*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = (cairo_t *) draw_data;
58*2d1272b8SAndroid Build Coastguard Worker
59*2d1272b8SAndroid Build Coastguard Worker cairo_move_to (cr, (double) to_x, (double) to_y);
60*2d1272b8SAndroid Build Coastguard Worker }
61*2d1272b8SAndroid Build Coastguard Worker
62*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_line_to(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st HB_UNUSED,float to_x,float to_y,void * user_data HB_UNUSED)63*2d1272b8SAndroid Build Coastguard Worker hb_cairo_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
64*2d1272b8SAndroid Build Coastguard Worker void *draw_data,
65*2d1272b8SAndroid Build Coastguard Worker hb_draw_state_t *st HB_UNUSED,
66*2d1272b8SAndroid Build Coastguard Worker float to_x, float to_y,
67*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
68*2d1272b8SAndroid Build Coastguard Worker {
69*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = (cairo_t *) draw_data;
70*2d1272b8SAndroid Build Coastguard Worker
71*2d1272b8SAndroid Build Coastguard Worker cairo_line_to (cr, (double) to_x, (double) to_y);
72*2d1272b8SAndroid Build Coastguard Worker }
73*2d1272b8SAndroid Build Coastguard Worker
74*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_cubic_to(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st HB_UNUSED,float control1_x,float control1_y,float control2_x,float control2_y,float to_x,float to_y,void * user_data HB_UNUSED)75*2d1272b8SAndroid Build Coastguard Worker hb_cairo_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
76*2d1272b8SAndroid Build Coastguard Worker void *draw_data,
77*2d1272b8SAndroid Build Coastguard Worker hb_draw_state_t *st HB_UNUSED,
78*2d1272b8SAndroid Build Coastguard Worker float control1_x, float control1_y,
79*2d1272b8SAndroid Build Coastguard Worker float control2_x, float control2_y,
80*2d1272b8SAndroid Build Coastguard Worker float to_x, float to_y,
81*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
82*2d1272b8SAndroid Build Coastguard Worker {
83*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = (cairo_t *) draw_data;
84*2d1272b8SAndroid Build Coastguard Worker
85*2d1272b8SAndroid Build Coastguard Worker cairo_curve_to (cr,
86*2d1272b8SAndroid Build Coastguard Worker (double) control1_x, (double) control1_y,
87*2d1272b8SAndroid Build Coastguard Worker (double) control2_x, (double) control2_y,
88*2d1272b8SAndroid Build Coastguard Worker (double) to_x, (double) to_y);
89*2d1272b8SAndroid Build Coastguard Worker }
90*2d1272b8SAndroid Build Coastguard Worker
91*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_close_path(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st HB_UNUSED,void * user_data HB_UNUSED)92*2d1272b8SAndroid Build Coastguard Worker hb_cairo_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED,
93*2d1272b8SAndroid Build Coastguard Worker void *draw_data,
94*2d1272b8SAndroid Build Coastguard Worker hb_draw_state_t *st HB_UNUSED,
95*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
96*2d1272b8SAndroid Build Coastguard Worker {
97*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = (cairo_t *) draw_data;
98*2d1272b8SAndroid Build Coastguard Worker
99*2d1272b8SAndroid Build Coastguard Worker cairo_close_path (cr);
100*2d1272b8SAndroid Build Coastguard Worker }
101*2d1272b8SAndroid Build Coastguard Worker
102*2d1272b8SAndroid Build Coastguard Worker static inline void free_static_cairo_draw_funcs ();
103*2d1272b8SAndroid Build Coastguard Worker
104*2d1272b8SAndroid Build Coastguard Worker static struct hb_cairo_draw_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t<hb_cairo_draw_funcs_lazy_loader_t>
105*2d1272b8SAndroid Build Coastguard Worker {
createhb_cairo_draw_funcs_lazy_loader_t106*2d1272b8SAndroid Build Coastguard Worker static hb_draw_funcs_t *create ()
107*2d1272b8SAndroid Build Coastguard Worker {
108*2d1272b8SAndroid Build Coastguard Worker hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
109*2d1272b8SAndroid Build Coastguard Worker
110*2d1272b8SAndroid Build Coastguard Worker hb_draw_funcs_set_move_to_func (funcs, hb_cairo_move_to, nullptr, nullptr);
111*2d1272b8SAndroid Build Coastguard Worker hb_draw_funcs_set_line_to_func (funcs, hb_cairo_line_to, nullptr, nullptr);
112*2d1272b8SAndroid Build Coastguard Worker hb_draw_funcs_set_cubic_to_func (funcs, hb_cairo_cubic_to, nullptr, nullptr);
113*2d1272b8SAndroid Build Coastguard Worker hb_draw_funcs_set_close_path_func (funcs, hb_cairo_close_path, nullptr, nullptr);
114*2d1272b8SAndroid Build Coastguard Worker
115*2d1272b8SAndroid Build Coastguard Worker hb_draw_funcs_make_immutable (funcs);
116*2d1272b8SAndroid Build Coastguard Worker
117*2d1272b8SAndroid Build Coastguard Worker hb_atexit (free_static_cairo_draw_funcs);
118*2d1272b8SAndroid Build Coastguard Worker
119*2d1272b8SAndroid Build Coastguard Worker return funcs;
120*2d1272b8SAndroid Build Coastguard Worker }
121*2d1272b8SAndroid Build Coastguard Worker } static_cairo_draw_funcs;
122*2d1272b8SAndroid Build Coastguard Worker
123*2d1272b8SAndroid Build Coastguard Worker static inline
free_static_cairo_draw_funcs()124*2d1272b8SAndroid Build Coastguard Worker void free_static_cairo_draw_funcs ()
125*2d1272b8SAndroid Build Coastguard Worker {
126*2d1272b8SAndroid Build Coastguard Worker static_cairo_draw_funcs.free_instance ();
127*2d1272b8SAndroid Build Coastguard Worker }
128*2d1272b8SAndroid Build Coastguard Worker
129*2d1272b8SAndroid Build Coastguard Worker static hb_draw_funcs_t *
hb_cairo_draw_get_funcs()130*2d1272b8SAndroid Build Coastguard Worker hb_cairo_draw_get_funcs ()
131*2d1272b8SAndroid Build Coastguard Worker {
132*2d1272b8SAndroid Build Coastguard Worker return static_cairo_draw_funcs.get_unconst ();
133*2d1272b8SAndroid Build Coastguard Worker }
134*2d1272b8SAndroid Build Coastguard Worker
135*2d1272b8SAndroid Build Coastguard Worker
136*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
137*2d1272b8SAndroid Build Coastguard Worker
138*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_push_transform(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,float xx,float yx,float xy,float yy,float dx,float dy,void * user_data HB_UNUSED)139*2d1272b8SAndroid Build Coastguard Worker hb_cairo_push_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
140*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
141*2d1272b8SAndroid Build Coastguard Worker float xx, float yx,
142*2d1272b8SAndroid Build Coastguard Worker float xy, float yy,
143*2d1272b8SAndroid Build Coastguard Worker float dx, float dy,
144*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
145*2d1272b8SAndroid Build Coastguard Worker {
146*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
147*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
148*2d1272b8SAndroid Build Coastguard Worker
149*2d1272b8SAndroid Build Coastguard Worker cairo_matrix_t m;
150*2d1272b8SAndroid Build Coastguard Worker
151*2d1272b8SAndroid Build Coastguard Worker cairo_save (cr);
152*2d1272b8SAndroid Build Coastguard Worker cairo_matrix_init (&m, (double) xx, (double) yx,
153*2d1272b8SAndroid Build Coastguard Worker (double) xy, (double) yy,
154*2d1272b8SAndroid Build Coastguard Worker (double) dx, (double) dy);
155*2d1272b8SAndroid Build Coastguard Worker cairo_transform (cr, &m);
156*2d1272b8SAndroid Build Coastguard Worker }
157*2d1272b8SAndroid Build Coastguard Worker
158*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_pop_transform(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,void * user_data HB_UNUSED)159*2d1272b8SAndroid Build Coastguard Worker hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
160*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
161*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
162*2d1272b8SAndroid Build Coastguard Worker {
163*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
164*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
165*2d1272b8SAndroid Build Coastguard Worker
166*2d1272b8SAndroid Build Coastguard Worker cairo_restore (cr);
167*2d1272b8SAndroid Build Coastguard Worker }
168*2d1272b8SAndroid Build Coastguard Worker
169*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_cairo_paint_color_glyph(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,hb_codepoint_t glyph,hb_font_t * font,void * user_data HB_UNUSED)170*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
171*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
172*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t glyph,
173*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font,
174*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
175*2d1272b8SAndroid Build Coastguard Worker {
176*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
177*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
178*2d1272b8SAndroid Build Coastguard Worker
179*2d1272b8SAndroid Build Coastguard Worker cairo_save (cr);
180*2d1272b8SAndroid Build Coastguard Worker
181*2d1272b8SAndroid Build Coastguard Worker hb_position_t x_scale, y_scale;
182*2d1272b8SAndroid Build Coastguard Worker hb_font_get_scale (font, &x_scale, &y_scale);
183*2d1272b8SAndroid Build Coastguard Worker cairo_scale (cr, x_scale, y_scale);
184*2d1272b8SAndroid Build Coastguard Worker
185*2d1272b8SAndroid Build Coastguard Worker cairo_glyph_t cairo_glyph = { glyph, 0, 0 };
186*2d1272b8SAndroid Build Coastguard Worker cairo_set_scaled_font (cr, c->scaled_font);
187*2d1272b8SAndroid Build Coastguard Worker cairo_set_font_size (cr, 1);
188*2d1272b8SAndroid Build Coastguard Worker cairo_show_glyphs (cr, &cairo_glyph, 1);
189*2d1272b8SAndroid Build Coastguard Worker
190*2d1272b8SAndroid Build Coastguard Worker cairo_restore (cr);
191*2d1272b8SAndroid Build Coastguard Worker
192*2d1272b8SAndroid Build Coastguard Worker return true;
193*2d1272b8SAndroid Build Coastguard Worker }
194*2d1272b8SAndroid Build Coastguard Worker
195*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_push_clip_glyph(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,hb_codepoint_t glyph,hb_font_t * font,void * user_data HB_UNUSED)196*2d1272b8SAndroid Build Coastguard Worker hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
197*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
198*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t glyph,
199*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font,
200*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
201*2d1272b8SAndroid Build Coastguard Worker {
202*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
203*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
204*2d1272b8SAndroid Build Coastguard Worker
205*2d1272b8SAndroid Build Coastguard Worker cairo_save (cr);
206*2d1272b8SAndroid Build Coastguard Worker cairo_new_path (cr);
207*2d1272b8SAndroid Build Coastguard Worker hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
208*2d1272b8SAndroid Build Coastguard Worker cairo_close_path (cr);
209*2d1272b8SAndroid Build Coastguard Worker cairo_clip (cr);
210*2d1272b8SAndroid Build Coastguard Worker }
211*2d1272b8SAndroid Build Coastguard Worker
212*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_push_clip_rectangle(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,float xmin,float ymin,float xmax,float ymax,void * user_data HB_UNUSED)213*2d1272b8SAndroid Build Coastguard Worker hb_cairo_push_clip_rectangle (hb_paint_funcs_t *pfuncs HB_UNUSED,
214*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
215*2d1272b8SAndroid Build Coastguard Worker float xmin, float ymin, float xmax, float ymax,
216*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
217*2d1272b8SAndroid Build Coastguard Worker {
218*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
219*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
220*2d1272b8SAndroid Build Coastguard Worker
221*2d1272b8SAndroid Build Coastguard Worker cairo_save (cr);
222*2d1272b8SAndroid Build Coastguard Worker cairo_rectangle (cr,
223*2d1272b8SAndroid Build Coastguard Worker (double) xmin, (double) ymin,
224*2d1272b8SAndroid Build Coastguard Worker (double) (xmax - xmin), (double) (ymax - ymin));
225*2d1272b8SAndroid Build Coastguard Worker cairo_clip (cr);
226*2d1272b8SAndroid Build Coastguard Worker }
227*2d1272b8SAndroid Build Coastguard Worker
228*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_pop_clip(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,void * user_data HB_UNUSED)229*2d1272b8SAndroid Build Coastguard Worker hb_cairo_pop_clip (hb_paint_funcs_t *pfuncs HB_UNUSED,
230*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
231*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
232*2d1272b8SAndroid Build Coastguard Worker {
233*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
234*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
235*2d1272b8SAndroid Build Coastguard Worker
236*2d1272b8SAndroid Build Coastguard Worker cairo_restore (cr);
237*2d1272b8SAndroid Build Coastguard Worker }
238*2d1272b8SAndroid Build Coastguard Worker
239*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_push_group(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,void * user_data HB_UNUSED)240*2d1272b8SAndroid Build Coastguard Worker hb_cairo_push_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
241*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
242*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
243*2d1272b8SAndroid Build Coastguard Worker {
244*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
245*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
246*2d1272b8SAndroid Build Coastguard Worker
247*2d1272b8SAndroid Build Coastguard Worker cairo_save (cr);
248*2d1272b8SAndroid Build Coastguard Worker cairo_push_group (cr);
249*2d1272b8SAndroid Build Coastguard Worker }
250*2d1272b8SAndroid Build Coastguard Worker
251*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_pop_group(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,hb_paint_composite_mode_t mode,void * user_data HB_UNUSED)252*2d1272b8SAndroid Build Coastguard Worker hb_cairo_pop_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
253*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
254*2d1272b8SAndroid Build Coastguard Worker hb_paint_composite_mode_t mode,
255*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
256*2d1272b8SAndroid Build Coastguard Worker {
257*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
258*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
259*2d1272b8SAndroid Build Coastguard Worker
260*2d1272b8SAndroid Build Coastguard Worker cairo_pop_group_to_source (cr);
261*2d1272b8SAndroid Build Coastguard Worker cairo_set_operator (cr, _hb_paint_composite_mode_to_cairo (mode));
262*2d1272b8SAndroid Build Coastguard Worker cairo_paint (cr);
263*2d1272b8SAndroid Build Coastguard Worker
264*2d1272b8SAndroid Build Coastguard Worker cairo_restore (cr);
265*2d1272b8SAndroid Build Coastguard Worker }
266*2d1272b8SAndroid Build Coastguard Worker
267*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_paint_color(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,hb_bool_t use_foreground,hb_color_t color,void * user_data HB_UNUSED)268*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_color (hb_paint_funcs_t *pfuncs HB_UNUSED,
269*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
270*2d1272b8SAndroid Build Coastguard Worker hb_bool_t use_foreground,
271*2d1272b8SAndroid Build Coastguard Worker hb_color_t color,
272*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
273*2d1272b8SAndroid Build Coastguard Worker {
274*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
275*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
276*2d1272b8SAndroid Build Coastguard Worker
277*2d1272b8SAndroid Build Coastguard Worker if (use_foreground)
278*2d1272b8SAndroid Build Coastguard Worker {
279*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CAIRO_USER_SCALED_FONT_GET_FOREGROUND_SOURCE
280*2d1272b8SAndroid Build Coastguard Worker double r, g, b, a;
281*2d1272b8SAndroid Build Coastguard Worker cairo_pattern_t *foreground = cairo_user_scaled_font_get_foreground_source (c->scaled_font);
282*2d1272b8SAndroid Build Coastguard Worker if (cairo_pattern_get_rgba (foreground, &r, &g, &b, &a) == CAIRO_STATUS_SUCCESS)
283*2d1272b8SAndroid Build Coastguard Worker cairo_set_source_rgba (cr, r, g, b, a * hb_color_get_alpha (color) / 255.);
284*2d1272b8SAndroid Build Coastguard Worker else
285*2d1272b8SAndroid Build Coastguard Worker #endif
286*2d1272b8SAndroid Build Coastguard Worker cairo_set_source_rgba (cr, 0, 0, 0, hb_color_get_alpha (color) / 255.);
287*2d1272b8SAndroid Build Coastguard Worker }
288*2d1272b8SAndroid Build Coastguard Worker else
289*2d1272b8SAndroid Build Coastguard Worker cairo_set_source_rgba (cr,
290*2d1272b8SAndroid Build Coastguard Worker hb_color_get_red (color) / 255.,
291*2d1272b8SAndroid Build Coastguard Worker hb_color_get_green (color) / 255.,
292*2d1272b8SAndroid Build Coastguard Worker hb_color_get_blue (color) / 255.,
293*2d1272b8SAndroid Build Coastguard Worker hb_color_get_alpha (color) / 255.);
294*2d1272b8SAndroid Build Coastguard Worker cairo_paint (cr);
295*2d1272b8SAndroid Build Coastguard Worker }
296*2d1272b8SAndroid Build Coastguard Worker
297*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_cairo_paint_image(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,hb_blob_t * blob,unsigned width,unsigned height,hb_tag_t format,float slant,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)298*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_image (hb_paint_funcs_t *pfuncs HB_UNUSED,
299*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
300*2d1272b8SAndroid Build Coastguard Worker hb_blob_t *blob,
301*2d1272b8SAndroid Build Coastguard Worker unsigned width,
302*2d1272b8SAndroid Build Coastguard Worker unsigned height,
303*2d1272b8SAndroid Build Coastguard Worker hb_tag_t format,
304*2d1272b8SAndroid Build Coastguard Worker float slant,
305*2d1272b8SAndroid Build Coastguard Worker hb_glyph_extents_t *extents,
306*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
307*2d1272b8SAndroid Build Coastguard Worker {
308*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
309*2d1272b8SAndroid Build Coastguard Worker
310*2d1272b8SAndroid Build Coastguard Worker return _hb_cairo_paint_glyph_image (c, blob, width, height, format, slant, extents);
311*2d1272b8SAndroid Build Coastguard Worker }
312*2d1272b8SAndroid Build Coastguard Worker
313*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_paint_linear_gradient(hb_paint_funcs_t * pfuncs 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)314*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_linear_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
315*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
316*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line,
317*2d1272b8SAndroid Build Coastguard Worker float x0, float y0,
318*2d1272b8SAndroid Build Coastguard Worker float x1, float y1,
319*2d1272b8SAndroid Build Coastguard Worker float x2, float y2,
320*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
321*2d1272b8SAndroid Build Coastguard Worker {
322*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
323*2d1272b8SAndroid Build Coastguard Worker
324*2d1272b8SAndroid Build Coastguard Worker _hb_cairo_paint_linear_gradient (c, color_line, x0, y0, x1, y1, x2, y2);
325*2d1272b8SAndroid Build Coastguard Worker }
326*2d1272b8SAndroid Build Coastguard Worker
327*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_paint_radial_gradient(hb_paint_funcs_t * pfuncs 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)328*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_radial_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
329*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
330*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line,
331*2d1272b8SAndroid Build Coastguard Worker float x0, float y0, float r0,
332*2d1272b8SAndroid Build Coastguard Worker float x1, float y1, float r1,
333*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
334*2d1272b8SAndroid Build Coastguard Worker {
335*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
336*2d1272b8SAndroid Build Coastguard Worker
337*2d1272b8SAndroid Build Coastguard Worker _hb_cairo_paint_radial_gradient (c, color_line, x0, y0, r0, x1, y1, r1);
338*2d1272b8SAndroid Build Coastguard Worker }
339*2d1272b8SAndroid Build Coastguard Worker
340*2d1272b8SAndroid Build Coastguard Worker static void
hb_cairo_paint_sweep_gradient(hb_paint_funcs_t * pfuncs HB_UNUSED,void * paint_data,hb_color_line_t * color_line,float x0,float y0,float start_angle,float end_angle,void * user_data HB_UNUSED)341*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
342*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
343*2d1272b8SAndroid Build Coastguard Worker hb_color_line_t *color_line,
344*2d1272b8SAndroid Build Coastguard Worker float x0, float y0,
345*2d1272b8SAndroid Build Coastguard Worker float start_angle, float end_angle,
346*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
347*2d1272b8SAndroid Build Coastguard Worker {
348*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
349*2d1272b8SAndroid Build Coastguard Worker
350*2d1272b8SAndroid Build Coastguard Worker _hb_cairo_paint_sweep_gradient (c, color_line, x0, y0, start_angle, end_angle);
351*2d1272b8SAndroid Build Coastguard Worker }
352*2d1272b8SAndroid Build Coastguard Worker
353*2d1272b8SAndroid Build Coastguard Worker static const cairo_user_data_key_t color_cache_key = {0};
354*2d1272b8SAndroid Build Coastguard Worker
355*2d1272b8SAndroid Build Coastguard Worker static void
_hb_cairo_destroy_map(void * p)356*2d1272b8SAndroid Build Coastguard Worker _hb_cairo_destroy_map (void *p)
357*2d1272b8SAndroid Build Coastguard Worker {
358*2d1272b8SAndroid Build Coastguard Worker hb_map_destroy ((hb_map_t *) p);
359*2d1272b8SAndroid Build Coastguard Worker }
360*2d1272b8SAndroid Build Coastguard Worker
361*2d1272b8SAndroid Build Coastguard Worker static hb_bool_t
hb_cairo_paint_custom_palette_color(hb_paint_funcs_t * funcs,void * paint_data,unsigned int color_index,hb_color_t * color,void * user_data HB_UNUSED)362*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_custom_palette_color (hb_paint_funcs_t *funcs,
363*2d1272b8SAndroid Build Coastguard Worker void *paint_data,
364*2d1272b8SAndroid Build Coastguard Worker unsigned int color_index,
365*2d1272b8SAndroid Build Coastguard Worker hb_color_t *color,
366*2d1272b8SAndroid Build Coastguard Worker void *user_data HB_UNUSED)
367*2d1272b8SAndroid Build Coastguard Worker {
368*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
369*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
370*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr = c->cr;
371*2d1272b8SAndroid Build Coastguard Worker
372*2d1272b8SAndroid Build Coastguard Worker #define HB_DEADBEEF HB_TAG(0xDE,0xAD,0xBE,0xEF)
373*2d1272b8SAndroid Build Coastguard Worker
374*2d1272b8SAndroid Build Coastguard Worker hb_map_t *color_cache = c->color_cache;
375*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t *v;
376*2d1272b8SAndroid Build Coastguard Worker if (likely (color_cache && color_cache->has (color_index, &v)))
377*2d1272b8SAndroid Build Coastguard Worker {
378*2d1272b8SAndroid Build Coastguard Worker if (*v == HB_DEADBEEF)
379*2d1272b8SAndroid Build Coastguard Worker return false;
380*2d1272b8SAndroid Build Coastguard Worker *color = *v;
381*2d1272b8SAndroid Build Coastguard Worker return true;
382*2d1272b8SAndroid Build Coastguard Worker }
383*2d1272b8SAndroid Build Coastguard Worker
384*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_t *options;
385*2d1272b8SAndroid Build Coastguard Worker double red, green, blue, alpha;
386*2d1272b8SAndroid Build Coastguard Worker
387*2d1272b8SAndroid Build Coastguard Worker options = cairo_font_options_create ();
388*2d1272b8SAndroid Build Coastguard Worker cairo_get_font_options (cr, options);
389*2d1272b8SAndroid Build Coastguard Worker if (CAIRO_STATUS_SUCCESS ==
390*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_get_custom_palette_color (options, color_index,
391*2d1272b8SAndroid Build Coastguard Worker &red, &green, &blue, &alpha))
392*2d1272b8SAndroid Build Coastguard Worker {
393*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_destroy (options);
394*2d1272b8SAndroid Build Coastguard Worker *color = HB_COLOR (round (255 * blue),
395*2d1272b8SAndroid Build Coastguard Worker round (255 * green),
396*2d1272b8SAndroid Build Coastguard Worker round (255 * red),
397*2d1272b8SAndroid Build Coastguard Worker round (255 * alpha));
398*2d1272b8SAndroid Build Coastguard Worker
399*2d1272b8SAndroid Build Coastguard Worker if (likely (color_cache && *color != HB_DEADBEEF))
400*2d1272b8SAndroid Build Coastguard Worker color_cache->set (color_index, *color);
401*2d1272b8SAndroid Build Coastguard Worker
402*2d1272b8SAndroid Build Coastguard Worker return true;
403*2d1272b8SAndroid Build Coastguard Worker }
404*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_destroy (options);
405*2d1272b8SAndroid Build Coastguard Worker
406*2d1272b8SAndroid Build Coastguard Worker if (likely (color_cache))
407*2d1272b8SAndroid Build Coastguard Worker color_cache->set (color_index, HB_DEADBEEF);
408*2d1272b8SAndroid Build Coastguard Worker
409*2d1272b8SAndroid Build Coastguard Worker #undef HB_DEADBEEF
410*2d1272b8SAndroid Build Coastguard Worker
411*2d1272b8SAndroid Build Coastguard Worker #endif
412*2d1272b8SAndroid Build Coastguard Worker
413*2d1272b8SAndroid Build Coastguard Worker return false;
414*2d1272b8SAndroid Build Coastguard Worker }
415*2d1272b8SAndroid Build Coastguard Worker
416*2d1272b8SAndroid Build Coastguard Worker static inline void free_static_cairo_paint_funcs ();
417*2d1272b8SAndroid Build Coastguard Worker
418*2d1272b8SAndroid Build Coastguard Worker static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_cairo_paint_funcs_lazy_loader_t>
419*2d1272b8SAndroid Build Coastguard Worker {
createhb_cairo_paint_funcs_lazy_loader_t420*2d1272b8SAndroid Build Coastguard Worker static hb_paint_funcs_t *create ()
421*2d1272b8SAndroid Build Coastguard Worker {
422*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
423*2d1272b8SAndroid Build Coastguard Worker
424*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr);
425*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr);
426*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_color_glyph_func (funcs, hb_cairo_paint_color_glyph, nullptr, nullptr);
427*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_cairo_push_clip_glyph, nullptr, nullptr);
428*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_cairo_push_clip_rectangle, nullptr, nullptr);
429*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_pop_clip_func (funcs, hb_cairo_pop_clip, nullptr, nullptr);
430*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_push_group_func (funcs, hb_cairo_push_group, nullptr, nullptr);
431*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_pop_group_func (funcs, hb_cairo_pop_group, nullptr, nullptr);
432*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_color_func (funcs, hb_cairo_paint_color, nullptr, nullptr);
433*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_image_func (funcs, hb_cairo_paint_image, nullptr, nullptr);
434*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_linear_gradient_func (funcs, hb_cairo_paint_linear_gradient, nullptr, nullptr);
435*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_radial_gradient_func (funcs, hb_cairo_paint_radial_gradient, nullptr, nullptr);
436*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_sweep_gradient_func (funcs, hb_cairo_paint_sweep_gradient, nullptr, nullptr);
437*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_set_custom_palette_color_func (funcs, hb_cairo_paint_custom_palette_color, nullptr, nullptr);
438*2d1272b8SAndroid Build Coastguard Worker
439*2d1272b8SAndroid Build Coastguard Worker hb_paint_funcs_make_immutable (funcs);
440*2d1272b8SAndroid Build Coastguard Worker
441*2d1272b8SAndroid Build Coastguard Worker hb_atexit (free_static_cairo_paint_funcs);
442*2d1272b8SAndroid Build Coastguard Worker
443*2d1272b8SAndroid Build Coastguard Worker return funcs;
444*2d1272b8SAndroid Build Coastguard Worker }
445*2d1272b8SAndroid Build Coastguard Worker } static_cairo_paint_funcs;
446*2d1272b8SAndroid Build Coastguard Worker
447*2d1272b8SAndroid Build Coastguard Worker static inline
free_static_cairo_paint_funcs()448*2d1272b8SAndroid Build Coastguard Worker void free_static_cairo_paint_funcs ()
449*2d1272b8SAndroid Build Coastguard Worker {
450*2d1272b8SAndroid Build Coastguard Worker static_cairo_paint_funcs.free_instance ();
451*2d1272b8SAndroid Build Coastguard Worker }
452*2d1272b8SAndroid Build Coastguard Worker
453*2d1272b8SAndroid Build Coastguard Worker static hb_paint_funcs_t *
hb_cairo_paint_get_funcs()454*2d1272b8SAndroid Build Coastguard Worker hb_cairo_paint_get_funcs ()
455*2d1272b8SAndroid Build Coastguard Worker {
456*2d1272b8SAndroid Build Coastguard Worker return static_cairo_paint_funcs.get_unconst ();
457*2d1272b8SAndroid Build Coastguard Worker }
458*2d1272b8SAndroid Build Coastguard Worker #endif
459*2d1272b8SAndroid Build Coastguard Worker
460*2d1272b8SAndroid Build Coastguard Worker static const cairo_user_data_key_t hb_cairo_face_user_data_key = {0};
461*2d1272b8SAndroid Build Coastguard Worker static const cairo_user_data_key_t hb_cairo_font_user_data_key = {0};
462*2d1272b8SAndroid Build Coastguard Worker static const cairo_user_data_key_t hb_cairo_font_init_func_user_data_key = {0};
463*2d1272b8SAndroid Build Coastguard Worker static const cairo_user_data_key_t hb_cairo_font_init_user_data_user_data_key = {0};
464*2d1272b8SAndroid Build Coastguard Worker static const cairo_user_data_key_t hb_cairo_scale_factor_user_data_key = {0};
465*2d1272b8SAndroid Build Coastguard Worker
hb_cairo_face_destroy(void * p)466*2d1272b8SAndroid Build Coastguard Worker static void hb_cairo_face_destroy (void *p) { hb_face_destroy ((hb_face_t *) p); }
hb_cairo_font_destroy(void * p)467*2d1272b8SAndroid Build Coastguard Worker static void hb_cairo_font_destroy (void *p) { hb_font_destroy ((hb_font_t *) p); }
468*2d1272b8SAndroid Build Coastguard Worker
469*2d1272b8SAndroid Build Coastguard Worker static cairo_status_t
hb_cairo_init_scaled_font(cairo_scaled_font_t * scaled_font,cairo_t * cr HB_UNUSED,cairo_font_extents_t * extents)470*2d1272b8SAndroid Build Coastguard Worker hb_cairo_init_scaled_font (cairo_scaled_font_t *scaled_font,
471*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr HB_UNUSED,
472*2d1272b8SAndroid Build Coastguard Worker cairo_font_extents_t *extents)
473*2d1272b8SAndroid Build Coastguard Worker {
474*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_t *font_face = cairo_scaled_font_get_font_face (scaled_font);
475*2d1272b8SAndroid Build Coastguard Worker
476*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font = (hb_font_t *) cairo_font_face_get_user_data (font_face,
477*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_user_data_key);
478*2d1272b8SAndroid Build Coastguard Worker
479*2d1272b8SAndroid Build Coastguard Worker if (!font)
480*2d1272b8SAndroid Build Coastguard Worker {
481*2d1272b8SAndroid Build Coastguard Worker hb_face_t *face = (hb_face_t *) cairo_font_face_get_user_data (font_face,
482*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_face_user_data_key);
483*2d1272b8SAndroid Build Coastguard Worker font = hb_font_create (face);
484*2d1272b8SAndroid Build Coastguard Worker
485*2d1272b8SAndroid Build Coastguard Worker #if !defined(HB_NO_VAR) && CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,16,0)
486*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_t *font_options = cairo_font_options_create ();
487*2d1272b8SAndroid Build Coastguard Worker
488*2d1272b8SAndroid Build Coastguard Worker // Set variations
489*2d1272b8SAndroid Build Coastguard Worker cairo_scaled_font_get_font_options (scaled_font, font_options);
490*2d1272b8SAndroid Build Coastguard Worker const char *variations = cairo_font_options_get_variations (font_options);
491*2d1272b8SAndroid Build Coastguard Worker hb_vector_t<hb_variation_t> vars;
492*2d1272b8SAndroid Build Coastguard Worker const char *p = variations;
493*2d1272b8SAndroid Build Coastguard Worker while (p && *p)
494*2d1272b8SAndroid Build Coastguard Worker {
495*2d1272b8SAndroid Build Coastguard Worker const char *end = strpbrk ((char *) p, ", ");
496*2d1272b8SAndroid Build Coastguard Worker hb_variation_t var;
497*2d1272b8SAndroid Build Coastguard Worker if (hb_variation_from_string (p, end ? end - p : -1, &var))
498*2d1272b8SAndroid Build Coastguard Worker vars.push (var);
499*2d1272b8SAndroid Build Coastguard Worker p = end ? end + 1 : nullptr;
500*2d1272b8SAndroid Build Coastguard Worker }
501*2d1272b8SAndroid Build Coastguard Worker hb_font_set_variations (font, &vars[0], vars.length);
502*2d1272b8SAndroid Build Coastguard Worker
503*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_destroy (font_options);
504*2d1272b8SAndroid Build Coastguard Worker #endif
505*2d1272b8SAndroid Build Coastguard Worker
506*2d1272b8SAndroid Build Coastguard Worker // Set scale; Note: should NOT set slant, or we'll double-slant.
507*2d1272b8SAndroid Build Coastguard Worker unsigned scale_factor = hb_cairo_font_face_get_scale_factor (font_face);
508*2d1272b8SAndroid Build Coastguard Worker if (scale_factor)
509*2d1272b8SAndroid Build Coastguard Worker {
510*2d1272b8SAndroid Build Coastguard Worker cairo_matrix_t font_matrix;
511*2d1272b8SAndroid Build Coastguard Worker cairo_scaled_font_get_scale_matrix (scaled_font, &font_matrix);
512*2d1272b8SAndroid Build Coastguard Worker hb_font_set_scale (font,
513*2d1272b8SAndroid Build Coastguard Worker round (font_matrix.xx * scale_factor),
514*2d1272b8SAndroid Build Coastguard Worker round (font_matrix.yy * scale_factor));
515*2d1272b8SAndroid Build Coastguard Worker }
516*2d1272b8SAndroid Build Coastguard Worker
517*2d1272b8SAndroid Build Coastguard Worker auto *init_func = (hb_cairo_font_init_func_t)
518*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_get_user_data (font_face,
519*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_init_func_user_data_key);
520*2d1272b8SAndroid Build Coastguard Worker if (init_func)
521*2d1272b8SAndroid Build Coastguard Worker {
522*2d1272b8SAndroid Build Coastguard Worker void *user_data = cairo_font_face_get_user_data (font_face,
523*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_init_user_data_user_data_key);
524*2d1272b8SAndroid Build Coastguard Worker font = init_func (font, scaled_font, user_data);
525*2d1272b8SAndroid Build Coastguard Worker }
526*2d1272b8SAndroid Build Coastguard Worker
527*2d1272b8SAndroid Build Coastguard Worker hb_font_make_immutable (font);
528*2d1272b8SAndroid Build Coastguard Worker }
529*2d1272b8SAndroid Build Coastguard Worker
530*2d1272b8SAndroid Build Coastguard Worker cairo_scaled_font_set_user_data (scaled_font,
531*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_user_data_key,
532*2d1272b8SAndroid Build Coastguard Worker (void *) hb_font_reference (font),
533*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_destroy);
534*2d1272b8SAndroid Build Coastguard Worker
535*2d1272b8SAndroid Build Coastguard Worker hb_position_t x_scale, y_scale;
536*2d1272b8SAndroid Build Coastguard Worker hb_font_get_scale (font, &x_scale, &y_scale);
537*2d1272b8SAndroid Build Coastguard Worker
538*2d1272b8SAndroid Build Coastguard Worker hb_font_extents_t hb_extents;
539*2d1272b8SAndroid Build Coastguard Worker hb_font_get_h_extents (font, &hb_extents);
540*2d1272b8SAndroid Build Coastguard Worker
541*2d1272b8SAndroid Build Coastguard Worker extents->ascent = (double) hb_extents.ascender / y_scale;
542*2d1272b8SAndroid Build Coastguard Worker extents->descent = (double) -hb_extents.descender / y_scale;
543*2d1272b8SAndroid Build Coastguard Worker extents->height = extents->ascent + extents->descent;
544*2d1272b8SAndroid Build Coastguard Worker
545*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
546*2d1272b8SAndroid Build Coastguard Worker hb_map_t *color_cache = hb_map_create ();
547*2d1272b8SAndroid Build Coastguard Worker if (unlikely (CAIRO_STATUS_SUCCESS != cairo_scaled_font_set_user_data (scaled_font,
548*2d1272b8SAndroid Build Coastguard Worker &color_cache_key,
549*2d1272b8SAndroid Build Coastguard Worker color_cache,
550*2d1272b8SAndroid Build Coastguard Worker _hb_cairo_destroy_map)))
551*2d1272b8SAndroid Build Coastguard Worker hb_map_destroy (color_cache);
552*2d1272b8SAndroid Build Coastguard Worker #endif
553*2d1272b8SAndroid Build Coastguard Worker
554*2d1272b8SAndroid Build Coastguard Worker return CAIRO_STATUS_SUCCESS;
555*2d1272b8SAndroid Build Coastguard Worker }
556*2d1272b8SAndroid Build Coastguard Worker
557*2d1272b8SAndroid Build Coastguard Worker static cairo_status_t
hb_cairo_text_to_glyphs(cairo_scaled_font_t * scaled_font,const char * utf8,int utf8_len,cairo_glyph_t ** glyphs,int * num_glyphs,cairo_text_cluster_t ** clusters,int * num_clusters,cairo_text_cluster_flags_t * cluster_flags)558*2d1272b8SAndroid Build Coastguard Worker hb_cairo_text_to_glyphs (cairo_scaled_font_t *scaled_font,
559*2d1272b8SAndroid Build Coastguard Worker const char *utf8,
560*2d1272b8SAndroid Build Coastguard Worker int utf8_len,
561*2d1272b8SAndroid Build Coastguard Worker cairo_glyph_t **glyphs,
562*2d1272b8SAndroid Build Coastguard Worker int *num_glyphs,
563*2d1272b8SAndroid Build Coastguard Worker cairo_text_cluster_t **clusters,
564*2d1272b8SAndroid Build Coastguard Worker int *num_clusters,
565*2d1272b8SAndroid Build Coastguard Worker cairo_text_cluster_flags_t *cluster_flags)
566*2d1272b8SAndroid Build Coastguard Worker {
567*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
568*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_user_data_key);
569*2d1272b8SAndroid Build Coastguard Worker
570*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *buffer = hb_buffer_create ();
571*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf8 (buffer, utf8, utf8_len, 0, utf8_len);
572*2d1272b8SAndroid Build Coastguard Worker hb_buffer_guess_segment_properties (buffer);
573*2d1272b8SAndroid Build Coastguard Worker hb_shape (font, buffer, nullptr, 0);
574*2d1272b8SAndroid Build Coastguard Worker
575*2d1272b8SAndroid Build Coastguard Worker hb_cairo_glyphs_from_buffer (buffer,
576*2d1272b8SAndroid Build Coastguard Worker true,
577*2d1272b8SAndroid Build Coastguard Worker font->x_scale, font->y_scale,
578*2d1272b8SAndroid Build Coastguard Worker 0., 0.,
579*2d1272b8SAndroid Build Coastguard Worker utf8, utf8_len,
580*2d1272b8SAndroid Build Coastguard Worker glyphs, (unsigned *) num_glyphs,
581*2d1272b8SAndroid Build Coastguard Worker clusters, (unsigned *) num_clusters,
582*2d1272b8SAndroid Build Coastguard Worker cluster_flags);
583*2d1272b8SAndroid Build Coastguard Worker
584*2d1272b8SAndroid Build Coastguard Worker hb_buffer_destroy (buffer);
585*2d1272b8SAndroid Build Coastguard Worker
586*2d1272b8SAndroid Build Coastguard Worker return CAIRO_STATUS_SUCCESS;
587*2d1272b8SAndroid Build Coastguard Worker }
588*2d1272b8SAndroid Build Coastguard Worker
589*2d1272b8SAndroid Build Coastguard Worker static cairo_status_t
hb_cairo_render_glyph(cairo_scaled_font_t * scaled_font,unsigned long glyph,cairo_t * cr,cairo_text_extents_t * extents)590*2d1272b8SAndroid Build Coastguard Worker hb_cairo_render_glyph (cairo_scaled_font_t *scaled_font,
591*2d1272b8SAndroid Build Coastguard Worker unsigned long glyph,
592*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr,
593*2d1272b8SAndroid Build Coastguard Worker cairo_text_extents_t *extents)
594*2d1272b8SAndroid Build Coastguard Worker {
595*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
596*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_user_data_key);
597*2d1272b8SAndroid Build Coastguard Worker
598*2d1272b8SAndroid Build Coastguard Worker hb_position_t x_scale, y_scale;
599*2d1272b8SAndroid Build Coastguard Worker hb_font_get_scale (font, &x_scale, &y_scale);
600*2d1272b8SAndroid Build Coastguard Worker cairo_scale (cr, +1./x_scale, -1./y_scale);
601*2d1272b8SAndroid Build Coastguard Worker
602*2d1272b8SAndroid Build Coastguard Worker hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
603*2d1272b8SAndroid Build Coastguard Worker
604*2d1272b8SAndroid Build Coastguard Worker cairo_fill (cr);
605*2d1272b8SAndroid Build Coastguard Worker
606*2d1272b8SAndroid Build Coastguard Worker return CAIRO_STATUS_SUCCESS;
607*2d1272b8SAndroid Build Coastguard Worker }
608*2d1272b8SAndroid Build Coastguard Worker
609*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
610*2d1272b8SAndroid Build Coastguard Worker
611*2d1272b8SAndroid Build Coastguard Worker static cairo_status_t
hb_cairo_render_color_glyph(cairo_scaled_font_t * scaled_font,unsigned long glyph,cairo_t * cr,cairo_text_extents_t * extents)612*2d1272b8SAndroid Build Coastguard Worker hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font,
613*2d1272b8SAndroid Build Coastguard Worker unsigned long glyph,
614*2d1272b8SAndroid Build Coastguard Worker cairo_t *cr,
615*2d1272b8SAndroid Build Coastguard Worker cairo_text_extents_t *extents)
616*2d1272b8SAndroid Build Coastguard Worker {
617*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
618*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_user_data_key);
619*2d1272b8SAndroid Build Coastguard Worker
620*2d1272b8SAndroid Build Coastguard Worker unsigned int palette = 0;
621*2d1272b8SAndroid Build Coastguard Worker #ifdef CAIRO_COLOR_PALETTE_DEFAULT
622*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_t *options = cairo_font_options_create ();
623*2d1272b8SAndroid Build Coastguard Worker cairo_scaled_font_get_font_options (scaled_font, options);
624*2d1272b8SAndroid Build Coastguard Worker palette = cairo_font_options_get_color_palette (options);
625*2d1272b8SAndroid Build Coastguard Worker cairo_font_options_destroy (options);
626*2d1272b8SAndroid Build Coastguard Worker #endif
627*2d1272b8SAndroid Build Coastguard Worker
628*2d1272b8SAndroid Build Coastguard Worker hb_color_t color = HB_COLOR (0, 0, 0, 255);
629*2d1272b8SAndroid Build Coastguard Worker hb_position_t x_scale, y_scale;
630*2d1272b8SAndroid Build Coastguard Worker hb_font_get_scale (font, &x_scale, &y_scale);
631*2d1272b8SAndroid Build Coastguard Worker cairo_scale (cr, +1./x_scale, -1./y_scale);
632*2d1272b8SAndroid Build Coastguard Worker
633*2d1272b8SAndroid Build Coastguard Worker hb_cairo_context_t c;
634*2d1272b8SAndroid Build Coastguard Worker c.scaled_font = scaled_font;
635*2d1272b8SAndroid Build Coastguard Worker c.cr = cr;
636*2d1272b8SAndroid Build Coastguard Worker c.color_cache = (hb_map_t *) cairo_scaled_font_get_user_data (scaled_font, &color_cache_key);
637*2d1272b8SAndroid Build Coastguard Worker
638*2d1272b8SAndroid Build Coastguard Worker hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color);
639*2d1272b8SAndroid Build Coastguard Worker
640*2d1272b8SAndroid Build Coastguard Worker
641*2d1272b8SAndroid Build Coastguard Worker return CAIRO_STATUS_SUCCESS;
642*2d1272b8SAndroid Build Coastguard Worker }
643*2d1272b8SAndroid Build Coastguard Worker
644*2d1272b8SAndroid Build Coastguard Worker #endif
645*2d1272b8SAndroid Build Coastguard Worker
646*2d1272b8SAndroid Build Coastguard Worker static cairo_font_face_t *
user_font_face_create(hb_face_t * face)647*2d1272b8SAndroid Build Coastguard Worker user_font_face_create (hb_face_t *face)
648*2d1272b8SAndroid Build Coastguard Worker {
649*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_t *cairo_face;
650*2d1272b8SAndroid Build Coastguard Worker
651*2d1272b8SAndroid Build Coastguard Worker cairo_face = cairo_user_font_face_create ();
652*2d1272b8SAndroid Build Coastguard Worker cairo_user_font_face_set_init_func (cairo_face, hb_cairo_init_scaled_font);
653*2d1272b8SAndroid Build Coastguard Worker cairo_user_font_face_set_text_to_glyphs_func (cairo_face, hb_cairo_text_to_glyphs);
654*2d1272b8SAndroid Build Coastguard Worker cairo_user_font_face_set_render_glyph_func (cairo_face, hb_cairo_render_glyph);
655*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
656*2d1272b8SAndroid Build Coastguard Worker if (hb_ot_color_has_png (face) || hb_ot_color_has_layers (face) || hb_ot_color_has_paint (face))
657*2d1272b8SAndroid Build Coastguard Worker cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph);
658*2d1272b8SAndroid Build Coastguard Worker #endif
659*2d1272b8SAndroid Build Coastguard Worker
660*2d1272b8SAndroid Build Coastguard Worker if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face,
661*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_face_user_data_key,
662*2d1272b8SAndroid Build Coastguard Worker (void *) hb_face_reference (face),
663*2d1272b8SAndroid Build Coastguard Worker hb_cairo_face_destroy)))
664*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
665*2d1272b8SAndroid Build Coastguard Worker
666*2d1272b8SAndroid Build Coastguard Worker return cairo_face;
667*2d1272b8SAndroid Build Coastguard Worker }
668*2d1272b8SAndroid Build Coastguard Worker
669*2d1272b8SAndroid Build Coastguard Worker /**
670*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_create_for_font:
671*2d1272b8SAndroid Build Coastguard Worker * @font: a #hb_font_t
672*2d1272b8SAndroid Build Coastguard Worker *
673*2d1272b8SAndroid Build Coastguard Worker * Creates a #cairo_font_face_t for rendering text according
674*2d1272b8SAndroid Build Coastguard Worker * to @font.
675*2d1272b8SAndroid Build Coastguard Worker *
676*2d1272b8SAndroid Build Coastguard Worker * Note that the scale of @font does not affect the rendering,
677*2d1272b8SAndroid Build Coastguard Worker * but the variations and slant that are set on @font do.
678*2d1272b8SAndroid Build Coastguard Worker *
679*2d1272b8SAndroid Build Coastguard Worker * Returns: (transfer full): a newly created #cairo_font_face_t
680*2d1272b8SAndroid Build Coastguard Worker *
681*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
682*2d1272b8SAndroid Build Coastguard Worker */
683*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_t *
hb_cairo_font_face_create_for_font(hb_font_t * font)684*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_face_create_for_font (hb_font_t *font)
685*2d1272b8SAndroid Build Coastguard Worker {
686*2d1272b8SAndroid Build Coastguard Worker hb_font_make_immutable (font);
687*2d1272b8SAndroid Build Coastguard Worker
688*2d1272b8SAndroid Build Coastguard Worker auto *cairo_face = user_font_face_create (font->face);
689*2d1272b8SAndroid Build Coastguard Worker
690*2d1272b8SAndroid Build Coastguard Worker if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face,
691*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_user_data_key,
692*2d1272b8SAndroid Build Coastguard Worker (void *) hb_font_reference (font),
693*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_destroy)))
694*2d1272b8SAndroid Build Coastguard Worker hb_font_destroy (font);
695*2d1272b8SAndroid Build Coastguard Worker
696*2d1272b8SAndroid Build Coastguard Worker return cairo_face;
697*2d1272b8SAndroid Build Coastguard Worker }
698*2d1272b8SAndroid Build Coastguard Worker
699*2d1272b8SAndroid Build Coastguard Worker /**
700*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_get_font:
701*2d1272b8SAndroid Build Coastguard Worker * @font_face: a #cairo_font_face_t
702*2d1272b8SAndroid Build Coastguard Worker *
703*2d1272b8SAndroid Build Coastguard Worker * Gets the #hb_font_t that @font_face was created from.
704*2d1272b8SAndroid Build Coastguard Worker *
705*2d1272b8SAndroid Build Coastguard Worker * Returns: (nullable) (transfer none): the #hb_font_t that @font_face was created from
706*2d1272b8SAndroid Build Coastguard Worker *
707*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
708*2d1272b8SAndroid Build Coastguard Worker */
709*2d1272b8SAndroid Build Coastguard Worker hb_font_t *
hb_cairo_font_face_get_font(cairo_font_face_t * font_face)710*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
711*2d1272b8SAndroid Build Coastguard Worker {
712*2d1272b8SAndroid Build Coastguard Worker return (hb_font_t *) cairo_font_face_get_user_data (font_face,
713*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_user_data_key);
714*2d1272b8SAndroid Build Coastguard Worker }
715*2d1272b8SAndroid Build Coastguard Worker
716*2d1272b8SAndroid Build Coastguard Worker /**
717*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_create_for_face:
718*2d1272b8SAndroid Build Coastguard Worker * @face: a #hb_face_t
719*2d1272b8SAndroid Build Coastguard Worker *
720*2d1272b8SAndroid Build Coastguard Worker * Creates a #cairo_font_face_t for rendering text according
721*2d1272b8SAndroid Build Coastguard Worker * to @face.
722*2d1272b8SAndroid Build Coastguard Worker *
723*2d1272b8SAndroid Build Coastguard Worker * Returns: (transfer full): a newly created #cairo_font_face_t
724*2d1272b8SAndroid Build Coastguard Worker *
725*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
726*2d1272b8SAndroid Build Coastguard Worker */
727*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_t *
hb_cairo_font_face_create_for_face(hb_face_t * face)728*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_face_create_for_face (hb_face_t *face)
729*2d1272b8SAndroid Build Coastguard Worker {
730*2d1272b8SAndroid Build Coastguard Worker hb_face_make_immutable (face);
731*2d1272b8SAndroid Build Coastguard Worker
732*2d1272b8SAndroid Build Coastguard Worker return user_font_face_create (face);
733*2d1272b8SAndroid Build Coastguard Worker }
734*2d1272b8SAndroid Build Coastguard Worker
735*2d1272b8SAndroid Build Coastguard Worker /**
736*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_get_face:
737*2d1272b8SAndroid Build Coastguard Worker * @font_face: a #cairo_font_face_t
738*2d1272b8SAndroid Build Coastguard Worker *
739*2d1272b8SAndroid Build Coastguard Worker * Gets the #hb_face_t associated with @font_face.
740*2d1272b8SAndroid Build Coastguard Worker *
741*2d1272b8SAndroid Build Coastguard Worker * Returns: (nullable) (transfer none): the #hb_face_t associated with @font_face
742*2d1272b8SAndroid Build Coastguard Worker *
743*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
744*2d1272b8SAndroid Build Coastguard Worker */
745*2d1272b8SAndroid Build Coastguard Worker hb_face_t *
hb_cairo_font_face_get_face(cairo_font_face_t * font_face)746*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_face_get_face (cairo_font_face_t *font_face)
747*2d1272b8SAndroid Build Coastguard Worker {
748*2d1272b8SAndroid Build Coastguard Worker return (hb_face_t *) cairo_font_face_get_user_data (font_face,
749*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_face_user_data_key);
750*2d1272b8SAndroid Build Coastguard Worker }
751*2d1272b8SAndroid Build Coastguard Worker
752*2d1272b8SAndroid Build Coastguard Worker /**
753*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_set_font_init_func:
754*2d1272b8SAndroid Build Coastguard Worker * @font_face: a #cairo_font_face_t
755*2d1272b8SAndroid Build Coastguard Worker * @func: The virtual method to use
756*2d1272b8SAndroid Build Coastguard Worker * @user_data: user data accompanying the method
757*2d1272b8SAndroid Build Coastguard Worker * @destroy: function to call when @user_data is not needed anymore
758*2d1272b8SAndroid Build Coastguard Worker *
759*2d1272b8SAndroid Build Coastguard Worker * Set the virtual method to be called when a cairo
760*2d1272b8SAndroid Build Coastguard Worker * face created using hb_cairo_font_face_create_for_face()
761*2d1272b8SAndroid Build Coastguard Worker * creates an #hb_font_t for a #cairo_scaled_font_t.
762*2d1272b8SAndroid Build Coastguard Worker *
763*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
764*2d1272b8SAndroid Build Coastguard Worker */
765*2d1272b8SAndroid Build Coastguard Worker void
hb_cairo_font_face_set_font_init_func(cairo_font_face_t * font_face,hb_cairo_font_init_func_t func,void * user_data,hb_destroy_func_t destroy)766*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
767*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_init_func_t func,
768*2d1272b8SAndroid Build Coastguard Worker void *user_data,
769*2d1272b8SAndroid Build Coastguard Worker hb_destroy_func_t destroy)
770*2d1272b8SAndroid Build Coastguard Worker {
771*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_set_user_data (font_face,
772*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_init_func_user_data_key,
773*2d1272b8SAndroid Build Coastguard Worker (void *) func,
774*2d1272b8SAndroid Build Coastguard Worker nullptr);
775*2d1272b8SAndroid Build Coastguard Worker if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (font_face,
776*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_init_user_data_user_data_key,
777*2d1272b8SAndroid Build Coastguard Worker (void *) user_data,
778*2d1272b8SAndroid Build Coastguard Worker destroy)) && destroy)
779*2d1272b8SAndroid Build Coastguard Worker {
780*2d1272b8SAndroid Build Coastguard Worker destroy (user_data);
781*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_set_user_data (font_face,
782*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_font_init_func_user_data_key,
783*2d1272b8SAndroid Build Coastguard Worker nullptr,
784*2d1272b8SAndroid Build Coastguard Worker nullptr);
785*2d1272b8SAndroid Build Coastguard Worker }
786*2d1272b8SAndroid Build Coastguard Worker }
787*2d1272b8SAndroid Build Coastguard Worker
788*2d1272b8SAndroid Build Coastguard Worker /**
789*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_scaled_font_get_font:
790*2d1272b8SAndroid Build Coastguard Worker * @scaled_font: a #cairo_scaled_font_t
791*2d1272b8SAndroid Build Coastguard Worker *
792*2d1272b8SAndroid Build Coastguard Worker * Gets the #hb_font_t associated with @scaled_font.
793*2d1272b8SAndroid Build Coastguard Worker *
794*2d1272b8SAndroid Build Coastguard Worker * Returns: (nullable) (transfer none): the #hb_font_t associated with @scaled_font
795*2d1272b8SAndroid Build Coastguard Worker *
796*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
797*2d1272b8SAndroid Build Coastguard Worker */
798*2d1272b8SAndroid Build Coastguard Worker hb_font_t *
hb_cairo_scaled_font_get_font(cairo_scaled_font_t * scaled_font)799*2d1272b8SAndroid Build Coastguard Worker hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font)
800*2d1272b8SAndroid Build Coastguard Worker {
801*2d1272b8SAndroid Build Coastguard Worker return (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font, &hb_cairo_font_user_data_key);
802*2d1272b8SAndroid Build Coastguard Worker }
803*2d1272b8SAndroid Build Coastguard Worker
804*2d1272b8SAndroid Build Coastguard Worker
805*2d1272b8SAndroid Build Coastguard Worker /**
806*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_set_scale_factor:
807*2d1272b8SAndroid Build Coastguard Worker * @scale_factor: The scale factor to use. See below
808*2d1272b8SAndroid Build Coastguard Worker * @font_face: a #cairo_font_face_t
809*2d1272b8SAndroid Build Coastguard Worker *
810*2d1272b8SAndroid Build Coastguard Worker * Sets the scale factor of the @font_face. Default scale
811*2d1272b8SAndroid Build Coastguard Worker * factor is zero.
812*2d1272b8SAndroid Build Coastguard Worker *
813*2d1272b8SAndroid Build Coastguard Worker * When a #cairo_font_face_t is created from a #hb_face_t using
814*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_create_for_face(), such face will create
815*2d1272b8SAndroid Build Coastguard Worker * #hb_font_t objects during scaled-font creation. The scale
816*2d1272b8SAndroid Build Coastguard Worker * factor defines how the scale set on such #hb_font_t objects
817*2d1272b8SAndroid Build Coastguard Worker * relates to the font-matrix (as such font size) of the cairo
818*2d1272b8SAndroid Build Coastguard Worker * scaled-font.
819*2d1272b8SAndroid Build Coastguard Worker *
820*2d1272b8SAndroid Build Coastguard Worker * If the scale-factor is zero (default), then the scale of the
821*2d1272b8SAndroid Build Coastguard Worker * #hb_font_t object will be left at default, which is the UPEM
822*2d1272b8SAndroid Build Coastguard Worker * value of the respective #hb_face_t.
823*2d1272b8SAndroid Build Coastguard Worker *
824*2d1272b8SAndroid Build Coastguard Worker * If the scale-factor is set to non-zero, then the X and Y scale
825*2d1272b8SAndroid Build Coastguard Worker * of the #hb_font_t object will be respectively set to the
826*2d1272b8SAndroid Build Coastguard Worker * @scale_factor times the xx and yy elements of the scale-matrix
827*2d1272b8SAndroid Build Coastguard Worker * of the cairo scaled-font being created.
828*2d1272b8SAndroid Build Coastguard Worker *
829*2d1272b8SAndroid Build Coastguard Worker * When using the hb_cairo_glyphs_from_buffer() API to convert the
830*2d1272b8SAndroid Build Coastguard Worker * HarfBuzz glyph buffer that resulted from shaping with such a #hb_font_t,
831*2d1272b8SAndroid Build Coastguard Worker * if the scale-factor was non-zero, you can pass it directly to
832*2d1272b8SAndroid Build Coastguard Worker * that API as both X and Y scale factors.
833*2d1272b8SAndroid Build Coastguard Worker *
834*2d1272b8SAndroid Build Coastguard Worker * If the scale-factor was zero however, or the cairo face was
835*2d1272b8SAndroid Build Coastguard Worker * created using the alternative constructor
836*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_create_for_font(), you need to calculate the
837*2d1272b8SAndroid Build Coastguard Worker * correct X/Y scale-factors to pass to hb_cairo_glyphs_from_buffer()
838*2d1272b8SAndroid Build Coastguard Worker * by dividing the #hb_font_t X/Y scale-factors by the
839*2d1272b8SAndroid Build Coastguard Worker * cairo scaled-font's scale-matrix XX/YY components respectively
840*2d1272b8SAndroid Build Coastguard Worker * and use those values. Or if you know that relationship offhand
841*2d1272b8SAndroid Build Coastguard Worker * (because you set the scale of the #hb_font_t yourself), use
842*2d1272b8SAndroid Build Coastguard Worker * the conversion rate involved.
843*2d1272b8SAndroid Build Coastguard Worker *
844*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
845*2d1272b8SAndroid Build Coastguard Worker */
846*2d1272b8SAndroid Build Coastguard Worker void
hb_cairo_font_face_set_scale_factor(cairo_font_face_t * font_face,unsigned int scale_factor)847*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
848*2d1272b8SAndroid Build Coastguard Worker unsigned int scale_factor)
849*2d1272b8SAndroid Build Coastguard Worker {
850*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_set_user_data (font_face,
851*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_scale_factor_user_data_key,
852*2d1272b8SAndroid Build Coastguard Worker (void *) (uintptr_t) scale_factor,
853*2d1272b8SAndroid Build Coastguard Worker nullptr);
854*2d1272b8SAndroid Build Coastguard Worker }
855*2d1272b8SAndroid Build Coastguard Worker
856*2d1272b8SAndroid Build Coastguard Worker /**
857*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_font_face_get_scale_factor:
858*2d1272b8SAndroid Build Coastguard Worker * @font_face: a #cairo_font_face_t
859*2d1272b8SAndroid Build Coastguard Worker *
860*2d1272b8SAndroid Build Coastguard Worker * Gets the scale factor set on the @font_face. Defaults to zero.
861*2d1272b8SAndroid Build Coastguard Worker * See hb_cairo_font_face_set_scale_factor() for details.
862*2d1272b8SAndroid Build Coastguard Worker *
863*2d1272b8SAndroid Build Coastguard Worker * Returns: the scale factor of @font_face
864*2d1272b8SAndroid Build Coastguard Worker *
865*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
866*2d1272b8SAndroid Build Coastguard Worker */
867*2d1272b8SAndroid Build Coastguard Worker unsigned int
hb_cairo_font_face_get_scale_factor(cairo_font_face_t * font_face)868*2d1272b8SAndroid Build Coastguard Worker hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
869*2d1272b8SAndroid Build Coastguard Worker {
870*2d1272b8SAndroid Build Coastguard Worker return (unsigned int) (uintptr_t)
871*2d1272b8SAndroid Build Coastguard Worker cairo_font_face_get_user_data (font_face,
872*2d1272b8SAndroid Build Coastguard Worker &hb_cairo_scale_factor_user_data_key);
873*2d1272b8SAndroid Build Coastguard Worker }
874*2d1272b8SAndroid Build Coastguard Worker
875*2d1272b8SAndroid Build Coastguard Worker
876*2d1272b8SAndroid Build Coastguard Worker /**
877*2d1272b8SAndroid Build Coastguard Worker * hb_cairo_glyphs_from_buffer:
878*2d1272b8SAndroid Build Coastguard Worker * @buffer: a #hb_buffer_t containing glyphs
879*2d1272b8SAndroid Build Coastguard Worker * @utf8_clusters: `true` if @buffer clusters are in bytes, instead of characters
880*2d1272b8SAndroid Build Coastguard Worker * @x_scale_factor: scale factor to divide #hb_position_t Y values by
881*2d1272b8SAndroid Build Coastguard Worker * @y_scale_factor: scale factor to divide #hb_position_t X values by
882*2d1272b8SAndroid Build Coastguard Worker * @x: X position to place first glyph
883*2d1272b8SAndroid Build Coastguard Worker * @y: Y position to place first glyph
884*2d1272b8SAndroid Build Coastguard Worker * @utf8: (nullable): the text that was shaped in @buffer
885*2d1272b8SAndroid Build Coastguard Worker * @utf8_len: the length of @utf8 in bytes
886*2d1272b8SAndroid Build Coastguard Worker * @glyphs: (out): return location for an array of #cairo_glyph_t
887*2d1272b8SAndroid Build Coastguard Worker * @num_glyphs: (inout): return location for the length of @glyphs
888*2d1272b8SAndroid Build Coastguard Worker * @clusters: (out) (nullable): return location for an array of cluster positions
889*2d1272b8SAndroid Build Coastguard Worker * @num_clusters: (inout) (nullable): return location for the length of @clusters
890*2d1272b8SAndroid Build Coastguard Worker * @cluster_flags: (out) (nullable): return location for cluster flags
891*2d1272b8SAndroid Build Coastguard Worker *
892*2d1272b8SAndroid Build Coastguard Worker * Extracts information from @buffer in a form that can be
893*2d1272b8SAndroid Build Coastguard Worker * passed to cairo_show_text_glyphs() or cairo_show_glyphs().
894*2d1272b8SAndroid Build Coastguard Worker * This API is modeled after cairo_scaled_font_text_to_glyphs() and
895*2d1272b8SAndroid Build Coastguard Worker * cairo_user_scaled_font_text_to_glyphs_func_t.
896*2d1272b8SAndroid Build Coastguard Worker *
897*2d1272b8SAndroid Build Coastguard Worker * The @num_glyphs argument should be preset to the number of glyph entries available
898*2d1272b8SAndroid Build Coastguard Worker * in the @glyphs buffer. If the @glyphs buffer is `NULL`, the value of
899*2d1272b8SAndroid Build Coastguard Worker * @num_glyphs must be zero. If the provided glyph array is too short for
900*2d1272b8SAndroid Build Coastguard Worker * the conversion (or for convenience), a new glyph array may be allocated
901*2d1272b8SAndroid Build Coastguard Worker * using cairo_glyph_allocate() and placed in @glyphs. Upon return,
902*2d1272b8SAndroid Build Coastguard Worker * @num_glyphs should contain the number of generated glyphs. If the value
903*2d1272b8SAndroid Build Coastguard Worker * @glyphs points at has changed after the call, the caller will free the
904*2d1272b8SAndroid Build Coastguard Worker * allocated glyph array using cairo_glyph_free(). The caller will also free
905*2d1272b8SAndroid Build Coastguard Worker * the original value of @glyphs, so this function shouldn't do so.
906*2d1272b8SAndroid Build Coastguard Worker *
907*2d1272b8SAndroid Build Coastguard Worker * If @clusters is not `NULL`, then @num_clusters and @cluster_flags
908*2d1272b8SAndroid Build Coastguard Worker * should not be either, and @utf8 must be provided, and cluster
909*2d1272b8SAndroid Build Coastguard Worker * mapping will be computed. The semantics of how
910*2d1272b8SAndroid Build Coastguard Worker * cluster array allocation works is similar to the glyph array. That is,
911*2d1272b8SAndroid Build Coastguard Worker * if @clusters initially points to a non-`NULL` value, that array may be used
912*2d1272b8SAndroid Build Coastguard Worker * as a cluster buffer, and @num_clusters points to the number of cluster
913*2d1272b8SAndroid Build Coastguard Worker * entries available there. If the provided cluster array is too short for
914*2d1272b8SAndroid Build Coastguard Worker * the conversion (or for convenience), a new cluster array may be allocated
915*2d1272b8SAndroid Build Coastguard Worker * using cairo_text_cluster_allocate() and placed in @clusters. In this case,
916*2d1272b8SAndroid Build Coastguard Worker * the original value of @clusters will still be freed by the caller. Upon
917*2d1272b8SAndroid Build Coastguard Worker * return, @num_clusters will contain the number of generated clusters.
918*2d1272b8SAndroid Build Coastguard Worker * If the value @clusters points at has changed after the call, the caller
919*2d1272b8SAndroid Build Coastguard Worker * will free the allocated cluster array using cairo_text_cluster_free().
920*2d1272b8SAndroid Build Coastguard Worker *
921*2d1272b8SAndroid Build Coastguard Worker * See hb_cairo_font_face_set_scale_factor() for the details of
922*2d1272b8SAndroid Build Coastguard Worker * the @scale_factor argument.
923*2d1272b8SAndroid Build Coastguard Worker *
924*2d1272b8SAndroid Build Coastguard Worker * The returned @glyphs vector actually has `@num_glyphs + 1` entries in
925*2d1272b8SAndroid Build Coastguard Worker * it and the x,y values of the extra entry at the end add up the advance
926*2d1272b8SAndroid Build Coastguard Worker * x,y of all the glyphs in the @buffer.
927*2d1272b8SAndroid Build Coastguard Worker *
928*2d1272b8SAndroid Build Coastguard Worker * Since: 7.0.0
929*2d1272b8SAndroid Build Coastguard Worker */
930*2d1272b8SAndroid Build Coastguard Worker void
hb_cairo_glyphs_from_buffer(hb_buffer_t * buffer,hb_bool_t utf8_clusters,double x_scale_factor,double y_scale_factor,double x,double y,const char * utf8,int utf8_len,cairo_glyph_t ** glyphs,unsigned int * num_glyphs,cairo_text_cluster_t ** clusters,unsigned int * num_clusters,cairo_text_cluster_flags_t * cluster_flags)931*2d1272b8SAndroid Build Coastguard Worker hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
932*2d1272b8SAndroid Build Coastguard Worker hb_bool_t utf8_clusters,
933*2d1272b8SAndroid Build Coastguard Worker double x_scale_factor,
934*2d1272b8SAndroid Build Coastguard Worker double y_scale_factor,
935*2d1272b8SAndroid Build Coastguard Worker double x,
936*2d1272b8SAndroid Build Coastguard Worker double y,
937*2d1272b8SAndroid Build Coastguard Worker const char *utf8,
938*2d1272b8SAndroid Build Coastguard Worker int utf8_len,
939*2d1272b8SAndroid Build Coastguard Worker cairo_glyph_t **glyphs,
940*2d1272b8SAndroid Build Coastguard Worker unsigned int *num_glyphs,
941*2d1272b8SAndroid Build Coastguard Worker cairo_text_cluster_t **clusters,
942*2d1272b8SAndroid Build Coastguard Worker unsigned int *num_clusters,
943*2d1272b8SAndroid Build Coastguard Worker cairo_text_cluster_flags_t *cluster_flags)
944*2d1272b8SAndroid Build Coastguard Worker {
945*2d1272b8SAndroid Build Coastguard Worker if (utf8 && utf8_len < 0)
946*2d1272b8SAndroid Build Coastguard Worker utf8_len = strlen (utf8);
947*2d1272b8SAndroid Build Coastguard Worker
948*2d1272b8SAndroid Build Coastguard Worker unsigned orig_num_glyphs = *num_glyphs;
949*2d1272b8SAndroid Build Coastguard Worker *num_glyphs = hb_buffer_get_length (buffer);
950*2d1272b8SAndroid Build Coastguard Worker hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, nullptr);
951*2d1272b8SAndroid Build Coastguard Worker hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, nullptr);
952*2d1272b8SAndroid Build Coastguard Worker if (orig_num_glyphs < *num_glyphs + 1)
953*2d1272b8SAndroid Build Coastguard Worker *glyphs = cairo_glyph_allocate (*num_glyphs + 1);
954*2d1272b8SAndroid Build Coastguard Worker
955*2d1272b8SAndroid Build Coastguard Worker if (clusters && utf8)
956*2d1272b8SAndroid Build Coastguard Worker {
957*2d1272b8SAndroid Build Coastguard Worker unsigned orig_num_clusters = *num_clusters;
958*2d1272b8SAndroid Build Coastguard Worker *num_clusters = *num_glyphs ? 1 : 0;
959*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 1; i < *num_glyphs; i++)
960*2d1272b8SAndroid Build Coastguard Worker if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
961*2d1272b8SAndroid Build Coastguard Worker (*num_clusters)++;
962*2d1272b8SAndroid Build Coastguard Worker if (orig_num_clusters < *num_clusters)
963*2d1272b8SAndroid Build Coastguard Worker *clusters = cairo_text_cluster_allocate (*num_clusters);
964*2d1272b8SAndroid Build Coastguard Worker }
965*2d1272b8SAndroid Build Coastguard Worker
966*2d1272b8SAndroid Build Coastguard Worker double x_scale = x_scale_factor ? 1. / x_scale_factor : 0.;
967*2d1272b8SAndroid Build Coastguard Worker double y_scale = y_scale_factor ? 1. / y_scale_factor : 0.;
968*2d1272b8SAndroid Build Coastguard Worker hb_position_t hx = 0, hy = 0;
969*2d1272b8SAndroid Build Coastguard Worker int i;
970*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < (int) *num_glyphs; i++)
971*2d1272b8SAndroid Build Coastguard Worker {
972*2d1272b8SAndroid Build Coastguard Worker (*glyphs)[i].index = hb_glyph[i].codepoint;
973*2d1272b8SAndroid Build Coastguard Worker (*glyphs)[i].x = x + (+hb_position->x_offset + hx) * x_scale;
974*2d1272b8SAndroid Build Coastguard Worker (*glyphs)[i].y = y + (-hb_position->y_offset + hy) * y_scale;
975*2d1272b8SAndroid Build Coastguard Worker hx += hb_position->x_advance;
976*2d1272b8SAndroid Build Coastguard Worker hy += -hb_position->y_advance;
977*2d1272b8SAndroid Build Coastguard Worker
978*2d1272b8SAndroid Build Coastguard Worker hb_position++;
979*2d1272b8SAndroid Build Coastguard Worker }
980*2d1272b8SAndroid Build Coastguard Worker (*glyphs)[i].index = -1;
981*2d1272b8SAndroid Build Coastguard Worker (*glyphs)[i].x = round (hx * x_scale);
982*2d1272b8SAndroid Build Coastguard Worker (*glyphs)[i].y = round (hy * y_scale);
983*2d1272b8SAndroid Build Coastguard Worker
984*2d1272b8SAndroid Build Coastguard Worker if (clusters && *num_clusters && utf8)
985*2d1272b8SAndroid Build Coastguard Worker {
986*2d1272b8SAndroid Build Coastguard Worker hb_memset ((void *) *clusters, 0, *num_clusters * sizeof ((*clusters)[0]));
987*2d1272b8SAndroid Build Coastguard Worker hb_bool_t backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer));
988*2d1272b8SAndroid Build Coastguard Worker *cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0;
989*2d1272b8SAndroid Build Coastguard Worker unsigned int cluster = 0;
990*2d1272b8SAndroid Build Coastguard Worker const char *start = utf8, *end;
991*2d1272b8SAndroid Build Coastguard Worker (*clusters)[cluster].num_glyphs++;
992*2d1272b8SAndroid Build Coastguard Worker if (backward)
993*2d1272b8SAndroid Build Coastguard Worker {
994*2d1272b8SAndroid Build Coastguard Worker for (i = *num_glyphs - 2; i >= 0; i--)
995*2d1272b8SAndroid Build Coastguard Worker {
996*2d1272b8SAndroid Build Coastguard Worker if (hb_glyph[i].cluster != hb_glyph[i+1].cluster)
997*2d1272b8SAndroid Build Coastguard Worker {
998*2d1272b8SAndroid Build Coastguard Worker assert (hb_glyph[i].cluster > hb_glyph[i+1].cluster);
999*2d1272b8SAndroid Build Coastguard Worker if (utf8_clusters)
1000*2d1272b8SAndroid Build Coastguard Worker end = start + hb_glyph[i].cluster - hb_glyph[i+1].cluster;
1001*2d1272b8SAndroid Build Coastguard Worker else
1002*2d1272b8SAndroid Build Coastguard Worker end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
1003*2d1272b8SAndroid Build Coastguard Worker (signed) (hb_glyph[i].cluster - hb_glyph[i+1].cluster));
1004*2d1272b8SAndroid Build Coastguard Worker (*clusters)[cluster].num_bytes = end - start;
1005*2d1272b8SAndroid Build Coastguard Worker start = end;
1006*2d1272b8SAndroid Build Coastguard Worker cluster++;
1007*2d1272b8SAndroid Build Coastguard Worker }
1008*2d1272b8SAndroid Build Coastguard Worker (*clusters)[cluster].num_glyphs++;
1009*2d1272b8SAndroid Build Coastguard Worker }
1010*2d1272b8SAndroid Build Coastguard Worker (*clusters)[cluster].num_bytes = utf8 + utf8_len - start;
1011*2d1272b8SAndroid Build Coastguard Worker }
1012*2d1272b8SAndroid Build Coastguard Worker else
1013*2d1272b8SAndroid Build Coastguard Worker {
1014*2d1272b8SAndroid Build Coastguard Worker for (i = 1; i < (int) *num_glyphs; i++)
1015*2d1272b8SAndroid Build Coastguard Worker {
1016*2d1272b8SAndroid Build Coastguard Worker if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
1017*2d1272b8SAndroid Build Coastguard Worker {
1018*2d1272b8SAndroid Build Coastguard Worker assert (hb_glyph[i].cluster > hb_glyph[i-1].cluster);
1019*2d1272b8SAndroid Build Coastguard Worker if (utf8_clusters)
1020*2d1272b8SAndroid Build Coastguard Worker end = start + hb_glyph[i].cluster - hb_glyph[i-1].cluster;
1021*2d1272b8SAndroid Build Coastguard Worker else
1022*2d1272b8SAndroid Build Coastguard Worker end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
1023*2d1272b8SAndroid Build Coastguard Worker (signed) (hb_glyph[i].cluster - hb_glyph[i-1].cluster));
1024*2d1272b8SAndroid Build Coastguard Worker (*clusters)[cluster].num_bytes = end - start;
1025*2d1272b8SAndroid Build Coastguard Worker start = end;
1026*2d1272b8SAndroid Build Coastguard Worker cluster++;
1027*2d1272b8SAndroid Build Coastguard Worker }
1028*2d1272b8SAndroid Build Coastguard Worker (*clusters)[cluster].num_glyphs++;
1029*2d1272b8SAndroid Build Coastguard Worker }
1030*2d1272b8SAndroid Build Coastguard Worker (*clusters)[cluster].num_bytes = utf8 + utf8_len - start;
1031*2d1272b8SAndroid Build Coastguard Worker }
1032*2d1272b8SAndroid Build Coastguard Worker }
1033*2d1272b8SAndroid Build Coastguard Worker else if (num_clusters)
1034*2d1272b8SAndroid Build Coastguard Worker *num_clusters = 0;
1035*2d1272b8SAndroid Build Coastguard Worker }
1036*2d1272b8SAndroid Build Coastguard Worker
1037*2d1272b8SAndroid Build Coastguard Worker #endif
1038