Skip to content

Commit

Permalink
Erase color behavioral improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
defano committed Jul 20, 2018
1 parent 7b39a7c commit 375bfad
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 18 deletions.
5 changes: 3 additions & 2 deletions src/main/java/com/defano/jmonet/tools/PencilTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ public PencilTool() {
protected void startPath(Scratch scratch, Stroke stroke, Paint fillPaint, Point initialPoint) {
Color pixel = new Color(getCanvas().getCanvasImage().getRGB(initialPoint.x, initialPoint.y), true);

if (getErasePaint() == null) {
if (getEraseColor() == null) {
isErasing = pixel.getAlpha() >= 128;
} else {
isErasing = (pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3 <= 128;
Color eraseColor = getEraseColor();
isErasing = eraseColor.getRed() != pixel.getRed() || eraseColor.getBlue() != pixel.getBlue() || eraseColor.getGreen() != pixel.getGreen();
}

renderStroke(scratch, fillPaint, new Line2D.Float(initialPoint, initialPoint));
Expand Down
16 changes: 8 additions & 8 deletions src/main/java/com/defano/jmonet/tools/builder/PaintTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public abstract class PaintTool implements SurfaceInteractionObserver, CanvasCom
private Observable<Stroke> strokeObservable = BehaviorSubject.createDefault(new BasicStroke(2));
private Observable<Paint> strokePaintObservable = BehaviorSubject.createDefault(Color.BLACK);
private Observable<Optional<Paint>> fillPaintObservable = BehaviorSubject.createDefault(Optional.empty());
private Observable<Optional<Paint>> erasePaintObservable = BehaviorSubject.createDefault(Optional.empty());
private Observable<Optional<Color>> eraseColorObservable = BehaviorSubject.createDefault(Optional.empty());
private Observable<Integer> shapeSidesObservable = BehaviorSubject.createDefault(5);
private Observable<Font> fontObservable = BehaviorSubject.createDefault(new Font("Courier", Font.PLAIN, 14));
private Observable<Color> fontColorObservable = BehaviorSubject.createDefault(Color.BLACK);
Expand Down Expand Up @@ -145,8 +145,8 @@ void setFillPaintObservable(Observable<Optional<Paint>> fillPaintObservable) {
this.fillPaintObservable = fillPaintObservable;
}

void setErasePaintObservable(Observable<Optional<Paint>> erasePaintObservable) {
this.erasePaintObservable = erasePaintObservable;
void setEraseColorObservable(Observable<Optional<Color>> eraseColorObservable) {
this.eraseColorObservable = eraseColorObservable;
}

void setIntensityObservable(Observable<Double> intensityObservable) {
Expand Down Expand Up @@ -183,8 +183,8 @@ public Paint getStrokePaint() {
return strokePaintObservable.blockingFirst();
}

public Paint getErasePaint() {
return erasePaintObservable.blockingFirst().orElse(null);
public Color getEraseColor() {
return eraseColorObservable.blockingFirst().orElse(null);
}

public Color getFontColor() {
Expand All @@ -195,8 +195,8 @@ public Observable<Optional<Paint>> getFillPaintObservable() {
return fillPaintObservable;
}

public Observable<Optional<Paint>> getErasePaintObservable() {
return erasePaintObservable;
public Observable<Optional<Color>> getEraseColorObservable() {
return eraseColorObservable;
}

public Observable<Stroke> getStrokeObservable() {
Expand Down Expand Up @@ -297,7 +297,7 @@ public void applyRenderingHints(Graphics2D g2d) {
}

protected void erase(Scratch scratch, Shape shape, Stroke stroke) {
Paint erasePaint = getErasePaint();
Paint erasePaint = getEraseColor();

Graphics2D g = erasePaint == null ?
scratch.getRemoveScratchGraphics(this, stroke, shape) :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class PaintToolBuilder {
private Observable<Stroke> strokeObservable;
private Observable<Paint> strokePaintObservable;
private Observable<Optional<Paint>> fillPaintObservable = BehaviorSubject.createDefault(Optional.empty());
private Observable<Optional<Paint>> erasePaintObservable = BehaviorSubject.createDefault(Optional.empty());
private Observable<Optional<Color>> erasePaintObservable = BehaviorSubject.createDefault(Optional.empty());
private Observable<Integer> shapeSidesObservable;
private Observable<Font> fontObservable;
private Observable<Color> fontColorObservable;
Expand Down Expand Up @@ -217,26 +217,38 @@ public PaintToolBuilder withFillPaintObservable(Observable<Optional<Paint>> pain
}

/**
* Specifies the paint (color) that pixels are changed to when they're erased. Specify null for fully-transparent
* (default behavior).
* Specifies the color that pixels are changed to when they're erased (via the eraser or pencil tools). Specify null
* for fully-transparent (default behavior).
* <p>
* Note that this color does not affect the color of "void" pixels that are left when selecting a region and moving
* or deleting it. Further note that the default boundary behavior associated with
* {@link com.defano.jmonet.tools.FillTool} looks for fully transparent pixels, thus, when changing the erase color
* to a non-null value, erased pixels will not be filled by this tool (install a custom
* {@link com.defano.jmonet.algo.fill.BoundaryFunction} if such behavior is desired).
*
* @param paint The color that erased pixels should become; null means fully transparent.
* @return The PaintToolBuilder
*/
public PaintToolBuilder withErasePaint(Paint paint) {
public PaintToolBuilder withEraseColor(Color paint) {
this.erasePaintObservable = BehaviorSubject.createDefault(paint == null ? Optional.empty() : Optional.of(paint));
return this;
}

/**
* Specifies an observable provider of the paint that pixels are changed to when they're erased. Specify null for
* fully-transparent (default behavior).
* Specifies an observable provider of the paint that pixels are changed to when they're erased (via the eraser or
* pencil tools). Specify {@link Optional#empty()} for fully-transparent (default behavior).
* <p>
* Note that this color does not affect the color of "void" pixels that are left when selecting a region and moving
* or deleting it. Further note that the default boundary behavior associated with
* {@link com.defano.jmonet.tools.FillTool} looks for fully transparent pixels, thus, when changing the erase color
* to a non-null value, erased pixels will not be filled by this tool (install a custom
* {@link com.defano.jmonet.algo.fill.BoundaryFunction} if such behavior is desired).
*
* @param erasePaintObservable Observable providing the color that erased pixels should become; null means fully
* transparent.
* @return The PaintToolBuilder
*/
public PaintToolBuilder withErasePaintObservable(Observable<Optional<Paint>> erasePaintObservable) {
public PaintToolBuilder withEraseColorObservable(Observable<Optional<Color>> erasePaintObservable) {
this.erasePaintObservable = erasePaintObservable;
return this;
}
Expand Down Expand Up @@ -364,7 +376,7 @@ public PaintTool build() {
}

if (erasePaintObservable != null) {
selectedTool.setErasePaintObservable(erasePaintObservable);
selectedTool.setEraseColorObservable(erasePaintObservable);
}

if (shapeSidesObservable != null) {
Expand Down

0 comments on commit 375bfad

Please sign in to comment.