Index: trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 10356)
+++ trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 10358)
@@ -69,4 +69,5 @@
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
+import org.openstreetmap.josm.gui.util.GuiSizesHelper;
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.plugins.PluginHandler;
@@ -145,11 +146,11 @@
         CURSOR(Main.pref.getInteger("iconsize.cursor", 32)),
         /** cursor overlay icon size */
-        CURSOROVERLAY(CURSOR.imageSize),
+        CURSOROVERLAY(CURSOR),
         /** menu icon size */
-        MENU(SMALLICON.imageSize),
+        MENU(SMALLICON),
         /** menu icon size in popup menus
          * @since 8323
          */
-        POPUPMENU(LARGEICON.imageSize),
+        POPUPMENU(LARGEICON),
         /** Layer list icon size
          * @since 8323
@@ -159,28 +160,62 @@
          * @since 9253
          */
-        TOOLBAR(LARGEICON.imageSize),
+        TOOLBAR(LARGEICON),
         /** Side button maximum height
          * @since 9253
          */
         SIDEBUTTON(Main.pref.getInteger("iconsize.sidebutton", 20)),
+        /** Settings tab icon size
+         * @since 9253
+         */
+        SETTINGS_TAB(Main.pref.getInteger("iconsize.settingstab", 48)),
         /**
          * The default image size
          * @since 9705
          */
-        DEFAULT(Main.pref.getInteger("iconsize.default", 24));
-
-        private final int imageSize;
+        DEFAULT(Main.pref.getInteger("iconsize.default", 24)),
+        /**
+         * Splash dialog logo size
+         * @since 10358
+         */
+        SPLASH_LOGO(128, 129),
+        /**
+         * About dialog logo size
+         * @since 10358
+         */
+        ABOUT_LOGO(256, 258);
+
+        private final int virtualWidth;
+        private final int virtualHeight;
 
         ImageSizes(int imageSize) {
-            this.imageSize = imageSize;
+            this.virtualWidth = imageSize;
+            this.virtualHeight = imageSize;
+        }
+
+        ImageSizes(int width, int height) {
+            this.virtualWidth = width;
+            this.virtualHeight = height;
+        }
+
+        ImageSizes(ImageSizes that) {
+            this.virtualWidth = that.virtualWidth;
+            this.virtualHeight = that.virtualHeight;
         }
 
         /**
-         * Returns the image size in pixels
-         * @return the image size in pixels
+         * Returns the image width in virtual pixels
+         * @return the image width in virtual pixels
+         */
+        public int getVirtualWidth() {
+            return virtualWidth;
+        }
+
+        /**
+         * Returns the image height in virtual pixels
+         * @return the image height in virtual pixels
          * @since 9705
          */
-        public int getImageSize() {
-            return imageSize;
+        public int getVirtualHeight() {
+            return virtualHeight;
         }
 
@@ -191,5 +226,5 @@
          */
         public Dimension getImageDimension() {
-            return new Dimension(imageSize, imageSize);
+            return new Dimension(virtualWidth, virtualHeight);
         }
     }
@@ -219,12 +254,12 @@
     /** directory inside the archive */
     protected String inArchiveDir;
-    /** width of the resulting image, -1 when original image data should be used */
-    protected int width = -1;
-    /** height of the resulting image, -1 when original image data should be used */
-    protected int height = -1;
-    /** maximum width of the resulting image, -1 for no restriction */
-    protected int maxWidth = -1;
-    /** maximum height of the resulting image, -1 for no restriction */
-    protected int maxHeight = -1;
+    /** virtual width of the resulting image, -1 when original image data should be used */
+    protected int virtualWidth = -1;
+    /** virtual height of the resulting image, -1 when original image data should be used */
+    protected int virtualHeight = -1;
+    /** virtual maximum width of the resulting image, -1 for no restriction */
+    protected int virtualMaxWidth = -1;
+    /** virtual maximum height of the resulting image, -1 for no restriction */
+    protected int virtualMaxHeight = -1;
     /** In case of errors do not throw exception but return <code>null</code> for missing image */
     protected boolean optional;
