1. GDI Plus library
- Posted by LewisTownsend Jan 23, 2010
- 1455 views
Howdy folks,
long time no post.
I've been trying to work with Al Getz' GDI+ wrapper lib as a hopefully faster alternative to Win32lib graphics functions. However, before I can even tell if this is going to be faster, I have to figure out some of the undocumented functions. I have figured out several but I'm currently stumped at the draw polygon functions. I'm not a C programmer so I don't know how exactly to format the points data in memory so that the cfunc can use it. I've tried just about everything I can think of and have done some Google searching but so far haven't got it to work. I'm assuming that the points are stored in some kind of standard c-array format but I don't know what that is. I have at least one other thing I can think to try but I figured I should ask before banging my head against this any more.
I know this lib hasn't been modified recently and the most relevant discussion here seems to be a few years ago. http://oe.cowgar.com/forum/87068.wc#87068 For fast image copying and basic graphics functions; should I be using something else, like DirectDraw, etc? Please note I'm not sure I could write my own wrapper and would probably have the same problem with anything else in C.
thanks for any help or advice
Lewis Townsend
2. Re: GDI Plus library
- Posted by ssallen Jan 26, 2010
- 1362 views
I feel your pain. I was looking for a Windows graphics lib a while back and took a look at GDI. It took about an hour before I gave up and downloaded Mic's CXImage library. Unfortunately it isn't fully converted and doesn't do 99% of what GDI can. Luckily for me it met the majority of my requirements which was mostly just loaders for the various file types and basic transformation ops. The rest I had to hack together utilizing SDL (like the primitive functions.) It works, but it sure ain't pretty.
Al Getz GDI+ wrapper looks great if it was documented better and/or I could understand half of it. :)
(EDIT: Welcome back by the way. Haven't seen your posts in ages!)
3. Re: GDI Plus library
- Posted by LewisTownsend Jan 26, 2010
- 1411 views
EDITED
Thanks ssallen,
I'm actually trying to edit the wrapper to make it easier to use. like making it do all the allocating and peeking and poking for you I've been able to figure out quite a bit and simplified it for my purposes but I'm still stuck on this points thing.
I think most Euphoria programmers like Euphoria because of it's simplicity. I think those same (most) probably couldn't use GDI+ because it returns the complexity of C
Ok, so I thought I might get more responses if I posted some code:
global procedure WrongDrawLinePolygon(atom p_graphics,atom p_pen, sequence points ) --,atom count) -- points is a 1-dimensional sequence in the form of {x1,y1,x2,y2,x3,y3...} atom status, p_points integer count sequence bytesAll,bytesPair count = length(points)-- count is the number of x and y values p_points = allocate( count*2 )-- allocate 4 bytes per pair which is just going to be another pointer bytesAll = "" for i = 1 to count-1 by 2 do status = allocate(8) -- the pointer for a pair bytesPair = ( int_to_bytes( points[i] ) ) bytesPair &= ( int_to_bytes( points[i+1] ) ) --bytesPair = bytesPair[1..2]&bytesPair[5..6] -- this is for if only using 2 bytes per integer poke( status, (bytesPair)) --reverse bytesAll &= status --& bytes end for poke( p_points, ( bytesAll ) ) --(GpGraphics *graphics,GpPen *pen,GDIPCONST GpPointF *points,INT count) if gdiplus>0 then status = c_func(xGdipDrawPolygon,{p_graphics,p_pen,p_points,count/2}) --else status = 0 end if puts(1, GetErrorString(status) & " " ) --bytes = "" for i = 1 to length( bytesAll ) do status = peek4u( bytesAll[i]) puts(1, "{"&sprint(status)&"," ) status = peek4u( bytesAll[i]+4) puts(1, sprint(status)&"}\t" ) free( bytesAll[i] ) end for --print(1, bytes) puts(1, '\n' ) free( p_points ) end procedure
4. Re: GDI Plus library
- Posted by petelomax Jan 27, 2010
- 1429 views
Ok, so I thought I might get more responses if I posted some code:
count = length(points)-- count is the number of x and y values p_points = allocate( count*2 )-- allocate 4 bytes per pair bytesAll = "" for i = 1 to count-1 by 2 do status = allocate(8) -- the pointer for a pair bytesPair = ( int_to_bytes( points[i] ) ) bytesPair &= ( int_to_bytes( points[i+1] ) ) poke( status, (bytesPair)) --reverse bytesAll &= status --& bytes end for poke( p_points, ( bytesAll ) )
If it is an array of pointers to 8-byte points (which I doubt), you would need to use poke4(p_points,bytesAll).
Have you tried allocating len*4 and a plain poke4(p_points,points)?
Or if it really is 2 bytes per integer, this may help:
procedure poke2(atom addr, object x) atom xi if atom(x) then poke(addr, and_bits(x,#FF)) poke(addr+1, floor(and_bits(x,#FF00)/256)) else -- sequence for i = 1 to length(x) do xi = x[i] -- (helps speedwise, also ensures we don't -- blindly poke nested sequences...) poke(addr, and_bits(xi,#FF)) addr += 1 poke(addr, floor(and_bits(xi,#FF00)/256)) addr += 1 end for end if end procedure
A quick search also landed me at
http://msdn.microsoft.com/en-us/library/system.drawing.pointf.pointf.aspx
which suggests it may be expecting a (flat) array of 32-bit floats?
Regards and hello again, Pete
5. Re: GDI Plus library
- Posted by LewisTownsend Jan 27, 2010
- 1331 views
Thanks Pete, The flat array doesn't seem to work either. That does make the most sense tho and it was the first thing I tried. I am tying my brain into knots trying to use pointers to pointers. Here is a simplified version that still doesn't work. Is this using the "(flat) array of 32-bit floats"?
global procedure DrawLinePolygon(atom p_graphics,atom p_pen, sequence points ) -- points is a 1-dimensional sequence in the form of {x1,y1,x2,y2,x3,y3...} atom status, p_points integer count count = length(points)-- count is the number of x and y values p_points = allocate( count*4 )-- allocate 4 bytes per integer poke4( p_points, points ) --(GpGraphics *graphics,GpPen *pen,GDIPCONST GpPointF *points,INT count) if gdiplus>0 then status = c_func(xGdipDrawPolygon,{p_graphics,p_pen,p_points,count}) end if puts(1, GetErrorString(status) & "\t" & sprint(points) & "\n" ) free( p_points ) end procedure
I read somewhere that the first byte of an array identifies what kind of data it holds. Does this sound right? Any idea what byte value that would be?
6. Re: GDI Plus library
- Posted by mattlewis (admin) Jan 27, 2010
- 1387 views
Thanks Pete, The flat array doesn't seem to work either. That does make the most sense tho and it was the first thing I tried. I am tying my brain into knots trying to use pointers to pointers. Here is a simplified version that still doesn't work. Is this using the "(flat) array of 32-bit floats"?
It looks like you're trying to wrap this function:
Status DrawPolygon( const Pen *pen, const PointF *points, INT *count );
The PointF class actually contains 2 REALs. According to GdiPlusTypes.h, a REAL is a float, which is a 32-bit floating point number. The array of PointFs is identical to a flat array of 'x' and 'y's. In C/C, a pointer to something is more or less how those languages deal with arrays. You can then manipulate the pointer to get array-like behavior. So all we have to do is store them sequentially in memory (which you were doing, except in the wrong form).
Also, count is actually a pointer to an int. Try this:
global procedure DrawLinePolygon(atom p_graphics,atom p_pen, sequence points ) -- points is a 1-dimensional sequence in the form of {x1,y1,x2,y2,x3,y3...} atom status, p_points integer count sequence floats count = length(points)-- count is the number of x and y values p_points = allocate( (count+1)*4 )-- allocate 4 bytes per integer poke4( p_points, count ) floats = {} for i = 1 to count do floats &= atom_to_float32( points[i] ) end for poke( p_points + 4, floats ) --(GpGraphics *graphics,GpPen *pen,GDIPCONST GpPointF *points,INT count) if gdiplus>0 then status = c_func(xGdipDrawPolygon,{p_graphics, p_pen, p_points+4, p_points}) end if puts(1, GetErrorString(status) & "\t" & sprint(points) & "\n" ) free( p_points ) end procedure
Matt
7. Re: GDI Plus library
- Posted by LewisTownsend Jan 27, 2010
- 1338 views
Thanks Matt!
Your version gave me a machine-level exception on the c_func call but I switched back to using a plain integer for the count and it works now. Thanks much!
Here is my working version if anyone else cares:
global procedure DrawLinePolygon(atom p_graphics,atom p_pen, sequence points ) -- points is a 1-dimensional sequence in the form of {x1,y1,x2,y2,x3,y3...} atom status, p_points integer count sequence floats count = length(points)-- count is the number of x and y values p_points = allocate( (count)*4 )-- allocate 4 bytes per integer floats = {} for i = 1 to count do floats &= atom_to_float32( points[i] ) end for poke( p_points , floats ) --(GpGraphics *graphics,GpPen *pen,GDIPCONST GpPointF *points,INT count) if gdiplus>0 then status = c_func(xGdipDrawPolygon,{p_graphics, p_pen, p_points, count}) end if --puts(1, GetErrorString(status) & "\t" & sprint(points) & "\n" ) free( p_points ) end procedure
8. Re: GDI Plus library
- Posted by DerekParnell (admin) Jan 28, 2010
- 1308 views
Thanks Matt!
Your version gave me a machine-level exception on the c_func call but I switched back to using a plain integer for the count and it works now.
It would appear that the MSDN documentation is misleading at best, or just plain wrong. The sample code and the rest of the MSDN text for this function implies that count is an integer and not a pointer.
9. Re: GDI Plus library
- Posted by mattlewis (admin) Jan 28, 2010
- 1373 views
Thanks Matt!
Your version gave me a machine-level exception on the c_func call but I switched back to using a plain integer for the count and it works now.
It would appear that the MSDN documentation is misleading at best, or just plain wrong. The sample code and the rest of the MSDN text for this function implies that count is an integer and not a pointer.
Yeah, obviously I didn't even look at the example. The header at koders appears to be from ReactOS, on closer inspection. It shows a pointer, just like the documentation:
Status DrawPolygon(const Pen *pen, const PointF *points, INT *count)
A version of the actual header shows an integer:
Status DrawPolygon(IN const Pen* pen, IN const PointF* points, IN INT count)
Matt