1 /*
2     SPDX-FileCopyrightText: 2010 Stefan Majewsky <majewsky@gmx.net>
3 
4     SPDX-License-Identifier: LGPL-2.0-only
5 */
6 
7 #ifndef LIBKDEGAMES_COLORPROXY_P_H
8 #define LIBKDEGAMES_COLORPROXY_P_H
9 
10 // Qt
11 #include <QHash>
12 #include <QPaintDevice>
13 #include <QPaintEngine>
14 
15 class QPaintEngineColorProxy;
16 
17 #ifndef KDEGAMES_QCOLOR_QHASH
18 #	define KDEGAMES_QCOLOR_QHASH
qHash(const QColor & color)19 	inline uint qHash(const QColor& color)
20 	{
21 		return color.rgba();
22 	}
23 #endif // KDEGAMES_QCOLOR_QHASH
24 
25 /**
26  * This QPaintDevice forwards all painting operations performed on it to the
27  * contained QPaintDevice. The only modification is that certain colors are
28  * replaced by others in all painting operations (except for drawImage and
29  * drawPixmap).
30  *
31  * @note Using this class results in a non-negligible performance penalty
32  * (~10-20% longer runtime), so use it only if the set of color replacements is
33  * non-empty.
34  */
35 class QPaintDeviceColorProxy : public QPaintDevice
36 {
37 	public:
38 		///@warning Replacement loops (e.g. color1 -> color2 -> color3 -> color1) lead to infinite loops.
39 		///@warning You should not interact with the @a proxiedDevice during the lifetime of this instance.
40 		QPaintDeviceColorProxy(QPaintDevice* proxiedDevice, const QHash<QColor, QColor>& replacements);
41 		~QPaintDeviceColorProxy() override;
42 
43 		QPaintDevice* proxiedDevice() const;
44 		QPaintEngine* paintEngine() const override;
45 
46 		QBrush map(const QBrush& brush) const;
47 		inline QColor map(const QColor& color) const;
48 		QPen map(const QPen& pen) const;
49 	protected:
50 		int metric(PaintDeviceMetric metric) const override;
51 	private:
52 		QPaintDevice* m_proxiedDevice;
53 		QPaintEngine* m_engine;
54 		QHash<QColor, QColor> m_replacements;
55 };
56 
57 class QPaintEngineColorProxy : public QPaintEngine
58 {
59 	public:
60 		QPaintEngineColorProxy();
61 		~QPaintEngineColorProxy() override;
62 
63 		bool begin(QPaintDevice* device) override;
64 		bool end() override;
65 		void drawEllipse(const QRectF& rect) override;
66 		void drawEllipse(const QRect& rect) override;
67 		void drawImage(const QRectF& rectangle, const QImage& image, const QRectF& sr, Qt::ImageConversionFlags flags = Qt::AutoColor) override;
68 		void drawLines(const QLineF* lines, int lineCount) override;
69 		void drawLines(const QLine* lines, int lineCount) override;
70 		void drawPath(const QPainterPath& path) override;
71 		void drawPixmap(const QRectF& r, const QPixmap& pm, const QRectF& sr) override;
72 		void drawPoints(const QPointF* points, int pointCount) override;
73 		void drawPoints(const QPoint* points, int pointCount) override;
74 		void drawPolygon(const QPointF* points, int pointCount, PolygonDrawMode mode) override;
75 		void drawPolygon(const QPoint* points, int pointCount, PolygonDrawMode mode) override;
76 		void drawRects(const QRectF* rects, int rectCount) override;
77 		void drawRects(const QRect* rects, int rectCount) override;
78 		void drawTextItem(const QPointF& p, const QTextItem& textItem) override;
79 		void drawTiledPixmap(const QRectF& rect, const QPixmap& pixmap, const QPointF& p) override;
80 		Type type() const override;
81 		void updateState(const QPaintEngineState& state) override;
82 	private:
83 		QPaintDeviceColorProxy* m_proxy;
84 		QPainter* m_painter;
85 };
86 
87 #endif // LIBKDEGAMES_COLORPROXY_P_H
88