Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 8085)
@@ -428,5 +428,5 @@
     }
 
-    protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, TextElement text) {
+    protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, boolean disabled, TextElement text) {
 
         Shape area = path.createTransformedShape(nc.getAffineTransform());
@@ -440,8 +440,8 @@
                 g.fill(area);
             } else {
-                TexturePaint texture = new TexturePaint(fillImage.getImage(),
+                TexturePaint texture = new TexturePaint(fillImage.getImage(disabled),
                         new Rectangle(0, 0, fillImage.getWidth(), fillImage.getHeight()));
                 g.setPaint(texture);
-                Float alpha = Utils.color_int2float(fillImage.alpha);
+                Float alpha = fillImage.getAlphaFloat();
                 if (alpha != 1f) {
                     g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
@@ -529,5 +529,5 @@
     }
 
-    public void drawArea(Relation r, Color color, MapImage fillImage, TextElement text) {
+    public void drawArea(Relation r, Color color, MapImage fillImage, boolean disabled, TextElement text) {
         Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, r);
         if (!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) {
@@ -539,11 +539,11 @@
                 drawArea(r, p,
                         pd.selected ? paintSettings.getRelationSelectedColor(color.getAlpha()) : color,
-                                fillImage, text);
-            }
-        }
-    }
-
-    public void drawArea(Way w, Color color, MapImage fillImage, TextElement text) {
-        drawArea(w, getPath(w), color, fillImage, text);
+                                fillImage, disabled, text);
+            }
+        }
+    }
+
+    public void drawArea(Way w, Color color, MapImage fillImage, boolean disabled, TextElement text) {
+        drawArea(w, getPath(w), color, fillImage, disabled, text);
     }
 
@@ -617,8 +617,8 @@
      * can be aligned with the way.
      */
