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

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include <kis_global.h>
0008 #include "kis_painting_tweaks.h"
0009 
0010 #include <QPen>
0011 #include <QRegion>
0012 #include <QPainter>
0013 #include <QTransform>
0014 
0015 #include "kis_debug.h"
0016 
0017 
0018 namespace KisPaintingTweaks {
0019 
0020 QRegion safeClipRegion(const QPainter &painter)
0021 {
0022     const QTransform t = painter.transform();
0023 
0024     QRegion region = t.type() <= QTransform::TxScale ?
0025         painter.clipRegion() :
0026         QRegion(painter.clipBoundingRect().toAlignedRect());
0027 
0028     if (region.rectCount() > 1000) {
0029         qWarning() << "WARNING: KisPaintingTweaks::safeClipRegion: too many rectangles in the region!" << ppVar(region.rectCount());
0030         region = QRegion(painter.clipBoundingRect().toAlignedRect());
0031     }
0032 
0033     return region;
0034 }
0035 
0036 QRect safeClipBoundingRect(const QPainter &painter)
0037 {
0038     return painter.clipBoundingRect().toAlignedRect();
0039 }
0040 
0041 void initAntsPen(QPen *antsPen, QPen *outlinePen,
0042                  int antLength, int antSpace)
0043 {
0044     QVector<qreal> antDashPattern;
0045     antDashPattern << antLength << antSpace;
0046 
0047     *antsPen = QPen(Qt::CustomDashLine);
0048     antsPen->setDashPattern(antDashPattern);
0049     antsPen->setCosmetic(true);
0050     antsPen->setColor(Qt::black);
0051 
0052     *outlinePen = QPen(Qt::SolidLine);
0053     outlinePen->setCosmetic(true);
0054     outlinePen->setColor(Qt::white);
0055 }
0056 
0057 PenBrushSaver::PenBrushSaver(QPainter *painter)
0058     : m_painter(painter),
0059       m_pen(painter->pen()),
0060       m_brush(painter->brush())
0061 {
0062 }
0063 
0064 PenBrushSaver::PenBrushSaver(QPainter *painter, const QPen &pen, const QBrush &brush)
0065     : PenBrushSaver(painter)
0066 {
0067     m_painter->setPen(pen);
0068     m_painter->setBrush(brush);
0069 }
0070 
0071 PenBrushSaver::PenBrushSaver(QPainter *painter, const QPair<QPen, QBrush> &pair)
0072     : PenBrushSaver(painter)
0073 {
0074     m_painter->setPen(pair.first);
0075     m_painter->setBrush(pair.second);
0076 }
0077 
0078 PenBrushSaver::PenBrushSaver(QPainter *painter, const QPair<QPen, QBrush> &pair, allow_noop_t)
0079     : m_painter(painter)
0080 {
0081     if (m_painter) {
0082         m_pen = m_painter->pen();
0083         m_brush = m_painter->brush();
0084         m_painter->setPen(pair.first);
0085         m_painter->setBrush(pair.second);
0086     }
0087 }
0088 
0089 PenBrushSaver::~PenBrushSaver()
0090 {
0091     if (m_painter) {
0092         m_painter->setPen(m_pen);
0093         m_painter->setBrush(m_brush);
0094     }
0095 }
0096 
0097 QColor blendColors(const QColor &c1, const QColor &c2, qreal r1)
0098 {
0099     const qreal r2 = 1.0 - r1;
0100 
0101     return QColor::fromRgbF(
0102         c1.redF() * r1 + c2.redF() * r2,
0103         c1.greenF() * r1 + c2.greenF() * r2,
0104         c1.blueF() * r1 + c2.blueF() * r2);
0105 }
0106 
0107 qreal colorDifference(const QColor &c1, const QColor &c2)
0108 {
0109     const qreal dr = c1.redF() - c2.redF();
0110     const qreal dg = c1.greenF() - c2.greenF();
0111     const qreal db = c1.blueF() - c2.blueF();
0112 
0113     return std::sqrt(2 * pow2(dr) + 4 * pow2(dg) + 3 * pow2(db));
0114 }
0115 
0116 void dragColor(QColor *color, const QColor &baseColor, qreal threshold)
0117 {
0118     while (colorDifference(*color, baseColor) < threshold) {
0119 
0120         QColor newColor = *color;
0121 
0122         if (newColor.lightnessF() > baseColor.lightnessF()) {
0123             newColor = newColor.lighter(120);
0124         } else {
0125             newColor = newColor.darker(120);
0126         }
0127 
0128         if (newColor == *color) {
0129             break;
0130         }
0131 
0132         *color = newColor;
0133     }
0134 }
0135 
0136 }