Differences in Font Size

Just starting out? Need help? Post your questions and find answers here.
User avatar
TI-994A
Addict
Addict
Posts: 2790
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Differences in Font Size

Post 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:

Image

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.
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
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Differences in Font Size

Post 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)
Last edited by Danilo on Wed Feb 29, 2012 11:37 am, edited 1 time in total.
User avatar
TI-994A
Addict
Addict
Posts: 2790
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Differences in Font Size

Post 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!
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
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Differences in Font Size

Post 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.

Code: Select all

Debug 96   / 72
Debug 96.0 / 72
MulDiv_() works also with Integer:

Code: Select all

cf\lfHeight = -MulDiv_(12,winDPI,72)
User avatar
TI-994A
Addict
Addict
Posts: 2790
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Differences in Font Size

Post 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.

Code: Select all

Debug 96   / 72
Debug 96.0 / 72
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?
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
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Differences in Font Size

Post 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
User avatar
TI-994A
Addict
Addict
Posts: 2790
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Differences in Font Size

Post by TI-994A »

Got it! Thank you very much Danilo. Truly appreciate your invaluable help.
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
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Differences in Font Size

Post 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))
"Have you tried turning it off and on again ?"
User avatar
TI-994A
Addict
Addict
Posts: 2790
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Differences in Font Size

Post 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.
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
Michael Vogel
Addict
Addict
Posts: 2835
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Differences in Font Size

Post 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
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Differences in Font Size

Post 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
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Differences in Font Size

Post 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.
User avatar
TI-994A
Addict
Addict
Posts: 2790
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Differences in Font Size

Post 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?
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
Post Reply