1 #ifndef MYPAINTSURFACE_H
2 #define MYPAINTSURFACE_H
3 
4 /* libmypaint - The MyPaint Brush Library
5  * Copyright (C) 2008 Martin Renold <martinxyz@gmx.ch>
6  * Copyright (C) 2012 Jon Nordby <jononor@gmail.com>
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include "mypaint-config.h"
22 #include "mypaint-rectangle.h"
23 
24 G_BEGIN_DECLS
25 
26 typedef struct MyPaintSurface MyPaintSurface;
27 
28 /*!
29  * Function used to retrieve the average color/alpha from a region of a surface.
30  *
31  * This kind of function calculates the average color/alpha from the pixels
32  * of the given surface, selected and weighted respectively by the area
33  * and opacity of a uniform dab with a given center and radius.
34  *
35  * @param self The surface to fetch the pixels from
36  * @param x, y The center of the dab that determine which pixels
37  * to include, and their respective impact on the result.
38  * @param radius The radius of the dab.
39  * @param[out] color_r, color_g, color_b, color_a
40  * The destination of the resulting colors, range: [0.0, 1.0]
41  */
42 typedef void (*MyPaintSurfaceGetColorFunction) (
43   MyPaintSurface *self,
44   float x, float y,
45   float radius,
46   float * color_r, float * color_g, float * color_b, float * color_a
47   );
48 
49 /*!
50  * Function used to draw a dab with the given properties on the surface.
51  *
52  * The function drawing the dab is one of the core parts of any surface
53  * implementation. These functions will usually not be invoked directly
54  * by library users, but indirectly as part of the ::mypaint_brush_stroke_to
55  * call, where the interpolated parameters for each dab are calculated.
56  *
57  * @param self The surface on which the dab will be drawn
58  * @param x, y The center of the dab
59  * @param radius The radius of the dab
60  * @param color_r, color_g, color_b, opaque color/opacity of the dab
61  * @param hardness Determines how opacity is retained for
62  * pixels further from the dab center.
63  * @param alpha_eraser Hell if I know
64  * @param aspect_ratio The width/height ratio of the dab.
65  * @param angle The angle of the dab (applied after __aspect_ratio__).
66  * @param lock_alpha The extent to which the alpha values of affected pixels
67  * on the surface are retained, regardless of other dab parameters.
68  * @param colorize: The extent to which the dab will __only__ affect the hue of
69  * existing pixels on the surface.
70  *
71  * @memberof MyPaintSurface
72  */
73 typedef int (*MyPaintSurfaceDrawDabFunction) (
74   MyPaintSurface *self,
75   float x, float y,
76   float radius,
77   float color_r, float color_g, float color_b,
78   float opaque, float hardness,
79   float alpha_eraser,
80   float aspect_ratio, float angle,
81   float lock_alpha,
82   float colorize
83   );
84 
85 /*!
86  * Destructor for surface implementations.
87  * @param self The surface to free/destroy
88  *
89  * @memberof MyPaintSurface
90  */
91 typedef void (*MyPaintSurfaceDestroyFunction) (MyPaintSurface *self);
92 
93 /*!
94  * Function for rendering a png file from a surface.
95  * @param self The surface to render from
96  * @param path The destination of the png file
97  * @param x, y The top left corner of the area to export
98  * @param width, height The dimensions of the area & of the resulting png
99  *
100  * @memberof MyPaintSurface
101  */
102 typedef void (*MyPaintSurfaceSavePngFunction) (MyPaintSurface *self, const char *path, int x, int y, int width, int height);
103 
104 /*!
105  * Prepare the surface for an atomic set of stroke operations.
106  *
107  * Each call to functions of this type should be matched by a call to a
108  * ::MyPaintSurfaceEndAtomicFunction with the same surface.
109  *
110  * @memberof MyPaintSurface
111  */
112 typedef void (*MyPaintSurfaceBeginAtomicFunction) (MyPaintSurface *self);
113 
114 /*!
115  * Finalize an atomic set of stroke operations, setting an invalidation rectangle.
116  *
117  * Each call to functions of this type should be matched by a call to a
118  * ::MyPaintSurfaceBeginAtomicFunction with the same surface.
119  *
120  * @memberof MyPaintSurface
121  */
122 typedef void (*MyPaintSurfaceEndAtomicFunction) (MyPaintSurface *self, MyPaintRectangle *roi);
123 
124 /*!
125   * Abstract surface type for the MyPaint brush engine. The surface interface
126   * lets the brush engine specify dabs to render, and get color data for use
127   * in interpolations.
128   *
129   * @sa MyPaintSurface2
130   */
131 struct MyPaintSurface {
132     /*! Function for drawing a dab on the surface.
133      *
134      * See ::MyPaintSurfaceDrawDabFunction for details.
135      */
136     MyPaintSurfaceDrawDabFunction draw_dab;
137     /*!
138      * Function for retrieving color data from the surface.
139      *
140      * See ::MyPaintSurfaceGetColorFunction for details.
141      */
142     MyPaintSurfaceGetColorFunction get_color;
143     /*!
144      * Prepare the surface for a set of atomic stroke/dab operations.
145      *
146      * See ::MyPaintSurfaceBeginAtomicFunction for details.
147      */
148     MyPaintSurfaceBeginAtomicFunction begin_atomic;
149     /*!
150      * Finalize the operations run after a call to #begin_atomic.
151      *
152      * See ::MyPaintSurfaceEndAtomicFunction for details.
153      */
154     MyPaintSurfaceEndAtomicFunction end_atomic;
155     /*!
156     * Destroy the surface (free up all allocated resources).
157     */
158     MyPaintSurfaceDestroyFunction destroy;
159     /*! Save a region of the surface to a png file.
160      *
161      * See MyPaintSurfaceSavePngFunction for details
162      */
163     MyPaintSurfaceSavePngFunction save_png;
164     /*! Reference count - number of references to the struct
165      *
166      * This is only useful when used in a context with automatic
167      * memory management and can be ignored if construction/destruction
168      * is handled manually.
169      */
170     int refcount;
171 };
172 
173 /*!
174  * Invoke MyPaintSurface::draw_dab
175  *
176  * @memberof MyPaintSurface
177  * @sa MyPaintSurfaceDrawDabFunction
178  */
179 int mypaint_surface_draw_dab(
180     MyPaintSurface* self, float x, float y, float radius, float color_r, float color_g, float color_b, float opaque,
181     float hardness, float alpha_eraser, float aspect_ratio, float angle, float lock_alpha, float colorize);
182 
183 /*!
184  * Invoke MyPaintSurface::get_color
185  *
186  * @memberof MyPaintSurface
187  * @sa MyPaintSurfaceGetColorFunction
188  */
189 void mypaint_surface_get_color(
190     MyPaintSurface* self, float x, float y, float radius, float* color_r, float* color_g, float* color_b,
191     float* color_a);
192 
193 /*!
194  * Invoke MyPaintSurface::get_color and return the alpha component
195  *
196  * @memberof MyPaintSurface
197  * @sa MyPaintSurfaceGetColorFunction
198  */
199 float mypaint_surface_get_alpha(MyPaintSurface* self, float x, float y, float radius);
200 
201 /*!
202  * Invoke MyPaintSurface::save_png
203  *
204  * @memberof MyPaintSurface
205  * @sa MyPaintSurfaceSavePngFunction
206  */
207 void
208 mypaint_surface_save_png(MyPaintSurface *self, const char *path, int x, int y, int width, int height);
209 
210 
211 /*!
212  * Invoke MyPaintSurface::begin_atomic
213  *
214  * @memberof MyPaintSurface
215  * @sa MyPaintSurfaceBeginAtomicFunction
216  */
217 void mypaint_surface_begin_atomic(MyPaintSurface *self);
218 
219 /*!
220  * Invoke MyPaintSurface::begin_atomic
221  *
222  * @memberof MyPaintSurface
223  * @sa MyPaintSurfaceBeginAtomicFunction
224  */
225 void mypaint_surface_end_atomic(MyPaintSurface *self, MyPaintRectangle *roi);
226 
227 /*!
228  * Set #refcount to 1
229  *
230  * @memberof MyPaintSurface
231  */
232 void mypaint_surface_init(MyPaintSurface *self);
233 
234 /*!
235  * Increase #refcount by 1
236  *
237  * @memberof MyPaintSurface
238  */
239 
240 void mypaint_surface_ref(MyPaintSurface *self);
241 
242 /*!
243  * Decrease #refcount by 1 and call #destroy if it reaches 0
244  *
245  * @memberof MyPaintSurface
246  */
247 void mypaint_surface_unref(MyPaintSurface *self);
248 
249 
250 /* Extended interface */
251 
252 typedef struct MyPaintSurface2 MyPaintSurface2;
253 
254 /*!
255  * Like #MyPaintSurfaceDrawDabFunction, but supporting posterization and spectral mixing
256  *
257  * @param posterize Posterization factor
258  * @param posterize_num Number of posterization levels
259  * @param paint Spectral mixing factor
260  *
261  * @sa MyPaintSurfaceDrawDabFunction
262  * @memberof MyPaintSurface2
263  */
264 typedef int (*MyPaintSurfaceDrawDabFunction2) (
265   MyPaintSurface2 *self,
266   float x, float y,
267   float radius,
268   float color_r, float color_g, float color_b,
269   float opaque, float hardness,
270   float alpha_eraser,
271   float aspect_ratio, float angle,
272   float lock_alpha,
273   float colorize,
274   float posterize,
275   float posterize_num,
276   float paint);
277 
278 
279 /*!
280  * Like #MyPaintSurfaceGetColorFunction, but for spectral colors.
281  *
282  * @param paint Spectral mixing factor.
283  * To what extent spectral weighting will be used in place of straight averaging.
284  * Input value range: [0.0, 1.0]
285  *
286  * @sa MyPaintSurfaceGetColorFunction
287  * @memberof MyPaintSurface2
288  */
289 typedef void (*MyPaintSurfaceGetColorFunction2) (
290   MyPaintSurface2 *self,
291   float x, float y,
292   float radius,
293   float * color_r, float * color_g, float * color_b, float * color_a,
294   float paint
295   );
296 
297 /*!
298  * Like #MyPaintSurfaceEndAtomicFunction, but with support for multiple invalidation rectangles.
299  *
300  * @sa MyPaintSurfaceEndAtomicFunction
301  * @memberof MyPaintSurface2
302  */
303 typedef void (*MyPaintSurfaceEndAtomicFunction2) (MyPaintSurface2 *self, MyPaintRectangles *roi);
304 
305 /*!
306  * Extends MyPaintSurface with support for spectral ops and multiple bounding boxes.
307  *
308  * This extends the regular MyPaintSurface with three new
309  * functions that support the use of spectral blending,
310  * for drawing dabs and getting color, and additionally
311  * supports using multiple invalidation rectangles when
312  * finalizing drawing operations.
313  *
314  * The interface functions for MyPaintSurface can be called
315  * with instances of MyPaintSurface2 via the use of
316  * mypaint_surface2_to_surface (or just casting). Concrete
317  * implementations of MypaintSurface2 should support this.
318  *
319  * @sa MyPaintSurface
320  */
321 struct MyPaintSurface2 {
322     /*! Parent interface */
323     MyPaintSurface parent;
324     /*! See #MyPaintSurfaceDrawDabFunction2 */
325     MyPaintSurfaceDrawDabFunction2 draw_dab_pigment;
326     /*! See #MyPaintSurfaceGetColorFunction2 */
327     MyPaintSurfaceGetColorFunction2 get_color_pigment;
328     /*! See #MyPaintSurfaceEndAtomicFunction2 */
329     MyPaintSurfaceEndAtomicFunction2 end_atomic_multi;
330 };
331 
332 /*!
333  * Safely access the parent MyPaintSurface interface
334  *
335  * @memberof MyPaintSurface2
336  */
337 MyPaintSurface* mypaint_surface2_to_surface(MyPaintSurface2 *self);
338 
339 /*!
340  * Call the surface's #get_color_pigment function.
341  *
342  * See #MyPaintSurfaceGetColorFunction2 for details.
343  *
344  * @memberof MyPaintSurface2
345  */
346 void mypaint_surface2_get_color(
347     MyPaintSurface2* self, float x, float y, float radius,float* color_r, float* color_g, float* color_b,
348     float* color_a, float paint);
349 
350 /*!
351  * Call the surface's #end_atomic_multi function.
352  *
353  * See #MyPaintSurfaceEndAtomicFunction2 for details.
354  *
355  * @memberof MyPaintSurface2
356  */
357 void mypaint_surface2_end_atomic(MyPaintSurface2 *self, MyPaintRectangles *roi);
358 
359 /*!
360  * Call the surface's #draw_dab_pigment function.
361  *
362  * See #MyPaintSurfaceDrawDabFunction2 for details.
363  *
364  * @memberof MyPaintSurface2
365  */
366 int mypaint_surface2_draw_dab(
367     MyPaintSurface2* self, float x, float y, float radius, float color_r, float color_g, float color_b, float opaque,
368     float hardness, float alpha_eraser, float aspect_ratio, float angle, float lock_alpha, float colorize,
369     float posterize, float posterize_num, float paint);
370 
371 G_END_DECLS
372 
373 #endif // MYPAINTSURFACE_H
374 
375