High DPI XPlatform

Both OSX and Windows have some support for high DPI displays - but handle them differently and i really don’t have a good handle on either. I would like to write good REUSABLE graphics pure Xojo code (not dependant on other settings in app) that would look good on either platform regardless of DPI settings, but am not sure how to go about it.

To make it clear what I am talking about let’s use the example of drawing a graph. There I want the textsize to be the same regardless of how the graph is resized on screen or the screen DPI (or more accurately PPI) but I want to be able to plot points/draw lines (and text) positioned to the maximum possible pixel accuracy.

What i THINK i know is that using a FontUnit of points TextSize pretty much takes care of textsize but positioning and absolute size/thickness is another matter. Besides positioning is I would like to be able to ensure that tic marks are the same size relative to the text regardless of DIP settings

On the Mac what I think I hear for retina is that for using the graphics class for drawing in terms of addressable X,Y position it acts as if it was 72 DPI but draws things with 144DPI crispness.

But on Windows I don’t have a clue and I heard there are changes to how Windows handles High DPI dislays as well.

It would be simple if you could just set TextPoint size, get the Screen PPI (DPI), g.DrawString returned the true size in pixels, and g.Draw* X,Y was truly pixel based for all DPI settings for all platforms… It would break old code but for stuff going forward we could code to work with any future DPI setting that comes along…

As it is I have no idea how best to code this type of stuff Xplatform … thoughts would be most welcome

I just rewrote some code where I was drawing things (graphics and text) in layers (pictures) for speed so that only the modified layer had to be redrawn when changed were made… I just realized that this would look bad on retina because the pictures would be upscaled because dimensions I get from the canvas will be have the true dimensions. I guess there must be a declare to get the scale factor I should use in drawing the layer… MacOSLib maybe?

But then what about Windows?

Maybe I should using the layer pictures and take the speed it of drawing directly?

Retina in OS X isn’t that difficult once you get your head around a couple of things.

#1 When drawing, try to use vector elements as these are resolution independent.
#2 Don’t use the Window backing scale, get the scale from the graphics context when you draw.
#3 Never cache the scale value as it can be changed by the user at any time.
#4 When using images, it’s best if you use NSImage, Apple have done all the hard work for you.

You can continue your existing technique of using images, however it’s a very good idea to check at draw time to see if the scale has changed, then refresh all the layers if needed. As you’re using Xojo images, you will need to create them double size (scale everything) and then draw down. Only do this on a Retina display, otherwise everything gets soft (although it can be fixed with a declare).

I dabbled with Window, there’s a blog article on the Xojo site. IMHO, HIDPI Windows is not ready yet. It doesn’t surprise me as there’s hardly any ‘Retina’ display machines on the market, those that are, the existing software performs terribly that people are disappointed in the Windows HIDPI experience.

[quote=105338:@Sam Rowlands]#2 Don’t use the Window backing scale, get the scale from the graphics context when you draw.

How would I do that?


  • Karen

I mentioned this elsewhere, but it’s worth mentioning it again: Remember that you can use custom fonts, so you may wish to wrap your vector drawings into a custom font (I believe your only other vector graphic alternative would be Cocoa vector-based images). This has the benefit of being cross-platform.

You can generate the fonts yourself, or use a tool like http://fontastic.me/ or http://icomoon.io/app/ to upload SVGs and get a font in return.

declare function CGContextConvertRectToDeviceSpace lib "AppKit" ( context as integer, rect as CGRect) as CGRect Dim userRect as CGRect = CGRectMake( x,y,w,h ) Dim repRect as CGRect = CGContextConvertRectToDeviceSpace( g.Handle( g.HandleTypeCGContextRef ), userRect )

You’ll also need a CGRect structure, which is comprised of 4 singles, CGRectMake is just my shortcut for populating the structure.

Basically you pass in the rect you want to draw and it’ll return the actual rect, You can then use that rect to draw into or calculate the scale.

Some tools implemented Google’s open source Skia Graphics Engine, enabling resolution independence, acceleration, cross-platform 2d graphics layer. Xojo should think something like that for a future update. Seems that the Lib treats PDF and SVG too as it was the base for the V7 engine of Google Chrome. Not sure, needs research.

I never tried to open a SVG with NSImage, but we use vector PDFs in our apps… Check out the just release Backup To Go and have a poke in the resources folder. I use NSImage via my Retina Kit wrapper code.

Well… my comment was about a cross platform, high-performace, HDPI compliant, resolution independent (your apps, controls, graphs will look good and with same sizes/positions) solution, already in use by others, it wasn’t specifically about vectors on Macs. Anyways… (just to give Kem a heartburn) thanks for the info.

Well, the PDF solution fits everything except for being mac-only. It’s still a pretty good option for 50% of Xojo devs :smiley: (I had never even thought about it, and since you can draw PDF on the fly and run it through this, it solves the problem nicely).

Now if only I could do Native PDF rendering in Windows and Linux :smiley: