Index: /trunk/src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 10805)
+++ /trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 10806)
@@ -8,7 +8,9 @@
 import java.text.MessageFormat;
 import java.util.Objects;
+import java.util.function.Consumer;
 
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.BBox;
+import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 
@@ -399,10 +401,14 @@
      */
     public Rectangle2D.Double asRect() {
-        double w = maxLon-minLon + (crosses180thMeridian() ? 360.0 : 0.0);
+        double w = getWidth();
         return new Rectangle2D.Double(minLon, minLat, w, maxLat-minLat);
     }
 
+    private double getWidth() {
+        return maxLon-minLon + (crosses180thMeridian() ? 360.0 : 0.0);
+    }
+
     public double getArea() {
-        double w = maxLon-minLon + (crosses180thMeridian() ? 360.0 : 0.0);
+        double w = getWidth();
         return w * (maxLat - minLat);
     }
@@ -440,4 +446,31 @@
         minLon = LatLon.toIntervalLon(minLon);
         maxLon = LatLon.toIntervalLon(maxLon);
+    }
+
+    /**
+     * Visit points along the edge of this bounds instance.
+     * @param projection The projection that should be used to determine how often the edge should be split along a given corner.
+     * @param visitor A function to call for the points on the edge.
+     * @since 10806
+     */
+    public void visitEdge(Projection projection, Consumer<LatLon> visitor) {
+        double width = getWidth();
+        double height = maxLat - minLat;
+        //TODO: Use projection to see if there is any need for doing this along each axis.
+        int splitX = Math.max((int) width / 10, 10);
+        int splitY = Math.max((int) height / 10, 10);
+
+        for (int step = 0; step < splitX; step++) {
+            visitor.accept(new LatLon(minLat, minLon + width * step / splitX));
+        }
+        for (int step = 0; step < splitY; step++) {
+            visitor.accept(new LatLon(minLat + height * step / splitY, maxLon));
+        }
+        for (int step = 0; step < splitX; step++) {
+            visitor.accept(new LatLon(maxLat, maxLon - width * step / splitX));
+        }
+        for (int step = 0; step < splitY; step++) {
+            visitor.accept(new LatLon(maxLat - height * step / splitY, minLon));
+        }
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 10805)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 10806)
@@ -54,6 +54,5 @@
     public void visit(Bounds b) {
         if (b != null) {
-            visit(b.getMin());
-            visit(b.getMax());
+            b.visitEdge(Main.getProjection(), this::visit);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 10805)
+++ /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 10806)
@@ -18,5 +18,4 @@
 import java.awt.event.MouseMotionListener;
 import java.awt.geom.Area;
-import java.awt.geom.GeneralPath;
 import java.awt.image.BufferedImage;
 import java.beans.PropertyChangeEvent;
@@ -46,5 +45,4 @@
 import org.openstreetmap.josm.data.ViewportData;
 import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -974,33 +972,4 @@
         tempG.setColor(Color.WHITE);
         Bounds b = getProjection().getWorldBoundsLatLon();
-        double lat = b.getMinLat();
-        double lon = b.getMinLon();
-
-        Point p = getPoint(b.getMin());
-
-        GeneralPath path = new GeneralPath();
-
-        double d = 1.0;
-        path.moveTo(p.x, p.y);
-        double max = b.getMax().lat();
-        for (; lat <= max; lat += d) {
-            p = getPoint(new LatLon(lat >= max ? max : lat, lon));
-            path.lineTo(p.x, p.y);
-        }
-        lat = max; max = b.getMax().lon();
-        for (; lon <= max; lon += d) {
-            p = getPoint(new LatLon(lat, lon >= max ? max : lon));
-            path.lineTo(p.x, p.y);
-        }
-        lon = max; max = b.getMinLat();
-        for (; lat >= max; lat -= d) {
-            p = getPoint(new LatLon(lat <= max ? max : lat, lon));
-            path.lineTo(p.x, p.y);
-        }
-        lat = max; max = b.getMinLon();
-        for (; lon >= max; lon -= d) {
-            p = getPoint(new LatLon(lat, lon <= max ? max : lon));
-            path.lineTo(p.x, p.y);
-        }
 
         int w = getWidth();
