If this formula ( 0.072/72*25.4*fontsize ) is secure ( under every circumstance ) there isn 't a problem to make it another ( but accurate ) function, I think.
Any opinion ?
Re: Accuracy of GetTextWidth()
Posted: Mon Aug 18, 2014 12:50 pm
by Pablo César
Very nteresting matter Esgici, please go ahead with your research.
Re: Accuracy of GetTextWidth()
Posted: Mon Aug 18, 2014 1:37 pm
by Pablo César
Hi Esgici,
I appreciate this matter so much and thanks for sharing.
/*
Test for accuracy of GetTextWidth() function and Height
2014-08-18
*/
#include <hmg.ch>
Function Main
DEFINE WINDOW frmGTWTest ;
AT 0,0 ;
WIDTH 250 ;
HEIGHT 200 ;
MAIN ;
TITLE "GTW Accuracy" ;
ON INIT { || MsgInfo( "Width (lblSize10):"+hb_ValToStr(GetTextWidth( NIL, "size10", _HMG_SYSDATA [ 36 ][2] ))+CRLF+"Width (lblSize20):"+hb_ValToStr(GetTextWidth( NIL, "size20", _HMG_SYSDATA [ 36 ][3] ))+CRLF+CRLF+"Height (lblSize10):"+hb_ValToStr(_HMG_SYSDATA [ 28 ][2] )+CRLF+"Height (lblSize20):"+hb_ValToStr(_HMG_SYSDATA [ 28 ][3] ),"Width and Height") }
ON KEY ESCAPE ACTION ThisWindow.Release
@ 50, 50 LABEL lblSize10 HEIGHT 20 VALUE "Size10" FONT "Verdana" SIZE 10
@ 100, 50 LABEL lblSize20 HEIGHT 30 VALUE "Size20" FONT "Verdana" SIZE 20
END WINDOW
frmGTWTest.Center()
// msgdebug(_HMG_SYSDATA [ 36 ] )
// msgdebug(_HMG_SYSDATA [ 28 ] )
frmGTWTest.Activate()
Return Nil
Here testing Height too.
Tela1.PNG (9.18 KiB) Viewed 4206 times
Message re-edited. Correcting for height in pixels.
Re: Accuracy of GetTextWidth()
Posted: Mon Aug 18, 2014 10:43 pm
by esgici
OK Sr. Cesar,
It seems, it's enough for correct result, sending font handle of control as third parameter to the function.
For this we need
- defined (and activated) form and control
- know index of control
Well, it's time to learn ( if possible ) width in pixel of any string without own any control
TIA
Re: Accuracy of GetTextWidth()
Posted: Tue Aug 19, 2014 5:53 am
by mol
I found differences in strings:
By the way, this function doesn't calculate exact string length, besides, when you use bold feature, calculation is very bad.
Re: Accuracy of GetTextWidth()
Posted: Tue Aug 19, 2014 6:48 am
by Rathinagiri
GetTextWidth() function requires more importantly the DeviceContext and the font handle. Because, the text width might be different in various devices (monitor, printer etc). So, it is better and accurate if we give the exact device on which we want to show the text.
Re: Accuracy of GetTextWidth()
Posted: Tue Aug 19, 2014 2:20 pm
by esgici
mol wrote:I found differences in strings:
...
By the way, this function doesn't calculate exact string length, besides, when you use bold feature, calculation is very bad.
I'm not sure, which width returned; width of given string as parameter or caption / value string of control
Rathinagiri wrote:
GetTextWidth() function requires more importantly the DeviceContext and the font handle. Because, the text width might be different in various devices (monitor, printer etc). So, it is better and accurate if we give the exact device on which we want to show the text.
Beside font handle, we ( at least I ) need more clarification: how can be specified DeviceContext
May be first parameter ( always omitted, sent NIL ) ?
And what are codes / names etc of that info ?
Regards
Accuracy of GetTextWidth()
Posted: Tue Aug 19, 2014 3:34 pm
by Pablo César
mol wrote:I found differences in strings:
Yeah, you are right. Thanks Marek to advise this detail. I passed many hours looking for differance in my new function.
mol wrote:By the way, this function doesn't calculate exact string length, besides, when you use bold feature, calculation is very bad.
For bold size differs so few (around 2 pixels) and width sizes came with small differances but I not sure if is considered part o character of empty pixels. As showing in picture below (yellow color):
char.jpg (13.2 KiB) Viewed 4094 times
I have done another sample and I noted when is changed any font property the GetTextWidth function does not takes the right result.
/*
Test for accuracy of GetTextWidth() function and Height
2014-08-19
*/
#include <hmg.ch>
Function Main(cFont,cBold)
Local nFnt, cFontName
Private aFonts:={"Verdana","Arial","Courier New"}, lBold
If cFont=NIL
cFont:="2"
Endif
nFnt := Val(cFont)
If nFnt>0 .and. nFnt<4
cFontName := aFonts[nFnt]
Else
MsgStop("Upto 3 fonts declared")
Quit
Endif
If cBold=NIL
lBold := .F.
Else
lBold := .T.
Endif
DEFINE WINDOW frmGTWTest ;
AT 0,0 ;
WIDTH 380 ;
HEIGHT 280 ;
MAIN ;
TITLE "Accuracy in pixels" ;
ON INIT Test()
ON KEY ESCAPE ACTION ThisWindow.Release
DEFINE LABEL lblSize10
ROW 50
COL 20
HEIGHT 20
VALUE "Size10"
FONTNAME cFontName
FONTSIZE 10
FONTBOLD lBold
BACKCOLOR GREEN
FONTCOLOR RED
END LABEL
DEFINE LABEL lblSize20
ROW 100
COL 20
HEIGHT 30
VALUE "Size20"
FONTNAME cFontName
FONTSIZE 20
FONTBOLD lBold
BACKCOLOR GREEN
FONTCOLOR RED
END LABEL
@ 50,180 LABEL lblText HEIGHT 80 WIDTH 124 VALUE "" SIZE 11
DEFINE COMBOBOX Combo_1
ROW 180
COL 20
WIDTH 120
HEIGHT 100
ITEMS {aFonts[1],aFonts[2],aFonts[3]}
VALUE nFnt
FONTNAME "Arial"
FONTSIZE 9
ONCHANGE ChngFntLbls(This.Value)
END COMBOBOX
DEFINE CHECKBOX Check_1
ROW 180
COL 160
WIDTH 60
HEIGHT 28
CAPTION " Bold"
VALUE lBold
FONTNAME "Arial"
FONTSIZE 9
ONCHANGE ChngBoldFntLbl(This.Value)
END CHECKBOX
DEFINE BUTTON Button_1
ROW 180
COL 220
WIDTH 120
HEIGHT 28
ACTION Test()
CAPTION "Get Labels sizes"
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
END BUTTON
END WINDOW
frmGTWTest.Center()
frmGTWTest.Activate()
Return Nil
Function ChngBoldFntLbl(lValue)
lBold:=!lBold
SetProperty("frmGTWTest","lblSize10","FONTBOLD",lBold)
SetProperty("frmGTWTest","lblSize20","FONTBOLD",lBold)
Test()
Return Nil
Function ChngFntLbls(nValue)
Local cFont := aFonts[nValue]
SetProperty("frmGTWTest","lblSize10","FONTNAME",cFont)
SetProperty("frmGTWTest","lblSize20","FONTNAME",cFont)
Test()
Return Nil
Function Test()
Local aSizes:={}, cText:=""
aSizes := GetPixelSizes ("frmGTWTest","lblSize10","Size10")
cText := "Width (lblSize10): "+AllTrim(Str(aSizes[1]))+CRLF+"Height (lblSize10): "+AllTrim(Str(aSizes[2]))+CRLF+CRLF
aSizes := GetPixelSizes ("frmGTWTest","lblSize20","Size20")
cText := cText + "Width (lblSize20): "+AllTrim(Str(aSizes[1]))+CRLF+"Height (lblSize20): "+AllTrim(Str(aSizes[2]))
SetProperty("frmGTWTest","lblText","Value",cText)
Return Nil
Function GetPixelSizes (cForm,cControl,cString)
Local hWnd := GetFormHandle(cForm)
Local hDC := GetDC( hWnd )
Local idx := GetControlIndex (cControl,cForm)
Local nHndFnt := _HMG_SYSDATA [ 36 ][ idx ]
Local nHeight := _HMG_SYSDATA [ 28 ][ idx ]
Local nWidth
DEFAULT cString := GetProperty(cForm,cControl,"Value")
nWidth := GetTextWidth( hDC, cString, nHndFnt )
// msgdebug(nwidth)
ReleaseDC (hWnd, hDC)
Return {nWidth,nHeight}
This code allow also to receive optional parameters at prompt of line command. Then you can test 3 fonts and bold cases.
Test made by prompt line command with parameters: 3 Bold
Screen_02.PNG (12.96 KiB) Viewed 4087 times
It seems that GetTextWidth is based on when the control is being defined and is not changeable it properties even being forced thru SetProperty...
Re: Accuracy of GetTextWidth()
Posted: Tue Aug 19, 2014 5:34 pm
by Rathinagiri
In source\c_controlmisc.c around line no 360 you can find out what happens when you pass nil in the place of hDC (handle of device context). When you omit the device context, the device context of the active window is taken as the default device context. If you try to use the same for printing it won't show the accurate width.