Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java	(revision 3862)
@@ -81,5 +81,5 @@
 
         outlineOnly = Main.pref.getBoolean("draw.data.area_outline_only", false);
-
+        
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintVisitor.java	(revision 3862)
@@ -101,6 +101,8 @@
         styles = MapPaintStyles.getStyles();
 
+        this.paintSettings = MapPaintSettings.INSTANCE;
+
         circum = nc.getDist100Pixel();
-        boolean drawArea = circum <= Main.pref.getInteger("mappaint.fillareas", 10000000);
+        boolean drawArea = circum <= Main.pref.getInteger("mappaint.fillareas", 10000000) && !paintSettings.isOutlineOnly();
         boolean drawMultipolygon = drawArea && Main.pref.getBoolean("mappaint.multipolygon", true);
         styles.setDrawMultipolygon(drawMultipolygon);
@@ -112,5 +114,4 @@
                         RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
 
-        this.paintSettings = MapPaintSettings.INSTANCE;
         this.painter = new MapPainter(paintSettings, g, inactive, nc, virtual, circum, leftHandTraffic);
 
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 3862)
@@ -11,6 +11,8 @@
 import java.awt.Polygon;
 import java.awt.Rectangle;
+import java.awt.TexturePaint;
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
 import java.util.Arrays;
 import java.util.Collection;
@@ -42,5 +44,4 @@
     private final boolean showNames;
     private final boolean showIcons;
-    private final boolean outlineOnly;
 
     private final Color inactiveColor;
@@ -78,5 +79,4 @@
         this.showNames = settings.getShowNamesDistance() > circum;
         this.showIcons = settings.getShowIconsDistance() > circum;
-        this.outlineOnly = settings.isOutlineOnly();
 
         this.inactiveColor = PaintColors.INACTIVE.get();
@@ -258,19 +258,21 @@
     }
 
-    public void drawArea(Way w, Color color, String name) {
+    public void drawArea(Way w, Color color, BufferedImage fillImage, String name) {
         Polygon polygon = getPolygon(w);
-        drawArea(polygon, color, name);
-    }
-
-    protected void drawArea(Polygon polygon, Color color, String name) {
-
-        g.setColor(color);
-
-        if (outlineOnly) {
-            g.drawPolygon(polygon);
+        drawArea(polygon, color, fillImage, name);
+    }
+
+    protected void drawArea(Polygon polygon, Color color, BufferedImage fillImage, String name) {
+
+        if (fillImage == null) {
+            g.setColor(color);
+            g.fillPolygon(polygon);
         } else {
-            g.fillPolygon(polygon);
-        }
-
+            TexturePaint texture = new TexturePaint(fillImage, 
+                    new Rectangle(polygon.xpoints[0], polygon.ypoints[0], fillImage.getWidth(), fillImage.getHeight()));
+
+            g.setPaint(texture);
+            g.fill(polygon);
+        }
 
         if (name != null) {
@@ -311,5 +313,5 @@
     }
 
-    public void drawArea(Relation r, Color color, String name) {
+    public void drawArea(Relation r, Color color, BufferedImage fillImage, String name) {
         Multipolygon multipolygon = new Multipolygon(nc);
         multipolygon.load(r);
@@ -320,5 +322,5 @@
                     continue;
                 }
-                drawArea(p, color, getAreaName(r));
+                drawArea(p, color, fillImage, getAreaName(r));
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 3862)
@@ -7,4 +7,5 @@
 import java.awt.Font;
 import java.awt.GridBagLayout;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -34,4 +35,5 @@
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
 import org.openstreetmap.josm.gui.mappaint.MultiCascade;
+import org.openstreetmap.josm.gui.mappaint.StyleCache;
 import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
 import org.openstreetmap.josm.gui.mappaint.StyleSource;
@@ -300,4 +302,19 @@
             txtMappaint.append("\n\n");
         }
+
+        if (sel.size() == 2) {
+            List<OsmPrimitive> selList = new ArrayList<OsmPrimitive>(sel);
+            StyleCache sc1 = selList.get(0).mappaintStyle;
+            StyleCache sc2 = selList.get(1).mappaintStyle;
+            if (sc1 == sc2) {
+                txtMappaint.append("The 2 selected Objects have identical style caches.");
+            }
+            if (!sc1.equals(sc2)) {
+                txtMappaint.append("The 2 selected Objects have different style caches.");
+            }
+            if (sc1.equals(sc2) && sc1 != sc2) {
+                txtMappaint.append("Warning: The 2 selected Objects have equal, but not identical style caches.");
+            }
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 3862)
@@ -3,4 +3,9 @@
 
 import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.TexturePaint;
+import java.awt.image.BufferedImage;
+
+import javax.swing.ImageIcon;
 
 import org.openstreetmap.josm.Main;
@@ -10,26 +15,49 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
+import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
 import org.openstreetmap.josm.tools.Utils;
+
 
 public class AreaElemStyle extends ElemStyle
 {
     public Color color;
+    public BufferedImage fillImage;
 
-    protected AreaElemStyle(Cascade c, Color color) {
+    protected AreaElemStyle(Cascade c, Color color, BufferedImage fillImage) {
         super(c);
         this.color = color;
+        this.fillImage = fillImage;
     }
 
     public static AreaElemStyle create(Cascade c) {
+        BufferedImage fillImage = null;
+        IconReference iconRef = c.get("fill-image", null, IconReference.class);
+        if (iconRef != null) {
+            ImageIcon icon = MapPaintStyles.getIcon(iconRef, false);
+            if (icon != null) {
+                if (!(icon.getImage() instanceof BufferedImage)) {
+                    icon = MapPaintStyles.getIcon(iconRef, true);
+                }
+                if (!(icon.getImage() instanceof BufferedImage))
+                    throw new RuntimeException();
+                fillImage = (BufferedImage) icon.getImage();
+            }
+        }
+
         Color color = c.get("fill-color", null, Color.class);
-        if (color == null)
+        if (color != null) {
+
+            int alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50))));
+            Integer pAlpha = color_float2int(c.get("fill-opacity", null, float.class));
+            if (pAlpha != null) {
+                alpha = pAlpha;
+            }
+            color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
+        }
+        
+        if (fillImage != null || color != null)
+            return new AreaElemStyle(c, color, fillImage);
+        else
             return null;
