package com.tddinaction.swing.plotmap.view; import java.awt.Color; import java.awt.Point; import java.awt.image.Raster; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.junit.Assert; import com.tddinaction.swing.plotmap.view.Pixel.PixelAssertion; public class Pixels { public static class PixelRangeAssertion { private final Raster raster; private int startX; private int startY; public PixelRangeAssertion(Raster raster) { this.raster = raster; } PixelRangeAssertion between(int x, int y) { this.startX = x; this.startY = y; return this; } PixelAssertion and(final int targetX, final int targetY) { return new PixelAssertion() { class PixelFinder { private final Set<Point> visited; private final Point target; private final Color color; public PixelFinder(Set<Point> visited, Point target, Color color) { this.visited = visited; this.target = target; this.color = color; } public boolean isConnectedTo( List<Point> siblingPoints) { for (Point p : siblingPoints) { if (p.x == targetX && p.y == targetY) { return true; } if (visited.contains(p)) { continue; } visited.add(p); if (Pixel.in(raster).at(p.x, p.y).is( color)) { PixelFinder recursiveFinder = new PixelFinder( visited, target, color); return recursiveFinder .isConnectedTo(Pixels .around(p)); } } return false; } } public void shouldBe(Color color) { Assert.assertTrue("No connecting pixels of " + color + " between (" + startX + "," + startY + ") and (" + targetX + "," + targetY + ")", is(color)); } public boolean is(Color color) { Set<Point> visited = new HashSet<Point>(); visited.add(new Point(startX, startY)); List<Point> siblingPoints = Pixels .around(new Point(startX, startY)); return new PixelFinder(visited, new Point( targetX, targetY), color) .isConnectedTo(siblingPoints); } }; }; } public static PixelRangeAssertion in(final Raster raster) { return new PixelRangeAssertion(raster); } public static List<Point> around(Point point) { List<Point> points = new ArrayList<Point>(); for (int x2 = point.x - 1; x2 <= point.x + 1; x2++) { for (int y2 = point.y - 1; y2 <= point.y + 1; y2++) { if (x2 != point.x || y2 != point.y) { points.add(new Point(x2, y2)); } } } return points; } }