@@ -306,8 +341,8 @@
         this.archive = image.archive;
         this.inArchiveDir = image.inArchiveDir;
-        this.width = image.width;
-        this.height = image.height;
-        this.maxWidth = image.maxWidth;
-        this.maxHeight = image.maxHeight;
+        this.virtualWidth = image.virtualWidth;
+        this.virtualHeight = image.virtualHeight;
+        this.virtualMaxWidth = image.virtualMaxWidth;
+        this.virtualMaxHeight = image.virtualMaxHeight;
         this.optional = image.optional;
         this.suppressWarnings = image.suppressWarnings;
@@ -389,6 +424,6 @@
      */
     public ImageProvider setSize(Dimension size) {
-        this.width = size.width;
-        this.height = size.height;
+        this.virtualWidth = size.width;
+        this.virtualHeight = size.height;
         return this;
     }
@@ -407,4 +442,18 @@
 
     /**
+     * Set the dimensions of the image.
+     *
+     * @param width final width of the image
+     * @param height final height of the image
+     * @return the current object, for convenience
+     * @since 10358
+     */
+    public ImageProvider setSize(int width, int height) {
+        this.virtualWidth = width;
+        this.virtualHeight = height;
+        return this;
+    }
+
+    /**
      * Set image width
      * @param width final width of the image
@@ -413,5 +462,5 @@
      */
     public ImageProvider setWidth(int width) {
-        this.width = width;
+        this.virtualWidth = width;
         return this;
     }
@@ -424,5 +473,5 @@
      */
     public ImageProvider setHeight(int height) {
-        this.height = height;
+        this.virtualHeight = height;
         return this;
     }
@@ -439,6 +488,6 @@
      */
     public ImageProvider setMaxSize(Dimension maxSize) {
-        this.maxWidth = maxSize.width;
-        this.maxHeight = maxSize.height;
+        this.virtualMaxWidth = maxSize.width;
+        this.virtualMaxHeight = maxSize.height;
         return this;
     }
@@ -458,9 +507,9 @@
      */
     public ImageProvider resetMaxSize(Dimension maxSize) {
-        if (this.maxWidth == -1 || maxSize.width < this.maxWidth) {
-            this.maxWidth = maxSize.width;
-        }
-        if (this.maxHeight == -1 || maxSize.height < this.maxHeight) {
-            this.maxHeight = maxSize.height;
+        if (this.virtualMaxWidth == -1 || maxSize.width < this.virtualMaxWidth) {
+            this.virtualMaxWidth = maxSize.width;
+        }
+        if (this.virtualMaxHeight == -1 || maxSize.height < this.virtualMaxHeight) {
+            this.virtualMaxHeight = maxSize.height;
         }
         return this;
@@ -498,5 +547,5 @@
      */
     public ImageProvider setMaxWidth(int maxWidth) {
-        this.maxWidth = maxWidth;
+        this.virtualMaxWidth = maxWidth;
         return this;
     }
@@ -509,5 +558,5 @@
      */
     public ImageProvider setMaxHeight(int maxHeight) {
-        this.maxHeight = maxHeight;
+        this.virtualMaxHeight = maxHeight;
         return this;
     }
@@ -557,8 +606,8 @@
         if (ir == null)
             return null;
-        if (maxWidth != -1 || maxHeight != -1)
-            return ir.getImageIconBounded(new Dimension(maxWidth, maxHeight));
+        if (virtualMaxWidth != -1 || virtualMaxHeight != -1)
+            return ir.getImageIconBounded(new Dimension(virtualMaxWidth, virtualMaxHeight));
         else
-            return ir.getImageIcon(new Dimension(width, height));
+            return ir.getImageIcon(new Dimension(virtualWidth, virtualHeight));
     }
 
@@ -656,4 +705,17 @@
 
     /**
+     * Load an empty image with a given size.
+     *
+     * @param size Target icon size
+     * @return The requested Image.
+     * @since 10358
+     */
+    public static ImageIcon getEmpty(ImageSizes size) {
+        Dimension iconRealSize = GuiSizesHelper.getDimensionDpiAdjusted(size.getImageDimension());
+        return new ImageIcon(new BufferedImage(iconRealSize.width, iconRealSize.height,
+            BufferedImage.TYPE_INT_ARGB));
+    }
+
+    /**
      * Load an image with a given file name.
      *
@@ -689,4 +751,20 @@
     public static ImageIcon getIfAvailable(String name) {
         return new ImageProvider(name).setOptional(true).get();
+    }
+
+    /**
+     * Scale image to virtual dimensions. This util method is used to hide real sizes calculations.
+     * All other classes should use this method to resize images.
+     *
+     * @param im image to be resized
+     * @param virtualWidth target width of image in virtual pixels
+     * @param virtualHeight target height of image in virtual pixels
+     * @return new scaled image in real dimensions
+     */
+    public static ImageIcon getScaledIcon(Image im, int virtualWidth, int virtualHeight) {
+        int realWidth = GuiSizesHelper.getSizeDpiAdjusted(virtualWidth);
+        int realHeight = GuiSizesHelper.getSizeDpiAdjusted(virtualHeight);
+
+        return new ImageIcon(im.getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH));
     }
 
