Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_ls_stroke_filter.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <cstdlib>
10
11#include <QBitArray>
12
13#include <resources/KoPattern.h>
14
16
17#include "psd.h"
18
21#include "kis_gaussian_kernel.h"
22
23#include "kis_pixel_selection.h"
24#include "kis_fill_painter.h"
26#include "kis_iterator_ng.h"
28
29#include "kis_psd_layer_style.h"
31
32#include "kis_ls_utils.h"
35#include "krita_utils.h"
37
38
39namespace {
40
41int borderSize(psd_stroke_position position, int size)
42{
43 int border = 1;
44
45 // The need rect border should not depend on the position;
46 // instead it should extend the area all the time. Otherwise
47 // small changes on the borderline will not be propagated to
48 // the inner side of the blob. See bug 429165.
49
50 switch (position) {
53 border = size + 1;
54 break;
56 border = qCeil(0.5 * size) + 1;
57 break;
58 }
59
60 return border;
61}
62
63}
64
65
67 : KisLayerStyleFilter(KoID("lsstroke", i18n("Stroke (style)")))
68{
69}
70
75
77{
78 return new KisLsStrokeFilter(*this);
79}
80
84 const QRect &applyRect,
85 const psd_layer_effects_stroke *config,
86 KisResourcesInterfaceSP resourcesInterface,
88{
89 if (applyRect.isEmpty()) return;
90
91 const QRect needRect = kisGrowRect(applyRect, borderSize(config->position(), config->size()));
92
93 KisSelectionSP baseSelection = blower->knockoutSelectionLazy();
94 KisPixelSelectionSP selection = baseSelection->pixelSelection();
95
97 KisPixelSelectionSP dilatedSelection = s1.selection()->pixelSelection();
98 KisLsUtils::selectionFromAlphaChannel(srcDevice, s1.selection(), needRect);
99
100 {
102 KisPixelSelectionSP erodedSelection = s2.selection()->pixelSelection();
103 erodedSelection->makeCloneFromRough(dilatedSelection, needRect);
104
105 if (config->position() == psd_stroke_outside) {
106 KisGaussianKernel::applyDilate(dilatedSelection, needRect, config->size(), QBitArray(), 0, true);
107 } else if (config->position() == psd_stroke_inside) {
108 KisGaussianKernel::applyErodeU8(erodedSelection, needRect, config->size(), QBitArray(), 0, true);
109 } else if (config->position() == psd_stroke_center) {
110 KisGaussianKernel::applyDilate(dilatedSelection, needRect, 0.5 * config->size(), QBitArray(), 0, true);
111 KisGaussianKernel::applyErodeU8(erodedSelection, needRect, 0.5 * config->size(), QBitArray(), 0, true);
112 }
113
114 KisPainter gc(selection);
115
117 gc.bitBlt(applyRect.topLeft(), dilatedSelection, applyRect);
118
120 gc.bitBlt(applyRect.topLeft(), erodedSelection, applyRect);
121 gc.end();
122 }
123
124 const QString compositeOp = config->blendMode();
125 const quint8 opacityU8 = quint8(qRound(255.0 / 100.0 * config->opacity()));
127 compositeOp,
128 opacityU8,
129 QBitArray(),
130 srcDevice);
131 KisLsUtils::fillOverlayDevice(dstDevice, applyRect, config, resourcesInterface, env);
132}
133
137 const QRect &applyRect,
138 KisPSDLayerStyleSP style,
140{
141 Q_UNUSED(env);
143
144 const psd_layer_effects_stroke *config = style->stroke();
145 if (!KisLsUtils::checkEffectEnabled(config, dst)) return;
146
148 applyStroke(src, dst, blower, applyRect, w.config, style->resourcesInterface(), env);
149}
150
152{
153 const psd_layer_effects_stroke *config = style->stroke();
154 if (!config->effectEnabled()) return rect;
155
157 return kisGrowRect(rect, borderSize(w.config->position(), w.config->size()));
158}
159
161{
162 return neededRect(rect, style, env);
163}
164
QPointF s1
QPointF s2
const QString COMPOSITE_COPY
const QString COMPOSITE_ERASE
static void applyErodeU8(KisPaintDeviceSP device, const QRect &rect, qreal radius, const QBitArray &channelFlags, KoUpdater *progressUpdater, bool createTransaction=false)
static void applyDilate(KisPaintDeviceSP device, const QRect &rect, qreal radius, const QBitArray &channelFlags, KoUpdater *progressUpdater, bool createTransaction=false)
QRect changedRect(const QRect &rect, KisPSDLayerStyleSP style, KisLayerStyleFilterEnvironment *env) const override
void processDirectly(KisPaintDeviceSP src, KisMultipleProjection *dst, KisLayerStyleKnockoutBlower *blower, const QRect &applyRect, KisPSDLayerStyleSP style, KisLayerStyleFilterEnvironment *env) const override
void applyStroke(KisPaintDeviceSP srcDevice, KisMultipleProjection *dst, KisLayerStyleKnockoutBlower *blower, const QRect &applyRect, const psd_layer_effects_stroke *config, KisResourcesInterfaceSP resourcesInterface, KisLayerStyleFilterEnvironment *env) const
KisLayerStyleFilter * clone() const override
KritaUtils::ThresholdMode sourcePlaneOpacityThresholdRequirement(KisPSDLayerStyleSP style) const
QRect neededRect(const QRect &rect, KisPSDLayerStyleSP style, KisLayerStyleFilterEnvironment *env) const override
KisPaintDeviceSP getProjection(const QString &id, const QString &compositeOpId, quint8 opacity, const QBitArray &channelFlags, KisPaintDeviceSP prototype)
void makeCloneFromRough(KisPaintDeviceSP src, const QRect &minimalRect)
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
void setCompositeOpId(const KoCompositeOp *op)
Definition KoID.h:30
qint32 opacity() const
Definition psd.h:281
QString blendMode() const
Definition psd.h:266
bool effectEnabled() const
Definition psd.h:261
qint32 size() const
Definition psd.h:306
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
T kisGrowRect(const T &rect, U offset)
Definition kis_global.h:186
int size(const Forest< T > &forest)
Definition KisForest.h:1232
void fillOverlayDevice(KisPaintDeviceSP fillDevice, const QRect &applyRect, const psd_layer_effects_overlay_base *config, KisResourcesInterfaceSP resourcesInterface, KisLayerStyleFilterEnvironment *env)
bool checkEffectEnabled(const psd_layer_effects_shadow_base *config, KisMultipleProjection *dst)
void selectionFromAlphaChannel(KisPaintDeviceSP srcDevice, KisSelectionSP dstSelection, const QRect &srcRect)
psd_stroke_position
Definition psd.h:121
@ psd_stroke_outside
Definition psd.h:121
@ psd_stroke_inside
Definition psd.h:121
@ psd_stroke_center
Definition psd.h:121
KisPixelSelectionSP pixelSelection
psd_stroke_position position() const
Definition psd.h:1280