0

Here's the problem. A TFont object is saved (streamed to a file) on a 96 DPI resolution with Size property set to 9pt. Then DPI is changed to 192 and when object is deserialized, its Size property value becomes 5pt.

Environment: app is a VCL forms app, marked as DPI-aware ("true/PM"). Form's Scaled property does not affect the behavior as TFont object is being saved/loaded outside of form's object, using WriteComponent/ReadRootComponent functions.

Screenshots to illustrate the problem using test app. The app merely saves TFont to a file and Load button reads it back and shows the loaded font's size/height in a memo.

Screenshot 1: program started on 96dpi system, font is Tahoma 8pt, saved to a file and loaded. Everything's fine.

enter image description here

Serialized font is saved in a file:

object TTest
  F.Charset = DEFAULT_CHARSET
  F.Color = clWindowText
  F.Height = -11
  F.Name = 'Tahoma'
  F.Style = []
end

Screesnhot 2: started on 192dpi system, loading the serialized font, and its size becomes 4pt. enter image description here

Delphi saves the Height property, and Size is being calculated based on Height, resulting in smaller fonts...

Is there a way, instead of manually scaling the size (NewHeight = Height * SystemDPI / 96), to make Delphi preserve the "pt" font size regardless of DPI setting? I feel that I'm missing something here...

djsoft
  • 1,051
  • 8
  • 19
  • You need to tell us the following: 1. Delphi version. 2. DPI aware setting of your manifest. 3. Value of the form's `Scaled` property. – David Heffernan Dec 05 '15 at 22:15
  • And you also need to take a decision on how you want to handle font scaling. FWIW, my advice at design time is that you only design on 96dpi monitors to avoid scaling and associated dfm noise. – David Heffernan Dec 05 '15 at 22:16
  • Delphi 10, Scaled is False (True for some forms). Of course I design everything @96dpi, to avoid problems. Dpi aware flag is True. – djsoft Dec 06 '15 at 09:48
  • From how I understand the "pt" measure, I don't really need to handle font scaling, as "pt" size should transform to correct pixel height depending on user's DPI setting. What actually happens, is that "pt" value is being re-calculated based ion stored "Height" value. – djsoft Dec 06 '15 at 09:49
  • You need to put all these details in the question. If you do that then I can answer. Please be more precise about the dpi awareness setting. Include an excerpt from your manifest. – David Heffernan Dec 06 '15 at 10:02
  • You also need to make it clear that you are talking about runtime deserialization. I'd assumed designtime. All this in an edit please. – David Heffernan Dec 06 '15 at 10:24
  • Take a look at this question http://stackoverflow.com/questions/8296784/how-do-i-make-my-gui-behave-well-when-windows-font-scaling-is-greater-than-100/8296833#8296833 - More specifically the answer by Ian Boyd. As you noticed, Delphi saves the height, not the size so it's trying to be DPI aware but it doesn't do a very good job. – Graymatter Dec 06 '15 at 18:29
  • @David, I've added some details. – djsoft Dec 06 '15 at 19:17
  • @Graymatter, yes, I've read this answer, but it's about anoother problem I think... – djsoft Dec 06 '15 at 19:18
  • Now you introduce `WriteComponent/ReadRootComponent` and I'm totally confused. Never mind. Hope someone else can help. – David Heffernan Dec 06 '15 at 19:44
  • @David, those are Delphi functions that I use to serialize and deserialize TFont object (F property of TTest class). The problem narrowed down to how TFont is saved. Size property is marked with "stored False" directive, so only Height is saved. – djsoft Dec 06 '15 at 20:01
  • Never mind. I've run out of energy to decipher this. If you would show a [mcve] then we would not have to decipher. – David Heffernan Dec 06 '15 at 20:05
  • Thanks for trying to help. I've examined VCL sources, and Delphi itself fixes the font height by calling MulDiv (when it loads a form with Scaled=true). I wonder why they're saving Height and not Size for TFont. Saving Size will eliminate the need to re-calculate font sizes on different DPI settings. – djsoft Dec 06 '15 at 21:49
  • You asked the font not to be scaled. – David Heffernan Dec 06 '15 at 22:54
  • Not quite. I wanted it to be the same size in points (pt, Size property), but as Delphi only saves its pixel size (px), Height property, I have to account for that and multiply Height based on user's DPI setting - thus returning the original Size value. Delphi itself does that when it calls ChangeScale for a form. It definitely should've saved the Size property instead - this way, everyone'll get font scaling for free. – djsoft Dec 06 '15 at 23:08
  • That would have been a better approach but it's difficult to make that sort of change now. The question I linked gives the appropriate solutions. You need to decide how to scale the UI and what metric to use for that scaling. – Graymatter Dec 06 '15 at 23:29
  • No. You set `Scaled` to `False`. You asked the font not to be scaled to match the dpi. – David Heffernan Dec 07 '15 at 07:10
  • @Graymatter, yes, I've implemented manual font scaling. I was hoping that there's some other solution I've overlooked... – djsoft Dec 07 '15 at 08:23
  • @David, Delphi uses incorrect approach to save font sizes in pixels. Saving them in points will eliminate the need to scale fonts regardless of what DPI is used (take a look at Height/Size properties implementation for TFont). – djsoft Dec 07 '15 at 08:24
  • It looks to me like it's your own fault for setting Scaled to False. You have asked for the font height in pixels to be invariant of dpi, and that's what you got. The framework gave you what you asked for. – David Heffernan Dec 07 '15 at 08:38
  • If TFont.Size was saved, then there won't be any need at all to scale fonts. It's a TFont design issue, and I think it's this way now for backwards compatibility purposes only. Nowadays saving font sizes in pixels is a bad approach: pt, em, pem is way better as it doesn't suffer from DPI changes. – djsoft Dec 07 '15 at 08:51

0 Answers0