File indexing completed on 2024-12-22 04:12:56

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "KisMaskedFreehandStrokePainter.h"
0008 
0009 #include "kis_assert.h"
0010 #include "kis_painter.h"
0011 #include "KisFreehandStrokeInfo.h"
0012 #include "kis_paintop.h"
0013 #include "kis_paintop_preset.h"
0014 
0015 
0016 KisMaskedFreehandStrokePainter::KisMaskedFreehandStrokePainter(KisFreehandStrokeInfo *strokeData, KisFreehandStrokeInfo *maskData)
0017     : m_stroke(strokeData),
0018       m_mask(maskData)
0019 {
0020 }
0021 
0022 KisPaintOpPresetSP KisMaskedFreehandStrokePainter::preset() const
0023 {
0024     return m_stroke->painter->preset();
0025 }
0026 
0027 template <class Func>
0028 void KisMaskedFreehandStrokePainter::applyToAllPainters(Func func)
0029 {
0030     KIS_SAFE_ASSERT_RECOVER_NOOP(m_stroke);
0031     func(m_stroke);
0032 
0033     if (m_mask) {
0034         func(m_mask);
0035     }
0036 }
0037 
0038 void KisMaskedFreehandStrokePainter::paintAt(const KisPaintInformation &pi)
0039 {
0040     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0041         data->painter->paintAt(pi, data->dragDistance);
0042     });
0043 }
0044 
0045 void KisMaskedFreehandStrokePainter::paintLine(const KisPaintInformation &pi1, const KisPaintInformation &pi2)
0046 {
0047     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0048         data->painter->paintLine(pi1, pi2, data->dragDistance);
0049     });
0050 }
0051 
0052 void KisMaskedFreehandStrokePainter::paintBezierCurve(const KisPaintInformation &pi1, const QPointF &control1, const QPointF &control2, const KisPaintInformation &pi2)
0053 {
0054     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0055         data->painter->paintBezierCurve(pi1, control1, control2, pi2, data->dragDistance);
0056     });
0057 }
0058 
0059 void KisMaskedFreehandStrokePainter::paintPolyline(const QVector<QPointF> &points, int index, int numPoints)
0060 {
0061     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0062         data->painter->paintPolyline(points, index, numPoints);
0063     });
0064 }
0065 
0066 void KisMaskedFreehandStrokePainter::paintPolygon(const QVector<QPointF> &points)
0067 {
0068     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0069         data->painter->paintPolygon(points);
0070     });
0071 }
0072 
0073 void KisMaskedFreehandStrokePainter::paintRect(const QRectF &rect)
0074 {
0075     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0076         data->painter->paintRect(rect);
0077     });
0078 }
0079 
0080 void KisMaskedFreehandStrokePainter::paintEllipse(const QRectF &rect)
0081 {
0082     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0083         data->painter->paintEllipse(rect);
0084     });
0085 }
0086 
0087 void KisMaskedFreehandStrokePainter::paintPainterPath(const QPainterPath &path)
0088 {
0089     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0090         data->painter->paintPainterPath(path);
0091     });
0092 }
0093 
0094 void KisMaskedFreehandStrokePainter::drawPainterPath(const QPainterPath &path, const QPen &pen)
0095 {
0096     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0097         data->painter->drawPainterPath(path, pen);
0098     });
0099 }
0100 
0101 void KisMaskedFreehandStrokePainter::drawAndFillPainterPath(const QPainterPath &path, const QPen &pen, const KoColor &customColor)
0102 {
0103     applyToAllPainters([&] (KisFreehandStrokeInfo *data) {
0104         data->painter->setBackgroundColor(customColor);
0105         data->painter->fillPainterPath(path);
0106         data->painter->drawPainterPath(path, pen);
0107     });
0108 }
0109 
0110 std::pair<int, bool> KisMaskedFreehandStrokePainter::doAsynchronousUpdate(QVector<KisRunnableStrokeJobData *> &jobs)
0111 {
0112     KIS_SAFE_ASSERT_RECOVER_NOOP(m_stroke);
0113 
0114     std::pair<int, bool> result =
0115         m_stroke->painter->paintOp()->doAsynchronousUpdate(jobs);
0116 
0117     if (m_mask) {
0118         QVector<KisRunnableStrokeJobData*> maskJobs;
0119         std::pair<int, bool> maskMetrics =
0120             m_mask->painter->paintOp()->doAsynchronousUpdate(maskJobs);
0121 
0122         result.first = std::max(result.first, maskMetrics.first);
0123         result.second = result.second | maskMetrics.second;
0124 
0125         jobs.append(maskJobs);
0126     }
0127 
0128     return result;
0129 }
0130 
0131 bool KisMaskedFreehandStrokePainter::hasDirtyRegion() const
0132 {
0133     KIS_SAFE_ASSERT_RECOVER_NOOP(m_stroke);
0134 
0135     bool result = m_stroke->painter->hasDirtyRegion();
0136 
0137     if (m_mask) {
0138         result |= m_mask->painter->hasDirtyRegion();
0139     }
0140 
0141     return result;
0142 }
0143 
0144 QVector<QRect> KisMaskedFreehandStrokePainter::takeDirtyRegion()
0145 {
0146     KIS_SAFE_ASSERT_RECOVER_NOOP(m_stroke);
0147 
0148     QVector<QRect> result = m_stroke->painter->takeDirtyRegion();
0149 
0150     if (m_mask) {
0151         result += m_mask->painter->takeDirtyRegion();
0152     }
0153 
0154     return result;
0155 }
0156 
0157 bool KisMaskedFreehandStrokePainter::hasMasking() const
0158 {
0159     return m_mask;
0160 }
0161