Hello all
What is the difference between
LOCAL __layoutRect:RectF
and
.data
_layoutRect RectF <>
.code
When I use the first, the procedure works
But the second does not work
In this procedure
_DrawString proc pGraphics:dword , Text_ :dword, szFontName :dword, fontSize :REAL4,X:dword,Y:dword,Color_:dword,Styl_:dword
LOCAL pFontFamily:dword,pFont:dword,pRedAlfaBrush:dword,_hGdiPlusStringFormat:dword
LOCAL __layoutRect:RectF
local _UnicodeText[512]: byte
local _UnicodeFont[32]: byte
.data
_layoutRect RectF <>
.code
finit
fild X
fstp _layoutRect.x ; <------------------ First works
; fstp __layoutRect.x ; <------------------ Secend not works
fild Y
fstp _layoutRect.y ; <------------------ First works
; fstp __layoutRect.y ; <------------------Secend not works
invoke MultiByteToWideChar,0,0, Text_,0ffffffffh,addr _UnicodeText,512
invoke MultiByteToWideChar,0,0, szFontName,0ffffffffh,addr _UnicodeFont,32
invoke GdipCreateFontFamilyFromName,addr _UnicodeFont, 0, addr pFontFamily
invoke GdipCreateFont,pFontFamily,fontSize,Styl_,3,addr pFont
invoke GdipDeleteFontFamily,pFontFamily
invoke GdipCreateSolidFill,Color_,addr pRedAlfaBrush
invoke GdipCreateStringFormat,0 , LANG_NEUTRAL, addr _hGdiPlusStringFormat
invoke GdipSetStringFormatAlign,_hGdiPlusStringFormat,StringAlignmentCenter
invoke GdipSetStringFormatLineAlign,_hGdiPlusStringFormat,StringAlignmentCenter
invoke GdipDrawString,pGraphics, addr _UnicodeText, 0ffffffffh, pFont, addr _layoutRect , _hGdiPlusStringFormat,pRedAlfaBrush
;invoke GdipDrawString,pGraphics, addr _UnicodeText, 0ffffffffh, pFont, addr __layoutRect , _hGdiPlusStringFormat,pRedAlfaBrush
invoke GdipDeleteFont,pFont
invoke GdipDeleteBrush,pRedAlfaBrush
ret
_DrawString endp
Thank you
Both assemble fine. What exactly is the problem?
You certainly know that local variables do not keep their values when they leave the proc, but that seems no problem here. The code below works just fine:
finit
fldpi
fldpi
fstp _layoutRect.x
fstp __layoutRect.x
print "First="
print real4$(_layoutRect.x), 13, 10
print "Second="
print real4$(__layoutRect.x), 13, 10
By the way, the real4$() trashes the FPU, so it works only if the two prints come at the end (the author had the bright idea to initialise the FPU before calling sprintf... 8))
I've included an example
Inside two PROC
_DrawString
_DrawString2
The only difference between them is that I used in the first
.data
_layoutRect RectF <>
In the second procedure
LOCAL __layoutRect:RectF
The first is show the text
but the second does not do
Add this:
fld FP4(200.0)
fstp __layoutRect._Width
fld FP4(200.0)
fstp __layoutRect.Height
Rectangles are more than just x & y ;-)
Why the first procedure does not need to determine the width/Height
In this function (GdipDrawString) , the text is written in a single line, if you do not specify a Width
But if you customize the Width, the text goes back to the line automatically
Quote
fild X
fstp _layoutRect.x ; <------------------ First works
; fstp __layoutRect.x ; <------------------ Secend not works
FSTP pops the value off the FP register stack (IOW it empties that register), and the next FSTP is storing a 'non-existent' register value, OR the next value on the stack that you don't want :biggrin:
As JJ says, you must push 2 values onto the FPU stack if you want to store/pop 2 values.
Read up on Raymonds Simply FPU tutorials http://www.ray.masmcode.com/ (http://www.ray.masmcode.com/)
;)
Hi K_F
Quote from: K_F on December 03, 2013, 02:30:00 AM
Quote
fild X
fstp _layoutRect.x ; <------------------ First works
; fstp __layoutRect.x ; <------------------ Secend not works
FSTP pops the value off the FP register stack (IOW it empties that register), and the next FSTP is storing a 'non-existent' register value, OR the next value on the stack that you don't want :biggrin:
As JJ says, you must push 2 values onto the FPU stack if you want to store/pop 2 values.
Read up on Raymonds Simply FPU tutorials http://www.ray.masmcode.com/ (http://www.ray.masmcode.com/)
;)
I use only one of them at the same time
See example attached
My question is :
Why when I create a layoutRect in .data section the text show,
and When I create a layoutRect as LOCAL the text not show
With a solution that created by jj2007, I lose the advantage of writing in one line
RectF STRUCT
x REAL4 ?
y REAL4 ?
_Width REAL4 ?
Height REAL4 ?
RectF ENDS
not like the RECT structure, which has top, left, right, bottom
it's more like a "position" structure
nonetheless, that would not explain why it might work one way and not the other
Quote from: mabdelouahab on December 03, 2013, 03:19:07 AM
With a solution that created by jj2007, I lose the advantage of writing in one line
LOCAL variables contain garbage, i.e. whatever happened to be in the stack area. With the global RectF, you got zero for _Width and Height, and apparently GDI+ is happy with these zeros. But it chokes on garbage...
Quote from: mabdelouahab on December 03, 2013, 03:19:07 AMMy question is :
Why when I create a layoutRect in .data section the text show,
and When I create a layoutRect as LOCAL the text not show
It is a feature documented by source (GdiPlusGraphics.h): the overloaded method DrawString(..., const PointF &origin,...) set the width and height of RectF to zero and then call GdipDrawString.
So your code with the global RectF does work, because the width and height are zero (default values).For the local variant, you did not initialize w/h thus it contains any value (or NAN).
those 2 answers are right
there is garbage on the stack for the local declaration
and, in the global declaration, the _Width and Height members are 0
fild X
;fstp _layoutRect.x ; <------------------ First works
fstp __layoutRect.x ; <------------------ Secend not works
fild Y
;fstp _layoutRect.y ; <------------------ First works
fstp __layoutRect.y ; <------------------Secend not works
xor ecx,ecx
mov dword ptr __layoutRect._Width,ecx
mov dword ptr __layoutRect.Height,ecx
the text now shows up in 2 places - lol
Quote from: dedndave on December 03, 2013, 04:06:57 AM
xor ecx, ecx
mov dword ptr __layoutRect._Width,ecx
mov dword ptr __layoutRect.Height,ecx[/code]
:t
And here is a solution that is one line shorter :P
xorps xmm0, xmm0
movlps qword ptr __layoutRect._Width, xmm0
How can I thank you all for the solution and also information
Thank you very much
Quote from: dedndave on December 03, 2013, 04:06:57 AM
fild X
;fstp _layoutRect.x ; <------------------ First works
fstp __layoutRect.x ; <------------------ Secend not works
fild Y
;fstp _layoutRect.y ; <------------------ First works
fstp __layoutRect.y ; <------------------Secend not works
xor ecx,ecx
mov dword ptr __layoutRect._Width,ecx
mov dword ptr __layoutRect.Height,ecx
the text now shows up in 2 places - lol
I will work with this solution :t
Thank you very much
Jochen and qWord get the credit
by the time i realized what was going on, they had posted - lol
at any rate, nice looking project :t