1. GDI Plus library

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

new topic     » topic index » view message » categorize

2. Re: GDI Plus library

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: GDI Plus library

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 
 
new topic     » goto parent     » topic index » view message » categorize

4. Re: GDI Plus library

LewisTownsend said...

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: GDI Plus library

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?

new topic     » goto parent     » topic index » view message » categorize

6. Re: GDI Plus library

LewisTownsend said...

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

new topic     » goto parent     » topic index » view message » categorize

7. Re: GDI Plus library

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 
new topic     » goto parent     » topic index » view message » categorize

8. Re: GDI Plus library

LewisTownsend said...

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.

new topic     » goto parent     » topic index » view message » categorize

9. Re: GDI Plus library

DerekParnell said...
LewisTownsend said...

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu