Page 1 of 1
Differences in Font Size
Posted: Wed Feb 29, 2012 10:53 am
by TI-994A
Hi guys! I've always used this formula to calculate the size of a font when using the CreateFontIndirect API function:
Code: Select all
newFont\lfHeight = -(pointSize * (deviceDPI / 72))
However, I notice that there's a big difference between my output and that of PureBasic's DrawText Function. I have to increase my logical font size to 16 points to match the output drawn by DrawText at 12 points:
Here's the test code:
Code: Select all
Enumeration
#MainWindow
#dtFont
EndEnumeration
wFlags = #PB_Window_ScreenCentered | #PB_Window_SystemMenu
OpenWindow(#MainWindow, #PB_Any, #PB_Any, 500, 200, "Font Sizes", wFlags)
LoadFont(#dtFont, "Arial", 12)
If StartDrawing(WindowOutput(#MainWindow))
Box(0, 0, 500, 200, RGB(255, 255, 255))
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#dtFont))
DrawText(10, 10, "Hello World! drawn by PureBasic's DrawText function at 12 points", #Red)
StopDrawing()
EndIf
Define cf.LOGFONT
fontName.s = "Arial"
For lenLoop = 0 To Len(fontName) - 1
cf\lfFaceName [lenLoop] = Asc(Mid(fontName, lenloop + 1, 1))
Next lenLoop
winDPI = GetDeviceCaps_(GetDC_(WindowID(#MainWindow)), #LOGPIXELSY)
cf\lfFaceName [Len(fontName)] = 0
cf\lfHeight = -(16 * (winDPI / 72))
winDC = GetDC_(WindowID(#MainWindow))
newFont = CreateFontIndirect_(cf)
oldFont = SelectObject_(winDC, newFont)
SetTextColor_(winDC, #Blue)
outStr.s = "Hello World! drawn by Windows' TextOut function at 16 points"
TextOut_(winDC, 10, 35, outStr, Len(outStr))
cf\lfHeight = -(12 * (winDPI / 72))
newFont = CreateFontIndirect_(cf)
ignore = SelectObject_(winDC, newFont)
SetTextColor_(winDC, #Black)
outStr.s = "Hello World! drawn by Windows' TextOut function at 12 points"
TextOut_(winDC, 10, 60, outStr, Len(outStr))
dispose = SelectObject_(winDC, oldFont)
DeleteObject_(newFont)
While WaitWindowEvent() ! #PB_Event_CloseWindow : CloseWindow : Wend
Am I missing something, or is the font height calculation incorrect?
Thanks.
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 11:29 am
by Danilo
TI-994A wrote:Code: Select all
winDPI = GetDeviceCaps_(GetDC_(WindowID(#MainWindow)), #LOGPIXELSY)
Change winDPI to winDPI.f
Code: Select all
winDPI.f = GetDeviceCaps_(GetDC_(WindowID(#MainWindow)), #LOGPIXELSY)
Alternatively use:
Code: Select all
cf\lfHeight = -MulDiv_(12,winDPI,72)
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 11:36 am
by TI-994A
Danilo wrote:Change winDPI to winDPI.f
Code: Select all
winDPI.f = GetDeviceCaps_(GetDC_(WindowID(#MainWindow)), #LOGPIXELSY)
Genius! I wouldn't have thought of that, since GetDeviceCaps returns a whole number for LOGPIXELSY. It works perfectly now.
Thank you, Danilo!
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 11:44 am
by Danilo
TI-994A wrote:Danilo wrote:I wouldn't have thought of that, since GetDeviceCaps returns a whole number for LOGPIXELSY.
It is the division "winDPI / 72" -> f.e. 96 / 72 = 1 with Integer/Long numbers.
MulDiv_() works also with Integer:
Code: Select all
cf\lfHeight = -MulDiv_(12,winDPI,72)
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 11:49 am
by TI-994A
Danilo wrote:TI-994A wrote:Danilo wrote:I wouldn't have thought of that, since GetDeviceCaps returns a whole number for LOGPIXELSY.
It is the division "winDPI / 72" -> f.e. 96 / 72 = 1 with Integer/Long numbers.
MulDiv_() works also with Integer:
Code: Select all
cf\lfHeight = -MulDiv_(12,winDPI,72)
Understood. I'm assuming MulDiv does the same thing with integers?
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 11:57 am
by Danilo
TI-994A wrote:Understood. I'm assuming MulDiv does the same thing with integers?
Yes.
MulDiv wrote:MulDiv Function
Multiplies two 32-bit values and then divides the 64-bit result by a third 32-bit value. The return value is rounded up or down to the nearest integer.
Syntax
Code: Select all
int MulDiv(
__in int nNumber,
__in int nNumerator,
__in int nDenominator
);
Parameters
nNumber [in]
The multiplicand.
nNumerator [in]
The multiplier.
nDenominator [in]
The number by which the result of the multiplication operation is to be divided.
Return Value
If the function succeeds, the return value is the result of the multiplication and division. If either an overflow occurred or nDenominator was 0, the return value is -1.
Minimum supported client:
Windows 2000 Professional
Minimum supported server:
Windows 2000 Server
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 12:33 pm
by TI-994A
Got it! Thank you very much Danilo. Truly appreciate your invaluable help.
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 12:56 pm
by luis
Another way it's to force a promotion to floating point this way:
cf\lfHeight = -(16 * (1.0 * winDPI / 72))
this is somewhat equivalent to the cast to float available in other languages, that's what I use when I don't want to alter a data type (winDPI.i in this case) for some reason.
or a little less explicit visually but it's the same
cf\lfHeight = -(16 * (winDPI / 72.0))
Re: Differences in Font Size
Posted: Wed Feb 29, 2012 2:55 pm
by TI-994A
luis wrote:Another way it's to force a promotion to floating point this way:
cf\lfHeight = -(16 * (1.0 * winDPI / 72))
this is somewhat equivalent to the cast to float available in other languages, that's what I use when I don't want to alter a data type (winDPI.i in this case) for some reason.
or a little less explicit visually but it's the same
cf\lfHeight = -(16 * (winDPI / 72.0))
Didn't know you could do that. This is a very useful casting trick, especially in lieu of CDbl(). Thank you for pointing that out.
Re: Differences in Font Size
Posted: Fri Mar 02, 2012 10:27 am
by Michael Vogel
I would prefer something like a
Float(WinDpi)/72
The other way round is easier:
a.f=3 : Debug
Int(a)<<1
Re: Differences in Font Size
Posted: Fri Mar 02, 2012 10:49 am
by Danilo
Michael Vogel wrote:I would prefer something like a
Float(WinDpi)/72 
Code: Select all
Procedure.f Float(value.q)
ProcedureReturn value
EndProcedure
Procedure.d Double(value.q)
ProcedureReturn value
EndProcedure
Debug 96 / 72
Debug Float (96)/ 72
Debug Double(96)/ 72
Code: Select all
Macro Float(value)
(1.0 * (value))
EndMacro
WinDPI = 96
Debug WinDPI / 72
Debug Float(WinDPI)/ 72
Debug Float(WinDPI / 72)
Debug 12 / 5
Debug Float(12)/ 5
Debug Float(12 / 5)
The Macro could be compiled as Resident.
For the problem in this topic you may just want to change the parenthesis:
Code: Select all
WinDPI = 96
Debug (12 * (winDPI / 72)) ; original , wrong
Debug ((12 * winDPI) / 72) ; MulDiv way, correct
Re: Differences in Font Size
Posted: Fri Mar 02, 2012 6:57 pm
by TerryHough
The original post's question and the answers will help me solve a font size issue I've been having. So, thanks everyone.
I've also been struggling with font sizes when printing to a printer using TextOut_. Seems like those never make sense to me. Might be the same issue.
Re: Differences in Font Size
Posted: Sat Mar 03, 2012 4:51 am
by TI-994A
TerryHough wrote:The original post's question and the answers will help me solve a font size issue I've been having. So, thanks everyone.
I've also been struggling with font sizes when printing to a printer using TextOut_. Seems like those never make sense to me. Might be the same issue.
Not that I'm an expert or anything, but do you actually draw to a device context (DC) that is compatible with the printer you're printing to?