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