Page 1 of 2

Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 12:46 am
by yrreti
I have a problem using fonts in Windows 7 when the customer adjusts the text size
via the Screen Resolution.

For example, say that I use the following fonts to set and adjust the displayed text
on some of the Gadgets in my program.

Code: Select all

LoadFont(#Font1, "Arial"  ,  8)
LoadFont(#Font2, "Verdana", 12, #PB_Font_Bold)
In Windows 7 under Screen Resolution, there is a setting that allows you to
'Make text and other items larger or smaller'. 100% 125% 150%
100% = default and looks great

Is it possible to prevent that setting from affecting the font setting in my program?
When using my program on someones computer where they have it set to 125%, the letters are
enlarged, get clipped on some Gadgets and it looks terrible. At 150%, just forget using the program,
it's useless.
I would appreciate any input on this problem, if it's possible to fix this.
Thank you for your input.

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 12:55 am
by rsts
My work-around is to separate the text from the gadget and create the "text" as it's own image or use an imagegadget. Crude perhaps, but it works.

Someone posted a method for calculating the font required, but it was problematic and really only worked for fixed-width fonts.

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 3:51 am
by TassyJim
The problem exists on all versions of Windows.
I first discovered it with Windows 3.11

As a beginner to PureBasic, I cannot give a PB example but the method is
Start with a big font size
Measure the width with: Width = TextWidth("Test string for setting safe size")
Keep reducing the font size until Width is below the safe size.

I find I need this when my applications are run under Wine.
(One of my reasons for trying PB is to produce native Linux apps)

Jim

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 4:58 am
by yrreti
Hi rsts
That's an interesting approach to use for Gadgets that use fixed words, like for example an Exit button.
But it still doesn't help with Gadgets whose text needs to change.
I wonder if there is a way to detect from windows, what the text size is changed to when it is changed this way?
If that were possible, then you could probably use that to set the font sizes you use in your program to compensate
for that.
Example: Detect using at 125%, so set each used font to a smaller size value internally to compensate.

TassyJim
Thank you for your reply too.

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 5:50 am
by TI-994A
yrreti wrote:Is it possible to prevent that setting from affecting the font setting in my program?
Hello yrreti. The DPI setting is system-wide, and it affects all apps, including Windows itself. There are registry hacks to change these settings, but since it requires a reboot to take effect, it's not very practical or user-friendly.

Custom drawn forms and controls usually circumvent this problem effectively, but on occasions when standard forms and controls are indispensable, I utilise the method suggested by TassyJim.

I've adapted a simple example which checks if the font pixel height matches the height at the time of development, and adjusts it accordingly. Ideally, the default font should be determined and used, and there should also be checks for the gadget string widths, but for illustration purposes, this works pretty well. I've included a screenshot of the output at 50%, 100% and 200% to show the results:

Code: Select all

#defaultUIFontSize = 14   ;dev gadget font pixel height

Procedure AdjustFont()
  fontSize = 16   ;start with 16 points
  gFontID = GetGadgetFont(#PB_Default)
  Repeat
    StartDrawing(WindowOutput(1))
      DrawingFont(gFontID)
      th = TextHeight("TEST TEXT")
      StopDrawing()
    If th > #defaultUIFontSize + 1
      fontSize - 1
    ElseIf th < #defaultUIFontSize - 1
      fontSize + 1
    Else
      SetGadgetFont(#PB_Default, gFontID)
      ProcedureReturn
    EndIf
    LoadFont(1, "Arial", fontSize)
    gFontID = FontID(1)
  ForEver
EndProcedure

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(1, #PB_Any, #PB_Any, 300, 100, "Font Resolution", wFlags)
AdjustFont()
ButtonGadget(2, 110, 40, 80, 20, "TEST TEXT")

While WaitWindowEvent() ! #PB_Event_CloseWindow : CloseWindow : Wend
Image

Just an example not built for precision, but it works. Hope it helps.

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 6:03 am
by Danilo
yrreti wrote:Example: Detect using at 125%, so set each used font to a smaller size value internally to compensate.
Not a good idea, because you should respect the user wishes and settings. If the user wants all fonts at 125% or 150%,
you should not display smaller fonts. Maybe the user is unable to read such small fonts on a high resolution display.

More work, but much better is a dynamic GUI, where width and height and font sizes of gadgets are calculated dynamically at runtime.
PB has no built-in layout engine, but with some splitter gadgets, scrollareas and resizable windows it should be pretty OK.
For measuring the text width/height you can just use TextHeight() and TextWidth() on an (hidden) CanvasGadget() or an image
with the same font as the gadgets.
Microsoft recommends to not use pixels for gadgets. Use inch, centimeter, or millimeter for gadget sizes and fonts, so they
are same size on all devices. You just need to calculate the sizes depending on the device DPI.

- Writing High-DPI Win32 Applications (PDF, XPS)
- Tutorial: Writing High-DPI Win32 Applications
- Making the Web Bigger: DPI Scaling and Internet Explorer 8
- Creating a DPI-Aware Application

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 7:57 am
by Fred
With PB 5.20, you can use GadgetWidth(0, #PB_Gadget_RequiredSize). It does work for all gadgets, but is mainly useful for those handling text (like TextGadget(), OptionGadget() etc.). It's what we use internally for the new 'Dialog' with auto layout (if you can, you should give it a try as well, as it will solve your layout issue in no time).

Code: Select all

#PB_Gadget_RequiredSize = 1 ; Missing in the resident in the current beta, will be in the next

OpenWindow(1, #PB_Any, #PB_Any, 400, 200, "Font Resolution", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

ButtonGadget(2, 110, 20, 0, 0, "TEST TEXT")
ResizeGadget(2, #PB_Ignore, #PB_Ignore, GadgetWidth(2, #PB_Gadget_RequiredSize), GadgetHeight(2, #PB_Gadget_RequiredSize))

ButtonGadget(3, 110, 50, 0, 0, "TEST TEXT")
SetGadgetFont(3, LoadFont(0, "Arial", 30))
ResizeGadget(3, #PB_Ignore, #PB_Ignore, GadgetWidth(3, #PB_Gadget_RequiredSize), GadgetHeight(3, #PB_Gadget_RequiredSize))


While WaitWindowEvent() ! #PB_Event_CloseWindow : CloseWindow : Wend

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 8:34 am
by User_Russian
Fred, thank you.
It would be great if it worked without ResizeGadget.

Code: Select all

ButtonGadget(2, 110, 20, 0, 0, "TEST TEXT", #PB_Gadget_RequiredSize)

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 2:14 pm
by yrreti
Wow, thanks - a lot of interesting comments.

But this is the problem that I'm trying to correct.
Using a button as an example in this test code.
I need to keep the button size at the same size on it's form.
That windows setting just changes the text size.
In the following code example, I use three buttons to adjust the text size
to show how if I could possibly detect that setting from windows to
adjust the text size. If for example that 125% was needed, I would use
the setting that would increase the font size - and still appear larger under
the 125% setting, but still be within the button.
So the 125% button would be set to a lower size font, but so that the text
would still be within the button.

Code: Select all

;{- Enumerations / DataSections
;{ Windows
Enumeration
   #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
   #TS100_btn
   #Test_btn
   #TS125_btn
   #TS150_btn
   #Test_Font1
   #Test_Font2
   #Test_Font3   
   #msg_txt
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
   If OpenWindow(#Window_0, 450, 200, 312, 213, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
         ButtonGadget(#TS100_btn, 49, 55, 91, 36, "Default = 100%")
         ButtonGadget(#Test_btn, 181, 102, 91, 36, "TEST TEXT")
         ButtonGadget(#TS125_btn, 49, 101, 91, 36, "125%")
         ButtonGadget(#TS150_btn, 49, 147, 91, 36, "150%")
         LoadFont(#Test_Font1, "Tahoma", 8);100
         LoadFont(#Test_Font2, "Tahoma", 10);125
         LoadFont(#Test_Font3, "Tahoma", 12.5);150
         SetGadgetFont(#Test_btn, FontID(#Test_Font1))
         TextGadget(#msg_txt, 172, 147, 121, 33, "Button size needs to stay the same size.")
         ; Gadget Colors
         PureCOLOR_SetButtonColor(#TS100_btn, #PureCOLOR_SystemColor, $C0C0C0)
         PureCOLOR_SetButtonColor(#Test_btn, #PureCOLOR_SystemColor, $C0C0C0)
         PureCOLOR_SetButtonColor(#TS125_btn, #PureCOLOR_SystemColor, $C0C0C0)
         PureCOLOR_SetButtonColor(#TS150_btn, #PureCOLOR_SystemColor, $C0C0C0)
   EndIf
EndProcedure

OpenWindow_Window_0()

;{- Event loop
Repeat
   Event = WaitWindowEvent(5)
   Select Event
      ; ///////////////////
      Case #PB_Event_Gadget
         EventGadget = EventGadget()
         EventType = EventType()
         If EventGadget = #TS100_btn
           SetGadgetFont(#Test_btn, FontID(#Test_Font1))
           SetGadgetText(#Test_btn,"TEST TEXT")
         ElseIf EventGadget = #TS125_btn
           SetGadgetFont(#Test_btn, FontID(#Test_Font2))
           SetGadgetText(#Test_btn,"TEST TEXT")
         ElseIf EventGadget = #TS150_btn
           SetGadgetFont(#Test_btn, FontID(#Test_Font3))
           SetGadgetText(#Test_btn,"TEST TEXT")
         EndIf
      ; ////////////////////////
      Case #PB_Event_CloseWindow
         EventWindow = EventWindow()
         If EventWindow = #Window_0
            CloseWindow(#Window_0)
            Break
         EndIf
   EndSelect
ForEver
;
;}
Doing some search on line, I found this link which illustrates this problem.
http://dascomputerconsultants.com/Magni ... Issues.htm
I don't use Visual Studio, but he fixed it using AutoScaleMode with option set to DPI.
Is something like that possible with PB? And if it is, I need to ask the experts here
how one could go about writing that code. Please :oops:

Re: Проблема со шрифтами в Windows 7 с настройте размер текс

Posted: Fri Jul 19, 2013 2:52 pm
by useful
GadgetHeight/Width(xxx, #PB_Gadget_RequiredSize) & ComboBoxGadget ???
Behave unpredictably or a workable methodology?

Re: Problem with fonts in Win 7 with text size adjust

Posted: Fri Jul 19, 2013 10:52 pm
by yrreti
Fred, your idea using #PB_Gadget_RequiredSize is an interesting idea, except it changes the Gadget Size
too much, which can crowd out adjacent placed gadgets. I really appreciate your taking the time to show me
that though.

TI-994A, I was looking over your suggestion, and I really appreciate the effort that you made in describing
and showing your method.
I don't have time today, but I think I am going to experiment with your method more later.

Mean while. I came up with a method using screen dpi detection to change the font size which seems to work
fairly well. To test, you need to set : under Screen Resolution
Make it easier to read what's on your screen
to the size you want to check. 100 120 150
(100=96 dpi 120=120 dpi 150=144 dpi)
Log off and Log back in, and run the program.
The left button has no correction while the right button and text is corrected.

Code: Select all

; ----------------------------------------------------
;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
  #TS100_btn
  #Test_btn
  #Test_Font
  #Txt_Font
  #Default_Test_Font
  #msg_txt
  #msg2_txt
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Global sdpi.i
sdpi= GetDeviceCaps_(GetDC_(GetDesktopWindow_()), #LOGPIXELSX)

Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 450, 200, 312, 220, "Text Size Test Window", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
    ButtonGadget(#TS100_btn, 49, 102, 95, 36, "Default 100%")
    LoadFont(#Default_Test_Font, "Tahoma",11);100
    SetGadgetFont(#TS100_btn, FontID(#Default_Test_Font))
    ButtonGadget(#Test_btn, 181, 102, 91, 36, "TEST TEXT")
    Select sdpi
      Case 96
        LoadFont(#Test_Font, "Tahoma",11)
        LoadFont(#Txt_Font, "Tahoma",10)
      Case 120
        LoadFont(#Test_Font, "Tahoma", 10)
        LoadFont(#Txt_Font, "Tahoma",9)
      Case 121 To 500;144
        LoadFont(#Test_Font, "Tahoma", 8)
        LoadFont(#Txt_Font, "Tahoma",7)
    EndSelect
    SetGadgetFont(#Test_btn, FontID(#Test_Font))
    TextGadget(#msg_txt, 172, 145, 121, 75, "dpi adjusted text.      Button size needs to stay the same size.")
    SetGadgetFont(#msg_txt, FontID(#Txt_Font))
    TextGadget(#msg2_txt, 49, 40, 121, 18, "dpi = "+Str(sdpi))
  EndIf
EndProcedure

OpenWindow_Window_0()

;{- Event loop
Repeat
  Event = WaitWindowEvent(5)
  Select Event
        ; ///////////////////
      Case #PB_Event_Gadget
        ; ////////////////////////
      Case #PB_Event_CloseWindow
        EventWindow = EventWindow()
        If EventWindow = #Window_0
          CloseWindow(#Window_0)
          Break
        EndIf
  EndSelect
ForEver
;}

Re: Problem with fonts in Win 7 with text size adjust

Posted: Sat Jul 20, 2013 11:15 am
by Fred
You will indeed have to adjust other gadget position relative to new width/height. Or use the Dialog automatic layout lib ;)

Re: Problem with fonts in Win 7 with text size adjust

Posted: Sat Jul 20, 2013 11:36 am
by PB
> When using my program on someones computer where they have it set to 125%, the letters are
> enlarged, get clipped on some Gadgets and it looks terrible. At 150%, just forget using the program

I had this problem way back in 2005. Here's the thread and discussion:

http://www.purebasic.fr/english/viewtop ... =7&t=15361

Re: Problem with fonts in Win 7 with text size adjust

Posted: Sat Jul 20, 2013 1:46 pm
by yrreti
Fred, I tried to find some info on the Added: Dialog library (with automatic layout support), but
didn't on the forum or in the help file? Could you please point me to a link, or an example that would
explain more how it can be used?

PB, thanks for the link and your example.

Re: Problem with fonts in Win 7 with text size adjust

Posted: Thu Aug 08, 2013 11:40 pm
by luis
Fred wrote: While WaitWindowEvent() ! #PB_Event_CloseWindow : CloseWindow : Wend
Why this code works ?
I understand the xor, I'm talking about the CloseWindow, you can replace it with "lalalalala" anyway.