How I make DPI-aware apps

Share your advanced PureBasic knowledge/code with the community.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: How I make DPI-aware apps

Post by Dude »

srod wrote:If you set your display to 125% DPI then you need to divide by 120 (the actual DPI) not 125. You're still confusing a % scale factor with an actual DPI. :)
Image
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: How I make DPI-aware apps

Post by srod »

I am finding that programs are scaling fine using simple DPI scaling except that in some cases, text is not quite fitting certain gadgets when scaling down. Margins and borders aside, the problem seems to be that fonts do not quite scale in a linear fashion which I find somewhat puzzling. More precisely text extents are not quite scaling linearly and is something which is commented upon in various places on the web. PB's DPIAware auto scaling is also suffering from this. We're only talking small 'discrepancies' but enough to upset the scaling of the affected gadgets.

For example, some text on my system rendered with Arial, 10 under 96 DPI has extent 180. When I switch to 120 DPI I would expect a text width of 225 when I actually get 218 pixels. You see then how, with this font at least, scaling down from 120 DPI to 96 DPI would produce text which is too long for even a text gadget as the scaled width of the gadget would then be a few pixels too short. Nothing to do with any rounding errors either.

It would seem then that with some gadgets (and perhaps some fonts only) we cannot simply rely upon simple scaling, but need to size gadgets (or some of them at least) after first examining TextWidth() or GadgetWidth(..., #PB_Gadget_RequiredSize) etc. This is always the safest way anyhow. Simple scaling then is fine for positioning controls, but sizing static-text based controls probably needs more refined calculations based upon TextWidth() etc.
Fred wrote:I will take a look
@Fred : I think this is a problem with the non-linear scaling of text extents which I am encountering. I have tested this under GDI and GDI+ and the result is the same. It is making simple DPI scaling unsuited (or insufficient) for some static-text based gadgets if the desired end result is to have the gadget's resize just enough to contain the static text. I don't think we can escape from utilising good old fashioned TextWidth() calculations for these gadgets in these circumstances - which is something I generally do anyhow. If I am right then, well, I think DPIAware needs a bit of a rethink because there seems to be no escaping this problem. Unless I am missing something of course... which is more than possible! :)
At the very least the manual should perhaps state that the automatic scaling employed may need to be supplemented by use of TextWidth() / GadgetWidth(..., #PB_Gadget_RequiredSize) etc. for certain static-text based gadgets.
I may look like a mule, but I'm not a complete ass.
Fred
Administrator
Administrator
Posts: 16619
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: How I make DPI-aware apps

Post by Fred »

Thanks for the info, i will do some more tests
User avatar
gurj
Enthusiast
Enthusiast
Posts: 658
Joined: Thu Jan 22, 2009 3:48 am
Location: china
Contact:

Re: How I make DPI-aware apps

Post by gurj »

;dpi and zoom
;DPI(Dots Per Inch)
;DPI = the number of horizontal or vertical pixels per inches screen

;{see also:
;Platform SDK: GDI+
; Graphics::GetDpiX()
; The GetDpiX method gets the horizontal resolution, in dots per inch, of the display device associated With this Graphics object.
;
; REAL GetDpiX(void)
;}

Code: Select all

;TODO :let Compiler not use DPI ,then test this:
dpi=GetDeviceCaps_(GetDC_(0),#LOGPIXELSX)
zoom.d=dpi/96
Debug "dpi="+dpi
Debug "zoom="+zoom

OpenWindow(0,200,200,180*zoom,100*zoom,"test",#PB_Window_SystemMenu)

x=10*zoom
w=155*zoom
h=20*zoom

TextGadget(1,x,10*zoom,w,h,"This is text that fills the gadget",#PB_Text_Border)
StringGadget(2,x,40*zoom,w,h,"Another small test of fitted text")
ButtonGadget(3,x,70*zoom,w,h,"And last example of exact text")

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow


; IDE Options = PureBasic 5.71 LTS (Windows - x86)
; CursorPosition = 9
; EnableXP

my pb for chinese:
http://ataorj.ys168.com
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How I make DPI-aware apps

Post by IdeasVacuum »

sRod:
need to size gadgets (or some of them at least) after first examining TextWidth() or GadgetWidth(..., #PB_Gadget_RequiredSize) etc.
That of course will destroy the appearance of GUI layouts, itself a nightmare.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How I make DPI-aware apps

Post by IdeasVacuum »

There are numerous factors:
1) The dpi and scale factor of the screen the form/gui was designed on by the developer
2) The screens of the Users (customers), who may have multiple screens @ different dpi and scale factor
3) The language. Words in some languages are way longer than in others, so a "good fit" in the developer's language should not be the target.

Edit: Other observations (If PB DPI Aware is Set):
a) If the User applies a Scale to Windows, image buttons are enlarged accordingly but not the image.
b) Similar issue with Canvas, especially if your code "fills" the canvas background by drawing a box.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply