The MASM Forum

General => The Campus => Topic started by: mabdelouahab on December 02, 2013, 08:07:34 PM

Title: RectF
Post by: mabdelouahab on December 02, 2013, 08:07:34 PM
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
Title: Re: RectF
Post by: jj2007 on December 02, 2013, 09:28:36 PM
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))
Title: Re: RectF
Post by: mabdelouahab on December 03, 2013, 12:00:44 AM
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
Title: Re: RectF
Post by: jj2007 on December 03, 2013, 12:53:24 AM
Add this:

      fld FP4(200.0)
      fstp __layoutRect._Width
      fld FP4(200.0)
      fstp __layoutRect.Height


Rectangles are more than just x & y ;-)
Title: Re: RectF
Post by: mabdelouahab on December 03, 2013, 01:45:20 AM
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
Title: Re: RectF
Post by: 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/)
;)
Title: Re: RectF
Post by: mabdelouahab on December 03, 2013, 03:19:07 AM
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
Title: Re: RectF
Post by: dedndave on December 03, 2013, 03:54:14 AM
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
Title: Re: RectF
Post by: jj2007 on December 03, 2013, 03:58:23 AM
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...
Title: Re: RectF
Post by: qWord on December 03, 2013, 03:59:28 AM
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).
Title: Re: RectF
Post by: dedndave on December 03, 2013, 04:06:57 AM
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
Title: Re: RectF
Post by: jj2007 on December 03, 2013, 04:13:22 AM
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

Title: Re: RectF
Post by: mabdelouahab on December 03, 2013, 04:25:50 AM
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
Title: Re: RectF
Post by: dedndave on December 03, 2013, 04:34:03 AM
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