-        int alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50))));
-        Integer pAlpha = color_float2int(c.get("fill-opacity", null, float.class));
-        if (pAlpha != null) {
-            alpha = pAlpha;
-        }
-        color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
-        return new AreaElemStyle(c, color);
     }
 
@@ -38,11 +66,21 @@
         if (osm instanceof Way)
         {
-            painter.drawArea((Way) osm,
-                    osm.isSelected() ? paintSettings.getSelectedColor(color.getAlpha()) : color,
+            Color myColor = color;
+            if (color != null) {
+                if (osm.isSelected()) {
+                    myColor = paintSettings.getSelectedColor(color.getAlpha());
+                }
+            }
+            painter.drawArea((Way) osm, myColor, fillImage,
                     painter.isShowNames() ? painter.getAreaName(osm) : null);
         } else if (osm instanceof Relation)
         {
-            painter.drawArea((Relation) osm,
-                    selected ? paintSettings.getRelationSelectedColor(color.getAlpha()) : color,
+            Color myColor = color;
+            if (color != null) {
+                if (selected) {
+                    myColor = paintSettings.getRelationSelectedColor(color.getAlpha());
+                }
+            }
+            painter.drawArea((Relation) osm, myColor, fillImage,
                     painter.getAreaName(osm));
         }
@@ -55,10 +93,19 @@
         if (!super.equals(obj))
             return false;
-        return Utils.equal(color, ((AreaElemStyle) obj).color);
+        AreaElemStyle other = (AreaElemStyle) obj;
+        // we should get the same image object due to caching
+        if (fillImage != other.fillImage && (fillImage == null || other.fillImage == null || fillImage != other.fillImage))
+            return false;
+        if (!Utils.equal(color, other.color))
+            return false;
+        return true;
     }
 
     @Override
     public int hashCode() {
-        return 11 * super.hashCode() + color.hashCode();
+        int hash = 3;
+        hash = 61 * hash + (this.color != null ? this.color.hashCode() : 0);
+        hash = 61 * hash + (this.fillImage != null ? this.fillImage.hashCode() : 0);
+        return hash;
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3862)
@@ -60,5 +60,5 @@
     }
 
-    public static ImageIcon getIcon(IconReference ref)
+    public static ImageIcon getIcon(IconReference ref, boolean sanitize)
     {
         String styleName = ref.source.getPrefName();
@@ -78,5 +78,5 @@
             }
         }
-        ImageIcon i = ImageProvider.getIfAvailable(dirs, "mappaint."+styleName, null, ref.iconName, ref.source.zipIcons);
+        ImageIcon i = ImageProvider.getIfAvailable(dirs, "mappaint."+styleName, null, ref.iconName, ref.source.zipIcons, sanitize);
         if(i == null)
         {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 3862)
@@ -37,6 +37,6 @@
         if (iconRef == null)
             return null;
