File indexing completed on 2024-05-12 15:58:30

0001 /*
0002  *  SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
0003  *  SPDX-FileCopyrightText: 2007, 2010 Sven Langkamp <sven.langkamp@gmail.com>
0004  *
0005  *  Outline algorithm based of the limn of fontutils
0006  *  SPDX-FileCopyrightText: 1992 Karl Berry <karl@cs.umb.edu>
0007  *  SPDX-FileCopyrightText: 1992 Kathryn Hargreaves <letters@cs.umb.edu>
0008  *
0009  *  SPDX-License-Identifier: GPL-2.0-or-later
0010  */
0011 
0012 #ifndef KIS_OUTLINE_GENERATOR_H
0013 #define KIS_OUTLINE_GENERATOR_H
0014 
0015 #include <QPolygon>
0016 
0017 #include "kritaimage_export.h"
0018 #include "kis_types.h"
0019 #include <kis_random_accessor_ng.h>
0020 class KoColorSpace;
0021 
0022 
0023 /**
0024  * Generates an 'outline' for a paint device. Used e.g. in for brushes and marching ants
0025  **/
0026 class KRITAIMAGE_EXPORT KisOutlineGenerator
0027 {
0028 public:
0029 
0030     /**
0031      * Create an outline generator
0032      * @param cs colorspace for the buffer passed to the generator
0033      * @param defaultOpacity opacity of pixels that shouldn't be included in the outline
0034      **/
0035     KisOutlineGenerator(const KoColorSpace* cs, quint8 defaultOpacity);
0036 
0037     /**
0038      * Generates the outline.
0039      * @param buffer buffer with the data for the outline
0040      * @param xOffset offset that will be used for the x coordinate of the polygon points
0041      * @param yOffset offset that will be used for the y coordinate of the polygon points
0042      * @param width width of the buffer
0043      * @param height height of the buffer
0044      * @returns list of polygons around every non-transparent area
0045      **/
0046     QVector<QPolygon> outline(quint8* buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height);
0047 
0048     QVector<QPolygon> outline(const KisPaintDevice *buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height);
0049 
0050 
0051     /**
0052      * Set the generator to produce simpile outline, skipping outline that are fully enclosed
0053      * @param simple set simple mode, if true enclosed outline will be skipped
0054      **/
0055     void setSimpleOutline(bool simple);
0056 
0057 private:
0058 
0059 
0060 private:
0061 
0062     enum EdgeType {
0063         TopEdge = 1, LeftEdge = 2, BottomEdge = 3, RightEdge = 0, NoEdge = 4
0064     };
0065 
0066     template <class StorageStrategy>
0067     QVector<QPolygon> outlineImpl(typename StorageStrategy::StorageType buffer,
0068                                   qint32 xOffset, qint32 yOffset,
0069                                   qint32 width, qint32 height);
0070 
0071     template <class StorageStrategy>
0072     bool isOutlineEdge(StorageStrategy &storage, EdgeType edge, qint32 x, qint32 y, qint32 bufWidth, qint32 bufHeight);
0073 
0074     template <class StorageStrategy>
0075     void nextOutlineEdge(StorageStrategy &storage, EdgeType *edge, qint32 *row, qint32 *col, qint32 width, qint32 height);
0076 
0077     EdgeType nextEdge(EdgeType edge) {
0078         return edge == NoEdge ? edge : static_cast<EdgeType>((edge + 1) % 4);
0079     }
0080 
0081     void appendCoordinate(QPolygon * path, int x, int y, EdgeType edge, EdgeType prevEdge);
0082 
0083 private:
0084 
0085     const KoColorSpace* m_cs;
0086     quint8 m_defaultOpacity;
0087     bool m_simple;
0088 
0089     KisRandomConstAccessorSP m_accessor;
0090 };
0091 
0092 #endif // KIS_OUTLINE_GENERATOR_H