File indexing completed on 2024-05-19 04:07:51

0001 /*
0002     SPDX-FileCopyrightText: 2010 Stefan Majewsky <majewsky@gmx.net>
0003     SPDX-FileCopyrightText: 2010 Johannes Löhnert <loehnert.kde@gmx.de>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef PALAPELI_PIECEVISUALS_H
0009 #define PALAPELI_PIECEVISUALS_H
0010 
0011 #include <QPixmap>
0012 
0013 namespace Palapeli
0014 {
0015     struct BevelPoint
0016     {
0017         BevelPoint() : strength(0), angle(0), orig_argb(0) {}
0018         // gives the strength of the bevel at this point, i.e. the amount of darken/lighten
0019         char strength;
0020         // full circle is divided into 256 units. The translate into usual degrees like this:
0021         // 256 => 360°, 64 => 90° ...
0022         // 0 is at 3 o'clock and +x is ccw.
0023         char angle;
0024         // color of unaltered pixmap at this point.
0025         // if strength=0, orig_color stores not the color, but the number of
0026         // consecutive 0 points (including the current),
0027         // providing a simple RLE for those runs to speed up things later.
0028         QRgb orig_argb;
0029     };
0030 
0031     // Note that width and height are not stored. For this one needs the original pixmap
0032     // where the BevelMap belongs to.
0033     typedef QList<BevelPoint> BevelMap;
0034 
0035     class PieceVisuals
0036     {
0037         public:
0038             PieceVisuals() {}
0039             PieceVisuals(const QImage& image, const QPoint& offset) : m_image(image), m_offset(offset) {}
0040             PieceVisuals(const QPixmap& pixmap, const QPoint& offset) : m_pixmap(pixmap), m_offset(offset) {}
0041 
0042             inline bool hasImage() const { return !m_image.isNull(); }
0043             inline bool hasPixmap() const { return !m_pixmap.isNull(); }
0044             inline bool isNull() const { return m_image.isNull() && m_pixmap.isNull(); }
0045             inline QPoint offset() const { return m_offset; }
0046 
0047             inline QImage image() const
0048             {
0049                 if (m_image.isNull())
0050                     m_image = m_pixmap.toImage();
0051                 return m_image;
0052             }
0053             inline QPixmap pixmap() const
0054             {
0055                 if (m_pixmap.isNull())
0056                     m_pixmap = QPixmap::fromImage(m_image);
0057                 return m_pixmap;
0058             }
0059             inline QSize size() const
0060             {
0061                 //One of them might be (0,0) if no conversion has happened yet.
0062                 return m_pixmap.size().expandedTo(m_image.size());
0063             }
0064         private:
0065             mutable QImage m_image;
0066             mutable QPixmap m_pixmap;
0067             QPoint m_offset;
0068 
0069     };
0070 
0071     //TODO: Many of these functions operate on QImages internally, and could therefore be more efficient when given a QImage.
0072     Palapeli::BevelMap calculateBevelMap(const QImage& source, int radius);
0073     QImage applyBevelMap(const QImage& source, const Palapeli::BevelMap& bevelmap, qreal angle);
0074     Palapeli::PieceVisuals createShadow(const Palapeli::PieceVisuals& pieceVisuals, const QSize& shadowSizeHint = QSize());
0075     Palapeli::PieceVisuals changeShadowColor(const Palapeli::PieceVisuals& shadowVisuals, const QColor& color);
0076     Palapeli::PieceVisuals mergeVisuals(const QList<Palapeli::PieceVisuals>& visuals);
0077     // visuals are needed to determine positioning of maps
0078     Palapeli::BevelMap mergeBevelMaps(const QList<Palapeli::PieceVisuals>& visuals, const QList<Palapeli::BevelMap>& bevelMaps);
0079 }
0080 
0081 #endif // PALAPELI_PIECEVISUALS_H