-
-        ImageIcon icon = MapPaintStyles.getIcon(iconRef);
+        ImageIcon icon = MapPaintStyles.getIcon(iconRef, false);
+        
         String text = c.get("text", null, String.class);
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java	(revision 3862)
@@ -36,5 +36,5 @@
         public void execute(Environment env) {
             Object value = (val instanceof Expression) ? ((Expression) val).evaluate(env) : val;
-            if (key.equals("icon-image")) {
+            if (key.equals("icon-image") || key.equals("fill-image")) {
                 if (value instanceof String) {
                     value = new IconReference((String) value, env.source);
Index: trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 3861)
+++ trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 3862)
@@ -52,7 +52,20 @@
 
     /**
+     * remember whether the image has been sanitized
+     */
+    private static class ImageWrapper {
+        Image img;
+        boolean sanitized;
+
+        public ImageWrapper(Image img, boolean sanitized) {
+            this.img = img;
+            this.sanitized = sanitized;
+        }
+    }
+
+    /**
      * The icon cache
      */
-    private static Map<String, Image> cache = new HashMap<String, Image>();
+    private static Map<String, ImageWrapper> cache = new HashMap<String, ImageWrapper>();
 
     /**
@@ -84,5 +97,5 @@
     }
 
-    public static final ImageIcon getIfAvailable(String[] dirs, String id, String subdir, String name) {
+    public static ImageIcon getIfAvailable(String[] dirs, String id, String subdir, String name) {
         return getIfAvailable(Arrays.asList(dirs), id, subdir, name);
     }
@@ -95,4 +108,8 @@
     public static ImageIcon getIfAvailable(Collection<String> dirs, String id, String subdir, String name) {
         return getIfAvailable(dirs, id, subdir, name, null);
+    }
+
+    public static ImageIcon getIfAvailable(Collection<String> dirs, String id, String subdir, String name, File archive) {
+        return getIfAvailable(dirs, id, subdir, name, archive, false);
     }
 
@@ -106,20 +123,34 @@
      * @param name      The name of the image. If it contains no '.', a png extension is added.
      * @param archive   A zip file where the image is located.
-     */
-    public static ImageIcon getIfAvailable(Collection<String> dirs, String id, String subdir, String name, File archive) {
+     * @param sanitize  If the image should be repainted to a new BufferedImage to work
+     *                  around certain issues.
+     */
+    public static ImageIcon getIfAvailable(Collection<String> dirs, String id, String subdir, String name, File archive, boolean sanitize) {
+        ImageWrapper iw = getIfAvailableImpl(dirs, id, subdir, name, archive);
+        if (iw == null)
+            return null;
+        if (sanitize && !iw.sanitized) {
+            iw.img = sanitize(iw.img);
+            iw.sanitized = true;
+        }
+        return new ImageIcon(iw.img);
+    }
+
+    private static ImageWrapper getIfAvailableImpl(Collection<String> dirs, String id, String subdir, String name, File archive) {
         if (name == null)
             return null;
         if (name.startsWith("http://")) {
-            Image img = cache.get(name);
-            if (img == null) {
+            ImageWrapper iw = cache.get(name);
+            if (iw == null) {
                 try {
                     MirroredInputStream is = new MirroredInputStream(name, new File(Main.pref.getPreferencesDir(),
                     "images").toString());
-                    img = Toolkit.getDefaultToolkit().createImage(is.getFile().toURI().toURL());
-                    cache.put(name, img);
+                    Image img = Toolkit.getDefaultToolkit().createImage(is.getFile().toURI().toURL());
+                    iw = new ImageWrapper(img, false);
+                    cache.put(name, iw);
                 } catch (IOException e) {
                 }
             }
-            return img == null ? null : new ImageIcon(img);
+            return iw;
         }
         if (subdir == null) {
@@ -139,6 +170,6 @@
         }
 
-        Image img = cache.get(cache_name);
-        if (img == null) {
+        ImageWrapper iw = cache.get(cache_name);
+        if (iw == null) {
             if(archive != null)
             {
@@ -162,5 +193,6 @@
                                 size -= l;
                             }
-                            img = Toolkit.getDefaultToolkit().createImage(buf);
+                            Image img = Toolkit.getDefaultToolkit().createImage(buf);
+                            iw = new ImageWrapper(img, false);
                         } finally {
                             if (is != null) {
@@ -185,15 +217,16 @@
             // and don't bother to create a URL unless we're actually
             // creating the image.
-            if(img == null)
+            if(iw == null)
             {
                 URL path = getImageUrl(full_name, dirs);
                 if (path == null)
                     return null;
-                img = Toolkit.getDefaultToolkit().createImage(path);
-            }
-            cache.put(cache_name, img);
-        }
-
-        return new ImageIcon(img);
+                Image img = Toolkit.getDefaultToolkit().createImage(path);
+                iw = new ImageWrapper(img, false);
+            }
+            cache.put(cache_name, iw);
+        }
+
+        return iw;
     }
 
@@ -405,3 +438,12 @@
         return get("data", type.getAPIName());
     }
+
+    public static BufferedImage sanitize(Image img) {
+        (new ImageIcon(img)).getImage(); // load competely
+        int width = img.getWidth(null);
+        int height = img.getHeight(null);
+        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        result.getGraphics().drawImage(img, 0, 0, null);
+        return result;
+    }
 }
