#ifndef MYPAINTTILEDSURFACE_H #define MYPAINTTILEDSURFACE_H #include #include "mypaint-surface.h" #include "mypaint-symmetry.h" #include "mypaint-config.h" G_BEGIN_DECLS typedef struct MyPaintTiledSurface MyPaintTiledSurface; typedef struct MyPaintTiledSurface2 MyPaintTiledSurface2; /*! * Tile request used by MyPaintTiledSurface and MyPaintTiledSurface2 * * Request for tile data for a given tile coordinate (tx, ty), also acting * as the response by defining fields to be populated by the receiver of * the request. * */ typedef struct { /*! The x-coordinate of the requested tile */ int tx; /*! The y-coordinate of the requested tile */ int ty; /*! Whether the tile data should be considered read-only */ gboolean readonly; /*! Pointer to the tile buffer, set by receiver of the request */ guint16 *buffer; /*! Additional data to be used by surface implementations __(unused)__.*/ gpointer context; /* Only to be used by the surface implementations. */ /*! Identifier of the thread from which the request is made.*/ int thread_id; /*! The mipmap level for which to fetch the tile __(unused)__.*/ int mipmap_level; } MyPaintTileRequest; /*! * Initiatilze a tile request * * @memberof MyPaintTileRequest */ void mypaint_tile_request_init(MyPaintTileRequest *data, int level, int tx, int ty, gboolean readonly); /*! * Function for beginning a tile request from the surface backend * * @memberof MyPaintTiledSurface * @sa MyPaintTileRequest, MyPaintTileRequestEndFunction */ typedef void (*MyPaintTileRequestStartFunction) (MyPaintTiledSurface *self, MyPaintTileRequest *request); /*! * Function for ending a tile request from the surface backend * * @memberof MyPaintTiledSurface * @sa MyPaintTileRequest, MyPaintTileRequestStartFunction */ typedef void (*MyPaintTileRequestEndFunction) (MyPaintTiledSurface *self, MyPaintTileRequest *request); /*! * Tile-backed implementation of MyPaintSurface * * Interface and convenience class for implementing a MyPaintSurface backed by * a tile store. * * The size of the surface is infinite, and consumers only need to provide * implementations for #tile_request_start and #tile_request_end * * @sa MyPaintTiledSurface2 */ struct MyPaintTiledSurface { /*! Surface interface */ MyPaintSurface parent; /* "private": */ /*! See #MyPaintTileRequestStartFunction */ MyPaintTileRequestStartFunction tile_request_start; /*! See #MyPaintTileRequestEndFunction */ MyPaintTileRequestEndFunction tile_request_end; /*! Whether vertical-line symmetry is enabled or not */ gboolean surface_do_symmetry; /*! The x-coordinate of the vertical symmetry line */ float surface_center_x; /*! Per-tile queue of pending dab operations */ struct OperationQueue *operation_queue; /*! * Invalidation rectangle recording areas changed between the calls to * #parent%'s MyPaintSurface::begin_atomic and MyPaintSurface::end_atomic */ MyPaintRectangle dirty_bbox; /*! Whether tile requests shuold be considered thread-safe or not */ gboolean threadsafe_tile_requests; /*! The side length of the (square) tiles */ int tile_size; }; /*! * Initialize the surface by providing the tile request implementations. * * Allocates the resources necessary for the surface to function. * @sa mypaint_tiled_surface_destroy * * @memberof MyPaintTiledSurface */ void mypaint_tiled_surface_init(MyPaintTiledSurface *self, MyPaintTileRequestStartFunction tile_request_start, MyPaintTileRequestEndFunction tile_request_end); /*! * Free the resources used by the surface, and the surface itself * * Frees up the resources allocated in mypaint_tiled_surface_init. * @sa mypaint_tiled_surface_init * * @memberof MyPaintTiledSurface */ void mypaint_tiled_surface_destroy(MyPaintTiledSurface *self); /*! * Set the symmetry state of the surface. * * When the symmetry is active, for each dab drawn with * ::mypaint_surface_draw_dab, reflected horizontally across the * vertical line defined by MyPaintTiledSurface.surface_center_x. * * @param active Whether symmetry should be used or not. * @param center_x The x-coordinate of the vertical line to reflect the dabs across * * @memberof MyPaintTiledSurface */ void mypaint_tiled_surface_set_symmetry_state(MyPaintTiledSurface *self, gboolean active, float center_x); /*! * Get the average alpha value of pixels covered by a standard dab. * * Equivalent to ::mypaint_surface_get_alpha * (this function should probably not have been made public). * * @memberof MyPaintTiledSurface */ float mypaint_tiled_surface_get_alpha (MyPaintTiledSurface *self, float x, float y, float radius); /*! * Fetch a tile out from the underlying tile store. * * When successful, request->data will be set to point to the fetched tile. * Consumers must *always* call mypaint_tiled_surface_tile_request_end with the same * request to complete the transaction. * * @memberof MyPaintTiledSurface */ void mypaint_tiled_surface_tile_request_start(MyPaintTiledSurface *self, MyPaintTileRequest *request); /*! * Put a (potentially modified) tile back into the underlying tile store. * * Consumers must *always* call mypaint_tiled_surface_tile_request_start() with the same * request to start the transaction before calling this function. * * @memberof MyPaintTiledSurface */ void mypaint_tiled_surface_tile_request_end(MyPaintTiledSurface *self, MyPaintTileRequest *request); /*! * Implementation of MyPaintSurface::begin_atomic * Note: Only intended to be used from MyPaintTiledSurface subclasses, * which should chain up to this if overriding MyPaintSurface::begin_atomic. * Application code should only use #mypaint_surface_begin_atomic * * @memberof MyPaintTiledSurface */ void mypaint_tiled_surface_begin_atomic(MyPaintTiledSurface *self); void mypaint_tiled_surface_end_atomic(MyPaintTiledSurface *self, MyPaintRectangle *roi); /* -- Extended interface -- */ /*! Functionally equivalent to #MyPaintTileRequestStartFunction * @memberof MyPaintTiledSurface2 */ typedef void (*MyPaintTileRequestStartFunction2) (MyPaintTiledSurface2 *self, MyPaintTileRequest *request); /*! Functionally equivalent to #MyPaintTileRequestEndFunction * @memberof MyPaintTiledSurface2 */ typedef void (*MyPaintTileRequestEndFunction2) (MyPaintTiledSurface2 *self, MyPaintTileRequest *request); /*! * Tile-backed implementation of MyPaintSurface2 * * Apart from the additional calls of MyPaintSurface2, this implementation * supports additional symmetry types, and the ability to adjust the symmetry * angle - it is otherwise identical to MyPaintTiledSurface. * * @sa MyPaintTiledSurface */ struct MyPaintTiledSurface2 { /*! Parent interface */ MyPaintSurface2 parent; /*! See #MyPaintTileRequestStartFunction2 */ MyPaintTileRequestStartFunction2 tile_request_start; /*! See #MyPaintTileRequestEndFunction2 */ MyPaintTileRequestEndFunction2 tile_request_end; /*! Per-tile queue of pending dab operations */ struct OperationQueue *operation_queue; /*! Whether tile requests shuold be considered thread-safe or not */ gboolean threadsafe_tile_requests; int tile_size; /*! The symmetry data used * * See MyPaintSymmetryData for details. */ MyPaintSymmetryData symmetry_data; /*! Length of #bboxes */ int num_bboxes; /*! The number of #bboxes that have been modified since they were last reset */ int num_bboxes_dirtied; /*! Pointer to an array of invalidation rectangles * * Records multiple invalidation rectangles when symmetry is enabled. */ MyPaintRectangle* bboxes; }; /*! * Initialize the surface by providing the tile request implementations. * * Allocates the resources necessary for the surface to function. * @sa mypaint_tiled_surface2_destroy * * @memberof MyPaintTiledSurface2 */ void mypaint_tiled_surface2_init( MyPaintTiledSurface2 *self, MyPaintTileRequestStartFunction2 tile_request_start, MyPaintTileRequestEndFunction2 tile_request_end ); /*! * Prepare the surface for handling a set of dab operations. * * @memberof MyPaintTiledSurface2 */ void mypaint_tiled_surface2_begin_atomic(MyPaintTiledSurface2 *self); /*! * Finalize any pending dab operations and set the resulting invalidation rectangles. * * @memberof MyPaintTiledSurface2 */ void mypaint_tiled_surface2_end_atomic(MyPaintTiledSurface2 *self, MyPaintRectangles *roi); /*! * Finalize any pending dab operations and set the resulting invalidation rectangles. * * @memberof MyPaintTiledSurface2 */ void mypaint_tiled_surface2_tile_request_start(MyPaintTiledSurface2 *self, MyPaintTileRequest *request); /*! * Finalize any pending dab operations and set the resulting invalidation rectangles. * * @memberof MyPaintTiledSurface2 */ void mypaint_tiled_surface2_tile_request_end(MyPaintTiledSurface2 *self, MyPaintTileRequest *request); /*! * Deallocate all resources used by the surface struct, and the struct itself. * * @memberof MyPaintTiledSurface2 */ void mypaint_tiled_surface2_destroy(MyPaintTiledSurface2 *self); /*! * Set new #symmetry_data values and mark it for update * * @memberof MyPaintTiledSurface2 * @sa MyPaintSymmetryData, MyPaintSymmetryState */ void mypaint_tiled_surface2_set_symmetry_state(MyPaintTiledSurface2 *self, gboolean active, float center_x, float center_y, float symmetry_angle, MyPaintSymmetryType symmetry_type, int rot_symmetry_lines); G_END_DECLS #endif // MYPAINTTILEDSURFACE_H