Using actual size in your Windows 8.1 app

WP_20140110_001

Unlike any version of Windows before it, Windows 8.1 exposes the actual pixel density of the display for you to take advantage of in code. In this post, we’ll talk about a few techniques for using pixel density, some of the code to use it in your app.

All the screens

One of the best things about Windows, is the choice of devices that people have to buy. Maybe a small Dell Venue, a do-everything Surface Pro 2, or big workhorse Dell XPS All-in-one. Maybe all three? Each of these devices has a different screen, and each of these screens has a different number of pixels. This is great because you can choose the perfect device for you, for the right price, battery life, visual crispness, thickness, and weight.

How many pixels in an inch?

Knowing the pixel density of your screen in a very cool thing. It let’s your code know how big things are in the real world in a language it can understand, pixels. This lets you do things that wouldn’t be possible without some sort of awkward calibration UI. Here are a few examples:

  1. Draw a ruler on screen so you can measure stuff with your tablet
  2. Show a bunch of weird insects at actual size
  3. Draw a button exactly the size of the average finger, no bigger, no smaller
  4. Show different UI when you’re on a TV or a tablet even though they have the same resolution.
  5. Make text more comfortably readable on small screens

Why I care

I’m super excited about this because in my previous life as a PM on the Windows team, we did a ton of work to plumb the display information provided in the driver EDID all the way up to the user-mode code so we can build the dynamic high-DPI scaling features in Windows 8 (See more in this post I wrote on Scaling to different screens). In Windows 8.1 the team has gone the last mile so you can use this in your app.

Lies, damned lies, and DPI

If every screen is a different size, with a different number of pixels, how does your app know how big an inch is? Your answer might be, “Simple, just use one of those DPI properties that have been around forever.” But you’d be wrong. DPI and PPI are some of the most incorrectly used terms out there, especially in API design.

Eight APIs that lie about giving you pixels per inch:

  1. window.screen.deviceXDPI
  2. window.screen.deviceYDPI
  3. window.screen.logicalXDPI
  4. window.screen.logicalYDPI
  5. window.screen.systemXDPI
  6. window.screen.systemYDPI
  7. Windows.Graphics.Display.DisplayInformation.LogicalDPI
  8. Windows.Graphics.Display.DisplayProperties.LogicalDPI

Don’t get me wrong, each of these APIs is useful for many scenarios related to the pixel density of the screen. Like if you should load a higher resolution image when your app is zoomed. None of these APIs, however, give you any information about the actual physical size of the display. They only give you a number that lets you calculate how much your app is zoomed.

Enter RawXDPI and RawYDPI

Windows 8.1 introduces Windows.Graphics.Display.DisplayInformation.RawXDPI and RawYDPI. These ones are actually the droids you’ve been looking for. I can’t imagine trying to name this API, I’m surprised it’s not TheRealDPIPleaseStandup since so many of the other properties are so convincingly named.

Pixel density and logical pixels

RawDPI tells you how many native pixels there are in every physical inch. This would be cool, but apps may be zoomed in in order to automatically make things big enough to touch or read, so one of your CSS or XAML (logical) pixels might be several native pixels. So the first thing you need to calculate is the number of logical pixels in a physical inch.

var info = Windows.Graphics.Display.DisplayInformation.getForCurrentView();
var logicalPPI = info.rawDpiX / info.resolutionScale / 100;

How do I draw an inch

You can just start using that logicalPPI value right away. In this case I’ll just make a DIV an inch wide.

// Resize the div to be an inch square
inchDiv.style.width = logicalPPI + "px";
inchDiv.style.height = logicalPPI + "px";

How big is the screen

If you want to figure out the size of the screen’s diagonal, just dust off a little high school math.

var screenSizeX = window.screen.width / logicalPPI; 
var screenSizeY = window.screen.height / logicalPPI; 
var screenSize = Math.sqrt(Math.pow(screenSizeX, 2) + 
                           Math.pow(screenSizeY, 2));

Real Ruler: an app that uses pixel density

Screenshot (18)

Whenever I find a new API or system capability that I want to try out, I make an app! So I decided to make “Real Ruler.” It’s basically like all the other ruler apps in the Windows 8 store except this one is the only one (so far) that doesn’t need calibration. I use the pixel density to draw the inches at the right size on the edge  of the screen, and I measure how many inches between your fingers when you put them both on the screen.

WindowsStore_badge_en_English_Green_large_120x462

Get the code

I published all the code for Real Ruler on github, go ahead and download if you want to make Real Centimeter Ruler. :)

https://github.com/dwcares/RealRuler

Update: Don’t forget about projectors

Don’t forget to handle projectors and other screens that don’t expose screen size. Read how in this post: Handle projectors when using actual size in your app.

6 thoughts on “Using actual size in your Windows 8.1 app

  1. Ian

    Nice! This is an awesome post, thank you for sharing the info and code!! Great to see thus is easier in Windows 8.1 now. That plus some of the automatic DPI scaling has Windows 8.1 in a good sport there for me :)

    Reply
  2. Pingback: Dew Drop – January 13, 2014 (#1700) | Morning Dew

  3. Pingback: Windows App Developer Links – 2014-01-27 | Dan Rigby

  4. Pingback: Handle projectors when using actual size in your app | David Washington

  5. Pingback: Aktuális képméret méretpontos megjelenítéshez | MolePlex

  6. led teeth whitening

    I am really inspired with your writing talents as well as with the
    layout to your weblog. Is this a paid theme or did you customize
    it your self? Either way stay up the excellent high quality writing, it’s uncommon to
    see a great weblog like this one today..

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>