Retina graphics trick

A small trick for using graphics in Retina without the need for two images (one normal and one x2):

For example:
If you need to display a 64x64 image, always use a 128x128 version.

Now draw it with:
g.drawpicture 0,0,64,64,0,0,128,128

This way it will look good on both non-Retina and Retina.

The rescale ‘artefacts’ are minimal and in most cases you don’t see the difference. But it will slow down graphics though (not much)

You also do not need to check if the Mac has Retina support or not.

I definitely would not do this. You’ll lose all sharpness on 1x resolutions. A 2px line will not turn into a 1px line, it’ll turn into an antialiased mess.

Scaling down is not as bad as scaling up, but it still produces less than perfect results.

Well, I did many test on both Retina and non-Retina and it works very good.
But yes, if the image is smaller then 20 pixels it can be messy indeed. But for larger images it is a good trick imo

[quote=14363:@Christophe De Vocht]Well, I did many test on both Retina and non-Retina and it works very good.
But yes, if the image is smaller then 20 pixels it can be messy indeed. But for larger images it is a good trick imo[/quote]
I wouldn’t do it at any size.

Also scaling on Windblows looks like the dogs dinner. When drawing photos it looks fantastic and some really complex icons can also be scaled nicely, but as Thom says for some vector art doesn’t look right when scaled.

There is also the performance hit, which for one or two images isn’t that much, but it can all stack up.

With this years OmegaBundle, it’ll be debuting the Retina Kit, where I’ve added a x-plat solution for Retina (okay so no Retina on anything but Cocoa), it uses the underlying OS APIs so it’s done exactly the same as if your application was written in Obj-C. This way the OS deals with the correct representation when it’s time to do so.

Mind you, Christophe’s mentioned solution is the only way I’ve found to get Retina graphics into a listbox.

Really? I’ve never had any issue using CellTextPaint and CellBackgroundPaint.

Sorry if it’s a little unclear.

Assigning a RowPicture only gets you a low res version, if you assign a larger (in dimensions) picture, it still draws in low resolution. So the only way I’ve found to draw images in high resolution within the listbox is to draw down a larger (dimensioned) image down to the size you want, in the paint events.

I’ve not been able to successful draw via CoreGraphics or NSGraphics to a listbox cell in these events, the locations are all messed up and I couldn’t figure out the pattern to get it to work.

How do you draw Retina ready images in a listbox?

Oh I use the cell paint events. I never, ever use RowPicture, since you really have no control over how it is displayed.

I see, which is why I just wanted to make sure we’re on the same page. For Retina you’re having to draw a larger image down in size in the paint event. Which is the only solution I’ve found too.

For anyone following this thread, here’s a function I use to determine retina status for a given graphics context.

I have this in a module with a private variable “lastRetinaMultiple”, so that once the app encounters retina, it stays retina until the next session.

[code]Function GetRetinaMultiple(g as Graphics) As Integer
#if DebugBuild then
'Return 2
#endif

if lastRetinaMultiple>1 then
Return lastRetinaMultiple
else
Declare function CGContextConvertRectToDeviceSpace lib “Cocoa” (context as integer, inRect as CGRect ) as CGRect
Dim CGContextRef as integer = g.handle( graphics.HandleTypeCGContextRef )
if CGContextRef<>0 then
Dim userRect as CGRect
userRect.x=1
userRect.y=1
userRect.width=1
userRect.height=1
Dim deviceRect as CGRect = CGContextConvertRectToDeviceSpace( CGContextRef, userRect )

  lastRetinaMultiple=deviceRect.Width/1
  
  Return lastRetinaMultiple
end

end

return 1
End Function
[/code]

A paint event would call it like so…

dim retina as integer = GetRetinaMultiple(g)

Personally I would advise that you continue to evaluate, the reason being is that many people use multiple screens, it should switch to Retina when the window is dragged to a retina screen and then back again when repositioned on a non retina screen. If you’re doing Retina in an Obj-C application or using the forthcoming Retina Kit (which uses the same techniques as a Obj-C application), this is what the Mac OS does for you.

You can even drag a window half way and the OS will continue to automatically choose the correct element for you.