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 **/
45 void
hb_draw_funcs_set_move_to_func(hb_draw_funcs_t * funcs,hb_draw_move_to_func_t move_to)46 hb_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 **/
62 void
hb_draw_funcs_set_line_to_func(hb_draw_funcs_t * funcs,hb_draw_line_to_func_t line_to)63 hb_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 **/
79 void
hb_draw_funcs_set_quadratic_to_func(hb_draw_funcs_t * funcs,hb_draw_quadratic_to_func_t quadratic_to)80 hb_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 **/
97 void
hb_draw_funcs_set_cubic_to_func(hb_draw_funcs_t * funcs,hb_draw_cubic_to_func_t cubic_to)98 hb_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 **/
114 void
hb_draw_funcs_set_close_path_func(hb_draw_funcs_t * funcs,hb_draw_close_path_func_t close_path)115 hb_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
122 static void
_move_to_nil(hb_position_t to_x HB_UNUSED,hb_position_t to_y HB_UNUSED,void * user_data HB_UNUSED)123 _move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
124
125 static void
_line_to_nil(hb_position_t to_x HB_UNUSED,hb_position_t to_y HB_UNUSED,void * user_data HB_UNUSED)126 _line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
127
128 static void
_quadratic_to_nil(hb_position_t control_x HB_UNUSED,hb_position_t control_y HB_UNUSED,hb_position_t to_x HB_UNUSED,hb_position_t to_y HB_UNUSED,void * user_data HB_UNUSED)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
133 static void
_cubic_to_nil(hb_position_t control1_x HB_UNUSED,hb_position_t control1_y HB_UNUSED,hb_position_t control2_x HB_UNUSED,hb_position_t control2_y HB_UNUSED,hb_position_t to_x HB_UNUSED,hb_position_t to_y HB_UNUSED,void * user_data HB_UNUSED)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
139 static void
_close_path_nil(void * user_data HB_UNUSED)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 **/
149 hb_draw_funcs_t *
hb_draw_funcs_create()150 hb_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 **/
174 hb_draw_funcs_t *
hb_draw_funcs_reference(hb_draw_funcs_t * funcs)175 hb_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 **/
189 void
hb_draw_funcs_destroy(hb_draw_funcs_t * funcs)190 hb_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 **/
205 void
hb_draw_funcs_make_immutable(hb_draw_funcs_t * funcs)206 hb_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 **/
223 hb_bool_t
hb_draw_funcs_is_immutable(hb_draw_funcs_t * funcs)224 hb_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 **/
241 hb_bool_t
hb_font_draw_glyph(hb_font_t * font,hb_codepoint_t glyph,const hb_draw_funcs_t * funcs,void * user_data)242 hb_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