1/*
2 * Copyright © 2019-2020 Ebrahim Byagowi
3 *
4 * This is part of HarfBuzz, a text shaping library.
5 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 */
24
25#include "hb.hh"
26
27#ifndef HB_NO_DRAW
28#ifdef HB_EXPERIMENTAL_API
29
30#include "hb-draw.hh"
31#include "hb-ot.h"
32#include "hb-ot-glyf-table.hh"
33#include "hb-ot-cff1-table.hh"
34#include "hb-ot-cff2-table.hh"
35
36/**
37 * hb_draw_funcs_set_move_to_func:
38 * @funcs: draw functions object
39 * @move_to: move-to callback
40 *
41 * Sets move-to callback to the draw functions object.
42 *
43 * Since: EXPERIMENTAL
44 **/
45void
46hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs,
47 hb_draw_move_to_func_t move_to)
48{
49 if (unlikely (hb_object_is_immutable (funcs))) return;
50 funcs->move_to = move_to;
51}
52
53/**
54 * hb_draw_funcs_set_line_to_func:
55 * @funcs: draw functions object
56 * @line_to: line-to callback
57 *
58 * Sets line-to callback to the draw functions object.
59 *
60 * Since: EXPERIMENTAL
61 **/
62void
63hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs,
64 hb_draw_line_to_func_t line_to)
65{
66 if (unlikely (hb_object_is_immutable (funcs))) return;
67 funcs->line_to = line_to;
68}
69
70/**
71 * hb_draw_funcs_set_quadratic_to_func:
72 * @funcs: draw functions object
73 * @move_to: quadratic-to callback
74 *
75 * Sets quadratic-to callback to the draw functions object.
76 *
77 * Since: EXPERIMENTAL
78 **/
79void
80hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs,
81 hb_draw_quadratic_to_func_t quadratic_to)
82{
83 if (unlikely (hb_object_is_immutable (funcs))) return;
84 funcs->quadratic_to = quadratic_to;
85 funcs->is_quadratic_to_set = true;
86}
87
88/**
89 * hb_draw_funcs_set_cubic_to_func:
90 * @funcs: draw functions
91 * @cubic_to: cubic-to callback
92 *
93 * Sets cubic-to callback to the draw functions object.
94 *
95 * Since: EXPERIMENTAL
96 **/
97void
98hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs,
99 hb_draw_cubic_to_func_t cubic_to)
100{
101 if (unlikely (hb_object_is_immutable (funcs))) return;
102 funcs->cubic_to = cubic_to;
103}
104
105/**
106 * hb_draw_funcs_set_close_path_func:
107 * @funcs: draw functions object
108 * @close_path: close-path callback
109 *
110 * Sets close-path callback to the draw functions object.
111 *
112 * Since: EXPERIMENTAL
113 **/
114void
115hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs,
116 hb_draw_close_path_func_t close_path)
117{
118 if (unlikely (hb_object_is_immutable (funcs))) return;
119 funcs->close_path = close_path;
120}
121
122static void
123_move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
124
125static void
126_line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
127
128static void
129_quadratic_to_nil (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED,
130 hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
131 void *user_data HB_UNUSED) {}
132
133static void
134_cubic_to_nil (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSED,
135 hb_position_t control2_x HB_UNUSED, hb_position_t control2_y HB_UNUSED,
136 hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
137 void *user_data HB_UNUSED) {}
138
139static void
140_close_path_nil (void *user_data HB_UNUSED) {}
141
142/**
143 * hb_draw_funcs_create:
144 *
145 * Creates a new draw callbacks object.
146 *
147 * Since: EXPERIMENTAL
148 **/
149hb_draw_funcs_t *
150hb_draw_funcs_create ()
151{
152 hb_draw_funcs_t *funcs;
153 if (unlikely (!(funcs = hb_object_create<hb_draw_funcs_t> ())))
154 return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
155
156 funcs->move_to = (hb_draw_move_to_func_t) _move_to_nil;
157 funcs->line_to = (hb_draw_line_to_func_t) _line_to_nil;
158 funcs->quadratic_to = (hb_draw_quadratic_to_func_t) _quadratic_to_nil;
159 funcs->is_quadratic_to_set = false;
160 funcs->cubic_to = (hb_draw_cubic_to_func_t) _cubic_to_nil;
161 funcs->close_path = (hb_draw_close_path_func_t) _close_path_nil;
162 return funcs;
163}
164
165/**
166 * hb_draw_funcs_reference:
167 * @funcs: draw functions
168 *
169 * Add to callbacks object refcount.
170 *
171 * Returns: The same object.
172 * Since: EXPERIMENTAL
173 **/
174hb_draw_funcs_t *
175hb_draw_funcs_reference (hb_draw_funcs_t *funcs)
176{
177 return hb_object_reference (funcs);
178}
179
180/**
181 * hb_draw_funcs_destroy:
182 * @funcs: draw functions
183 *
184 * Decreases refcount of callbacks object and deletes the object if it reaches
185 * to zero.
186 *
187 * Since: EXPERIMENTAL
188 **/
189void
190hb_draw_funcs_destroy (hb_draw_funcs_t *funcs)
191{
192 if (!hb_object_destroy (funcs)) return;
193
194 free (funcs);
195}
196
197/**
198 * hb_draw_funcs_make_immutable:
199 * @funcs: draw functions
200 *
201 * Makes funcs object immutable.
202 *
203 * Since: EXPERIMENTAL
204 **/
205void
206hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs)
207{
208 if (hb_object_is_immutable (funcs))
209 return;
210
211 hb_object_make_immutable (funcs);
212}
213
214/**
215 * hb_draw_funcs_is_immutable:
216 * @funcs: draw functions
217 *
218 * Checks whether funcs is immutable.
219 *
220 * Returns: If is immutable.
221 * Since: EXPERIMENTAL
222 **/
223hb_bool_t
224hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs)
225{
226 return hb_object_is_immutable (funcs);
227}
228
229/**
230 * hb_font_draw_glyph:
231 * @font: a font object
232 * @glyph: a glyph id
233 * @funcs: draw callbacks object
234 * @user_data: parameter you like be passed to the callbacks when are called
235 *
236 * Draw a glyph.
237 *
238 * Returns: Whether the font had the glyph and the operation completed successfully.
239 * Since: EXPERIMENTAL
240 **/
241hb_bool_t
242hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
243 const hb_draw_funcs_t *funcs,
244 void *user_data)
245{
246 if (unlikely (funcs == &Null (hb_draw_funcs_t) ||
247 glyph >= font->face->get_num_glyphs ()))
248 return false;
249
250 draw_helper_t draw_helper (funcs, user_data);
251 if (font->face->table.glyf->get_path (font, glyph, draw_helper)) return true;
252#ifndef HB_NO_CFF
253 if (font->face->table.cff1->get_path (font, glyph, draw_helper)) return true;
254 if (font->face->table.cff2->get_path (font, glyph, draw_helper)) return true;
255#endif
256
257 return false;
258}
259
260#endif
261#endif
262