Index: trunk/src/org/openstreetmap/josm/gui/MapViewState.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 11024)
+++ trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 11026)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.gui.download.DownloadDialog;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.bugreport.BugReport;
 
@@ -58,4 +59,9 @@
      */
     public static final int OUTSIDE_RIGHT = 8;
+
+    /**
+     * Additional pixels outside the view for where to start clipping.
+     */
+    private static final int CLIP_BOUNDS = 50;
 
     private final transient Projecting projecting;
@@ -257,4 +263,12 @@
         return new AffineTransform(1.0 / scale, 0.0, 0.0, -1.0 / scale, -topLeft.east() / scale,
                 topLeft.north() / scale);
+    }
+
+    /**
+     * Gets a rectangle that is several pixel bigger than the view. It is used to define the view clipping.
+     * @return The rectangle.
+     */
+    public MapViewRectangle getViewClipRectangle() {
+        return getForView(-CLIP_BOUNDS, -CLIP_BOUNDS).rectTo(getForView(getViewWidth() + CLIP_BOUNDS, getViewHeight() + CLIP_BOUNDS));
     }
 
@@ -665,4 +679,37 @@
             return getInView().intersects(getViewArea().getInView());
         }
+
+        /**
+         * Gets the entry point at which a line between start and end enters the current view.
+         * @param start The start
+         * @param end The end
+         * @return The entry point or <code>null</code> if the line does not intersect this view.
+         */
+        public MapViewPoint getLineEntry(MapViewPoint start, MapViewPoint end) {
+            ProjectionBounds bounds = getProjectionBounds();
+            if (bounds.contains(start.getEastNorth())) {
+                return start;
+            }
+
+            double dx = end.getEastNorth().east() - start.getEastNorth().east();
+            double boundX = dx > 0 ? bounds.minEast : bounds.maxEast;
+            EastNorth borderIntersection = Geometry.getSegmentSegmentIntersection(start.getEastNorth(), end.getEastNorth(),
+                    new EastNorth(boundX, bounds.minNorth),
+                    new EastNorth(boundX, bounds.maxNorth));
+            if (borderIntersection != null) {
+                return getPointFor(borderIntersection);
+            }
+
+            double dy = end.getEastNorth().north() - start.getEastNorth().north();
+            double boundY = dy > 0 ? bounds.minNorth : bounds.maxNorth;
+            borderIntersection = Geometry.getSegmentSegmentIntersection(start.getEastNorth(), end.getEastNorth(),
+                    new EastNorth(bounds.minEast, boundY),
+                    new EastNorth(bounds.maxEast, boundY));
+            if (borderIntersection != null) {
+                return getPointFor(borderIntersection);
+            }
+
+            return null;
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java	(revision 11024)
+++ trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java	(revision 11026)
@@ -1,4 +1,7 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.draw;
+
+import java.awt.geom.Point2D;
+import java.text.MessageFormat;
 
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -7,7 +10,10 @@
 import org.openstreetmap.josm.gui.MapViewState;
 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
+import org.openstreetmap.josm.gui.MapViewState.MapViewRectangle;
 
 /**
  * This is a version of a java Path2D that allows you to add points to it by simply giving their east/north, lat/lon or node coordinates.
+ * <p>
+ * Paths far outside the view area are automatically clipped to increase performance.
  * @author Michael Zangl
  * @since 10875
@@ -61,4 +67,6 @@
     /**
      * Draw a line to the node.
+     * <p>
+     * line clamping to view is done automatically.
      * @param n The node
      * @return this for easy chaining.
@@ -71,4 +79,6 @@
     /**
      * Draw a line to the position.
+     * <p>
+     * line clamping to view is done automatically.
      * @param eastNorth The position
      * @return this for easy chaining.
@@ -81,5 +91,31 @@
     @Override
     public MapViewPath lineTo(MapViewPoint p) {
-        super.lineTo(p);
+        Point2D currentPoint = getCurrentPoint();
+        if (currentPoint == null) {
+            throw new IllegalStateException("Path not started yet.");
+        }
+        MapViewPoint current = state.getForView(currentPoint.getX(), currentPoint.getY());
+        MapViewPoint end = p;
+
+        MapViewRectangle clip = state.getViewClipRectangle();
+        MapViewPoint entry = clip.getLineEntry(current, end);
+        if (entry == null) {
+            // skip this one - outside the view.
+            super.moveTo(end);
+        } else {
+            if (!entry.equals(current)) {
+                super.moveTo(entry);
+            }
+            MapViewPoint exit = clip.getLineEntry(end, current);
+            if (exit == null) {
+                throw new AssertionError(MessageFormat.format(
+                        "getLineEntry produces wrong results when doing the reverse lookup. Attempt: {0}->{1}",
+                        end.getEastNorth(), current.getEastNorth()));
+            }
+            super.lineTo(exit);
+            if (!exit.equals(end)) {
+                super.moveTo(end);
+            }
+        }
         return this;
     }
