/*
* Copyright 2016 Laszlo Balazs-Csiki
*
* This file is part of Pixelitor. Pixelitor is free software: you
* can redistribute it and/or modify it under the terms of the GNU
* General Public License, version 3 as published by the Free
* Software Foundation.
*
* Pixelitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Pixelitor. If not, see <http://www.gnu.org/licenses/>.
*/
package pixelitor.tools.brushes;
import pixelitor.colors.FgBgColors;
import pixelitor.utils.debug.DebugNode;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
/**
* The brush used by the Smudge Tool
*/
public class SmudgeBrush extends CopyBrush {
/**
* The smudge brush samples the source image at
* the last mouse coordinates and puts the pixels to
* the current coordinates.
*/
private double lastX;
private double lastY;
private float strength;
private boolean firstUsageInStroke = true;
/**
* If true, we start with the foreground color
*/
private boolean fingerPainting = false;
public SmudgeBrush(int radius, CopyBrushType type) {
super(radius, type, new FixedDistanceSpacing(1.0));
}
public void setSource(BufferedImage sourceImage, double srcX, double srcY, float strength) {
this.sourceImage = sourceImage;
lastX = srcX;
lastY = srcY;
this.strength = strength;
firstUsageInStroke = true;
}
@Override
void setupBrushStamp(double x, double y) {
Graphics2D g = brushImage.createGraphics();
type.beforeDrawImage(g);
if (firstUsageInStroke && fingerPainting) {
g.setColor(FgBgColors.getFG());
g.fillRect(0, 0, diameter, diameter);
} else {
// samples the source image at lastX, lastY into the brush image
g.drawImage(sourceImage,
AffineTransform.getTranslateInstance(
-lastX + radius,
-lastY + radius), null);
}
type.afterDrawImage(g);
g.dispose();
firstUsageInStroke = false;
super.debugImage();
}
@Override
public void putDab(double x, double y, double theta) {
AffineTransform transform = AffineTransform.getTranslateInstance(
x - radius,
y - radius
);
// does not handle transparency
targetG.setComposite(AlphaComposite.SrcAtop.derive(strength));
// targetG.setComposite(BlendComposite.CrossFade.derive(strength));
targetG.drawImage(brushImage, transform, null);
lastX = x;
lastY = y;
updateComp((int) x, (int) y);
}
public void setFingerPainting(boolean fingerPainting) {
this.fingerPainting = fingerPainting;
}
@Override
public DebugNode getDebugNode() {
DebugNode node = super.getDebugNode();
node.addDoubleChild("lastX", lastX);
node.addDoubleChild("lastY", lastY);
node.addFloatChild("strength", strength);
node.addBooleanChild("firstUsageInStroke", firstUsageInStroke);
return node;
}
}