CatchSystemFont(#Font [, Flags])

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2137
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

CatchSystemFont(#Font [, Flags])

Post by Andre »

To write cross-platform applications, which use the standard setting (= the system font set by the user here), it would be very useful to have a native command catching/getting this one for us.

The syntax can be like in the title, or maybe also GetSystemFont(), where #Font is a constant value or #PB_Any, and end in the same state like when the programmer has loaded the font himself via LoadFont().

The optional flags parameter is there, if the programmer want to catch specific types of system-fonts (regular one, big one, bold one, ...). Don't know exactly, if we especially need this, or if the normal standard font is enough...
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2137
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by Andre »

I'm the only one, who see a need for this request?
Or maybe you all (with a need for that) know about good solutions using own code... 8)

Let me explain a bit more about my wish:

I'm developing a cross-platform application on Windows and MacOS, where very different system fonts are used, causing the created windows/gadgets to look very different and needing different space in width and height.
This effect can already be seen, if you simply compare WinXP and Win7 layout.

I know, that I can create my application with loading a specific font first, and then adapting the GUI layout to it. Let the user choose, which font he like to use, and then again adapt the GUI sizes according to this.

Instead (or better additionally) to that I want to use the standard font settings on the users system as standard / initial setting. That's the point, where my feature request comes into action: With a native CatchSystemFont() function I would like to get a valid FontID, just like the other CreateXXX() or CatchXXX() offer, including #PB_Any support. :D
The optional Flags parameter can the useful, if it's possible to choose from several system fonts (the standard one, the big one, etc.).

Or do I think in the wrong direction, and there are much better solutions? Thanks!
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: CatchSystemFont(#Font [, Flags])

Post by c4s »

Good idea. +1
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: CatchSystemFont(#Font [, Flags])

Post by davido »

Andre:

I noticed this with Linux versus Windows.

Thank you for the explanation, very helpful. :D

+1
DE AA EB
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: CatchSystemFont(#Font [, Flags])

Post by MachineCode »

FontID=GetGadgetFont(#PB_Default) will use the default system font. Or am I missing something?
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2137
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by Andre »

MachineCode wrote:FontID=GetGadgetFont(#PB_Default) will use the default system font. Or am I missing something?
I think you will need already a valid FontID, previously loaded and set with SetGadgetFont().

To get a valid FontID from the users system settings (instead of loading a selected font myself first) is my feature request :)
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: CatchSystemFont(#Font [, Flags])

Post by MachineCode »

This is what I mean:

Code: Select all

OpenWindow(0,100,100,200,100,"test")

ButtonGadget(1,10,10,180,25,"times new roman")
  tnr=LoadFont(0,"Times New Roman",15)
  SetGadgetFont(1,tnr)

ButtonGadget(2,10,50,180,25,"Click to make default")
  SetGadgetFont(2,tnr)

Repeat

  ev=WaitWindowEvent()

  If ev=#PB_Event_Gadget And EventGadget()=2
    SetGadgetFont(2,GetGadgetFont(#PB_Default)); No valid Font ID used or loaded.
  EndIf

Until ev=#PB_Event_CloseWindow
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2137
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by Andre »

Thanks MachineCode for your suggestions :-)

I did some more tests by extending your example with following test code:

Code: Select all

OpenWindow(0,100,100,200,100,"test")

ButtonGadget(1,10,10,180,25,"times new roman")
  tnr=LoadFont(0,"Times New Roman",15)
  SetGadgetFont(1,tnr)
  
StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  Debug "Sizes of loaded 'Times' font:"
  Debug "  TextWidth = " + TextWidth("Dummy String")
  Debug "  TextHeight = " + TextHeight("Dummy String")
StopDrawing()
  
ButtonGadget(2,10,50,180,25,"Click to make default")
  SetGadgetFont(2,tnr)

Repeat

  ev=WaitWindowEvent()

  If ev=#PB_Event_Gadget And EventGadget()=2
    SetGadgetFont(2,GetGadgetFont(#PB_Default)); No valid Font ID used or loaded.
    
    DefaultFontID = GetGadgetFont(#PB_Default)
    StartDrawing(WindowOutput(0))
      DrawingFont(FontID(DefaultFontID))
      Debug "Sizes of standard system font:"
      Debug "  TextWidth = " + TextWidth("Dummy String")
      Debug "  TextHeight = " + TextHeight("Dummy String")
    StopDrawing()
    
  EndIf

Until ev=#PB_Event_CloseWindow
Your original example seems to work as expected (even if the help says, that on MacOS a valid Font must be assigned to the gadget to make GetGadgetFont() work), at least the gadget font of the second gadget is changed after clicking on it.

Bad thing is, that the Debug output gives both times the same results. But that shouldn't happen, if the used fonts are really different... And I need correct results of TextWidth() and TextHeight() to make all needed calculations for a proper Multi-OS GUI...

I would be interested what Fred / Timo say about the correct way to get all system font ID's, and if this feature request makes sense then, and if they will implement it... :twisted:
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by blueznl »

Oh, +1 and a bit :-)

GetDefaultFontName()
GetDefaultFontSize()

... or something similar.

Definitely! Seems to me a grand goal for beta 8 8)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
TI-994A
Addict
Addict
Posts: 2705
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by TI-994A »

Andre wrote:...the Debug output gives both times the same results. But that shouldn't happen, if the used fonts are really different... And I need correct results of TextWidth() and TextHeight()...
Hi Andre. Looking at your modification of MachineCode's example, I noticed a small error; GetGadgetFont() returns the font ID which can be used directly with DrawingFont(), without having to use the FontID() function. With this correction, the debug output is as it should be:

Code: Select all

OpenWindow(0,100,100,200,100,"test")

ButtonGadget(1,10,10,180,25,"times new roman")
  tnr=LoadFont(0,"Times New Roman",15)
  SetGadgetFont(1,tnr)
  
StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  Debug "Sizes of loaded 'Times' font:"
  Debug "  TextWidth = " + TextWidth("Dummy String")
  Debug "  TextHeight = " + TextHeight("Dummy String")
StopDrawing()
  
ButtonGadget(2,10,50,180,25,"Click to make default")
  SetGadgetFont(2,tnr)

Repeat

  ev=WaitWindowEvent()

  If ev=#PB_Event_Gadget And EventGadget()=2
    SetGadgetFont(2,GetGadgetFont(#PB_Default)); No valid Font ID used or loaded.
    
;================================================================================        
    DefaultFontID = GetGadgetFont(#PB_Default) ; returns font ID, not font number
    StartDrawing(WindowOutput(0))
      ;DrawingFont(FontID(DefaultFontID))      ; FontID() function not required
      DrawingFont(DefaultFontID)               ; drawing font set to default font
;================================================================================

      Debug "Sizes of standard system font:"
      Debug "  TextWidth = " + TextWidth("Dummy String")
      Debug "  TextHeight = " + TextHeight("Dummy String")
    StopDrawing()
    
  EndIf

Until ev=#PB_Event_CloseWindow
the debug output:

Code: Select all

Sizes of loaded 'Times' font:
  TextWidth = 112
  TextHeight = 22
Sizes of standard system font:
  TextWidth = 65
  TextHeight = 13
I believe that this default gadget font is the system font that you're looking for. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by blueznl »

After messing around a bit I still think we still need such a function. GetTextHeight is NOT an accurate way to find default system font.

(See also here: http://www.purebasic.fr/english/viewtop ... 55#p419455)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
TI-994A
Addict
Addict
Posts: 2705
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by TI-994A »

blueznl wrote:After messing around a bit I still think we still need such a function. GetTextHeight is NOT an accurate way to find default system font.
Hi blueznl. From my experience, the predominant confusion with fonts is the pixel height and the point size. By default, Windows returns the pixel height, and this needs to be converted to the point size. The size parameter in PureBasic's LoadFont() function requires points, and not pixels. This short example gets the default system font with the GetGadgetFont() function, and converts its pixel height to points. The font is then loaded with this point size as a separate resource and the output compared:

Code: Select all

EnableExplicit
Enumeration
  #MainWindow
  #Text1
  #Text2
  #Text3
  #Font
EndEnumeration

Define sysFont.LOGFONT, sysFontName.s
Define wFlags, yDPI, scrDC, sysFontID, sysFontPointSize

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#MainWindow, #PB_Any, #PB_Any, 400, 140, "Font Metrics", wFlags)
TextGadget(#Text1, 20, 10, 180, 20, "drawn with default gadget font:")
TextGadget(#Text2, 200, 10, 200, 20, "drawn with matching loaded font:")
TextGadget(#Text3, 20, 60, 300, 80, "")

scrDC = StartDrawing(WindowOutput(#MainWindow))
  yDPI = GetDeviceCaps_(scrDC, #LOGPIXELSY)
  sysFontID = GetGadgetFont(#PB_Default)
  Box(0, 35, 400, 15, #White)
  DrawingFont(sysFontID)
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(20, 35, "AaBbCcDdEeFfGgHhIiJjKk", #Red)
StopDrawing()

GetObject_(sysFontID, SizeOf(LOGFONT), @sysFont)
sysFontName = PeekS(@sysFont\lfFaceName[0])
sysFontPointSize = MulDiv_(-sysFont\lfHeight, 72, yDPI)
SetGadgetText(#Text3, "Font data from GetGadgetFont():" + #CRLF$ +
                      "name: " + sysFontName + #CRLF$ +
                      "pixel height: " + Str(-sysFont\lfHeight) +
                      #CRLF$ + "point size: " + sysFontPointSize)
LoadFont(#Font, sysFontName, sysFontPointSize)

StartDrawing(WindowOutput(#MainWindow))
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawingFont(FontID(#Font))
  DrawText(200, 35, "AaBbCcDdEeFfGgHhIiJjKk", #Blue)
StopDrawing()

While WaitWindowEvent() ! #PB_Event_CloseWindow : CloseWindow : Wend
Since these additional data have been collected through API functions, perhaps an expansion of PureBasic's font functions may be useful for cross-platform solutions. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by blueznl »

Which was exactly my point :-) And not even mine to start with :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2137
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by Andre »

TI-994A wrote:
blueznl wrote:After messing around a bit I still think we still need such a function. GetTextHeight is NOT an accurate way to find default system font.
Hi blueznl. From my experience, the predominant confusion with fonts is the pixel height and the point size. By default, Windows returns the pixel height, and this needs to be converted to the point size. The size parameter in PureBasic's LoadFont() function requires points, and not pixels. This short example gets the default system font with the GetGadgetFont() function, and converts its pixel height to points. The font is then loaded with this point size as a separate resource and the output compared:

........ <code example>

Since these additional data have been collected through API functions, perhaps an expansion of PureBasic's font functions may be useful for cross-platform solutions. :)
Thanks a lot for your clarification, TI-994A! :-)

But as you finally said, it would be good to have a native cross-platform for the way, you're showing us using WinAPI...
Maybe a final addition to PB5.20, Fred....? :twisted:
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: CatchSystemFont(#Font [, Flags])

Post by Didelphodon »

+1
Go, tell it on the mountains.
Post Reply