package com.kreative.paint.tool; import java.awt.Cursor; import java.awt.Image; import java.awt.event.KeyEvent; import com.kreative.paint.document.tile.PaintSurface; import com.kreative.paint.material.sprite.Sprite; public class SmudgeTool extends AbstractPaintTool implements ToolOptions.Brushes { private static final int K = 0xFF000000; private static final Image icon = ToolUtilities.makeIcon( 16, 16, new int[] { 0,0,0,0,0,0,K,0,0,0,0,0,0,K,0,0, 0,0,0,0,0,K,0,0,0,0,0,0,0,K,0,0, 0,0,0,0,K,0,0,0,0,0,0,0,0,K,0,0, 0,0,0,K,0,K,0,0,0,0,0,0,0,0,K,0, 0,0,K,0,K,0,K,0,0,0,0,0,0,0,K,0, 0,0,K,K,0,K,0,K,0,0,0,0,0,0,K,0, 0,0,K,0,K,0,K,0,0,0,K,0,0,0,K,0, 0,0,K,K,0,K,0,0,0,K,K,0,0,0,K,0, 0,0,0,K,0,K,0,0,K,0,K,0,0,0,K,0, 0,0,0,K,K,0,0,K,K,K,0,0,0,K,0,0, 0,0,0,0,K,0,0,K,0,0,0,0,K,0,0,0, 0,0,0,K,0,0,K,K,K,K,K,K,0,0,0,0, 0,0,0,K,0,0,K,0,0,0,0,0,0,0,0,0, 0,0,K,0,0,K,0,0,0,0,0,0,0,0,0,0, 0,K,0,0,K,0,0,0,0,0,0,0,0,0,0,0, 0,K,K,K,0,0,0,0,0,0,0,0,0,0,0,0, } ); public ToolCategory getCategory() { return ToolCategory.MISC; } protected Image getBWIcon() { return icon; } private int w, h, hx, hy; private int[] rgb; private void unmakeBrush(Sprite brush) { w = brush.getWidth(); h = brush.getHeight(); hx = brush.getHotspotX(); hy = brush.getHotspotY(); rgb = brush.getPreparedPixels(); } public boolean mousePressed(ToolEvent e) { unmakeBrush(e.tc().getBrush()); e.beginTransaction(getName()); float x = e.getX() - hx; float y = e.getY() - hy; blurRGB(e.getPaintSurface(), (int)x, (int)y, w, h, rgb); return true; } public boolean mouseDragged(ToolEvent e) { float lastX = e.getPreviousX(); float lastY = e.getPreviousY(); float x = e.getX(); float y = e.getY(); drag(e.getPaintSurface(), lastX, lastY, x, y); return true; } public boolean mouseReleased(ToolEvent e) { float lastX = e.getPreviousX(); float lastY = e.getPreviousY(); float x = e.getX(); float y = e.getY(); drag(e.getPaintSurface(), lastX, lastY, x, y); e.commitTransaction(); return true; } private void drag(PaintSurface srf, float sx, float sy, float dx, float dy) { int m = (int)Math.ceil(Math.max(Math.abs(dx-sx),Math.abs(dy-sy))); for (int i = 1; i <= m; i++) { float x = sx + ((dx-sx)*i)/m - hx; float y = sy + ((dy-sy)*i)/m - hy; blurRGB(srf, (int)x, (int)y, w, h, rgb); } } private void blurRGB(PaintSurface srf, int x, int y, int w, int h, int[] argb) { int[] irgb = new int[(w+2)*(h+2)]; int[] orgb = new int[(w+2)*(h+2)]; srf.getRGB(x-1, y-1, w+2, h+2, irgb, 0, w+2); srf.getRGB(x-1, y-1, w+2, h+2, orgb, 0, w+2); for (int yy = 0, ay = 0, iy = w+3; yy < h; yy++, ay += w, iy += w+2) { for (int xx = 0, ax = ay, ix = iy; xx < w; xx++, ax++, ix++) { int c = argb[ax]; if (((c & 0xFF000000) < 0) && ((c & 0xFF0000) < 0x800000) && ((c & 0xFF00) < 0x8000) && ((c & 0xFF) < 0x80)) { int c0 = irgb[ix]; int c1 = irgb[ix-1]; int c2 = irgb[ix+1]; int c3 = irgb[ix-w-2]; int c4 = irgb[ix+w+2]; int aa = (((c0>>>24)&0xFF)*4+((c1>>>24)&0xFF)+((c2>>>24)&0xFF)+((c3>>>24)&0xFF)+((c4>>>24)&0xFF))/8; int ra = (((c0>>>16)&0xFF)*4+((c1>>>16)&0xFF)+((c2>>>16)&0xFF)+((c3>>>16)&0xFF)+((c4>>>16)&0xFF))/8; int ga = (((c0>>>8)&0xFF)*4+((c1>>>8)&0xFF)+((c2>>>8)&0xFF)+((c3>>>8)&0xFF)+((c4>>>8)&0xFF))/8; int ba = ((c0&0xFF)*4+(c1&0xFF)+(c2&0xFF)+(c3&0xFF)+(c4&0xFF))/8; int ca = ((aa&0xFF)<<24) | ((ra&0xFF)<<16) | ((ga&0xFF)<<8) | (ba&0xFF); orgb[ix] = ca; } } } srf.setRGB(x-1, y-1, w+2, h+2, orgb, 0, w+2); } public boolean keyPressed(ToolEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: case KeyEvent.VK_DOWN: e.tc().prevBrush(); break; case KeyEvent.VK_RIGHT: case KeyEvent.VK_UP: e.tc().nextBrush(); break; } return false; } public Cursor getCursor(ToolEvent e) { return e.tc().getBrush().getPreparedCursor(true); } public boolean shiftConstrainsCoordinates() { return true; } public boolean doubleClickForOptions() { return true; } }