- 浏览: 400813 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (309)
- xaml C# wpf (0)
- scala java inner clas (1)
- Tools UML Eclipse UML2 (1)
- Timer .NET Framework (1)
- perl (6)
- python function paramter (1)
- Python Docstring (1)
- Python how to compare types (1)
- Python (8)
- java (5)
- C# (76)
- C# WPF (0)
- p4 (0)
- WPF (46)
- .net (6)
- xaml (1)
- javascript (40)
- windows (10)
- scala (4)
- winform (1)
- c++ (48)
- tools (12)
- cmd (1)
- os (0)
- CI (0)
- shell (0)
- C (2)
- haskell (49)
- functional (1)
- tool (1)
- gnu (1)
- linux (1)
- kaskell (0)
- svn (0)
- wcf (3)
- android (1)
最新评论
This is a repost of the dev center document, under the same title. you can find the same document under DPI and Device-Independent Pixels
To program effectively with Windows graphics, you must understand two related concepts:
- Dots per inch (DPI)
- Device-independent pixel (DIPs).
Let's start with DPI. This will require a short detour into typography. In typography, the size of type is measured in units calledpoints. One point equals 1/72 of an inch.
Note This is the desktop publishing definition of point. Historically, the exact measure of a point has varied.
For example, a 12-point font is designed to fit within a 1/6" (12/72) line of text. Obviously, this does not mean that every character in the font is exactly 1/6" tall. In fact, some characters might be taller than 1/6". For example, in many fonts the character Å is taller than the nominal height of the font. To display correctly, the font needs some additional space between the text. This space is called the leading.
The following illustration shows a 72-point font. The solid lines show a 1" tall bounding box around the text. The dashed line is called the baseline. Most of the characters in a font rest on the baseline. The height of the font includes the portion above the baseline (the ascent) and the portion below the baseline (the descent). In the font shown here, the ascent is 56 points and the descent is 16 points.
An illustration that shows a 72-point font.
When it comes to a computer display, however, measuring text size is problematic, because pixels are not all the same size. The size of a pixel depends on two factors: the display resolution, and the physical size of the monitor. Therefore, physical inches are not a useful measure, because there is no fixed relation between physical inches and pixels. Instead, fonts are measured in logical units. A 72-point font is defined to be one logical inch tall. Logical inches are then converted to pixels. For many years, Windows used the following conversion: One logical inch equals 96 pixels. Using this scaling factor, a 72-point font is rendered as 96 pixels tall. A 12-point font is 16 pixels tall.
This scaling factor is described as 96 dots per inch (DPI). The term dots derives from printing, where physical dots of ink are put onto paper. For computer displays, it would be more accurate to say 96 pixels per logical inch, but the term DPI has stuck.
Because actual pixel sizes vary, text that is readable on one monitor might be too small on another monitor. Also, people have different preferences—some people prefer larger text. For this reason, Windows enables the user to change the DPI setting. For example, if the user sets the display to 144 DPI, a 72-point font is 144 pixels tall. The standard DPI settings are 100% (96 DPI), 125% (120 DPI), and 150% (144 DPI). The user can also apply a custom setting. Starting in Windows 7, DPI is a per-user setting.
DWM Scaling
If a program does not account for DPI, the following defects might be apparent at high-DPI settings:
- Clipped UI elements.
- Incorrect layout.
- Pixilated bitmaps and icons.
- Incorrect mouse coordinates, which can affect hit testing, drag and drop, and so forth.
To ensure that older programs work at high-DPI settings, the DWM implements a useful fallback. If a program is not marked as being DPI aware, the DWM will scale the entire UI to match the DPI setting. For example, at 144 DPI, the UI is scaled by 150%, including text, graphics, controls, and window sizes. If the program creates a 500 × 500 window, the window actually appears as 750 × 750 pixels, and the contents of the window are scaled accordingly.
This behavior means that older programs "just work" at high-DPI settings. However, scaling also results in a somewhat blurry appearance, because the scaling is applied after the window is drawn.
DPI-Aware Applications
To avoid DWM scaling, a program can mark itself as DPI-aware. This tells the DWM not to perform any automatic DPI scaling. All new applications should be designed to be DPI-aware, because DPI awareness improves the appearance of the UI at higher DPI settings.
A program declares itself DPI-aware through its application manifest. A manifest is a simply an XML file that describes a DLL or application. The manifest is typically embedded in the executable file, although it can be provided as a separate file. A manifest contains information such as DLL dependencies, the requested privilege level, and what version of Windows the program was designed for.
To declare that your program is DPI-aware, include the following information in the manifest.
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" > <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> </asmv3:windowsSettings> </asmv3:application> </assembly>
The listing shown here is only a partial manifest, but the Visual Studio linker generates the rest of the manifest for you automatically. To include a partial manifest in your project, perform the following steps in Visual Studio.
- On the Project menu, click Property.
- In the left pane, expand Configuration Properties, expand Manifest Tool, and then click Input and Output.
- In the Additional Manifest Files text box, type the name of the manifest file, and then click OK.
By marking your program as DPI-aware, you are telling the DWM not to scale your application window. Now if you create a 500 × 500 window, the window will occupy 500 × 500 pixels, regardless of the user's DPI setting.
GDI and DPI
GDI drawing is measured in pixels. That means if your program is marked as DPI-aware, and you ask GDI to draw a 200 × 100 rectangle, the resulting rectangle will be 200 pixels wide and 100 pixels tall on the screen. However, GDI font sizes are scaled to the current DPI setting. In other words, if you create a 72-point font, the size of the font will be 96 pixels at 96 DPI, but 144 pixels at 144 DPI. Here is a 72 point font rendered at 144 DPI using GDI.
A diagram that shows DPI font scaling in GDI.
If your application is DPI-aware and you use GDI for drawing, scale all of your drawing coordinates to match the DPI.
Direct2D and DPI
Direct2D automatically performs scaling to match the DPI setting. In Direct2D, coordinates are measured in units called device-independent pixels (DIPs). A DIP is defined as 1/96th of a logical inch. In Direct2D, all drawing operations are specified in DIPs and then scaled to the current DPI setting.
96 | 1 pixel |
120 | 1.25 pixels |
144 | 1.5 pixels |
For example, if the user's DPI setting is 144 DPI, and you ask Direct2D to draw a 200 × 100 rectangle, the rectangle will be 300 × 150 physical pixels. In addition, DirectWrite measures font sizes in DIPs, rather than points. To create a 12-point font, specify 16 DIPs (12 points = 1/6 logical inch = 96/6 DIPs). When the text is drawn on the screen, Direct2D converts the DIPs to physical pixels. The benefit of this system is that the units of measurement are consistent for both text and drawing, regardless of the current DPI setting.
A word of caution: Mouse and window coordinates are still given in physical pixels, not DIPs. For example, if you process theWM_LBUTTONDOWN message, the mouse-down position is given in physical pixels. To draw a point at that position, you must convert the pixel coordinates to DIPs.
Converting Physical Pixels to DIPs
The conversion from physical pixels to DIPs uses the following formula.
To get the DPI setting, call the ID2D1Factory::GetDesktopDpi method. The DPI is returned as two floating-point values, one for the x-axis and one for the y-axis. In theory, these values can differ. Calculate a separate scaling factor for each axis.
float g_DPIScaleX = 1.0f; float g_DPIScaleY = 1.0f; void InitializeDPIScale(ID2D1Factory *pFactory) { FLOAT dpiX, dpiY; pFactory->GetDesktopDpi(&dpiX, &dpiY); g_DPIScaleX = dpiX/96.0f; g_DPIScaleY = dpiY/96.0f; } template <typename T> float PixelsToDipsX(T x) { return static_cast<float>(x) / g_DPIScaleX; } template <typename T> float PixelsToDipsY(T y) { return static_cast<float>(y) / g_DPIScaleY; }
Here is an alternate way to get the DPI setting if you are not using Direct2D:
void InitializeDPIScale(HWND hwnd) { HDC hdc = GetDC(hwnd); g_DPIScaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f; g_DPIScaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0f; ReleaseDC(hwnd, hdc); }
Resizing the Render Target
If the size of the window changes, you must resize the render target to match. In most cases, you will also need to update the layout and repaint the window. The following code shows these steps.
void MainWindow::Resize() { if (pRenderTarget != NULL) { RECT rc; GetClientRect(m_hwnd, &rc); D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom); pRenderTarget->Resize(size); CalculateLayout(); InvalidateRect(m_hwnd, NULL, FALSE); } }
The GetClientRect function gets the new size of the client area, in physical pixels (not DIPs). TheID2D1HwndRenderTarget::Resize method updates the size of the render target, also specified in pixels. The InvalidateRectfunction forces a repaint by adding the entire client area to the window's update region. (See Painting the Window, in Module 1.)
As the window grows or shrinks, you will typically need to recalculate the position of the objects that you draw. For example, in the circle program, the radius and center point must be updated:
void MainWindow::CalculateLayout() { if (pRenderTarget != NULL) { D2D1_SIZE_F size = pRenderTarget->GetSize(); const float x = size.width / 2; const float y = size.height / 2; const float radius = min(x, y); ellipse = D2D1::Ellipse(D2D1::Point2F(x, y), radius, radius); } }
The ID2D1RenderTarget::GetSize method returns the size of the render target in DIPs (not pixels), which is the appropriate unit for calculating layout. There is a closely related method, ID2D1RenderTarget::GetPixelSize, that returns the size in physical pixels. For an HWND render target, this value matches the size returned by GetClientRect. But remember that drawing is performed in DIPs, not pixels.
Next
发表评论
-
C# - PInvoke, gotchas on the RegisterClassEx and the CreateWindowEx
2013-06-24 13:49 2576I get an exception message li ... -
c# - Use PInvoke to create simple win32 Application
2013-06-24 11:59 10952In this post, .net platform h ... -
windows - trying to create WIN32 application with PInvoke
2013-06-19 14:34 0While it is stupid to do such ... -
Windows - communication with Mailslots
2012-12-19 14:50 1157Mailslot is some mechanism on W ... -
tools - gpupdate to update the group policy settings
2012-11-20 17:23 491you can update your local group ... -
Exceed to remote connect to Linux box
2012-11-13 17:58 364in this post, I will introduce ... -
Cmd - Remove directories on Windows
2012-10-31 11:18 816on windows, there is no rm -rf ... -
windows - create symbolic/hard links
2012-09-19 14:30 739If you are working on the windo ... -
windows - Maximum Path Length Limitation
2012-09-11 11:13 1232Maximum Path Length Limitat ... -
Windows Print Metric/Unit Systems in System.Printing and System.Drawing.Priting
2012-08-03 15:59 1687There are two worlds in the win ... -
Windows Desktop Document and Printing, and the Printing System
2012-08-03 15:26 1267This blog is mainly a entry/int ...
相关推荐
- **dip (device-independent pixels)**:设备独立像素,用于构建虚拟坐标系,使得界面布局不依赖于具体的屏幕密度。在实际开发中,应尽量使用 dip 单位而非像素单位 px,以确保应用能自适应不同屏幕。 - **dp ...
在Android开发中,常见的像素单位有px(pixels)、dip(device-independent pixels)、sp(scaled pixels)等,这些单位各有特点,适用于不同的场景。 - **px (Pixels)**:像素是屏幕显示的基本单位,一个像素通常...
2、度量单位含义dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。 dp: dip是一样的px: pixels
**dip**(device-independent pixels),也称为**dp**(density-independent pixels),是一种与设备无关的像素单位,用于定义布局中的元素大小。它根据设备的屏幕密度来确定实际的物理像素值,目的是确保不同设备上的UI...
3. **使用比例尺寸单位**:在布局文件中,尽量使用dp(density-independent pixels)或sp(scale-independent pixels)作为尺寸单位,而不是像素(px)。dp不受设备密度影响,而sp则考虑了字体大小的缩放。 4. **...
- **使用比例单位(dp和sp)**:dp(density-independent pixels)用于尺寸,sp(scale-independent pixels)用于字体大小,这两个单位会根据设备的像素密度进行自动缩放。 - **使用Android Studio的预览功能**:...
5. **dp(设备独立像素)**:dp,全称为device-independent pixels,是一种基于设备密度的抽象单位。在160dpi(dots per inch,每英寸点数)的标准屏幕密度下,1dp等于1px。在其他密度的屏幕上,系统会自动调整dp的...
在编写XML布局文件时,使用“dp”(density-independent pixels)和“sp”(scale-independent pixels)作为尺寸单位,可以确保元素在不同DPI设备上保持相对一致的大小。dp适用于布局元素,sp则用于文本大小,考虑...
dp(Device independent pixels,设备独立像素) dp 是 Android 中的一种长度单位,它是设备独立的,即不依赖于设备的硬件。dp 的长度是以设备的屏幕密度(density)为基准的,一般来说,1dp 等于 1px 在密度为 160...
API: All API functions now accept and return device-independent-pixels API: Fixed input panel not running on_cancel when re-showing the input panel API: Fixed selector scoring with the & operator API:...
独立像素dp: (dips device independent pixels): DP用在Android上,PT用在Apple上 衡量设备的物理像素密度 DPI 和 PPI DPI 指 Dots Per Inch(dpi ldpi mdpi hdpi for android) PPI指 Pixels Per Inch。 window....
1. dip (device independent pixels) - 设备独立像素: 这是一种基于设备的物理特性(如屏幕密度)的抽象单位,旨在确保UI元素在不同分辨率的屏幕上看起来大小一致。例如,1dip在160dpi的设备上等于1px。当设计适配...
而dp(device independent pixels)和pt(point)则是设备无关像素,它们不受设备物理分辨率的影响。dpr(devicePixelRatio)表示设备像素缩放比,用于计算物理像素和逻辑像素之间的关系。例如,iPhone5的屏幕分辨率...
DPI,全称为Device Independent Pixels,是衡量屏幕像素密度的一个单位,直接影响着设备的显示效果。高DPI意味着更高的像素密度,显示内容会更清晰;低DPI则会让屏幕内容看起来更大,更适合阅读或操作。在平板模式下...
1. **设备无关单位:** WPF使用设备无关单位(Device Independent Pixels, DIPs)来定义UI元素的尺寸,每个设备无关单位等于1/96英寸。这意味着无论实际屏幕的DPI如何,元素的实际物理尺寸在各种分辨率下都能保持...
为了适应不同PPI屏幕的显示差异,引入了设备独立像素(Device Independent Pixels),在iOS上称为PT(Points),在Android上称为DIP(Device Independent Pixels)或DP。它们是为了确保不同屏幕尺寸和分辨率的设备...
- **dip (device independent pixels)**:与dp相同,旧版本的Android使用的术语。 - **pt (points)**:点,1pt等于1/72英寸。在印刷业中常见,但在Android中使用较少。 - **in (inches)**:英寸,长度单位。 - **mm ...
dp (dip): 即设备无关像素(device independent pixels),这种尺寸单位在不同设备上的物理大小相同。 px:即像素(pixel),这个不用多说。 pt:通常用来作为字体的尺寸单位,1 pt相当于1/72英寸。 inch:英寸...
1. **线宽与分辨率的关系**:WPF中的线条宽度是基于设备独立像素(Device Independent Pixels, DPI)的,这意味着当ViewBox进行缩放时,如果线宽设置得太小,它可能会在高DPI环境中变得难以察觉。 2. **缩放比例的...
1. dip(设备独立像素,Device Independent Pixels):dip是一种抽象单位,旨在确保在不同密度的屏幕上元素看起来具有相同的大小。它不直接对应于物理像素,而是根据设备的像素密度进行调整。例如,在160dpi的设备上...