#ifndef MYPAINTSYMMETRY_H #define MYPAINTSYMMETRY_H /* libmypaint - The MyPaint Brush Library * Copyright (C) 2017-2019 The MyPaint Team * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "mypaint-matrix.h" #include "mypaint-glib-compat.h" /*! * Enumeration of different kinds of symmetry * * @see MyPaintSymmetryState, MyPaintSymmetryData */ typedef enum { /*! * reflection across the (vertical) y-axis */ MYPAINT_SYMMETRY_TYPE_VERTICAL, /*! * reflection across the (horizontal) x-axis */ MYPAINT_SYMMETRY_TYPE_HORIZONTAL, /*! * reflection across both the x-axis and the y-axis */ MYPAINT_SYMMETRY_TYPE_VERTHORZ, /*! * rotational symmetry */ MYPAINT_SYMMETRY_TYPE_ROTATIONAL, /*! * rotational symmetry and its reflection */ MYPAINT_SYMMETRY_TYPE_SNOWFLAKE, /*! * number of available symmetry types (only use to enumerate) */ MYPAINT_SYMMETRY_TYPES_COUNT } MyPaintSymmetryType; /*! * Contains the basis for symmetry calculations * * The data in this structure is used to calculate the matrices that are * used for the actual symmetry calculations, and to determine when those * matrices need to be recalculated. * * @see MyPaintSymmetryData * */ typedef struct { /*! * The type of symmetry to use */ MyPaintSymmetryType type; /*! * The x coordinate of the symmetry center */ float center_x; /*! * The y coordinate of the symmetry center */ float center_y; /*! * The angle of the symmetry, in radians */ float angle; /*! * The number of symmetry lines to use, only relevant when #type is one of * @ref MYPAINT_SYMMETRY_TYPE_ROTATIONAL or @ref MYPAINT_SYMMETRY_TYPE_SNOWFLAKE */ float num_lines; } MyPaintSymmetryState; /*! * Contains data used for symmetry calculations * * Instances contain a current and pending symmetry basis, and the * matrices used for the actual symmetry transforms. When the pending * state is modified, the "pending_changes" flag should be set. * Matrix recalculation should not be performed during draw operations. * * @see MyPaintTiledSurface2 */ typedef struct { /*! * The current symmetry state. This is the data used for symmetry calculations * if #active is TRUE. */ MyPaintSymmetryState state_current; /*! * The pending symmetry state. This is copied to #state_current when the * #symmetry_matrices are recalculated, and used to check whether the matrices * need to be recalculated. */ MyPaintSymmetryState state_pending; /*! * Flag used to check if #state_pending needs to be compared * against #state_current (does not necessarily mean that the * #symmetry_matrices need to be recalculated. */ gboolean pending_changes; /*! * Whether symmetry is used or not */ gboolean active; /*! * The size of #symmetry_matrices, depends on __type__ and __num_lines__ of #state_current **/ int num_symmetry_matrices; /*! * The matrices used for the actual symmetry calculations */ MyPaintTransform *symmetry_matrices; } MyPaintSymmetryData; /*! * If necessary, recalculate #symmetry_matrices * * @memberof MyPaintSymmetryData */ void mypaint_update_symmetry_state(MyPaintSymmetryData * const symmetry_data); /*! * Create a default symmetry data instance * * Creates a symmetry data object in an inactive state. Also attempts to * allocate space for an initial fixed number of matrices. If the allocation * is successful, the data is initialized, otherwise #symmetry_matrices is * NULL, and the object is left uninitialized. * * @memberof MyPaintSymmetryData */ MyPaintSymmetryData mypaint_default_symmetry_data(); /*! * Destroy resources used by the data struct, and the struct itself. * * @memberof MyPaintSymmetryData */ void mypaint_symmetry_data_destroy(MyPaintSymmetryData *); /*! * Update #state_pending and #active and set #pending_changes to TRUE. * * Apart from __active__, the arguments correspond to the fields of * MyPaintSymmetryState * * @memberof MyPaintSymmetryData */ void mypaint_symmetry_set_pending( MyPaintSymmetryData* data, gboolean active, float center_x, float center_y, float symmetry_angle, MyPaintSymmetryType symmetry_type, int rot_symmetry_lines); #endif