Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2012-213
$eventId
ID of event: wwdc2012
$eventContentId
ID of session without event part: 213
$eventShortId
Shortened ID of event: wwdc12
$year
Year of session: 2012
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2012] [Session 213] Introductio...

WWDC12 • Session 213

Introduction to High Resolution on OS X

Essentials • OS X • 48:51

Give your users the best experience by taking advantage of High Resolution on OS X. Learn how to move your applications to High Resolution, create crisp application assets, and find out how to avoid common pitfalls.

Speakers: Patrick Heynen, Dan Schimpf

Unlisted on Apple Developer site

Downloads from Apple

HD Video (257.5 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning. Welcome to session 213, Introduction to High Resolution on OS X. My name is Dan Schimpf. I'm an engineer on the Cocoa Frameworks team. I'd like to start with a little bit of an introduction. As you all know, 2x Retina displays arrived first with the iPhone 4. On the Mac side, we've only really had one scale factor to deal with for a long time. There's been many different screen sizes, of course, but only one scale factor for the pixels on screen. That's, of course, until now.

The good part is OS X takes care of a lot of the details for you and your apps. But full adoption for your applications will require some work, but it's going to be worth it, trust us. So here's what we're going to be talking about today. Brief overview of what High Resolution is for the Mac. Then we're going to talk about some things you need to do to optimize your application for High Resolution. Talk about what to do with your bitmap images.

Talk about your icons in the Finder and your document icons. Talk about some final touches to make your application really the best on the new hardware. And some problems you may come into while you're optimizing your application. So how does High Resolution work? So there are new High Resolution display modes for the retina displays on the new hardware.

The screens in the windows now have a 4:1 pixel per point density. and the frameworks provide the scaling between the 1X and the 2X operation for your Windows and screens. The Quartz Window Manager, which manages all of the windows and the display on the screen, ensures a consistent presentation of these windows across multiple displays of different scale factors.

What is High Resolution? What are we talking about here? Well, with High Resolution, the number of pixels on screen actually quadruples. You may see 2X, but you actually get four times as many pixels. So, that's four pixels on screen for each point. Well, what is a point? Point is a unit of measurement. It's commonly referred to as 1/72 of an inch, although on actual computer monitors, this can vary. And what this leads to is more pixels to display your text, sharper text and more detailed graphics, as we say.

So let's do a quick demonstration. This is a point on screen. There are many points like it, but this one is mine. So at 1x, that point corresponds to one pixel. That pixel may be big or small, but it's one point equals one pixel. At 2x, we have the same point, but that corresponds to four pixels in the same area.

So how does this compare to iOS, which you may be familiar with? Well, it's actually very similar. The basic tenets are the same between the two platforms. They both have an integral UI scale factor, 1x and 2x, and they both provide a lot of automatic scaling from the application frameworks.

There are some enhanced functionality for the unique needs of OS X, particularly in the realm of multiple displays. If you have multiple displays attached, one can be at 1X, another one can be at 2X, depending on the capabilities of that hardware. So there's unique functionality in OS X to handle this.

This corresponds to Windows versus screens, because different screens have different scale factors, so that means different Windows can have different scale factors as well. And the Mac has to be more dynamic in terms of the resolution changes. Displays coming and going, the user changing the settings as well.

More pixels on screen means we can do more with them. If there's a yellow blob on screen at 1X, you can see there's lots of fuzziness on the edges. But if we take it to 2X, we can show a finer detail. And with the same, let's say the same shape, the same mathematical shape corresponds to a sharper detail in that shape.

So here we are at 1X again. 16 by 8, 16 pixels, 16 points, with, but we got a 2X, all of a sudden we have 32 pixels for the same number of 16 points. So how does this work? On OS X, we've got a unified coordinate system. That means all coordinates are in points.

This means view frames, window locations, screen sizes, all these things are in points. And because different displays can be different scale factors, it can differ by screen and window. But the good news is, for the most part, your apps don't need to care about this. You just pay attention to what we're telling you, and your applications will probably work, for the most part, without any changes.

So here's two screens hooked up to your system. They both have the same number of points. Because one is running at 2x, they both show up with the same number of points. But it turns out the 2x one actually has two times as many pixels on each dimension. So they come across as the same logical size.

So how does this work with your current apps right now? Well, by default, Cocoa apps are scaled automatically. That means that you get sharp text and crisp Aqua graphics for free. Well, except your custom bitmaps that you have, they're not going to be optimized. We can't invent pixels that aren't there. So they're just going to be magnified. By default, Carbon apps are magnified. This means that the text and UI widgets are magnified as well and needing to be unoptimized.

So here's what you need to do with your app to make them ready for High Resolution. First, you're going to go through all of your 1x bitmaps, and you're going to need to add 2x representations of all of them. and then you're going to need to do High Resolution icons for use in the Finder. These are your application icons and your document icons.

Then you're going to need to look through your code for any uses of deprecated API, things that may have been hanging around maybe a bit too long, and now's a good time to switch to a more modern equivalent because it turns out these modern methods are more capable of handling things. They have more information. We can make better decisions about them.

And while you're doing that, also look through and see if you're making any bad assumptions about pixels. We've long said that one point does not equal one pixel, and now's the time where we're making it real. But perhaps the best thing to do is just give it a try. If you get your hands on some hardware, you can try it out there, but you can also try it out on your home system. You don't need to wait for your hardware to show up, and you may be surprised by how well it works.

So here's how to test it at home before your hardware shows up. If you haven't already, install the graphics tools for Xcode, because you're going to want to open Quartz Debug and open the UI Resolution window from the menu bar. And you're going to select High DPI Display Modes.

And what that's going to do is after you log out and log back in-- You can use the Display System Preferences pane to select a high DPI display mode. This is an example from a laptop, which will be kind of small if you don't have the nice new hardware, but you can still use it to test. Okay, I'm going to hand it over to my colleague Patrick, who's going to talk more about what to do with your artwork.

Thank you, Dan. So, my name is Patrick Heynen, and I'm here to tell you about artwork. Why are we talking about artwork? Well, at the end of the day, with the Retina display, it's really all about pixels, isn't it? and well executed designs really can have an extraordinary impact on the quality, on the impact on your application and how well it looks.

Let's take a look at some case studies here of Standard Resolution versus High Resolution, just to give you an idea of what the difference really is and what Retina really gives you for your application. So this is Final Cut Pro X, and what we're looking at here is a standard resolution screenshot.

And this is the Retina Resolution screenshot. I'm going to go back and forward. Now, what I'd like to call attention to here is that it's not just a standard upscale here, but the opportunity here is to actually add significant amounts of detail to your application graphics and really put a whole different look and feel onto your product. So, for example, I'd like to call attention to the camera icon there. With Standard Resolution, there's probably not much going on there, a few little details.

But at High Resolution, there's a whole lot more detail. And there's also other subtle things you can do to your design on Retina Display that are just simply not possible at Standard Resolution. Let's look at another example here. This is Reminders. This is Reminders at Standard Resolution and at Retina Resolution. Standard Resolution.

Retina Resolution. I'd like to call attention to the finer detail on the paper texture and some of the subtle highlights and gradients that are much more able to be rendered in a much more higher quality fashion at the Retina Resolution level. What do you need to do to achieve these kind of results? Well, graphics resources simply need to be created at twice the pixel density.

And you just need to integrate these new @2x image resources into your project, and you're done. It's really that easy. There is not really, in normal cases with well-behaved Cocoa applications, you really do not need to write any code to integrate these High Resolution artwork assets. So it's really easy.

A few things to keep in mind here, uprezzing large quantities of graphics in applications that feature a lot of graphic resources can be a very challenging design test. And I want to emphasize here for those of you who are maybe involved in design test as well, this is not to be underestimated, this portion of the project.

In fact, it has been our experience that artwork-related tasks can typically consume over 50% of the overall effort of making your application optimized for the retina display. It's not just a bunch of image files. There's a huge amount of work and there's a lot of organization that has to go into it. And good communication between designer and developers are essential to making this process run smoothly. Otherwise, it can be death by a thousand paper So let's get more into the technical nitty-gritty.

So what kind of image resource categories do you have to worry about for High Resolution? Well, there's really three: a bitmap, a vector, and application and document icons. I'm going to talk about each of these and some of the unique considerations for each of these under the Retina display.

So, bitmap image resources. This is perhaps the most common category of image resources. And here, the most important thing to know about is that there is a file naming convention that we have taken from iOS, which is the @2x file name suffix. It works very simply and straightforwardly.

You have your standard resolution asset with just a normal file name, and then you take that same file name, add the @2x suffix, and that should be -- and that is how you indicate to the system that this is a double resolution retina asset. So, some details about this.

So the @2x assets differ from the standard resolution assets in that they have exactly twice as many pixels. And they should be exactly twice the width and height in pixels. Of course, the thing to keep in mind is, on actual display, these things are going to be the same physical size on the Retina display as their standard resolution counterparts.

This is frequently forgotten, but it's an essential point that I'm going to be circling around in a bunch of different ways. So here, once again, this is looking at things just pixel for pixel. But of course, on the actual Retina display, point for point, that's what it's going to look like.

So, how does this look like in code? How do you achieve success? How do you get this magic automatic behavior where you don't have to write a single line of code? Well, it does help if you've already written the right code to begin with. So, NSImage will automatically locate and use the high resolution 2x image representations if you use the image lookup by name constructors for NSImage.

NSImage also supports multi-resolution TIFFs, which you can generate automatically using Xcode's combined High Resolution images project build setting. And that presents some slight efficiencies in file system and runtime performance as well. So that's another option you have available to you. So how does NSImage help you in this High Resolution world? Well, the magic thing about NSImage is that it actually is able to handle rendering of an image at any resolution, both Standard Resolution and High Resolution.

And this is actually critically important for the Mac compared to iOS, because on the Mac, you have multiple displays with multiple possible resolutions. And in NSImage, because of its ability to support multiple representations, both Standard and High Resolution, in the same NSImage object instance, it can be ready for duty in any resolution context.

So, once again, you need to make sure you use the by name lookup to get this automatic behavior where it finds the appropriately named file name resources. There's either the classic NSImageImageNamed or the new NSBundle category method we introduced in 10.7 Lion, which allows you to do the same by name lookup from any arbitrary NSBundle, not just the main app bundle.

Keep in mind, with NSImage, the size of the image, the size of the NSImage instance, that is, is always in points. But the pixel geometry of the individual representations may actually vary. In fact, for proper operation, the second representation should always be ideally twice the pixel geometry of the first.

And then at draw time, what NSImage does is it actually chooses the best representation to draw based on the characteristics of the rendering destination. So it computes how many pixels it's going to draw into, and then looks at the representations it has, and picks the one that's going to be the best match.

So in a High Resolution scenario, in a 32 by 32 point destination rectangle, it's going to pick the 2x64 by 64 pixel representation. In contrast, both CG image and UI image, for that matter, have a geometry that's always in pixels. Actually, CG image isn't always in pixels. UI image is slightly different. And it's only limited to one resolution. So if you're working with CG image directly, you have to do some of this management yourself and be aware of the difference there.

Okay, so the next image category, Vector Image Resources. Here we're really, at the end of the day, talking about PDF. And the nice thing about PDF is that they scale automatically, both to any user size, that is, you know, size on screen, as well as to any pixel density. So that, in some ways, they're ideal for High Resolution.

[Transcript missing]

The way template images work is we just treat the image as a shape. And they're typically indicated by either having the file name suffix and in template, or you can mark an image as a template by saying NSImageSetTemplate, yes? And what happens is at draw time, AppKit actually takes that shape that you provide and uses some image effects to actually provide context-specific appearance appropriate to the current state of the control or the window. So, for example, you automatically get pressed, disabled, inactive, you know, rollover appearances.

All that stuff is provided automatically and matches the look and feel of the system. And most importantly, this effects rendering and the rasterization of your shape is done at full backing resolution, which means you automatically get a high-quality look on both standard and high resolution. Okay, so that covers vector image resources. Now let's talk about application and document icons.

So you may have encountered these before. These are the traditional back by ICNS files. And these are some-- and they're used by Finder, Open Save Panel, Spotlight Menu, a couple other areas. These are really the way your application advertises itself to the rest of the system. So you don't typically see these resources in your app, but they're typically consumed by other Apple software or other pieces of software outside of your app. So they're an important part of the overall imagery of your app.

Now, they're kind of special, right? Because ICNS files and icons in general are the only sort of image category that have both-- have a variable user size. They have the magical property that they can be rendered any size and are supposed to have a high quality result at almost any size that you draw them into.

So, how does it do this? Well, ICNS, as you may know, has five slots for providing individual bitmap representations. 16x16, 32x32, 128, 256, and 512. And then what happens at draw time, very similar to the way I described in this image working, it just chooses the most appropriate pixel slot based on how many pixels it's about to draw into.

So, for example, if on High Resolution we're drawing into a 128-point point rectangle, which really is 256 pixels, it'll just go and find that 256-pixel slot, take that representation, and draw it. So what's the problem? Why am I even blathering on about this? Well, there is a problem, unfortunately. Retina displays are different.

Let's go into detail here, what I mean here. So let's look at a 16 by 16 icon. So at 2x, that's what you really want to draw, a 16 by 16 icon. As for example, in a list view in Finder or in the Open Panel, you really need 32 pixels.

[Transcript missing]

Now, here's a key point. There's two key points I'm going to talk about here. And I'm going to spend a little bit of time on them. First off, icons with the same pixel count, but different target resolution-- by target resolution, I really mean target pixel density-- may need different visual treatment because of the display size.

Since these are not just the same-- these are the same exact amount of pixels, but because on a retina display, things are so much physically smaller, from a graphical design perspective, you will probably find yourself needing to use different heuristics to get the same perceptual effect. You might want to, for example, strengthen and emphasize strokes, use slightly more saturated colors, or just use a slightly different graphical treatment than you would at the same physical size on a standard resolution display, just because the perceptual characteristics of the retina display are different.

[Transcript missing]

Okay, so what have we done to actually make this happen? Two things. The first is we have enhanced the ICNS format to support 2X variants for every user size slot. And by the way, everything I mention here, although it's got that new badge, it's actually new in 10.7.4 and Mountain Lion. It's not just limited to Mountain Lion. So it's starting with the new MacBook Pro right now. Under High Resolution, these @2x variants are prioritized when you're actually drawing to a retina display or a high resolution window backing store.

and some of you who have been following this story of High Resolution over the years would like to know that -- would be interested to know that the 1024 by 1024 size that we introduced last year has now been just relabeled. It's now the 512 by 512 at 2X. And the 1024 size slot itself is effectively deprecated.

Not every slot in this full matrix needs to be populated for the Icon runtime machinery to work correctly, but having all of the 2x counterparts is kind of recommended as a practical measure. Because once you go to the effort of doing your optimization for Retina, it's really just simpler to just provide them all. That's been our experience at the very least. Okay, next.

So how do you actually create one of these image resources with this crazy new format? Well, you may have used Icon Composer before, and it's got the workflow of building an icon one image well at a time. You get your graphics from wherever, and then you've got to go drag them in into all these image wells.

Well, we've decided that's just fundamentally broken, that whole workflow. So Icon Composer is effectively deprecated as of now. And there was much rejoicing. So what have we done to replace it? Well, we're introducing something called Icon Sets. Icon Sets are a new icon art delivery format for High Resolution.

And what it really is, it's really actually quite simple. It's almost too simple. It's just a folder and file naming convention. So it's a folder, and it has to have a suffix called .iconset. And what it contains inside of it are a whole bunch of PNG files, and they look a little familiar, and they should. They have their-- just like standard bitmap graphic resources, except with one additional twist.

They have encoded into the file name not just whether they're standard resolution and high resolution, but also what size slot they conform to. And so there's a standard naming convention for each of these files organized into a folder with the .iconset extension. And this is the way that we expect you to integrate your artwork into your project sources.

So, what are the features and benefits of icon sets? Well, first and foremost, they are a much better fit with existing design workflows. I'm going to demonstrate this in a second, but really, given that designers are working in some random image authoring app to actually create these things, what they know how to do really well and reliably, which is very important, is create a bunch of bitmap images like PNG files.

What nobody likes to do is have to then use a different tool to transform what their master file is into what they actually have to integrate into the project sources. So, this gets rid of that, eliminates that middleman, and just allows designers to create exactly what needs to be integrated into project sources. Also, not to be underestimated, much more reliable color management because, again, there's less transformation going on between the icon art deliveries and what happens on its way into the software.

And speaking of on its way into the software, the magic thing about icon sets is we've added support in Xcode to automatically transform these into compliant ICNS files at project build time. So Xcode 4.4 and 4.5 have been augmented to understand icon sets as a basic graphic resource and can automatically transform these. Just like the way that ping files and add to X pings can get transformed automatically to TIFFs, it also knows how to convert icon sets into ICNSs.

We've also provided a quick look plugin for verification of icon sets. So for example, if you're a designer, you want to make sure that what you've just generated is actually working correctly and is properly registered and aligned. You can just hit the space bar in the finder on the folder and it pops a little UI with a slider. I'll demonstrate that in a second. We've also provided a command line tool, IconUtil, ships as part of the base system as of 10.7.4, which allows you to go back and forth between ICNS files and icon sets, convert back and forth. It's very simple, doesn't do much more.

But it's quite handy. Also, one last little thing we added to IconComposer, in case you've lost your original sources to your icons and you need a way to bootstrap the process, we've added a export to icon set feature to IconComposer. And that's available in the graphics tools image for Xcode 4.4 and later.

Okay, that's enough talking. Let's do some demoing. So, what we've got here is we've got an actual MacBook Pro with Retina display. And the first thing I'm going to demonstrate is how the process of adding High Resolution artwork to your application. So, we've got a wonderful, really mission-critical application here called Fishbike.

And what I'd like to call your attention to here is that it has pretty low resolution graphics. What is up with that? And it doesn't do much. It plays a few sounds if the sound levels were up. But that's okay. We'll try that again when we add our High Resolution artwork.

So, I happen to have gotten an artwork delivery from my designer. And look, there it is. There's the bike and the fish with the appropriate file names, and I'm going to add it to my resources folder. And I'm going to copy them into place. And I'm going to rebuild. And voila.

It's that simple. There is no step three. Let's see if the sound works. Oh, yeah. That's a fish sound if I ever heard one. And that's a bike sound, if I ever heard one. It's a really important app. OK. So that's the process of adding artwork. Now, but I'm still missing an icon for my application. So what do I do about that? Well, my designer gave me a folder called New Icon. What's in here? Oh my goodness. He gave me his source files. He was a bit lazy. He didn't create an icon set. Well, let's go figure out how that's actually done.

So what I have here is I have a template file, which is a sort of a typical-- you don't have to use this kind of workflow, but this is a very typical kind of design workflow, where you have a single Photoshop template with all of your various sizes in it. Over here are all the standard resolution representations. And here are all the 2x representations.

And you'll notice that there are a variety, that the image is all sliced up. Every one of the representations has a little slice around it. And what that allows me to do is if I use the Save for Web feature, I can use this little setting export that I created myself, and all this does is it just makes sure that it places them all into a folder called myicon.iconset. It doesn't do anything really fancy beyond that. Create those out.

[Transcript missing]

And you notice here, you can sort of see here implicitly all the names of the files. So the file names are actually--the little missing link I should have mentioned before is this is using the Photoshop feature where the file names are encoded as slice names so that when you do use the Safer Web, it automatically creates these files. And let's take a look And perfect.

Fully transparent icon. Let me just demo it here. So this is the Quick Look plugin that gives you the little slider that lets you exercise all the different sizes of the icons. And actually, if I had a multiple display set up here, if I had, say, this display hooked up to this MacBook Pro, and I dragged this window across to it, it would actually show the standard resolution.

So what we're looking at here are all the 2x reps. If I were to present that window on the standard resolution display, it would show me the 1x reps. So it's a good way to debug your icon. So, well, how do we add it to our app? Well, first, let's name it something appropriate.

And now let's go back to our Fishbike app, and let's add it to the resources here. And let's rebuild. And I don't know if you noticed that, but I'll bring it up here. Voila, we have a beautiful icon already built. Built automatically by Xcode. And just because it's fun, play the sounds again. Oh, that's definitely a fish sound. : All right. I think we're done.

We've got a perfectly optimized High Resolution app for the MacBook Pro right in the display. All right. And that's the end of my demo. I'm going to hand it back over to my colleague, Dan Schimpf. And he's going to talk about some final touches you can put on your apps and some considerations. You go, Dan. Thank you, Patrick.

Thank you. Okay. So what are some final things you're going to need to know about as you work on this? As I said before, the display scale is dynamic. It can change. The user is allowed to change it any time. They can attach a different display. They can attach a projector. That is a different scale factor. They can drag a window from one display to another. That's changing its scale factor.

Here's a quick demonstration of how that works. If I've got a 1x display and a 2x display right next to each other, and I've got a window straddled between both of them. As you can see, the window is labeled 1x right now. That's because it's primarily on the 1x side. The display that owns more of the window wins in this case.

So what happens when the user, say, drags it over to the 2x side? Well, now more than 50% of that window is on the 2X display, so the window automatically rebuilds itself into a 2X backing store. So how do you do this? How do you react to display changes? Well, you don't need to do much. In fact, you may not need to do anything at all. NSWindow automatically redraws itself when it switches scale factor.

So that means that any content that you have that's dynamic automatically works. If you're caching bitmap drawing, you may have to do some extra work. So preferably don't cache any drawing at a specific scale factor. But if you do, what you have to do is invalidate that cache at the react to the change when it happens.

Let's talk a little about deprecated API that you may still be using, but is going to cause you some trouble when moving to High Resolution. Convert Rect to Base. It turns out this method had two uses in the past, and now in the High Resolution world, those two different uses have two different answers. So we deprecated Convert Rect to Base, and we're replacing it with two methods for each of those two uses.

Convert Rect to Layer will deal with converting a rectangle, or there's also corresponding size and point variance. So you can convert those coordinates from a view to its layer. And then there's Convert Rect to View, which has been around for a long time, with a nil view to get the window coordinates.

NSImage composite to point, also dissolve to point. This has been long deprecated and now it will -- this is the time when you really want to get rid of these calls because they will have funny behaviors at High Resolution in some cases. We recommend using the NSImage methods that begin with draw. So if you're going to draw an image, look for a method beginning with draw and you should be all set.

NSScreen user space scale factor is tied to the pre-10.7 model of High Resolution interface, and it will always return one now.

[Transcript missing]

If you're caching those bitmap drawings, you may have to take some special considerations to deal with High Resolution accurately. So the preferred way to do this is to create an NSBitmapImageRep and then use an NSGraphicsContext to draw it into.

The benefits of this is that it's automatically scaled to the correct scale factor for wherever context you're drawing into. CG bitmap context, which some of you may be using, is similar to CG image in that it's measured in pixels. So if you're going to use CG bitmap context, you're going to need to scale the context yourself by the scale of your final drawing destination. Keep in mind that you need to invalidate that cache when the destination scale factor changes. So that's something extra you need to keep track of. Okay. So, let's talk about a few things, a few problems you may run into when you're converting your application into High Resolution.

So my two X images aren't drawing. I've got them. I think they're there, but I don't see them showing up. My images are still a little bit fuzzy. Well, first thing you should do is check out your build product to make sure they're actually there. Maybe Xcode isn't including them for some reason. They're in the wrong spot. Keep in mind that they can either be at 2x ping, or if you combine them to a High Resolution TIFF, you need to look for the TIFF.

And there's a tool in Quartz Debug that helps you with this. If you have Quartz Debug installed already, you can use the Tools menu to enable Color 1x Artwork. And this is similar to an option that's available in the iOS Simulator, where it will paint any image that is scaling up from 1x to 2x to make them pop out at you.

Now my image is actually drawing four times as big. It's being scaled twice somehow. So make sure you're not scaling this twice inadvertently or on purpose when we're already scaling it for you. And again, the best thing to do here is ignore the 2x as much as possible and let AppKit handle it.

That will make your code cleaner and make this better. This is another case where things like Composite to Point really come back to bite you. Depending on how your context is set up, especially if you're doing off-screen bitmap drawing, using Composite to Point can sometimes lead to image drawing way too big.

Let's say my views aren't aligned. I'm doing some manual layout in code. I'm setting some frame, I'm calculating frames, and now all of a sudden they're just a little bit off. There's maybe some pixel cracks. So there's this method in NSView, centerScanRect. You pass it a frame, it gives you back another frame that's aligned on a good grid boundary. And you're going to want to use that instead of, say, rounding the frame values yourself or using floor or anything like that.

Because it turns out at 2x, you can actually have something at 0.5x and still be on a good grid boundary because you've got a pixel there. So it's not going to be misaligned.

[Transcript missing]

There can be rounding differences between 1X and 2X because all the pixel sizes are doubled at 2X. So that means that there are really no odd pixel values at 2X unless you're doing something very custom. And that can lead to some rounding differences.

So if you can manage that, try to control the rounding and see if you can modify your 1x to match it. So I'm doing some window layout, and my window's in the wrong place now. If you've been doing High Resolution before, you may be scaling your window coordinates. But you don't need to do that anymore. Window coordinates, just like everything else in the system, are in points.

If I have a custom core animation layer, it's not sharp, it's fuzzy. You need to set the content scale on layers that you manage yourself. If AppKit is hosting that layer, you don't need to worry about it. We'll handle all the details for you. But if you've got your own CA layer, you need to handle the content scale on that. There's also a delegate method you can handle this easily for custom contents in the layer.

OpenGL content, by default, for compatibility reasons, is not opted into 2x drawing. So you need to do that. You need to opt into sharp OpenGL drawing. So now I'm going to do another quick demo on some image drawing issues that you may run into and some solutions that you can use.

Let's open my project up. This is another incredibly sexy application that draws three images. Helpfully, my designer has chosen to embed the scale factor right into the image so we can all tell what they are. And we're drawing this in three different ways. This is the one on the left, obviously, is a regular NS image view. The one in the middle is an off-screen bitmap.

And then the one on the right is a custom layer that I'm inserting. So right now, we can see that all these images are at 1x. Thanks. So the first thing I need to do, like we did before, is grab my 2x image and just drag it in.

and Rebuild. Now they're all drawn at 2x. Well, I'm done, right? Well, one thing that's somewhat hard to demonstrate here is what happens if you've got one display at 1x and another display at 2x. What we're not seeing here is that if this display was running at 1x and I had a 2x display attached, the off-screen bitmap and the custom layer images would actually always be drawing the 2x image. They'd just be scaling it down. And that's not any better. So we're actually still not done here. So let's look at how we're drawing the off-screen bitmap image.

I can see there's a cache image method that he calls lock focus and then calls composite to point with another image. And then we're drawing that image with composite to point again. So how can we make this better? Using my demo file that we all have. So I'm going to copy this and I'll explain it once it's at its much larger font size. So here is a much larger method.

[Transcript missing]

at the pixel size, so that's scaled up by the scale factor that we're drawing into.

[Transcript missing]

and Dan Schimpf. We're going to get a unit size, use convert size to backing to see what in pixels how big that unit size becomes, compare it against my cached image scale, then I can know if I need to recache that image. Then we're going to draw that cached image in the normal spot. You may think, well, that's all fine and dandy. That's a lot more code than I used to have, though. Is there anything better? And it turns out there is.

. I can take all of this code, copy it, and replace it with something much smaller. There's a new method on NSImage and Mountain Lion for drawing NSImages using a block. So in my cache image method, what we can do is create a new image with the logical size that we're drawing into, the point size, and then using this block, AppKit will invoke this block when it needs to redraw that image. So it will cache the bitmap, cache the drawn contents. But any time we need to redraw it because of scale factor changes, we'll use this block again.

[Transcript missing]

So what's the problem there? CA layers can have primarily have CG images as their contents. And so what's the problem here? Well, if you've got a 1X monitor and a 2X monitor, how is it going to know which image to pick for this case? Because I'm not really passing any context information in. So what's it going to do? It's going to pick the densest screen and use that. So this is always going to pick the 2X image and get me the CG image for that from the image.

Well, since 10.6, you can actually set the NS image as the contents of a CA layer. So that can be your first step. And then that could be it right there. Because AppKit will automatically switch back and forth. If you've got an NS image in a layer, it'll know to switch out the actual pixels based on what scale factor it needs to draw. So you could stop right there.

If you've got something more complex than just a simple image, it's going to know to switch out the actual pixels based on what scale factor it needs to draw. There's a couple other things you can do. You can use the delegate method. So, let's say, let's replace this with -- I'm going to make myself the delegate.

and Dan Schimpf, and then copy this. And again, this is going to be more complicated than you need to just for a simple image case, but if you've got more complicated drawing that you want to do over that image or something else, this is a good way to do it.

So then I have this delegate method, should inherit content scale. I say, yes, we do want to inherit that content scale. And that's going to then immediately go back and try to redraw the contents of that image, which is going to then call this other method, the other delegate method, draw layer in the context.

I'm going to make an NSGraphics context out of that. And again, if you've got something more complicated, you can replace this section. But this is just whatever you're drawing into your layer can be here. But you'll get automatically redrawn when that layer needs to be drawn at a new scale factor.

Okay, so those are some simple problems you may have drawing images. So for more information on all of this... and we highly encourage you to check out the documentation. These are all new guides on High Resolution. Highly recommend you check these out. It's a great read. Really keep you up at night. The Apple developer forums are there for any help that you may need from your fellow developers and us. Okay. So a summary of what we covered today. There are new High Resolution display modes for your hardware that corresponds to four pixels on screen for every point.

So what you need to do to adapt this, you need to add 2x bitmaps to your apps for all of your 1x art, and you need to look at your icons and up-res them as well. You need to look at your code and see what you can clean up for 2x. It may not be a lot, and your users will definitely thank you.

and you need to make sure that you're handling display changes. So not just, I launch at 2x and I'm always going to be at 2x, but I need to handle going from 1x to 2x and then back again. and Dan Schimpf. And then please read the documentation. We worked on it very hard and it's great. Thank you very much for coming. Have a great week.