-    public void drawRepeatImage(Way way, Image pattern, float offset, float spacing, float phase, LineImageAlignment align) {
-        final int imgWidth = pattern.getWidth(null);
+    public void drawRepeatImage(Way way, MapImage pattern, boolean disabled, float offset, float spacing, float phase, LineImageAlignment align) {
+        final int imgWidth = pattern.getWidth();
         final double repeat = imgWidth + spacing;
-        final int imgHeight = pattern.getHeight(null);
+        final int imgHeight = pattern.getHeight();
 
         Point lastP = null;
@@ -669,10 +669,10 @@
                     // segment is too short for a complete image
                     if (pos > segmentLength + spacing) {
-                        g.drawImage(pattern, 0, dy1, (int) segmentLength, dy2,
+                        g.drawImage(pattern.getImage(disabled), 0, dy1, (int) segmentLength, dy2,
                                 (int) (repeat - pos), 0,
                                 (int) (repeat - pos + segmentLength), imgHeight, null);
                     // rest of the image fits fully on the current segment
                     } else {
-                        g.drawImage(pattern, 0, dy1, (int) (pos - spacing), dy2,
+                        g.drawImage(pattern.getImage(disabled), 0, dy1, (int) (pos - spacing), dy2,
                                 (int) (repeat - pos), 0, imgWidth, imgHeight, null);
                     }
@@ -682,8 +682,8 @@
                     // cut off at the end?
                     if (pos + imgWidth > segmentLength) {
-                        g.drawImage(pattern, (int) pos, dy1, (int) segmentLength, dy2,
+                        g.drawImage(pattern.getImage(disabled), (int) pos, dy1, (int) segmentLength, dy2,
                                 0, 0, (int) segmentLength - (int) pos, imgHeight, null);
                     } else {
-                        g.drawImage(pattern, (int) pos, dy1, nc);
+                        g.drawImage(pattern.getImage(disabled), (int) pos, dy1, nc);
                     }
                     pos += repeat;
@@ -725,21 +725,23 @@
     }
 
-    public void drawNodeIcon(Node n, Image img, float alpha, boolean selected, boolean member) {
+    public void drawNodeIcon(Node n, MapImage img, boolean disabled, boolean selected, boolean member) {
         Point p = nc.getPoint(n);
 
-        final int w = img.getWidth(null), h=img.getHeight(null);
+        final int w = img.getWidth(), h = img.getHeight();
         if(n.isHighlighted()) {
             drawPointHighlight(p, Math.max(w, h));
         }
 
+        float alpha = img.getAlphaFloat();
+
         if (alpha != 1f) {
             g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
         }
-        g.drawImage(img, p.x-w/2, p.y-h/2, nc);
+        g.drawImage(img.getImage(disabled), p.x - w/2 + img.offsetX, p.y - h/2 + img.offsetY, nc);
         g.setPaintMode();
         if (selected || member)
         {
             Color color;
-            if (isInactiveMode || n.isDisabled()) {
+            if (disabled) {
                 color = inactiveColor;
             } else if (selected) {
@@ -749,5 +751,5 @@
             }
             g.setColor(color);
-            g.drawRect(p.x-w/2-2, p.y-h/2-2, w+4, h+4);
+            g.drawRect(p.x - w/2 + img.offsetX - 2, p.y - h/2 + img.offsetY - 2, w + 4, h + 4);
         }
     }
@@ -888,5 +890,5 @@
     }
 
-    public void drawRestriction(Relation r, MapImage icon) {
+    public void drawRestriction(Relation r, MapImage icon, boolean disabled) {
         Way fromWay = null;
         Way toWay = null;
@@ -1057,5 +1059,5 @@
         }
 
-        drawRestriction(isInactiveMode || r.isDisabled() ? icon.getDisabled() : icon.getImage(),
+        drawRestriction(icon.getImage(disabled),
                 pVia, vx, vx2, vy, vy2, iconAngle, r.isSelected());
     }
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java	(revision 8085)
@@ -42,7 +42,6 @@
         if (iconRef != null) {
             fillImage = new MapImage(iconRef.iconName, iconRef.source);
-            fillImage.getImage();
 
-            color = new Color(fillImage.getImage().getRGB(
+            color = new Color(fillImage.getImage(false).getRGB(
                     fillImage.getWidth() / 2, fillImage.getHeight() / 2)
             );
@@ -97,10 +96,10 @@
                 }
             }
-            painter.drawArea((Way) osm, myColor, fillImage, text);
+            painter.drawArea((Way) osm, myColor, fillImage, painter.isInactiveMode() || osm.isDisabled(), text);
         } else if (osm instanceof Relation) {
             if (color != null && (selected || outermember)) {
                 myColor = paintSettings.getRelationSelectedColor(color.getAlpha());
             }
-            painter.drawArea((Relation) osm, myColor, fillImage, text);
+            painter.drawArea((Relation) osm, myColor, fillImage, painter.isInactiveMode() || osm.isDisabled(), text);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 8085)
@@ -14,6 +14,6 @@
 public abstract class ElemStyle implements StyleKeys {
 
-    protected static final String[] ICON_KEYS = {"icon-image", "icon-width", "icon-height", "icon-opacity"};
-    protected static final String[] REPEAT_IMAGE_KEYS = {"repeat-image", "repeat-image-width", "repeat-image-height", "repeat-image-opacity"};
+    protected static final String[] ICON_KEYS = {"icon-image", "icon-width", "icon-height", "icon-opacity", "icon-offset-x", "icon-offset-y"};
+    protected static final String[] REPEAT_IMAGE_KEYS = {"repeat-image", "repeat-image-width", "repeat-image-height", "repeat-image-opacity", null, null};
 
     public float major_z_index;
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/MapImage.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/MapImage.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/MapImage.java	(revision 8085)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.gui.mappaint;
 
+import java.awt.Graphics;
 import java.awt.Image;
 import java.awt.Rectangle;
@@ -17,4 +18,7 @@
 import org.openstreetmap.josm.tools.Utils;
 
+/**
+ * An image that will be displayed on the map.
+ */
 public class MapImage {
 
@@ -26,7 +30,4 @@
     private BufferedImage img;
 
-    /**
-     * The 5 following fields are only used to check for equality.
-     */
     public int alpha = 255;
     public String name;
@@ -34,7 +35,9 @@
     public int width = -1;
     public int height = -1;
+    public int offsetX = 0;
+    public int offsetY = 0;
 
     private boolean temporary;
-    private Image disabledImgCache;
+    private BufferedImage disabledImgCache;
 
     public MapImage(String name, StyleSource source) {
@@ -43,14 +46,36 @@
     }
 
-    public Image getDisabled() {
+    /**
+     * Get the image associated with this MapImage object.
+     * 
+     * @param disabled {@code} true to request disabled version, {@code false} for the standard version
+     * @return the image
+     */
+    public BufferedImage getImage(boolean disabled) {
+        if (disabled) {
+            return getDisabled();
+        } else {
+            return getImage();
+        }
+    }
+
+    private BufferedImage getDisabled() {
         if (disabledImgCache != null)
                 return disabledImgCache;
         if (img == null)
             getImage(); // fix #7498 ?
-        disabledImgCache = GuiHelper.getDisabledImage(img);
+        Image disImg = GuiHelper.getDisabledImage(img);
+        if (disImg instanceof BufferedImage) {
+            disabledImgCache = (BufferedImage) disImg;
+        } else {
+            disabledImgCache = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_BYTE_GRAY);
+            Graphics g = disabledImgCache.getGraphics();
+            g.drawImage(disImg, 0, 0, null);
+            g.dispose();
+        }
         return disabledImgCache;
     }
 
-    public BufferedImage getImage() {
+    private BufferedImage getImage() {
         if (img != null)
             return img;
@@ -72,5 +97,5 @@
                                 img = noIcon == null ? null : (BufferedImage) noIcon.getImage();
                             } else {
-                                img = (BufferedImage) result.getImage();
+                                img = (BufferedImage) rescale(result.getImage());
                             }
                             if (temporary) {
@@ -159,11 +184,10 @@
 
     /**
-     * Returns the really displayed node icon for this {@code MapImage}.
-     * @param disabled {@code} true to request disabled version, {@code false} for the standard version
+     * Rescale excessively large images.
+     * @param image the unscaled image
      * @return The scaled down version to 16x16 pixels if the image height and width exceeds 48 pixels and no size has been explicitely specified
-     * @since 6174
-     */
-    public Image getDisplayedNodeIcon(boolean disabled) {
-        final Image image = disabled ? getDisabled() : getImage();
+     */
+    private Image rescale(Image image) {
+        if (image == null) return null;
         // Scale down large (.svg) images to 16x16 pixels if no size is explicitely specified
         if (mustRescale(image)) {
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 8085)
@@ -167,5 +167,5 @@
                         if (mapImage != null) {
                             if (includeDeprecatedIcon || mapImage.name == null || !"misc/deprecated.png".equals(mapImage.name)) {
-                                return new ImageIcon(mapImage.getDisplayedNodeIcon(false));
+                                return new ImageIcon(mapImage.getImage(false));
                             } else {
                                 return null; // Deprecated icon found but not wanted
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 8085)
@@ -148,8 +148,17 @@
         int height = heightF == null ? -1 : Math.round(heightF);
 
+        float offsetXF = 0f;
+        float offsetYF = 0f;
+        if (keys[ICON_OFFSET_X_IDX] != null) {
+            offsetXF = c.get(keys[ICON_OFFSET_X_IDX], 0f, Float.class);
+            offsetYF = c.get(keys[ICON_OFFSET_Y_IDX], 0f, Float.class);
+        }
+
         final MapImage mapImage = new MapImage(iconRef.iconName, iconRef.source);
 
         mapImage.width = width;
         mapImage.height = height;
+        mapImage.offsetX = Math.round(offsetXF);
+        mapImage.offsetY = Math.round(offsetYF);
 
         mapImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.icon-image-alpha", 255))));
@@ -246,19 +255,5 @@
             Node n = (Node) primitive;
             if (mapImage != null && painter.isShowIcons()) {
-                final Image nodeIcon;
-                if (painter.isInactiveMode() || n.isDisabled()) {
-                    if (disabledNodeIcon == null || disabledNodeIconIsTemporary) {
-                        disabledNodeIcon = mapImage.getDisplayedNodeIcon(true);
-                        disabledNodeIconIsTemporary = mapImage.isTemporary();
-                    }
-                    nodeIcon = disabledNodeIcon;
-                } else {
-                    if (enabledNodeIcon == null || enabledNodeIconIsTemporary) {
-                        enabledNodeIcon = mapImage.getDisplayedNodeIcon(false);
-                        enabledNodeIconIsTemporary = mapImage.isTemporary();
-                    }
-                    nodeIcon = enabledNodeIcon;
-                }
-                painter.drawNodeIcon(n, nodeIcon, Utils.color_int2float(mapImage.alpha), selected, member);
+                painter.drawNodeIcon(n, mapImage, painter.isInactiveMode() || n.isDisabled(), selected, member);
             } else if (symbol != null) {
                 Color fillColor = symbol.fillColor;
@@ -321,5 +316,5 @@
             }
         } else if (primitive instanceof Relation && mapImage != null) {
-            painter.drawRestriction((Relation) primitive, mapImage);
+            painter.drawRestriction((Relation) primitive, mapImage, painter.isInactiveMode() || primitive.isDisabled());
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/RepeatImageElemStyle.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/RepeatImageElemStyle.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/RepeatImageElemStyle.java	(revision 8085)
@@ -53,5 +53,5 @@
             boolean selected, boolean outermember, boolean member) {
         Way w = (Way) primitive;
-        painter.drawRepeatImage(w, pattern.getImage(), offset, spacing, phase, align);
+        painter.drawRepeatImage(w, pattern, painter.isInactiveMode() || w.isDisabled(), offset, spacing, phase, align);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/StyleKeys.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/StyleKeys.java	(revision 8084)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/StyleKeys.java	(revision 8085)
@@ -32,3 +32,5 @@
     int ICON_HEIGHT_IDX = 2;
     int ICON_OPACITY_IDX = 3;
+    int ICON_OFFSET_X_IDX = 4;
+    int ICON_OFFSET_Y_IDX = 5;
 }