@@ -1008,5 +977,5 @@
 
         // Work around OpenJDK having problems when drawing out of bounds
-        final Area border = new Area(path);
+        final Area border = getState().getArea(b);
         // Make the viewport 1px larger in every direction to prevent an
         // additional 1px border when zooming in
Index: /trunk/src/org/openstreetmap/josm/gui/MapViewState.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 10805)
+++ /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 10806)
@@ -6,4 +6,6 @@
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.Path2D;
 import java.awt.geom.Point2D;
 import java.awt.geom.Point2D.Double;
@@ -215,4 +217,18 @@
     }
 
+    public Area getArea(Bounds bounds) {
+        Path2D area = new Path2D.Double();
+        bounds.visitEdge(getProjection(), latlon -> {
+            MapViewPoint point = getPointFor(latlon);
+            if (area.getCurrentPoint() == null) {
+                area.moveTo(point.getInViewX(), point.getInViewY());
+            } else {
+                area.lineTo(point.getInViewX(), point.getInViewY());
+            }
+        });
+        area.closePath();
+        return new Area(area);
+    }
+
     /**
      * Creates a new state that is the same as the current state except for that it is using a new center.
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 10805)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 10806)
@@ -13,9 +13,9 @@
 import java.awt.GraphicsEnvironment;
 import java.awt.GridBagLayout;
-import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.TexturePaint;
 import java.awt.event.ActionEvent;
 import java.awt.geom.Area;
+import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.io.File;
@@ -52,4 +52,5 @@
 import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.conflict.ConflictCollection;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
@@ -82,4 +83,5 @@
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
@@ -111,4 +113,5 @@
  */
 public class OsmDataLayer extends AbstractModifiableLayer implements Listener, SelectionChangedListener {
+    private static final int HATCHED_SIZE = 15;
     /** Property used to know if this layer has to be saved on disk */
     public static final String REQUIRES_SAVE_TO_DISK_PROP = OsmDataLayer.class.getName() + ".requiresSaveToDisk";
@@ -304,7 +307,7 @@
 
     /**
-     * a paint texture for non-downloaded area
-     */
-    private static volatile TexturePaint hatched;
+     * a texture for non-downloaded area
+     */
+    private static volatile BufferedImage hatched;
 
     static {
@@ -332,15 +335,14 @@
      */
     public static void createHatchTexture() {
-        BufferedImage bi = new BufferedImage(15, 15, BufferedImage.TYPE_INT_ARGB);
+        BufferedImage bi = new BufferedImage(HATCHED_SIZE, HATCHED_SIZE, BufferedImage.TYPE_INT_ARGB);
         Graphics2D big = bi.createGraphics();
         big.setColor(getBackgroundColor());
         Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
         big.setComposite(comp);
-        big.fillRect(0, 0, 15, 15);
+        big.fillRect(0, 0, HATCHED_SIZE, HATCHED_SIZE);
         big.setColor(getOutsideColor());
         big.drawLine(-1, 6, 6, -1);
         big.drawLine(4, 16, 16, 4);
-        Rectangle r = new Rectangle(0, 0, 15, 15);
-        hatched = new TexturePaint(bi, r);
+        hatched = bi;
     }
 
@@ -408,12 +410,12 @@
                     continue;
                 }
-                Point p1 = mv.getPoint(bounds.getMin());
-                Point p2 = mv.getPoint(bounds.getMax());
-                Rectangle r = new Rectangle(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.abs(p2.x-p1.x), Math.abs(p2.y-p1.y));
-                a.subtract(new Area(r));
+                a.subtract(mv.getState().getArea(bounds));
             }
 
             // paint remainder
-            g.setPaint(hatched);
+            MapViewPoint anchor = mv.getState().getPointFor(new EastNorth(0, 0));
+            Rectangle2D anchorRect = new Rectangle2D.Double(anchor.getInView().getX() % HATCHED_SIZE,
+                    anchor.getInView().getY() % HATCHED_SIZE, HATCHED_SIZE, HATCHED_SIZE);
+            g.setPaint(new TexturePaint(hatched, anchorRect));
             g.fill(a);
         }
