comparison mupdf-source/thirdparty/harfbuzz/src/hb-draw.hh @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
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 HB_DRAW_FUNC_IMPLEMENT (move_to) \
37 HB_DRAW_FUNC_IMPLEMENT (line_to) \
38 HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \
39 HB_DRAW_FUNC_IMPLEMENT (cubic_to) \
40 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 { func.move_to (this, draw_data, &st,
68 to_x, to_y,
69 !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 { func.line_to (this, draw_data, &st,
73 to_x, to_y,
74 !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 { func.quadratic_to (this, draw_data, &st,
79 control_x, control_y,
80 to_x, to_y,
81 !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 { func.cubic_to (this, draw_data, &st,
87 control1_x, control1_y,
88 control2_x, control2_y,
89 to_x, to_y,
90 !user_data ? nullptr : user_data->cubic_to); }
91 void emit_close_path (void *draw_data, hb_draw_state_t &st)
92 { func.close_path (this, draw_data, &st,
93 !user_data ? nullptr : user_data->close_path); }
94
95
96 void move_to (void *draw_data, hb_draw_state_t &st,
97 float to_x, float to_y)
98 {
99 if (st.path_open) close_path (draw_data, st);
100 st.current_x = to_x;
101 st.current_y = to_y;
102 }
103
104 void line_to (void *draw_data, hb_draw_state_t &st,
105 float to_x, float to_y)
106 {
107 if (!st.path_open) start_path (draw_data, st);
108 emit_line_to (draw_data, st, to_x, to_y);
109 st.current_x = to_x;
110 st.current_y = to_y;
111 }
112
113 void
114 quadratic_to (void *draw_data, hb_draw_state_t &st,
115 float control_x, float control_y,
116 float to_x, float to_y)
117 {
118 if (!st.path_open) start_path (draw_data, st);
119 emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
120 st.current_x = to_x;
121 st.current_y = to_y;
122 }
123
124 void
125 cubic_to (void *draw_data, hb_draw_state_t &st,
126 float control1_x, float control1_y,
127 float control2_x, float control2_y,
128 float to_x, float to_y)
129 {
130 if (!st.path_open) start_path (draw_data, st);
131 emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
132 st.current_x = to_x;
133 st.current_y = to_y;
134 }
135
136 void
137 close_path (void *draw_data, hb_draw_state_t &st)
138 {
139 if (st.path_open)
140 {
141 if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
142 emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
143 emit_close_path (draw_data, st);
144 }
145 st.path_open = false;
146 st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0;
147 }
148
149 protected:
150
151 void start_path (void *draw_data, hb_draw_state_t &st)
152 {
153 assert (!st.path_open);
154 emit_move_to (draw_data, st, st.current_x, st.current_y);
155 st.path_open = true;
156 st.path_start_x = st.current_x;
157 st.path_start_y = st.current_y;
158 }
159 };
160 DECLARE_NULL_INSTANCE (hb_draw_funcs_t);
161
162 struct hb_draw_session_t
163 {
164 hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f)
165 : slant {slant_}, not_slanted {slant == 0.f},
166 funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT
167 {}
168
169 ~hb_draw_session_t () { close_path (); }
170
171 void move_to (float to_x, float to_y)
172 {
173 if (likely (not_slanted))
174 funcs->move_to (draw_data, st,
175 to_x, to_y);
176 else
177 funcs->move_to (draw_data, st,
178 to_x + to_y * slant, to_y);
179 }
180 void line_to (float to_x, float to_y)
181 {
182 if (likely (not_slanted))
183 funcs->line_to (draw_data, st,
184 to_x, to_y);
185 else
186 funcs->line_to (draw_data, st,
187 to_x + to_y * slant, to_y);
188 }
189 void
190 quadratic_to (float control_x, float control_y,
191 float to_x, float to_y)
192 {
193 if (likely (not_slanted))
194 funcs->quadratic_to (draw_data, st,
195 control_x, control_y,
196 to_x, to_y);
197 else
198 funcs->quadratic_to (draw_data, st,
199 control_x + control_y * slant, control_y,
200 to_x + to_y * slant, to_y);
201 }
202 void
203 cubic_to (float control1_x, float control1_y,
204 float control2_x, float control2_y,
205 float to_x, float to_y)
206 {
207 if (likely (not_slanted))
208 funcs->cubic_to (draw_data, st,
209 control1_x, control1_y,
210 control2_x, control2_y,
211 to_x, to_y);
212 else
213 funcs->cubic_to (draw_data, st,
214 control1_x + control1_y * slant, control1_y,
215 control2_x + control2_y * slant, control2_y,
216 to_x + to_y * slant, to_y);
217 }
218 void close_path ()
219 {
220 funcs->close_path (draw_data, st);
221 }
222
223 protected:
224 float slant;
225 bool not_slanted;
226 hb_draw_funcs_t *funcs;
227 void *draw_data;
228 hb_draw_state_t st;
229 };
230
231 #endif /* HB_DRAW_HH */