File indexing completed on 2025-02-02 04:15:57
0001 /* 0002 * SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KISOPTIMIZEDBRUSHOUTLINE_H 0008 #define KISOPTIMIZEDBRUSHOUTLINE_H 0009 0010 #include <QList> 0011 #include <QPolygonF> 0012 #include <QTransform> 0013 #include <boost/iterator/iterator_facade.hpp> 0014 #include <kritaimage_export.h> 0015 0016 class QPainterPath; 0017 0018 /** 0019 * An special class for storing the brush outline 0020 * in an optimized way. It converts the outline into 0021 * the vector of QPolygonF objects right away and avoids 0022 * doing any modifications and/or transformations to it 0023 * until the final stage, when the outline is requested 0024 * to be drawn. 0025 */ 0026 class KRITAIMAGE_EXPORT KisOptimizedBrushOutline 0027 { 0028 public: 0029 class KRITAIMAGE_EXPORT const_iterator : 0030 public boost::iterator_facade <const_iterator, 0031 QPolygonF, 0032 boost::forward_traversal_tag, 0033 QPolygonF> 0034 { 0035 public: 0036 const_iterator() 0037 : m_outline(0), 0038 m_index(0) {} 0039 0040 const_iterator(const KisOptimizedBrushOutline *outline, int index) 0041 : m_outline(outline), 0042 m_index(index) {} 0043 0044 private: 0045 friend class boost::iterator_core_access; 0046 0047 void increment() { 0048 m_index++; 0049 } 0050 0051 bool equal(const_iterator const& other) const { 0052 return m_index == other.m_index && 0053 m_outline == other.m_outline; 0054 } 0055 0056 QPolygonF dereference() const; 0057 0058 private: 0059 const KisOptimizedBrushOutline *m_outline; 0060 int m_index; 0061 }; 0062 0063 public: 0064 KisOptimizedBrushOutline(); 0065 KisOptimizedBrushOutline(const QPainterPath &path); 0066 KisOptimizedBrushOutline(const QVector<QPolygonF> &subpaths); 0067 0068 QRectF boundingRect() const; 0069 0070 bool isEmpty() const; 0071 0072 void addRect(const QRectF &rc); 0073 void addEllipse(const QPointF ¢er, qreal rx, qreal ry); 0074 void addPath(const QPainterPath &path); 0075 void addPath(const KisOptimizedBrushOutline &path); 0076 0077 void translate(qreal tx, qreal ty); 0078 void translate(const QPointF &offset); 0079 0080 /** 0081 * Transforms all the polygons belonging to the outline. 0082 * The transformation is done in optimized way, that is, 0083 * no polygons are transformed until the final iteration 0084 * over them. 0085 */ 0086 void map(const QTransform &t); 0087 0088 /** 0089 * A helper function for \see map() 0090 */ 0091 KisOptimizedBrushOutline mapped(const QTransform &t) const; 0092 0093 /** 0094 * Begins iteration over the polygons contained in the 0095 * brush outline. KisOptimizedBrushOutline will never return 0096 * a constructed QVector of the polygons, because it may 0097 * require too many memory allocations. 0098 * 0099 * One cannot change the internal polygon, because the 0100 * returned polygon is transformed using the transformation 0101 * that is stored separately. 0102 */ 0103 const_iterator begin() const; 0104 0105 /** 0106 * End iterator for iteration over all the embedded polygons 0107 */ 0108 const_iterator end() const; 0109 0110 private: 0111 QVector<QPolygonF> m_subpaths; 0112 QVector<QPolygonF> m_additionalDecorations; 0113 QTransform m_transform; 0114 mutable QRectF m_cachedBoundingRect; 0115 }; 0116 0117 #endif // KISOPTIMIZEDBRUSHOUTLINE_H