File indexing completed on 2024-05-05 05:35:34

0001 #ifndef oxygentileset_h
0002 #define oxygentileset_h
0003 
0004 /*
0005  * SPDX-FileCopyrightText: 2009-2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0006  * SPDX-FileCopyrightText: 2008 Long Huynh Huu <long.upcase@googlemail.com>
0007  * SPDX-FileCopyrightText: 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
0008  *
0009  * SPDX-License-Identifier: LGPL-2.0-only
0010  */
0011 
0012 #include "oxygen_export.h"
0013 
0014 #include <QPixmap>
0015 #include <QRect>
0016 #include <QVector>
0017 
0018 //* handles proper scaling of pixmap to match widget rect.
0019 /**
0020 tilesets are collections of stretchable pixmaps corresponding to a given widget corners, sides, and center.
0021 corner pixmaps are never stretched. center pixmaps are
0022 */
0023 namespace Oxygen
0024 {
0025 class OXYGEN_EXPORT TileSet final
0026 {
0027 public:
0028     //* default size for tileset tiles
0029     enum { DefaultSize = 7 };
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 QPixmap &, 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 QPixmap &pix, int w1, int h1, int w3, int h3, int x2, int y2, int w2, int h2);
0060 
0061     //* empty constructor
0062     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         Top = 0x1,
0072         Left = 0x2,
0073         Bottom = 0x4,
0074         Right = 0x8,
0075         Center = 0x10,
0076         TopLeft = Top | Left,
0077         TopRight = Top | Right,
0078         BottomLeft = Bottom | Left,
0079         BottomRight = Bottom | Right,
0080         Ring = Top | Left | Bottom | Right,
0081         Horizontal = Left | Right | Center,
0082         Vertical = Top | Bottom | Center,
0083         Full = Ring | Center
0084     };
0085     Q_DECLARE_FLAGS(Tiles, Tile)
0086 
0087     /**
0088     Adjust rect to deal with missing tiles
0089     This will extend the relevant side so that the missing tiles extends beyond the
0090     rect passed as argument
0091     */
0092 
0093     QRect adjust(const QRect &, Tiles) const;
0094 
0095     /**
0096     Fills the specified rect with tiled chunks. Corners are never tiled,
0097     edges are tiled in one direction, and the center chunk is tiled in both
0098     directions. Partial tiles are used as needed so that the entire rect is
0099     perfectly filled. Filling is performed as if all chunks are being drawn.
0100     */
0101     void render(const QRect &, QPainter *, Tiles = Ring) const;
0102 
0103     //* return size associated to this tileset
0104     QSize size(void) const
0105     {
0106         return QSize(_w1 + _w3, _h1 + _h3);
0107     }
0108 
0109     //* is valid
0110     bool isValid(void) const
0111     {
0112         return _pixmaps.size() == 9;
0113     }
0114 
0115     //* side extend
0116     /**
0117     it is used to (pre) tile the side pixmaps, in order to make further tiling faster when rendering, at the cost of
0118     using more memory for the cache. Changes to this member only affects tilesets that are created afterwards.
0119     */
0120     void setSideExtent(int value)
0121     {
0122         _sideExtent = value;
0123     }
0124 
0125     //* returns pixmap for given index
0126     QPixmap pixmap(int index) const
0127     {
0128         return _pixmaps[index];
0129     }
0130 
0131 private:
0132     //* shortcut to pixmap list
0133     using PixmapList = QVector<QPixmap>;
0134 
0135     //* initialize pixmap
0136     void initPixmap(PixmapList &, const QPixmap &, int w, int h, const QRect &);
0137 
0138     //* side extend
0139     /**
0140     it is used to (pre) tile the side pixmaps, in order to make further tiling faster when rendering, at the cost of
0141     using more memory for the cache.
0142     */
0143     static int _sideExtent;
0144 
0145     //* pixmap arry
0146     PixmapList _pixmaps;
0147 
0148     // dimensions
0149     int _w1 = 0;
0150     int _h1 = 0;
0151     int _w3 = 0;
0152     int _h3 = 0;
0153 };
0154 }
0155 
0156 Q_DECLARE_OPERATORS_FOR_FLAGS(Oxygen::TileSet::Tiles)
0157 
0158 #endif // TILESET_H