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 }