File indexing completed on 2024-04-28 05:32:21

0001 #ifndef oxygentileset_h
0002 #define oxygentileset_h
0003 /*
0004 * this file is part of the oxygen gtk engine
0005 * SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0006 *
0007 * SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include "oxygenflags.h"
0011 #include "oxygencairosurface.h"
0012 
0013 #include <cairo.h>
0014 #include <vector>
0015 
0016 namespace Oxygen
0017 {
0018 
0019     // forward declaration
0020     namespace Cairo
0021     { class Context; }
0022 
0023     class TileSet
0024     {
0025 
0026         public:
0027 
0028         //! empty constructor
0029         TileSet();
0030 
0031         /*!
0032         Create a TileSet from a pixmap. The size of the bottom/right chunks is
0033         whatever is left over from the other chunks, whose size is specified
0034         in the required parameters.
0035 
0036         @param w1 width of the left chunks
0037         @param h1 height of the top chunks
0038         @param w2 width of the not-left-or-right chunks
0039         @param h2 height of the not-top-or-bottom chunks
0040         */
0041         TileSet( const Cairo::Surface& surface, int w1, int h1, int w2, int h2 );
0042 
0043         /*!
0044         Create a TileSet from a pixmap. The size of the top/left and bottom/right
0045         chunks is specified, with the middle chunks created from the specified
0046         portion of the pixmap. This allows the middle chunks to overlap the outer
0047         chunks (or to not use all pixels). The top/left and bottom/right chunks
0048         are carved out of the corners of the pixmap.
0049 
0050         @param w1 width of the left chunks
0051         @param h1 height of the top chunks
0052         @param w3 width of the right chunks
0053         @param h3 height of bottom chunks
0054         @param x2 x-coordinate of the top of the not-left-or-right chunks
0055         @param y2 y-coordinate of the left of the not-top-or-bottom chunks
0056         @param w2 width of the not-left-or-right chunks
0057         @param h2 height of the not-top-or-bottom chunks
0058         */
0059         TileSet( const Cairo::Surface& surface, int w1, int h1, int w3, int h3, int x2, int y2, int w2, int h2 );
0060 
0061         //! destructor
0062         virtual ~TileSet();
0063 
0064         /*!
0065         Flags specifying what sides to draw in ::render. Corners are drawn when
0066         the sides forming that corner are drawn, e.g. Top|Left draws the
0067         top-center, center-left, and top-left chunks. The center-center chunk is
0068         only drawn when Center is requested.
0069         */
0070         enum Tile
0071         {
0072             Top = 1<<0,
0073             Left = 1<<1,
0074             Bottom = 1<<2,
0075             Right = 1<<3,
0076             Center = 1<<4,
0077             TopLeft = Top|Left,
0078             TopRight = Top|Right,
0079             BottomLeft = Bottom|Left,
0080             BottomRight = Bottom|Right,
0081             Ring = Top|Left|Bottom|Right,
0082             Horizontal = Left|Right|Center,
0083             Vertical = Top|Bottom|Center,
0084             Full = Ring|Center
0085         };
0086 
0087         OX_DECLARE_FLAGS( Tiles, Tile );
0088 
0089         //! return size associated to this tileset
0090         int width( void ) const
0091         { return _w1 + _w3; }
0092 
0093         //! return size associated to this tileset
0094         int height( void ) const
0095         { return _h1 + _h3; }
0096 
0097         //! is valid
0098         bool isValid( void ) const
0099         { return _surfaces.size() == 9; }
0100 
0101         /*!
0102         Fills the specified rect with tiled chunks. Corners are never tiled,
0103         edges are tiled in one direction, and the center chunk is tiled in both
0104         directions. Partial tiles are used as needed so that the entire rect is
0105         perfectly filled. Filling is performed as if all chunks are being drawn.
0106         */
0107         void render( cairo_t*, int x, int y, int w, int h, unsigned int = Ring) const;
0108 
0109         //! returns surface for given index
0110         const Cairo::Surface& surface( unsigned int index ) const
0111         {
0112             assert( index < _surfaces.size() );
0113             return _surfaces[index];
0114         }
0115 
0116         protected:
0117 
0118         //!@name internal constructors
0119         //@{
0120         void init( const Cairo::Surface&, int w1, int h1, int w2, int h2 );
0121         void init( const Cairo::Surface&, int w1, int h1, int w3, int h3, int x2, int y2, int w2, int h2 );
0122         //@}
0123 
0124         //! shortcut to pixmap list
0125         typedef std::vector< Cairo::Surface > SurfaceList;
0126 
0127         //! initialize pixmap
0128         void initSurface( SurfaceList&, const Cairo::Surface&, int w, int h, int sx, int sy, int sw, int sh );
0129 
0130         //! copy pixmap
0131         void copySurface( cairo_t*, int x, int y, const Cairo::Surface&, int sx, int sy, int sw, int sh, cairo_extend_t ) const;
0132 
0133         private:
0134 
0135         //! pixmap arry
0136         SurfaceList _surfaces;
0137 
0138         // dimensions
0139         int _w1;
0140         int _h1;
0141         int _w3;
0142         int _h3;
0143 
0144     };
0145 
0146     OX_DECLARE_OPERATORS_FOR_FLAGS( TileSet::Tiles );
0147 
0148 }
0149 
0150 #endif