It is currently Sat May 25, 2013 5:17 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 13 posts ] 
Author Message
 Post subject: Differences in Font Size
PostPosted: Wed Feb 29, 2012 10:53 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 393
Hi guys! I've always used this formula to calculate the size of a font when using the CreateFontIndirect API function:
Code:
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:
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 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!


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 11:29 am 
Offline
Addict
Addict
User avatar

Joined: Sat Apr 26, 2003 8:26 am
Posts: 1290
TI-994A wrote:
Code:
  winDPI = GetDeviceCaps_(GetDC_(WindowID(#MainWindow)), #LOGPIXELSY)

Change winDPI to winDPI.f
Code:
  winDPI.f = GetDeviceCaps_(GetDC_(WindowID(#MainWindow)), #LOGPIXELSY)


Alternatively use:
Code:
cf\lfHeight = -MulDiv_(12,winDPI,72)


Last edited by Danilo on Wed Feb 29, 2012 11:37 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 11:36 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 393
Danilo wrote:
Change winDPI to winDPI.f
Code:
  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 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!


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 11:44 am 
Offline
Addict
Addict
User avatar

Joined: Sat Apr 26, 2003 8:26 am
Posts: 1290
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:
Debug 96   / 72
Debug 96.0 / 72

MulDiv_() works also with Integer:
Code:
cf\lfHeight = -MulDiv_(12,winDPI,72)


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 11:49 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 393
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:
Debug 96   / 72
Debug 96.0 / 72

MulDiv_() works also with Integer:
Code:
cf\lfHeight = -MulDiv_(12,winDPI,72)
Understood. I'm assuming MulDiv does the same thing with integers?

_________________
Texas Instruments 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!


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 11:57 am 
Offline
Addict
Addict
User avatar

Joined: Sat Apr 26, 2003 8:26 am
Posts: 1290
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:
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


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 12:33 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 393
Got it! Thank you very much Danilo. Truly appreciate your invaluable help.

_________________
Texas Instruments 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!


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 12:56 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Aug 31, 2005 11:09 pm
Posts: 2242
Location: Italy
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))

_________________
[ Home ] [ My PC ] [ New to PB ? ]


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Wed Feb 29, 2012 2:55 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 393
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 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!


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Fri Mar 02, 2012 10:27 am 
Offline
Addict
Addict
User avatar

Joined: Thu Feb 09, 2006 11:27 pm
Posts: 1716
I would prefer something like a Float(WinDpi)/72 :|

The other way round is easier: a.f=3 : Debug Int(a)<<1


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Fri Mar 02, 2012 10:49 am 
Offline
Addict
Addict
User avatar

Joined: Sat Apr 26, 2003 8:26 am
Posts: 1290
Michael Vogel wrote:
I would prefer something like a Float(WinDpi)/72 :|

Code:
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:
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:
WinDPI = 96

Debug (12 * (winDPI / 72)) ; original  , wrong

Debug ((12 * winDPI) / 72) ; MulDiv way, correct


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Fri Mar 02, 2012 6:57 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Apr 25, 2003 6:51 pm
Posts: 762
Location: NC, USA
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.


Top
 Profile  
 
 Post subject: Re: Differences in Font Size
PostPosted: Sat Mar 03, 2012 4:51 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 393
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 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!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: Exabot [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye