You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Trac3r-rust/doc/winit/dpi/index.html

75 lines
12 KiB

5 years ago
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `dpi` mod in crate `winit`."><meta name="keywords" content="rust, rustlang, rust-lang, dpi"><title>winit::dpi - Rust</title><link rel="stylesheet" type="text/css" href="../../normalize.css"><link rel="stylesheet" type="text/css" href="../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../dark.css"><link rel="stylesheet" type="text/css" href="../../light.css" id="themeStyle"><script src="../../storage.js"></script><noscript><link rel="stylesheet" href="../../noscript.css"></noscript><link rel="shortcut icon" href="../../favicon.ico"><style type="text/css">#crate-search{background-image:url("../../down-arrow.svg");}</style></head><body class="rustdoc mod"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../../winit/index.html'><div class='logo-container'><img src='../../rust-logo.png' alt='logo'></div></a><p class='location'>Module dpi</p><div class="sidebar-elems"><div class="block items"><ul><li><a href="#structs">Structs</a></li><li><a href="#functions">Functions</a></li></ul></div><p class='location'><a href='../index.html'>winit</a></p><script>window.sidebarCurrent = {name: 'dpi', ty: 'mod', relpath: '../'};</script><script defer src="../sidebar-items.js"></script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!"><img src="../../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices"></div></div><script src="../../theme.js"></script><nav class="sub"><form class="search-form js-only"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><a id="settings-menu" href="../../settings.html"><img src="../../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><h1 class='fqn'><span class='out-of-band'><span id='render-detail'><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class='inner'>&#x2212;</span>]</a></span><a class='srclink' href='../../src/winit/dpi.rs.html#2-331' title='goto source code'>[src]</a></span><span class='in-band'>Module <a href='../index.html'>winit</a>::<wbr><a class="mod" href=''>dpi</a></span></h1><div class='docblock'><p>DPI is important, so read the docs for this module if you don't want to be confused.</p>
<p>Originally, <code>winit</code> dealt entirely in physical pixels (excluding unintentional inconsistencies), but now all
window-related functions both produce and consume logical pixels. Monitor-related functions still use physical
pixels, as do any context-related functions in <code>glutin</code>.</p>
<p>If you've never heard of these terms before, then you're not alone, and this documentation will explain the
concepts.</p>
<p>Modern screens have a defined physical resolution, most commonly 1920x1080. Indepedent of that is the amount of
space the screen occupies, which is to say, the height and width in millimeters. The relationship between these two
measurements is the <em>pixel density</em>. Mobile screens require a high pixel density, as they're held close to the
eyes. Larger displays also require a higher pixel density, hence the growing presence of 1440p and 4K displays.</p>
<p>So, this presents a problem. Let's say we want to render a square 100px button. It will occupy 100x100 of the
screen's pixels, which in many cases, seems perfectly fine. However, because this size doesn't account for the
screen's dimensions or pixel density, the button's size can vary quite a bit. On a 4K display, it would be unusably
small.</p>
<p>That's a description of what happens when the button is 100x100 <em>physical</em> pixels. Instead, let's try using 100x100
<em>logical</em> pixels. To map logical pixels to physical pixels, we simply multiply by the DPI (dots per inch) factor.
On a &quot;typical&quot; desktop display, the DPI factor will be 1.0, so 100x100 logical pixels equates to 100x100 physical
pixels. However, a 1440p display may have a DPI factor of 1.25, so the button is rendered as 125x125 physical pixels.
Ideally, the button now has approximately the same perceived size across varying displays.</p>
<p>Failure to account for the DPI factor can create a badly degraded user experience. Most notably, it can make users
feel like they have bad eyesight, which will potentially cause them to think about growing elderly, resulting in
them entering an existential panic. Once users enter that state, they will no longer be focused on your application.</p>
<p>There are two ways to get the DPI factor:</p>
<ul>
<li>You can track the <a href="../enum.WindowEvent.html#variant.HiDpiFactorChanged"><code>HiDpiFactorChanged</code></a> event of your
windows. This event is sent any time the DPI factor changes, either because the window moved to another monitor,
or because the user changed the configuration of their screen.</li>
<li>You can also retrieve the DPI factor of a monitor by calling
<a href="../struct.MonitorId.html#method.get_hidpi_factor"><code>MonitorId::get_hidpi_factor</code></a>, or the
current DPI factor applied to a window by calling
<a href="../struct.Window.html#method.get_hidpi_factor"><code>Window::get_hidpi_factor</code></a>, which is roughly equivalent
to <code>window.get_current_monitor().get_hidpi_factor()</code>.</li>
</ul>
<p>Depending on the platform, the window's actual DPI factor may only be known after
the event loop has started and your window has been drawn once. To properly handle these cases,
the most robust way is to monitor the <a href="../enum.WindowEvent.html#variant.HiDpiFactorChanged"><code>HiDpiFactorChanged</code></a>
event and dynamically adapt your drawing logic to follow the DPI factor.</p>
<p>Here's an overview of what sort of DPI factors you can expect, and where they come from:</p>
<ul>
<li><strong>Windows:</strong> On Windows 8 and 10, per-monitor scaling is readily configured by users from the display settings.
While users are free to select any option they want, they're only given a selection of &quot;nice&quot; DPI factors, i.e.
1.0, 1.25, 1.5... on Windows 7, the DPI factor is global and changing it requires logging out.</li>
<li><strong>macOS:</strong> The buzzword is &quot;retina displays&quot;, which have a DPI factor of 2.0. Otherwise, the DPI factor is 1.0.
Intermediate DPI factors are never used, thus 1440p displays/etc. aren't properly supported. It's possible for any
display to use that 2.0 DPI factor, given the use of the command line.</li>
<li><strong>X11:</strong> On X11, we calcuate the DPI factor based on the millimeter dimensions provided by XRandR. This can
result in a wide range of possible values, including some interesting ones like 1.0833333333333333. This can be
overridden using the <code>WINIT_HIDPI_FACTOR</code> environment variable, though that's not recommended.</li>
<li><strong>Wayland:</strong> On Wayland, DPI factors are set per-screen by the server, and are always integers (most often 1 or 2).</li>
<li><strong>iOS:</strong> DPI factors are both constant and device-specific on iOS.</li>
<li><strong>Android:</strong> This feature isn't yet implemented on Android, so the DPI factor will always be returned as 1.0.</li>
</ul>
<p>The window's logical size is conserved across DPI changes, resulting in the physical size changing instead. This
may be surprising on X11, but is quite standard elsewhere. Physical size changes always produce a
<a href="../enum.WindowEvent.html#variant.Resized"><code>Resized</code></a> event, even on platforms where no resize actually occurs,
such as macOS and Wayland. As a result, it's not necessary to separately handle
<a href="../enum.WindowEvent.html#variant.HiDpiFactorChanged"><code>HiDpiFactorChanged</code></a> if you're only listening for size.</p>
<p>Your GPU has no awareness of the concept of logical pixels, and unless you like wasting pixel density, your
framebuffer's size should be in physical pixels.</p>
<p><code>winit</code> will send <a href="../enum.WindowEvent.html#variant.Resized"><code>Resized</code></a> events whenever a window's logical size
changes, and <a href="../enum.WindowEvent.html#variant.HiDpiFactorChanged"><code>HiDpiFactorChanged</code></a> events
whenever the DPI factor changes. Receiving either of these events means that the physical size of your window has
changed, and you should recompute it using the latest values you received for each. If the logical size and the
DPI factor change simultaneously, <code>winit</code> will send both events together; thus, it's recommended to buffer
these events and process them at the end of the queue.</p>
<p>If you never received any <a href="../enum.WindowEvent.html#variant.HiDpiFactorChanged"><code>HiDpiFactorChanged</code></a> events,
then your window's DPI factor is 1.</p>
</div><h2 id='structs' class='section-header'><a href="#structs">Structs</a></h2>
<table><tr class='module-item'><td><a class="struct" href="struct.LogicalPosition.html" title='winit::dpi::LogicalPosition struct'>LogicalPosition</a></td><td class='docblock-short'><p>A position represented in logical pixels.</p>
</td></tr><tr class='module-item'><td><a class="struct" href="struct.LogicalSize.html" title='winit::dpi::LogicalSize struct'>LogicalSize</a></td><td class='docblock-short'><p>A size represented in logical pixels.</p>
</td></tr><tr class='module-item'><td><a class="struct" href="struct.PhysicalPosition.html" title='winit::dpi::PhysicalPosition struct'>PhysicalPosition</a></td><td class='docblock-short'><p>A position represented in physical pixels.</p>
</td></tr><tr class='module-item'><td><a class="struct" href="struct.PhysicalSize.html" title='winit::dpi::PhysicalSize struct'>PhysicalSize</a></td><td class='docblock-short'><p>A size represented in physical pixels.</p>
</td></tr></table><h2 id='functions' class='section-header'><a href="#functions">Functions</a></h2>
<table><tr class='module-item'><td><a class="fn" href="fn.validate_hidpi_factor.html" title='winit::dpi::validate_hidpi_factor fn'>validate_hidpi_factor</a></td><td class='docblock-short'><p>Checks that the DPI factor is a normal positive <code>f64</code>.</p>
</td></tr></table></section><section id="search" class="content hidden"></section><section class="footer"></section><aside id="help" class="hidden"><div><h1 class="hidden">Help</h1><div class="shortcuts"><h2>Keyboard Shortcuts</h2><dl><dt><kbd>?</kbd></dt><dd>Show this help dialog</dd><dt><kbd>S</kbd></dt><dd>Focus the search field</dd><dt><kbd></kbd></dt><dd>Move up in search results</dd><dt><kbd></kbd></dt><dd>Move down in search results</dd><dt><kbd></kbd></dt><dd>Switch tab</dd><dt><kbd>&#9166;</kbd></dt><dd>Go to active search result</dd><dt><kbd>+</kbd></dt><dd>Expand all sections</dd><dt><kbd>-</kbd></dt><dd>Collapse all sections</dd></dl></div><div class="infos"><h2>Search Tricks</h2><p>Prefix searches with a type followed by a colon (e.g., <code>fn:</code>) to restrict the search to a given type.</p><p>Accepted types are: <code>fn</code>, <code>mod</code>, <code>struct</code>, <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, and <code>const</code>.</p><p>Search functions by type signature (e.g., <code>vec -> usize</code> or <code>* -> vec</code>)</p><p>Search multiple things at once by splitting your query with comma (e.g., <code>str,u8</code> or <code>String,struct:Vec,test</code>)</p></div></div></aside><script>window.rootPath = "../../";window.currentCrate = "winit";</script><script src="../../aliases.js"></script><script src="../../main.js"></script><script defer src="../../search-index.js"></script></body></html>