001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.tools; 003 004import java.awt.Dimension; 005import java.awt.GraphicsEnvironment; 006import java.awt.Toolkit; 007 008import org.openstreetmap.josm.spi.preferences.Config; 009 010/** 011 * Support class to handle size information of Gui elements 012 * This is needed, because display resolution may vary a lot and a common set 013 * of sizes wont work for all users alike. 014 * @since 12682 (moved from {@code gui.util} package) 015 * @since 10358 016 */ 017public final class GuiSizesHelper { 018 019 private GuiSizesHelper() { 020 // Hide default constructor for utils classes 021 } 022 023 /** cache value for screen resolution */ 024 private static float screenDPI = -1; 025 026 /** 027 * Request the screen resolution (cached) 028 * @return screen resolution in DPI 029 */ 030 private static float getScreenDPI() { 031 if (screenDPI == -1) { 032 synchronized (GuiSizesHelper.class) { 033 if (screenDPI == -1) { 034 float scalePref = (float) Config.getPref().getDouble("gui.scale", 1.0); 035 if (scalePref != 0) { 036 screenDPI = 96f * scalePref; 037 } else { 038 if (!GraphicsEnvironment.isHeadless()) { 039 screenDPI = Toolkit.getDefaultToolkit().getScreenResolution(); 040 } else { 041 screenDPI = 96; 042 } 043 } 044 } 045 } 046 } 047 return screenDPI; 048 } 049 050 /** 051 * Returns coefficient of monitor pixel density. All hardcoded sizes must be multiplied by this value. 052 * 053 * @return float value. 1 - means standard monitor, 2 and high - "retina" display. 054 */ 055 public static float getPixelDensity() { 056 return getScreenDPI() / 96f; 057 } 058 059 /** 060 * Sets coefficient of monitor pixel density. 061 * @param pixelDensity coefficient of monitor pixel density to be set. 062 */ 063 public static void setPixelDensity(float pixelDensity) { 064 screenDPI = pixelDensity * 96f; 065 } 066 067 /** 068 * Check if a high DPI resolution is used 069 * @return <code>true</code> for HIDPI screens 070 */ 071 public static boolean isHiDPI() { 072 return getPixelDensity() >= 2f; 073 } 074 075 /** 076 * Returns a resolution adapted size 077 * @param size Size value to adapt (base size is a low DPI screen) 078 * @return adapted size (may be unmodified) 079 */ 080 public static int getSizeDpiAdjusted(int size) { 081 if (size <= 0) return size; 082 return Math.round(size * getScreenDPI() / 96); 083 } 084 085 /** 086 * Returns a resolution adapted size 087 * @param size Size value to adapt (base size is a low DPI screen) 088 * @return adapted size (may be unmodified) 089 */ 090 public static float getSizeDpiAdjusted(float size) { 091 if (size <= 0f) return size; 092 return size * getScreenDPI() / 96; 093 } 094 095 /** 096 * Returns a resolution adapted size 097 * @param size Size value to adapt (base size is a low DPI screen) 098 * @return adapted size (may be unmodified) 099 */ 100 public static double getSizeDpiAdjusted(double size) { 101 if (size <= 0d) return size; 102 return size * getScreenDPI() / 96; 103 } 104 105 /** 106 * Returns a resolution adapted Dimension 107 * @param dim Dimension value to adapt (base size is a low DPI screen) 108 * @return adapted dimension (may be unmodified) 109 */ 110 public static Dimension getDimensionDpiAdjusted(Dimension dim) { 111 float pixelPerInch = getScreenDPI(); 112 int width = dim.width; 113 int height = dim.height; 114 if (dim.width > 0) { 115 width = Math.round(dim.width * pixelPerInch / 96); 116 } 117 118 if (dim.height > 0) { 119 height = Math.round(dim.height * pixelPerInch / 96); 120 } 121 122 return new Dimension(width, height); 123 } 124}