Page 1 of 2

CatchSystemFont(#Font [, Flags])

Posted: Sun Mar 10, 2013 1:56 pm
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...

Re: CatchSystemFont(#Font [, Flags])

Posted: Fri May 24, 2013 11:38 pm
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!

Re: CatchSystemFont(#Font [, Flags])

Posted: Sat May 25, 2013 9:35 am
by c4s
Good idea. +1

Re: CatchSystemFont(#Font [, Flags])

Posted: Sat May 25, 2013 4:42 pm
by davido
Andre:

I noticed this with Linux versus Windows.

Thank you for the explanation, very helpful. :D

+1

Re: CatchSystemFont(#Font [, Flags])

Posted: Sun May 26, 2013 1:12 am
by MachineCode
FontID=GetGadgetFont(#PB_Default) will use the default system font. Or am I missing something?

Re: CatchSystemFont(#Font [, Flags])

Posted: Sun May 26, 2013 9:54 pm
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 :)

Re: CatchSystemFont(#Font [, Flags])

Posted: Sun May 26, 2013 11:04 pm
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

Re: CatchSystemFont(#Font [, Flags])

Posted: Mon May 27, 2013 10:28 pm
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:

Re: CatchSystemFont(#Font [, Flags])

Posted: Sat Jul 27, 2013 11:31 pm
by blueznl
Oh, +1 and a bit :-)

GetDefaultFontName()
GetDefaultFontSize()

... or something similar.

Definitely! Seems to me a grand goal for beta 8 8)

Re: CatchSystemFont(#Font [, Flags])

Posted: Sun Jul 28, 2013 12:44 am
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. :)

Re: CatchSystemFont(#Font [, Flags])

Posted: Tue Jul 30, 2013 10:57 pm
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)

Re: CatchSystemFont(#Font [, Flags])

Posted: Wed Jul 31, 2013 11:35 am
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. :)

Re: CatchSystemFont(#Font [, Flags])

Posted: Wed Jul 31, 2013 8:04 pm
by blueznl
Which was exactly my point :-) And not even mine to start with :-)

Re: CatchSystemFont(#Font [, Flags])

Posted: Wed Jul 31, 2013 8:51 pm
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:

Re: CatchSystemFont(#Font [, Flags])

Posted: Thu Sep 05, 2013 1:11 pm
by Didelphodon
+1