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 * Check if a high DPI resolution is used 061 * @return <code>true</code> for HIDPI screens 062 */ 063 public static boolean isHiDPI() { 064 return getPixelDensity() >= 2f; 065 } 066 067 /** 068 * Returns a resolution adapted size 069 * @param size Size value to adapt (base size is a low DPI screen) 070 * @return adapted size (may be unmodified) 071 */ 072 public static int getSizeDpiAdjusted(int size) { 073 if (size <= 0) return size; 074 return Math.round(size * getScreenDPI() / 96); 075 } 076 077 /** 078 * Returns a resolution adapted size 079 * @param size Size value to adapt (base size is a low DPI screen) 080 * @return adapted size (may be unmodified) 081 */ 082 public static float getSizeDpiAdjusted(float size) { 083 if (size <= 0f) return size; 084 return size * getScreenDPI() / 96; 085 } 086 087 /** 088 * Returns a resolution adapted size 089 * @param size Size value to adapt (base size is a low DPI screen) 090 * @return adapted size (may be unmodified) 091 */ 092 public static double getSizeDpiAdjusted(double size) { 093 if (size <= 0d) return size; 094 return size * getScreenDPI() / 96; 095 } 096 097 /** 098 * Returns a resolution adapted Dimension 099 * @param dim Dimension value to adapt (base size is a low DPI screen) 100 * @return adapted dimension (may be unmodified) 101 */ 102 public static Dimension getDimensionDpiAdjusted(Dimension dim) { 103 float pixelPerInch = getScreenDPI(); 104 int width = dim.width; 105 int height = dim.height; 106 if (dim.width > 0) { 107 width = Math.round(dim.width * pixelPerInch / 96); 108 } 109 110 if (dim.height > 0) { 111 height = Math.round(dim.height * pixelPerInch / 96); 112 } 113 114 return new Dimension(width, height); 115 } 116}