DisplayMetrics.java revision 64f59342d41849bd365cb43fad7505d5e3daa417
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.util; 18 19import android.content.res.CompatibilityInfo; 20import android.content.res.Configuration; 21import android.os.*; 22 23 24/** 25 * A structure describing general information about a display, such as its 26 * size, density, and font scaling. 27 */ 28public class DisplayMetrics { 29 /** 30 * The reference density used throughout the system. 31 * 32 * @hide Pending API council approval 33 */ 34 public static final int DEFAULT_DENSITY = 160; 35 36 /** 37 * The device's density. 38 * @hide 39 */ 40 public static final int DEVICE_DENSITY = getDeviceDensity(); 41 42 /** 43 * The absolute width of the display in pixels. 44 */ 45 public int widthPixels; 46 /** 47 * The absolute height of the display in pixels. 48 */ 49 public int heightPixels; 50 /** 51 * The logical density of the display. This is a scaling factor for the 52 * Density Independent Pixel unit, where one DIP is one pixel on an 53 * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 54 * providing the baseline of the system's display. Thus on a 160dpi screen 55 * this density value will be 1; on a 106 dpi screen it would be .75; etc. 56 * 57 * <p>This value does not exactly follow the real screen size (as given by 58 * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of 59 * the overall UI in steps based on gross changes in the display dpi. For 60 * example, a 240x320 screen will have a density of 1 even if its width is 61 * 1.8", 1.3", etc. However, if the screen resolution is increased to 62 * 320x480 but the screen size remained 1.5"x2" then the density would be 63 * increased (probably to 1.5). 64 * 65 * @see #DEFAULT_DENSITY 66 */ 67 public float density; 68 /** 69 * A scaling factor for fonts displayed on the display. This is the same 70 * as {@link #density}, except that it may be adjusted in smaller 71 * increments at runtime based on a user preference for the font size. 72 */ 73 public float scaledDensity; 74 /** 75 * The exact physical pixels per inch of the screen in the X dimension. 76 */ 77 public float xdpi; 78 /** 79 * The exact physical pixels per inch of the screen in the Y dimension. 80 */ 81 public float ydpi; 82 83 public DisplayMetrics() { 84 } 85 86 public void setTo(DisplayMetrics o) { 87 widthPixels = o.widthPixels; 88 heightPixels = o.heightPixels; 89 density = o.density; 90 scaledDensity = o.scaledDensity; 91 xdpi = o.xdpi; 92 ydpi = o.ydpi; 93 } 94 95 public void setToDefaults() { 96 widthPixels = 0; 97 heightPixels = 0; 98 density = DEVICE_DENSITY / (float) DEFAULT_DENSITY; 99 scaledDensity = density; 100 xdpi = DEVICE_DENSITY; 101 ydpi = DEVICE_DENSITY; 102 } 103 104 /** 105 * Update the display metrics based on the compatibility info and orientation 106 * {@hide} 107 */ 108 public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) { 109 int xOffset = 0; 110 if (!compatibilityInfo.isConfiguredExpandable()) { 111 // Note: this assume that configuration is updated before calling 112 // updateMetrics method. 113 int defaultWidth; 114 int defaultHeight; 115 switch (orientation) { 116 case Configuration.ORIENTATION_LANDSCAPE: { 117 defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density); 118 defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density); 119 break; 120 } 121 case Configuration.ORIENTATION_PORTRAIT: 122 case Configuration.ORIENTATION_SQUARE: 123 default: { 124 defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density); 125 defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density); 126 break; 127 } 128 case Configuration.ORIENTATION_UNDEFINED: { 129 // don't change 130 return; 131 } 132 } 133 134 if (defaultWidth == widthPixels && defaultHeight == heightPixels) { 135 // the screen size is same as expected size. make it expandable 136 compatibilityInfo.setExpandable(true); 137 } else { 138 compatibilityInfo.setExpandable(false); 139 // adjust the size only when the device's screen is bigger. 140 if (defaultWidth < widthPixels) { 141 // content/window's x offset in original pixels 142 xOffset = ((widthPixels - defaultWidth) / 2); 143 widthPixels = defaultWidth; 144 } 145 if (defaultHeight < heightPixels) { 146 heightPixels = defaultHeight; 147 } 148 } 149 } 150 compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels); 151 if (compatibilityInfo.isScalingRequired()) { 152 float invertedRatio = compatibilityInfo.applicationInvertedScale; 153 density *= invertedRatio; 154 scaledDensity *= invertedRatio; 155 xdpi *= invertedRatio; 156 ydpi *= invertedRatio; 157 widthPixels *= invertedRatio; 158 heightPixels *= invertedRatio; 159 } 160 } 161 162 @Override 163 public String toString() { 164 return "DisplayMetrics{density=" + density + ", width=" + widthPixels + 165 ", height=" + heightPixels + ", scaledDensity=" + scaledDensity + 166 ", xdpi=" + xdpi + ", ydpi=" + ydpi + "}"; 167 } 168 169 private static int getDeviceDensity() { 170 // qemu.sf.lcd_density can be used to override ro.sf.lcd_density 171 // when running in the emulator, allowing for dynamic configurations. 172 // The reason for this is that ro.sf.lcd_density is write-once and is 173 // set by the init process when it parses build.prop before anything else. 174 return SystemProperties.getInt("qemu.sf.lcd_density", 175 SystemProperties.getInt("ro.sf.lcd_density", DEFAULT_DENSITY)); 176 } 177} 178