1 #ifndef MYPAINTTILEDSURFACE_H
2 #define MYPAINTTILEDSURFACE_H
3 
4 #include <stdint.h>
5 #include "mypaint-surface.h"
6 #include "mypaint-symmetry.h"
7 #include "mypaint-config.h"
8 
9 G_BEGIN_DECLS
10 
11 typedef struct MyPaintTiledSurface MyPaintTiledSurface;
12 typedef struct MyPaintTiledSurface2 MyPaintTiledSurface2;
13 
14 /*!
15  * Tile request used by MyPaintTiledSurface and MyPaintTiledSurface2
16  *
17  * Request for tile data for a given tile coordinate (tx, ty), also acting
18  * as the response by defining fields to be populated by the receiver of
19  * the request.
20  *
21  */
22 typedef struct {
23     /*! The x-coordinate of the requested tile */
24     int tx;
25     /*! The y-coordinate of the requested tile */
26     int ty;
27     /*! Whether the tile data should be considered read-only */
28     gboolean readonly;
29     /*! Pointer to the tile buffer, set by receiver of the request */
30     guint16 *buffer;
31     /*! Additional data to be used by surface implementations __(unused)__.*/
32     gpointer context; /* Only to be used by the surface implementations. */
33     /*! Identifier of the thread from which the request is made.*/
34     int thread_id;
35     /*! The mipmap level for which to fetch the tile __(unused)__.*/
36     int mipmap_level;
37 } MyPaintTileRequest;
38 
39 /*!
40  * Initiatilze a tile request
41  *
42  * @memberof MyPaintTileRequest
43  */
44 void
45 mypaint_tile_request_init(MyPaintTileRequest *data, int level,
46                           int tx, int ty, gboolean readonly);
47 
48 /*!
49  * Function for beginning a tile request from the surface backend
50  *
51  * @memberof MyPaintTiledSurface
52  * @sa MyPaintTileRequest, MyPaintTileRequestEndFunction
53  */
54 typedef void (*MyPaintTileRequestStartFunction) (MyPaintTiledSurface *self, MyPaintTileRequest *request);
55 
56 /*!
57  * Function for ending a tile request from the surface backend
58  *
59  * @memberof MyPaintTiledSurface
60  * @sa MyPaintTileRequest, MyPaintTileRequestStartFunction
61  */
62 typedef void (*MyPaintTileRequestEndFunction) (MyPaintTiledSurface *self, MyPaintTileRequest *request);
63 
64 /*!
65  * Tile-backed implementation of MyPaintSurface
66  *
67  * Interface and convenience class for implementing a MyPaintSurface backed by
68  * a tile store.
69  *
70  * The size of the surface is infinite, and consumers only need to provide
71  * implementations for #tile_request_start and #tile_request_end
72  *
73  * @sa MyPaintTiledSurface2
74  */
75 struct MyPaintTiledSurface {
76     /*! Surface interface */
77     MyPaintSurface parent;
78     /* "private": */
79     /*! See #MyPaintTileRequestStartFunction */
80     MyPaintTileRequestStartFunction tile_request_start;
81     /*! See #MyPaintTileRequestEndFunction */
82     MyPaintTileRequestEndFunction tile_request_end;
83     /*! Whether vertical-line symmetry is enabled or not */
84     gboolean surface_do_symmetry;
85     /*! The x-coordinate of the vertical symmetry line */
86     float surface_center_x;
87     /*! Per-tile queue of pending dab operations */
88     struct OperationQueue *operation_queue;
89     /*!
90      * Invalidation rectangle recording areas changed between the calls to
91      * #parent%'s MyPaintSurface::begin_atomic and MyPaintSurface::end_atomic
92      */
93     MyPaintRectangle dirty_bbox;
94     /*! Whether tile requests shuold be considered thread-safe or not */
95     gboolean threadsafe_tile_requests;
96     /*! The side length of the (square) tiles */
97     int tile_size;
98 };
99 
100 /*!
101  * Initialize the surface by providing the tile request implementations.
102  *
103  * Allocates the resources necessary for the surface to function.
104  * @sa mypaint_tiled_surface_destroy
105  *
106  * @memberof MyPaintTiledSurface
107  */
108 void
109 mypaint_tiled_surface_init(MyPaintTiledSurface *self,
110                            MyPaintTileRequestStartFunction tile_request_start,
111                            MyPaintTileRequestEndFunction tile_request_end);
112 
113 
114 /*!
115  * Free the resources used by the surface, and the surface itself
116  *
117  * Frees up the resources allocated in mypaint_tiled_surface_init.
118  * @sa mypaint_tiled_surface_init
119  *
120  * @memberof MyPaintTiledSurface
121  */
122 void
123 mypaint_tiled_surface_destroy(MyPaintTiledSurface *self);
124 
125 
126 /*!
127  * Set the symmetry state of the surface.
128  *
129  * When the symmetry is active, for each dab drawn with
130  * ::mypaint_surface_draw_dab, reflected horizontally across the
131  * vertical line defined by MyPaintTiledSurface.surface_center_x.
132  *
133  * @param active Whether symmetry should be used or not.
134  * @param center_x The x-coordinate of the vertical line to reflect the dabs across
135  *
136  * @memberof MyPaintTiledSurface
137  */
138 void
139 mypaint_tiled_surface_set_symmetry_state(MyPaintTiledSurface *self, gboolean active, float center_x);
140 
141 /*!
142  * Get the average alpha value of pixels covered by a standard dab.
143  *
144  * Equivalent to ::mypaint_surface_get_alpha
145  * (this function should probably not have been made public).
146  *
147  * @memberof MyPaintTiledSurface
148  */
149 float
150 mypaint_tiled_surface_get_alpha (MyPaintTiledSurface *self, float x, float y, float radius);
151 
152 /*!
153  * Fetch a tile out from the underlying tile store.
154  *
155  * When successful, request->data will be set to point to the fetched tile.
156  * Consumers must *always* call mypaint_tiled_surface_tile_request_end with the same
157  * request to complete the transaction.
158  *
159  * @memberof MyPaintTiledSurface
160  */
161 void mypaint_tiled_surface_tile_request_start(MyPaintTiledSurface *self, MyPaintTileRequest *request);
162 
163 /*!
164  * Put a (potentially modified) tile back into the underlying tile store.
165  *
166  * Consumers must *always* call mypaint_tiled_surface_tile_request_start() with the same
167  * request to start the transaction before calling this function.
168  *
169  * @memberof MyPaintTiledSurface
170  */
171 void mypaint_tiled_surface_tile_request_end(MyPaintTiledSurface *self, MyPaintTileRequest *request);
172 
173 /*!
174  * Implementation of MyPaintSurface::begin_atomic
175  * Note: Only intended to be used from MyPaintTiledSurface subclasses,
176  * which should chain up to this if overriding MyPaintSurface::begin_atomic.
177  * Application code should only use #mypaint_surface_begin_atomic
178  *
179  * @memberof MyPaintTiledSurface
180  */
181 void mypaint_tiled_surface_begin_atomic(MyPaintTiledSurface *self);
182 void mypaint_tiled_surface_end_atomic(MyPaintTiledSurface *self, MyPaintRectangle *roi);
183 
184 
185 /* -- Extended interface -- */
186 
187 /*! Functionally equivalent to #MyPaintTileRequestStartFunction
188  * @memberof MyPaintTiledSurface2
189  */
190 typedef void (*MyPaintTileRequestStartFunction2) (MyPaintTiledSurface2 *self, MyPaintTileRequest *request);
191 /*! Functionally equivalent to #MyPaintTileRequestEndFunction
192  * @memberof MyPaintTiledSurface2
193  */
194 typedef void (*MyPaintTileRequestEndFunction2) (MyPaintTiledSurface2 *self, MyPaintTileRequest *request);
195 
196 /*!
197   * Tile-backed implementation of MyPaintSurface2
198   *
199   * Apart from the additional calls of MyPaintSurface2, this implementation
200   * supports additional symmetry types, and the ability to adjust the symmetry
201   * angle - it is otherwise identical to MyPaintTiledSurface.
202   *
203   * @sa MyPaintTiledSurface
204   */
205 struct MyPaintTiledSurface2 {
206   /*! Parent interface */
207   MyPaintSurface2 parent;
208   /*! See #MyPaintTileRequestStartFunction2 */
209   MyPaintTileRequestStartFunction2 tile_request_start;
210   /*! See #MyPaintTileRequestEndFunction2 */
211   MyPaintTileRequestEndFunction2 tile_request_end;
212   /*! Per-tile queue of pending dab operations */
213   struct OperationQueue *operation_queue;
214   /*! Whether tile requests shuold be considered thread-safe or not */
215   gboolean threadsafe_tile_requests;
216   int tile_size;
217   /*! The symmetry data used
218    *
219    * See MyPaintSymmetryData for details.
220    */
221   MyPaintSymmetryData symmetry_data;
222   /*! Length of #bboxes */
223   int num_bboxes;
224   /*! The number of #bboxes that have been modified since they were last reset */
225   int num_bboxes_dirtied;
226   /*! Pointer to an array of invalidation rectangles
227    *
228    * Records multiple invalidation rectangles when symmetry is enabled.
229    */
230   MyPaintRectangle* bboxes;
231 };
232 
233 /*!
234  * Initialize the surface by providing the tile request implementations.
235  *
236  * Allocates the resources necessary for the surface to function.
237  * @sa mypaint_tiled_surface2_destroy
238  *
239  * @memberof MyPaintTiledSurface2
240  */
241 void
242 mypaint_tiled_surface2_init(
243   MyPaintTiledSurface2 *self,
244   MyPaintTileRequestStartFunction2 tile_request_start,
245   MyPaintTileRequestEndFunction2 tile_request_end
246   );
247 
248 /*!
249  * Prepare the surface for handling a set of dab operations.
250  *
251  * @memberof MyPaintTiledSurface2
252  */
253 void mypaint_tiled_surface2_begin_atomic(MyPaintTiledSurface2 *self);
254 
255 /*!
256  * Finalize any pending dab operations and set the resulting invalidation rectangles.
257  *
258  * @memberof MyPaintTiledSurface2
259  */
260 void mypaint_tiled_surface2_end_atomic(MyPaintTiledSurface2 *self, MyPaintRectangles *roi);
261 
262 /*!
263  * Finalize any pending dab operations and set the resulting invalidation rectangles.
264  *
265  * @memberof MyPaintTiledSurface2
266  */
267 void mypaint_tiled_surface2_tile_request_start(MyPaintTiledSurface2 *self, MyPaintTileRequest *request);
268 
269 /*!
270  * Finalize any pending dab operations and set the resulting invalidation rectangles.
271  *
272  * @memberof MyPaintTiledSurface2
273  */
274 void mypaint_tiled_surface2_tile_request_end(MyPaintTiledSurface2 *self, MyPaintTileRequest *request);
275 
276 /*!
277  * Deallocate all resources used by the surface struct, and the struct itself.
278  *
279  * @memberof MyPaintTiledSurface2
280  */
281 void
282 mypaint_tiled_surface2_destroy(MyPaintTiledSurface2 *self);
283 
284 /*!
285  * Set new #symmetry_data values and mark it for update
286  *
287  * @memberof MyPaintTiledSurface2
288  * @sa MyPaintSymmetryData, MyPaintSymmetryState
289  */
290 void
291 mypaint_tiled_surface2_set_symmetry_state(MyPaintTiledSurface2 *self, gboolean active,
292                                          float center_x, float center_y,
293                                          float symmetry_angle,
294                                          MyPaintSymmetryType symmetry_type,
295                                          int rot_symmetry_lines);
296 
297 G_END_DECLS
298 
299 #endif // MYPAINTTILEDSURFACE_H
300