News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

RectF

Started by mabdelouahab, December 02, 2013, 08:07:34 PM

Previous topic - Next topic

mabdelouahab

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

jj2007

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))

mabdelouahab

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

jj2007

Add this:

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


Rectangles are more than just x & y ;-)

mabdelouahab

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

K_F

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/
;)
'Sire, Sire!... the peasants are Revolting !!!'
'Yes, they are.. aren't they....'

mabdelouahab

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/
;)

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

dedndave

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

jj2007

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

qWord

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).
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

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

jj2007

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


mabdelouahab

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

dedndave

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