/src/harfbuzz/src/hb-draw.hh
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright © 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 | | #ifndef HB_DRAW_HH |
26 | | #define HB_DRAW_HH |
27 | | |
28 | | #include "hb.hh" |
29 | | |
30 | | |
31 | | /* |
32 | | * hb_draw_funcs_t |
33 | | */ |
34 | | |
35 | | #define HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS \ |
36 | 0 | HB_DRAW_FUNC_IMPLEMENT (move_to) \ |
37 | 0 | HB_DRAW_FUNC_IMPLEMENT (line_to) \ |
38 | 0 | HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \ |
39 | 0 | HB_DRAW_FUNC_IMPLEMENT (cubic_to) \ |
40 | 0 | HB_DRAW_FUNC_IMPLEMENT (close_path) \ |
41 | | /* ^--- Add new callbacks here */ |
42 | | |
43 | | struct hb_draw_funcs_t |
44 | | { |
45 | | hb_object_header_t header; |
46 | | |
47 | | struct { |
48 | | #define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_func_t name; |
49 | | HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS |
50 | | #undef HB_DRAW_FUNC_IMPLEMENT |
51 | | } func; |
52 | | |
53 | | struct { |
54 | | #define HB_DRAW_FUNC_IMPLEMENT(name) void *name; |
55 | | HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS |
56 | | #undef HB_DRAW_FUNC_IMPLEMENT |
57 | | } *user_data; |
58 | | |
59 | | struct { |
60 | | #define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name; |
61 | | HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS |
62 | | #undef HB_DRAW_FUNC_IMPLEMENT |
63 | | } *destroy; |
64 | | |
65 | | void emit_move_to (void *draw_data, hb_draw_state_t &st, |
66 | | float to_x, float to_y) |
67 | 440k | { func.move_to (this, draw_data, &st, |
68 | 440k | to_x, to_y, |
69 | 440k | !user_data ? nullptr : user_data->move_to); } |
70 | | void emit_line_to (void *draw_data, hb_draw_state_t &st, |
71 | | float to_x, float to_y) |
72 | 11.9M | { func.line_to (this, draw_data, &st, |
73 | 11.9M | to_x, to_y, |
74 | 11.9M | !user_data ? nullptr : user_data->line_to); } |
75 | | void emit_quadratic_to (void *draw_data, hb_draw_state_t &st, |
76 | | float control_x, float control_y, |
77 | | float to_x, float to_y) |
78 | 1.92M | { func.quadratic_to (this, draw_data, &st, |
79 | 1.92M | control_x, control_y, |
80 | 1.92M | to_x, to_y, |
81 | 1.92M | !user_data ? nullptr : user_data->quadratic_to); } |
82 | | void emit_cubic_to (void *draw_data, hb_draw_state_t &st, |
83 | | float control1_x, float control1_y, |
84 | | float control2_x, float control2_y, |
85 | | float to_x, float to_y) |
86 | 2.66M | { func.cubic_to (this, draw_data, &st, |
87 | 2.66M | control1_x, control1_y, |
88 | 2.66M | control2_x, control2_y, |
89 | 2.66M | to_x, to_y, |
90 | 2.66M | !user_data ? nullptr : user_data->cubic_to); } |
91 | | void emit_close_path (void *draw_data, hb_draw_state_t &st) |
92 | 440k | { func.close_path (this, draw_data, &st, |
93 | 440k | !user_data ? nullptr : user_data->close_path); } |
94 | | |
95 | | |
96 | | void |
97 | | HB_ALWAYS_INLINE |
98 | | move_to (void *draw_data, hb_draw_state_t &st, |
99 | | float to_x, float to_y) |
100 | 452k | { |
101 | 452k | if (unlikely (st.path_open)) close_path (draw_data, st); |
102 | | |
103 | 452k | st.current_x = to_x; |
104 | 452k | st.current_y = to_y; |
105 | 452k | } |
106 | | |
107 | | void |
108 | | HB_ALWAYS_INLINE |
109 | | line_to (void *draw_data, hb_draw_state_t &st, |
110 | | float to_x, float to_y) |
111 | 11.9M | { |
112 | 11.9M | if (unlikely (!st.path_open)) start_path (draw_data, st); |
113 | | |
114 | 11.9M | emit_line_to (draw_data, st, to_x, to_y); |
115 | | |
116 | 11.9M | st.current_x = to_x; |
117 | 11.9M | st.current_y = to_y; |
118 | 11.9M | } |
119 | | |
120 | | void |
121 | | HB_ALWAYS_INLINE |
122 | | quadratic_to (void *draw_data, hb_draw_state_t &st, |
123 | | float control_x, float control_y, |
124 | | float to_x, float to_y) |
125 | 1.92M | { |
126 | 1.92M | if (unlikely (!st.path_open)) start_path (draw_data, st); |
127 | | |
128 | 1.92M | emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y); |
129 | | |
130 | 1.92M | st.current_x = to_x; |
131 | 1.92M | st.current_y = to_y; |
132 | 1.92M | } |
133 | | |
134 | | void |
135 | | HB_ALWAYS_INLINE |
136 | | cubic_to (void *draw_data, hb_draw_state_t &st, |
137 | | float control1_x, float control1_y, |
138 | | float control2_x, float control2_y, |
139 | | float to_x, float to_y) |
140 | 2.54M | { |
141 | 2.54M | if (unlikely (!st.path_open)) start_path (draw_data, st); |
142 | | |
143 | 2.54M | emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); |
144 | | |
145 | 2.54M | st.current_x = to_x; |
146 | 2.54M | st.current_y = to_y; |
147 | 2.54M | } |
148 | | |
149 | | void |
150 | | HB_ALWAYS_INLINE |
151 | | close_path (void *draw_data, hb_draw_state_t &st) |
152 | 6.14M | { |
153 | 6.14M | if (likely (st.path_open)) |
154 | 440k | { |
155 | 440k | if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y)) |
156 | 64.9k | emit_line_to (draw_data, st, st.path_start_x, st.path_start_y); |
157 | 440k | emit_close_path (draw_data, st); |
158 | 440k | } |
159 | 6.14M | st.path_open = false; |
160 | 6.14M | st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0; |
161 | 6.14M | } |
162 | | |
163 | | protected: |
164 | | |
165 | | void start_path (void *draw_data, hb_draw_state_t &st) |
166 | 440k | { |
167 | 440k | assert (!st.path_open); |
168 | 440k | emit_move_to (draw_data, st, st.current_x, st.current_y); |
169 | 440k | st.path_open = true; |
170 | 440k | st.path_start_x = st.current_x; |
171 | 440k | st.path_start_y = st.current_y; |
172 | 440k | } |
173 | | }; |
174 | | DECLARE_NULL_INSTANCE (hb_draw_funcs_t); |
175 | | |
176 | | struct hb_draw_session_t |
177 | | { |
178 | | hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_) |
179 | 5.71M | : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT |
180 | 5.71M | {} |
181 | | |
182 | 5.71M | ~hb_draw_session_t () { close_path (); } |
183 | | |
184 | | HB_ALWAYS_INLINE |
185 | | void move_to (float to_x, float to_y) |
186 | 363k | { |
187 | 363k | funcs->move_to (draw_data, st, |
188 | 363k | to_x, to_y); |
189 | 363k | } |
190 | | HB_ALWAYS_INLINE |
191 | | void line_to (float to_x, float to_y) |
192 | 11.7M | { |
193 | 11.7M | funcs->line_to (draw_data, st, |
194 | 11.7M | to_x, to_y); |
195 | 11.7M | } |
196 | | void |
197 | | HB_ALWAYS_INLINE |
198 | | quadratic_to (float control_x, float control_y, |
199 | | float to_x, float to_y) |
200 | 1.60M | { |
201 | 1.60M | funcs->quadratic_to (draw_data, st, |
202 | 1.60M | control_x, control_y, |
203 | 1.60M | to_x, to_y); |
204 | 1.60M | } |
205 | | void |
206 | | HB_ALWAYS_INLINE |
207 | | cubic_to (float control1_x, float control1_y, |
208 | | float control2_x, float control2_y, |
209 | | float to_x, float to_y) |
210 | 2.49M | { |
211 | 2.49M | funcs->cubic_to (draw_data, st, |
212 | 2.49M | control1_x, control1_y, |
213 | 2.49M | control2_x, control2_y, |
214 | 2.49M | to_x, to_y); |
215 | 2.49M | } |
216 | | HB_ALWAYS_INLINE |
217 | | void close_path () |
218 | 6.00M | { |
219 | 6.00M | funcs->close_path (draw_data, st); |
220 | 6.00M | } |
221 | | |
222 | | public: |
223 | | hb_draw_funcs_t *funcs; |
224 | | void *draw_data; |
225 | | hb_draw_state_t st; |
226 | | }; |
227 | | |
228 | | |
229 | | HB_INTERNAL hb_draw_funcs_t * |
230 | | hb_draw_extents_get_funcs (); |
231 | | |
232 | | |
233 | | #endif /* HB_DRAW_HH */ |