@@ -1333,12 +1411,12 @@
                     MapImage icon = nodeStyle.mapImage;
                     if (icon != null) {
-                        int backgroundWidth = iconSize.width;
-                        int backgroundHeight = iconSize.height;
-                        int iconWidth = icon.getWidth();
-                        int iconHeight = icon.getHeight();
-                        BufferedImage image = new BufferedImage(backgroundWidth, backgroundHeight,
+                        int backgroundRealWidth = GuiSizesHelper.getSizeDpiAdjusted(iconSize.width);
+                        int backgroundRealHeight = GuiSizesHelper.getSizeDpiAdjusted(iconSize.height);
+                        int iconRealWidth = icon.getWidth();
+                        int iconRealHeight = icon.getHeight();
+                        BufferedImage image = new BufferedImage(backgroundRealWidth, backgroundRealHeight,
                                 BufferedImage.TYPE_INT_ARGB);
-                        double scaleFactor = Math.min(backgroundWidth / (double) iconWidth, backgroundHeight
-                                / (double) iconHeight);
+                        double scaleFactor = Math.min(backgroundRealWidth / (double) iconRealWidth, backgroundRealHeight
+                                / (double) iconRealHeight);
                         BufferedImage iconImage = icon.getImage(false);
                         Image scaledIcon;
@@ -1347,15 +1425,15 @@
                         if (scaleFactor < 1) {
                             // Scale icon such that it fits on background.
-                            scaledWidth = (int) (iconWidth * scaleFactor);
-                            scaledHeight = (int) (iconHeight * scaleFactor);
+                            scaledWidth = (int) (iconRealWidth * scaleFactor);
+                            scaledHeight = (int) (iconRealHeight * scaleFactor);
                             scaledIcon = iconImage.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH);
                         } else {
                             // Use original size, don't upscale.
-                            scaledWidth = iconWidth;
-                            scaledHeight = iconHeight;
+                            scaledWidth = iconRealWidth;
+                            scaledHeight = iconRealHeight;
                             scaledIcon = iconImage;
                         }
-                        image.getGraphics().drawImage(scaledIcon, (backgroundWidth - scaledWidth) / 2,
-                                (backgroundHeight - scaledHeight) / 2, null);
+                        image.getGraphics().drawImage(scaledIcon, (backgroundRealWidth - scaledWidth) / 2,
+                                (backgroundRealHeight - scaledHeight) / 2, null);
 
                         return new ImageIcon(image);
@@ -1394,33 +1472,35 @@
      */
     public static BufferedImage createImageFromSvg(SVGDiagram svg, Dimension dim) {
-        float realWidth = svg.getWidth();
-        float realHeight = svg.getHeight();
-        int width = Math.round(realWidth);
-        int height = Math.round(realHeight);
-        Double scaleX = null, scaleY = null;
+        float sourceWidth = svg.getWidth();
+        float sourceHeight = svg.getHeight();
+        int realWidth = Math.round(GuiSizesHelper.getSizeDpiAdjusted(sourceWidth));
+        int realHeight = Math.round(GuiSizesHelper.getSizeDpiAdjusted(sourceHeight));
+        Double scaleX, scaleY;
         if (dim.width != -1) {
-            width = dim.width;
-            scaleX = (double) width / realWidth;
+            realWidth = dim.width;
+            scaleX = (double) realWidth / sourceWidth;
             if (dim.height == -1) {
                 scaleY = scaleX;
-                height = (int) Math.round(realHeight * scaleY);
+                realHeight = (int) Math.round(sourceHeight * scaleY);
             } else {
-                height = dim.height;
-                scaleY = (double) height / realHeight;
+                realHeight = dim.height;
+                scaleY = (double) realHeight / sourceHeight;
             }
         } else if (dim.height != -1) {
-            height = dim.height;
-            scaleX = scaleY = (double) height / realHeight;
-            width = (int) Math.round(realWidth * scaleX);
-        }
-        if (width == 0 || height == 0) {
+            realHeight = dim.height;
+            scaleX = scaleY = (double) realHeight / sourceHeight;
+            realWidth = (int) Math.round(sourceWidth * scaleX);
+        }
+        else {
+            scaleX = scaleY = (double) realHeight / sourceHeight;
+        }
+
+        if (realWidth == 0 || realHeight == 0) {
             return null;
         }
-        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        BufferedImage img = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
         Graphics2D g = img.createGraphics();
-        g.setClip(0, 0, width, height);
-        if (scaleX != null && scaleY != null) {
-            g.scale(scaleX, scaleY);
-        }
+        g.setClip(0, 0, realWidth, realHeight);
+        g.scale(scaleX, scaleY);
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         try {
Index: trunk/src/org/openstreetmap/josm/tools/ImageResource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageResource.java	(revision 10356)
+++ trunk/src/org/openstreetmap/josm/tools/ImageResource.java	(revision 10358)
@@ -14,4 +14,5 @@
 
 import com.kitfox.svg.SVGDiagram;
+import org.openstreetmap.josm.gui.util.GuiSizesHelper;
 
 /**
@@ -50,5 +51,27 @@
         CheckParameterUtil.ensureParameterNotNull(img);
         this.baseImage = img;
+
+        img = scaleBaseImageIfNeeded(img);
+
         imgCache.put(DEFAULT_DIMENSION, img);
+    }
+
+    /** Scale image according to screen DPI if needed.
+     *
+     * @param img an image loaded from file (it's width and height are virtual pixels)
+     * @return original img if virtual size is the same as real size or new image resized to real pixels
+     */
+    private static Image scaleBaseImageIfNeeded(Image img) {
+        int imgWidth = img.getWidth(null);
+        int imgHeight = img.getHeight(null);
+        int realWidth = GuiSizesHelper.getSizeDpiAdjusted(imgWidth);
+        int realHeight = GuiSizesHelper.getSizeDpiAdjusted(imgHeight);
+        if (realWidth != -1 && realHeight != -1 && imgWidth != realWidth && imgHeight != realHeight) {
+            Image realImage = img.getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH);
+            BufferedImage bimg = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
+            bimg.getGraphics().drawImage(realImage, 0, 0, null);
+            img = bimg;
+        }
+        return img;
     }
 
@@ -88,7 +111,10 @@
      */
     public void getImageIcon(AbstractAction a) {
-        ImageIcon icon = getImageIconBounded(ImageProvider.ImageSizes.SMALLICON.getImageDimension());
+        Dimension iconDimension = ImageProvider.ImageSizes.SMALLICON.getImageDimension();
+        ImageIcon icon = getImageIconBounded(iconDimension);
         a.putValue(Action.SMALL_ICON, icon);
-        icon = getImageIconBounded(ImageProvider.ImageSizes.LARGEICON.getImageDimension());
+
+        iconDimension = ImageProvider.ImageSizes.LARGEICON.getImageDimension();
+        icon = getImageIconBounded(iconDimension);
         a.putValue(Action.LARGE_ICON_KEY, icon);
         a.putValue("ImageResource", this);
@@ -123,5 +149,6 @@
         }
         if (svg != null) {
-            BufferedImage bimg = ImageProvider.createImageFromSvg(svg, dim);
+            Dimension realDim = GuiSizesHelper.getDimensionDpiAdjusted(dim);
+            BufferedImage bimg = ImageProvider.createImageFromSvg(svg, realDim);
             if (bimg == null) {
                 return null;
@@ -137,17 +164,17 @@
             if (baseImage == null) throw new AssertionError();
 
-            int width = dim.width;
-            int height = dim.height;
+            int realWidth = GuiSizesHelper.getSizeDpiAdjusted(dim.width);
+            int realHeight = GuiSizesHelper.getSizeDpiAdjusted(dim.height);
             ImageIcon icon = new ImageIcon(baseImage);
-            if (width == -1 && height == -1) {
-                width = icon.getIconWidth();
-                height = icon.getIconHeight();
-            } else if (width == -1) {
-                width = Math.max(1, icon.getIconWidth() * height / icon.getIconHeight());
-            } else if (height == -1) {
-                height = Math.max(1, icon.getIconHeight() * width / icon.getIconWidth());
-            }
-            Image i = icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH);
-            BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+            if (realWidth == -1 && realHeight == -1) {
+                realWidth = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconWidth());
+                realHeight = GuiSizesHelper.getSizeDpiAdjusted(icon.getIconHeight());
+            } else if (realWidth == -1) {
+                realWidth = Math.max(1, icon.getIconWidth() * realHeight / icon.getIconHeight());
+            } else if (realHeight == -1) {
+                realHeight = Math.max(1, icon.getIconHeight() * realWidth / icon.getIconWidth());
+            }
+            Image i = icon.getImage().getScaledInstance(realWidth, realHeight, Image.SCALE_SMOOTH);
+            BufferedImage bimg = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);
             bimg.getGraphics().drawImage(i, 0, 0, null);
             if (overlayInfo != null) {
@@ -172,20 +199,20 @@
         if (maxSize.width < -1 || maxSize.width == 0 || maxSize.height < -1 || maxSize.height == 0)
             throw new IllegalArgumentException(maxSize+" is invalid");
-        float realWidth;
-        float realHeight;
+        float sourceWidth;
+        float sourceHeight;
         int maxWidth = maxSize.width;
         int maxHeight = maxSize.height;
         if (svg != null) {
-            realWidth = svg.getWidth();
-            realHeight = svg.getHeight();
+            sourceWidth = svg.getWidth();
+            sourceHeight = svg.getHeight();
         } else {
             if (baseImage == null) throw new AssertionError();
             ImageIcon icon = new ImageIcon(baseImage);
-            realWidth = icon.getIconWidth();
-            realHeight = icon.getIconHeight();
-            if (realWidth <= maxWidth) {
+            sourceWidth = icon.getIconWidth();
+            sourceHeight = icon.getIconHeight();
+            if (sourceWidth <= maxWidth) {
                 maxWidth = -1;
             }
-            if (realHeight <= maxHeight) {
+            if (sourceHeight <= maxHeight) {
                 maxHeight = -1;
             }
@@ -198,5 +225,5 @@
         else if (maxHeight == -1)
             return getImageIcon(new Dimension(maxWidth, -1));
-        else if (realWidth / maxWidth > realHeight / maxHeight)
+        else if (sourceWidth / maxWidth > sourceHeight / maxHeight)
             return getImageIcon(new Dimension(maxWidth, -1));
         else
