Krita Source Code Documentation
Loading...
Searching...
No Matches
KisSharpnessOption.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
3 * SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
8
10#include <kis_paintop.h>
12
14
16namespace kpou = KisPaintOpOptionUtils;
17
18
23
25 : KisCurveOption(data)
26 , m_alignOutlinePixels(data.alignOutlinePixels)
27 , m_softness(data.softness)
28{
29
30}
31
32void KisSharpnessOption::apply(const KisPaintInformation &info, const QPointF &pt, qint32 &x, qint32 &y, qreal &xFraction, qreal &yFraction) const
33{
34 if (isChecked() && m_alignOutlinePixels && strengthValue() > 0.0) {
35 qreal processedSharpness = computeSizeLikeValue(info);
36
37 if (qFuzzyCompare(processedSharpness, 1.0)) {
38 // pen
39 xFraction = 0.0;
40 yFraction = 0.0;
41 x = qRound(pt.x());
42 y = qRound(pt.y());
43 }
44 else {
45 // something in between
46 qint32 xi = qRound(pt.x());
47 qint32 yi = qRound(pt.y());
48
49 qreal xf = processedSharpness * xi + (1.0 - processedSharpness) * pt.x();
50 qreal yf = processedSharpness * yi + (1.0 - processedSharpness) * pt.y();
51
52 KisPaintOp::splitCoordinate(xf, &x, &xFraction);
53 KisPaintOp::splitCoordinate(yf, &y, &yFraction);
54 }
55 } else {
56 // brush
57 KisPaintOp::splitCoordinate(pt.x(), &x, &xFraction);
58 KisPaintOp::splitCoordinate(pt.y(), &y, &yFraction);
59 }
60}
61
63{
64 if (!isChecked()) return;
65 const KoColorSpace * cs = dab->colorSpace();
66
67 // Set all alpha > opaque/2 to opaque, the rest to transparent.
68 // XXX: Using 4/10 as the 1x1 circle brush paints nothing with 0.5.
69 quint8* dabPointer = dab->data();
70 QRect rc = dab->bounds();
71
72 qreal threshold = computeSizeLikeValue(info);
73
74 quint32 pixelSize = dab->pixelSize();
75 int pixelCount = rc.width() * rc.height();
76
77 quint32 tolerance = quint32(OPACITY_OPAQUE_U8 - (threshold * OPACITY_OPAQUE_U8));
78
79 for (int i = 0; i < pixelCount; i++) {
80 quint8 opacity = cs->opacityU8(dabPointer);
81
82 // Check what pixel goes sharp
83 if (opacity > (tolerance) ) {
84 cs->setOpacity(dabPointer, OPACITY_OPAQUE_U8, 1);
85 } else {
86 // keep original value if in soft range
87 if (opacity <= (100 - m_softness) * tolerance / 100) {
88 cs->setOpacity(dabPointer, OPACITY_TRANSPARENT_U8, 1);
89 }
90 }
91 dabPointer += pixelSize;
92 }
93}
94
const quint8 OPACITY_TRANSPARENT_U8
const quint8 OPACITY_OPAQUE_U8
qreal strengthValue() const
bool isChecked() const
qreal computeSizeLikeValue(const KisPaintInformation &info, bool useStrengthValue=true) const
const KoColorSpace * colorSpace() const
void applyThreshold(KisFixedPaintDeviceSP dab, const KisPaintInformation &info)
void apply(const KisPaintInformation &info, const QPointF &pt, qint32 &x, qint32 &y, qreal &xFraction, qreal &yFraction) const
bool alignOutlineToPixels() const
KisSharpnessOption(const KisPropertiesConfiguration *setting)
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
static bool qFuzzyCompare(half p1, half p2)
static void splitCoordinate(qreal coordinate, qint32 *whole, qreal *fraction)