Font sizes!

Share your advanced PureBasic knowledge/code with the community.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Font sizes!

Post by srod »

Code updated for 5.20+

Code: Select all

; ************************************************ 
; Code:    Point fonts.
; Authors: srod and omit59.
; Date:    January 2007. 
; OS:      Windows only 
; ************************************************ 
This little library contains two procedures, each of which returns a font handle:

Code: Select all

GetExactPointFont()
GetLogicalPointFont()

Each procedure creates a font based on typographic points (1 point = 1/72 of an inch) and require a handle to a device context (hdc).

For a printer device context such as that obtained with Startdrawing(PrinterOutput()), both functions are absolutely identical and produce a font in exact measurements of 1/72 inches.
E.g. a font size of 72 would equate metrically to a font size of 1 inch (roughly speaking as font metrics do not easily equate to such precise values).
Printer output using such fonts will, for example, correspond exactly with the printed output from MS Word using the same fonts and font size etc.

For a screen device context such as that obtained with StartDrawing(WindowOutput(#win)), the two functions operate very differently.
The first will return a font of exact typographic measurements regardless of screen resolution and dpi. E.g. a font size of 36 will equate to roughly half an inch regardless of screen resolution.
Thus text displayed on the screen with such a font will have exactly the same metric size as when displayed on a printer (with the same font).

The second function, on the other hand, deals with 'logical inches' which can be a little fiddly to appreciate. Basically a logical inch is generally larger than a physical inch and depend upon the screen resolution and dpi setting.
(They act like a magnification factor to account for the fact that we generally view the screen from further away than when reading a printed page etc.)
Have a look at MS Word to get an idea of how logical inches can scale the measurements.
This second function returns a font which is scaled appropriately to keep pace with the size of a logical inch (depending upon the screen res. etc).
In this case, for example, a font size of 36 will correspond to half a LOGICAL INCH (not a physical one). Such fonts thus keep pace with changes to the display settings.

Code to follow in the next post.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Code: Select all

; ************************************************ 
; Code:    Point fonts.
; Authors: srod and omit59.
; Date:    January 2007. 
; OS:      Windows only 
; ************************************************ 

Procedure.l GetExactPointFont(hdc, fontname.s, pointsize.l, style.l=0)
  Protected logy, height, font, oldfont, tm.TEXTMETRIC, weight=400, italic, underline, strikeout
  ;Convert the required point size to device units.
  ;Recall that each typographic point = 1/72 of an inch.
    logy = (25.4*GetDeviceCaps_(hdc, #VERTRES))/GetDeviceCaps_(hdc, #VERTSIZE)
    height=-MulDiv_(pointsize, logy, 72)
  ;Since we can't use LoadFont() between StartDrawing() and StopDrawing() we instead
  ;create a copy of the required font using API.
    If style&#PB_Font_Bold
      weight=#FW_BOLD
    EndIf
    If style&#PB_Font_Italic
      italic=1
    EndIf
    If style&#PB_Font_Underline
      underline=1
    EndIf
    If style&#PB_Font_StrikeOut
      strikeout=1
    EndIf
    font=CreateFont_(height, 0, 0, 0,weight,italic,underline,strikeout,0,0,0,0,0,fontname)
  ProcedureReturn font
EndProcedure


Procedure.l GetLogicalPointFont(hdc, fontname.s, pointsize.l, style.l=0)
  Protected logy, height, font, oldfont, tm.TEXTMETRIC, weight=400, italic, underline, strikeout
  ;Convert the required point size to device units.
  ;Recall that each typographic point = 1/72 of an inch.
    logy = GetDeviceCaps_(hdc,#LOGPIXELSY) 
    height=-MulDiv_(pointsize, logy, 72)
  ;Since we can't use LoadFont() between StartDrawing() and StopDrawing() we instead
  ;create a copy of the required font using API.
    If style&#PB_Font_Bold
      weight=#FW_BOLD
    EndIf
    If style&#PB_Font_Italic
      italic=1
    EndIf
    If style&#PB_Font_Underline
      underline=1
    EndIf
    If style&#PB_Font_StrikeOut
      strikeout=1
    EndIf
    font=CreateFont_(height, 0, 0, 0,weight,italic,underline,strikeout,0,0,0,0,0,fontname)
  ProcedureReturn font
EndProcedure
An example follows in the next post.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Example of using the above library.

Either use the above code in the form of an 'include' etc. or physically paste the following code into the same source file as above.

Code: Select all

;An example where the printed output matches exactly the window output.
If PrintRequester() 
  If StartPrinting("Test") 
    hdc = StartDrawing(PrinterOutput()) 
      font=GetExactPointFont(hdc, "Arial", 14, #PB_Font_Bold|#PB_Font_Italic) 
      DrawingFont(font) 
      DrawText(0, 30,"Hello from PUREBASIC!") 
    StopDrawing() 
  EndIf 
  StopPrinting() 
  DeleteObject_(font)
EndIf
OpenWindow(0, 100, 200, 400, 400, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
Repeat
  EventID = WaitWindowEvent()
  If EventID=#WM_PAINT
    hdc = StartDrawing(WindowOutput(0)) 
      font=GetExactPointFont(hdc, "Arial", 14, #PB_Font_Bold|#PB_Font_Italic) 
      DrawingFont(font) 
      DrawText(0, 30,"Hello from PUREBASIC!") 
    StopDrawing() 
    DeleteObject_(font)
  EndIf
Until EventID = #PB_Event_CloseWindow
End 
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

If anyone is wondering why I'm not using PB's LoadFont() command, then basically it's a little fiddlier and the size of the internal leading space has to be accounted for.

See http://www.purebasic.fr/english/viewtopic.php?t=25528 for details and a code example.
I may look like a mule, but I'm not a complete ass.
zikitrake
Addict
Addict
Posts: 876
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Post by zikitrake »

You saved my life!!! I was going crazy with a customer!
PB 6.21 beta, PureVision User
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

:)

Actually, I had completely overlooked this problem with fonts myself in a print engine I'm working on! Thank God for omit59 making the original post regarding fonts else I'd have had to rip apart massive chunks of the library!

Glad it's useful.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

More to learn now. My brain is shrinking and I still need to feed it stuff!! I have to decide how to print customer invoices now so this will be my next study:):)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Study away lad, it's good for the old grey matter! :)
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4791
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

srod wrote:Study away lad, it's good for the old grey matter! :)
lad??? What have you been smoking??

You're right about one thing, it's old and grey and doesn't matter!!!

By the way, shouldn't you be painting the house instead of engaging in witty repartee??? And NO, I AM NOT HELPING!!!!
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I am covered from head to toe in paint and cuts and blood! I think I prefer programming than diy! :)
I may look like a mule, but I'm not a complete ass.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

srod wrote:I am covered from head to toe in paint and cuts and blood! I think I prefer programming than diy! :)
Then use a brush instead of a saw :)

cheers
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

rsts wrote:
srod wrote:I am covered from head to toe in paint and cuts and blood! I think I prefer programming than diy! :)
Then use a brush instead of a saw :)

cheers
Damn, I've been wondering why it was taking me so long to cut timber! :)
I may look like a mule, but I'm not a complete ass.
Post Reply