Commit 54735126 authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Added support for choosing the composite op for Indirect Painting mode

Now the KisPainOpSettings-based class is allowed to choose which composite
op should be use for indirect painting mode. This is used by duplicate op,
which resets the op to COMPOSITE_COPY to store a real copy of the layer on
a temporary paint device.

BUG:322184
parent ad290d57
......@@ -26,6 +26,7 @@
#include <KoColor.h>
#include <KoColorSpace.h>
#include <KoColorSpaceRegistry.h>
#include <KoCompositeOpRegistry.h>
#include <KoViewConverter.h>
#include "kis_node.h"
......@@ -140,6 +141,10 @@ bool KisPaintOpSettings::isLoadable()
return isValid();
}
QString KisPaintOpSettings::indirectPaintingCompositeOp() const {
return COMPOSITE_ALPHA_DARKEN;
}
QPainterPath KisPaintOpSettings::brushOutline(const QPointF& pos, OutlineMode mode, qreal scale, qreal rotation) const
{
QPainterPath path;
......
......@@ -99,6 +99,13 @@ public:
return true;
}
/**
* @return the composite op it to which the indirect painting device
* should be initialized to. This is used by duplicate op to reset
* the composite op to COMPOSITE_COPY
*/
virtual QString indirectPaintingCompositeOp() const;
/**
* Whether this paintop wants to deposit paint even when not moving, i.e. the
* tool needs to activate its timer.
......
......@@ -17,11 +17,13 @@
*/
#include "kis_stroke_strategy.h"
#include <KoCompositeOpRegistry.h>
KisStrokeStrategy::KisStrokeStrategy(QString id, QString name)
: m_exclusive(false),
m_needsIndirectPainting(false),
m_indirectPaintingCompositeOp(COMPOSITE_ALPHA_DARKEN),
m_id(id),
m_name(name)
{
......@@ -77,6 +79,11 @@ bool KisStrokeStrategy::needsIndirectPainting() const
return m_needsIndirectPainting;
}
QString KisStrokeStrategy::indirectPaintingCompositeOp() const
{
return m_indirectPaintingCompositeOp;
}
QString KisStrokeStrategy::id() const
{
return m_id;
......@@ -96,3 +103,8 @@ void KisStrokeStrategy::setNeedsIndirectPainting(bool value)
{
m_needsIndirectPainting = value;
}
void KisStrokeStrategy::setIndirectPaintingCompositeOp(const QString &id)
{
m_indirectPaintingCompositeOp = id;
}
......@@ -43,6 +43,7 @@ public:
bool isExclusive() const;
bool needsIndirectPainting() const;
QString indirectPaintingCompositeOp() const;
QString id() const;
QString name() const;
......@@ -68,10 +69,12 @@ protected:
void setExclusive(bool value);
void setNeedsIndirectPainting(bool value);
void setIndirectPaintingCompositeOp(const QString &id);
private:
bool m_exclusive;
bool m_needsIndirectPainting;
QString m_indirectPaintingCompositeOp;
QString m_id;
QString m_name;
......
......@@ -112,22 +112,22 @@ qreal KisDuplicateOp::minimizeEnergy(const qreal* m, qreal* sol, int w, int h)
KisSpacingInformation KisDuplicateOp::paintAt(const KisPaintInformation& info)
{
if (!painter()) return 1.0;
if (!m_duplicateStartIsSet) {
m_duplicateStartIsSet = true;
m_duplicateStart = info.pos();
}
if (!source()) return 1.0;
if (!painter()->device()) return 1.0;
KisBrushSP brush = m_brush;
if (!brush)
return 1.0;
if (! brush->canPaintFor(info))
if (!brush->canPaintFor(info))
return 1.0;
if (!m_duplicateStartIsSet) {
m_duplicateStartIsSet = true;
m_duplicateStart = info.pos();
}
KisPaintDeviceSP realSourceDevice = settings->node()->paintDevice();
qreal scale = m_sizeOption.apply(info);
if (checkSizeTooSmall(scale)) return KisSpacingInformation();
......@@ -193,7 +193,7 @@ KisSpacingInformation KisDuplicateOp::paintAt(const KisPaintInformation& info)
QPointF translat = duplicateStartPositionT - positionStartPaintingT;
KisRectIteratorSP dstIt = m_srcdev->createRectIteratorNG(0, 0, sw, sh);
KisRandomSubAccessorSP srcAcc = source()->createRandomSubAccessor();
KisRandomSubAccessorSP srcAcc = realSourceDevice->createRandomSubAccessor();
//Action
do {
QPointF p = KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, QPointF(dstIt->x() + x, dstIt->y() + y)) + translat);
......@@ -205,7 +205,7 @@ KisSpacingInformation KisDuplicateOp::paintAt(const KisPaintInformation& info)
} else {
KisPainter copyPainter(m_srcdev);
copyPainter.setCompositeOp(COMPOSITE_COPY);
copyPainter.bitBltOldData(0, 0, source(), srcPoint.x(), srcPoint.y(), sw, sh);
copyPainter.bitBltOldData(0, 0, realSourceDevice, srcPoint.x(), srcPoint.y(), sw, sh);
copyPainter.end();
}
......@@ -216,9 +216,9 @@ KisSpacingInformation KisDuplicateOp::paintAt(const KisPaintInformation& info)
quint16 tmpData[4];
qreal* matrix = new qreal[ 3 * sw * sh ];
// First divide
const KoColorSpace* srcCs = source()->colorSpace();
const KoColorSpace* tmpCs = source()->colorSpace();
KisHLineConstIteratorSP srcIt = source()->createHLineConstIteratorNG(x, y, sw);
const KoColorSpace* srcCs = realSourceDevice->colorSpace();
const KoColorSpace* tmpCs = m_srcdev->colorSpace();
KisHLineConstIteratorSP srcIt = realSourceDevice->createHLineConstIteratorNG(x, y, sw);
KisHLineIteratorSP tmpIt = m_srcdev->createHLineIteratorNG(0, 0, sw);
qreal* matrixIt = &matrix[0];
for (int j = 0; j < sh; j++) {
......@@ -255,7 +255,7 @@ KisSpacingInformation KisDuplicateOp::paintAt(const KisPaintInformation& info)
}
// Finaly multiply
KisHLineIteratorSP srcIt2 = source()->createHLineIteratorNG(x, y, sw);
KisHLineIteratorSP srcIt2 = realSourceDevice->createHLineIteratorNG(x, y, sw);
KisHLineIteratorSP tmpIt2 = m_srcdev->createHLineIteratorNG(0, 0, sw);
matrixIt = &matrix[0];
for (int j = 0; j < sh; j++) {
......
......@@ -28,6 +28,7 @@
#include <QDomDocument>
#include <KoPointerEvent.h>
#include <KoCompositeOpRegistry.h>
#include <kis_image.h>
#include <kis_brush_option_widget.h>
......@@ -50,9 +51,13 @@ KisDuplicateOpSettings::~KisDuplicateOpSettings()
bool KisDuplicateOpSettings::paintIncremental()
{
return true;
return false;
}
QString KisDuplicateOpSettings::indirectPaintingCompositeOp() const
{
return COMPOSITE_COPY;
}
QPointF KisDuplicateOpSettings::offset() const
{
......
......@@ -41,6 +41,7 @@ public:
virtual ~KisDuplicateOpSettings();
bool paintIncremental();
QString indirectPaintingCompositeOp() const;
QPointF offset() const;
QPointF position() const;
......
......@@ -78,6 +78,7 @@ KisDynaPaintOp::~KisDynaPaintOp()
void KisDynaPaintOp::paintLine(const KisPaintInformation &pi1, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance)
{
Q_UNUSED(currentDistance);
Q_UNUSED(pi2);
if (!painter()) return;
if (!m_dab) {
......
......@@ -19,6 +19,7 @@
#include "freehand_stroke_test.h"
#include <qtest_kde.h>
#include <KoCompositeOpRegistry.h>
#include "stroke_testing_utils.h"
#include "strokes/freehand_stroke.h"
#include "kis_resources_snapshot.h"
......@@ -46,7 +47,7 @@ protected:
new FreehandStrokeStrategy::PainterInfo(painter,
new KisDistanceInformation());
return new FreehandStrokeStrategy(indirectPainting, resources, m_painterInfo, QLatin1String("Freehand Stroke"));
return new FreehandStrokeStrategy(indirectPainting, COMPOSITE_ALPHA_DARKEN, resources, m_painterInfo, QLatin1String("Freehand Stroke"));
}
void addPaintingJobs(KisImageWSP image, KisResourcesSnapshotSP resources, KisPainter *painter) {
......
......@@ -46,10 +46,10 @@ KisFigurePaintingToolHelper::KisFigurePaintingToolHelper(const QString &name,
new PainterInfo(new KisPainter(),
new KisDistanceInformation());
bool indirectPainting = m_resources->needsIndirectPainting();
KisStrokeStrategy *stroke =
new FreehandStrokeStrategy(indirectPainting, m_resources, m_painterInfo, name);
new FreehandStrokeStrategy(m_resources->needsIndirectPainting(),
m_resources->indirectPaintingCompositeOp(),
m_resources, m_painterInfo, name);
m_strokeId = m_strokesFacade->startStroke(stroke);
}
......
......@@ -206,6 +206,11 @@ bool KisResourcesSnapshot::needsIndirectPainting() const
return !m_d->currentPaintOpPreset->settings()->paintIncremental();
}
QString KisResourcesSnapshot::indirectPaintingCompositeOp() const
{
return m_d->currentPaintOpPreset->settings()->indirectPaintingCompositeOp();
}
bool KisResourcesSnapshot::needsAirbrushing() const
{
return m_d->currentPaintOpPreset->settings()->isAirbrushing();
......
......@@ -51,6 +51,7 @@ public:
KisNodeSP currentNode() const;
KisImageWSP image() const;
bool needsIndirectPainting() const;
QString indirectPaintingCompositeOp() const;
bool needsAirbrushing() const;
int airbrushingRate() const;
......
......@@ -126,15 +126,14 @@ void KisToolFreehandHelper::initPaint(KoPointerEvent *event,
m_d->resources->setCurrentNode(overrideNode);
}
bool indirectPainting = m_d->resources->needsIndirectPainting();
if(m_d->recordingAdapter) {
m_d->recordingAdapter->startStroke(image, m_d->resources);
}
KisStrokeStrategy *stroke =
new FreehandStrokeStrategy(indirectPainting,
m_d->resources, m_d->painterInfos, i18n("Freehand Stroke"));
new FreehandStrokeStrategy(m_d->resources->needsIndirectPainting(),
m_d->resources->indirectPaintingCompositeOp(),
m_d->resources, m_d->painterInfos, i18n("Freehand Stroke"));
m_d->strokeId = m_d->strokesFacade->startStroke(stroke);
......
......@@ -26,28 +26,32 @@
FreehandStrokeStrategy::FreehandStrokeStrategy(bool needsIndirectPainting,
const QString &indirectPaintingCompositeOp,
KisResourcesSnapshotSP resources,
PainterInfo *painterInfo,
const QString &name)
: KisPainterBasedStrokeStrategy("FREEHAND_STROKE", name,
resources, painterInfo)
{
init(needsIndirectPainting);
init(needsIndirectPainting, indirectPaintingCompositeOp);
}
FreehandStrokeStrategy::FreehandStrokeStrategy(bool needsIndirectPainting,
const QString &indirectPaintingCompositeOp,
KisResourcesSnapshotSP resources,
QVector<PainterInfo*> painterInfos,
const QString &name)
: KisPainterBasedStrokeStrategy("FREEHAND_STROKE", name,
resources, painterInfos)
{
init(needsIndirectPainting);
init(needsIndirectPainting, indirectPaintingCompositeOp);
}
void FreehandStrokeStrategy::init(bool needsIndirectPainting)
void FreehandStrokeStrategy::init(bool needsIndirectPainting,
const QString &indirectPaintingCompositeOp)
{
setNeedsIndirectPainting(needsIndirectPainting);
setIndirectPaintingCompositeOp(indirectPaintingCompositeOp);
enableJob(KisSimpleStrokeStrategy::JOB_DOSTROKE);
}
......
......@@ -106,11 +106,13 @@ public:
public:
FreehandStrokeStrategy(bool needsIndirectPainting,
const QString &indirectPaintingCompositeOp,
KisResourcesSnapshotSP resources,
PainterInfo *painterInfo,
const QString &name);
FreehandStrokeStrategy(bool needsIndirectPainting,
const QString &indirectPaintingCompositeOp,
KisResourcesSnapshotSP resources,
QVector<PainterInfo*> painterInfos,
const QString &name);
......@@ -118,7 +120,7 @@ public:
void doStrokeCallback(KisStrokeJobData *data);
private:
void init(bool needsIndirectPainting);
void init(bool needsIndirectPainting, const QString &indirectPaintingCompositeOp);
};
#endif /* __FREEHAND_STROKE_H */
......@@ -83,7 +83,8 @@ KisSelectionSP KisPainterBasedStrokeStrategy::activeSelection()
void KisPainterBasedStrokeStrategy::initPainters(KisPaintDeviceSP targetDevice,
KisSelectionSP selection,
bool hasIndirectPainting)
bool hasIndirectPainting,
const QString &indirectPaintingCompositeOp)
{
foreach(PainterInfo *info, m_painterInfos) {
KisPainter *painter = info->painter;
......@@ -92,7 +93,7 @@ void KisPainterBasedStrokeStrategy::initPainters(KisPaintDeviceSP targetDevice,
m_resources->setupPainter(painter);
if(hasIndirectPainting) {
painter->setCompositeOp(targetDevice->colorSpace()->compositeOp(COMPOSITE_ALPHA_DARKEN));
painter->setCompositeOp(targetDevice->colorSpace()->compositeOp(indirectPaintingCompositeOp));
painter->setOpacity(OPACITY_OPAQUE_U8);
painter->setChannelFlags(QBitArray());
}
......@@ -146,7 +147,7 @@ void KisPainterBasedStrokeStrategy::initStrokeCallback()
m_transaction = new KisTransaction(name(), targetDevice);
initPainters(targetDevice, selection, hasIndirectPainting);
initPainters(targetDevice, selection, hasIndirectPainting, indirectPaintingCompositeOp());
m_targetDevice = targetDevice;
m_activeSelection = selection;
......
......@@ -68,7 +68,8 @@ private:
void init();
void initPainters(KisPaintDeviceSP targetDevice,
KisSelectionSP selection,
bool hasIndirectPainting);
bool hasIndirectPainting,
const QString &indirectPaintingCompositeOp);
void deletePainters();
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment