winapi Polygon() Polyline() etc


  • I want to use the Polygon function in winapi (gdi.lua) and I note that it requires an array of cdata POINTs as its second argument. I can make this in my code with something like:-

    local pts = ffi.new("struct tagPOINT[" .. cnt .. "]") -- where cnt is the number of points

    but I was wondering if it would be better to change the Polygon function to accept a lua table of points to keep the application code cleaner and simpler. Something like:-

    function Polygon(hdc, points, cnt)
    local pts = ffi.new("struct tagPOINT[" .. cnt .. "]") -- an array of 'c' POINTs
    for i=1, cnt do
    pts[i-1].x=points[i][1] -- copy the points from points{} to pts[]
    pts[i-1].y=points[i][2]
    end
    return checknz(C.Polygon(hdc, pts, cnt)) end

    This adds the overhead of copying points from the lua table to the c array, but I suspect this is insignificant compared to actual task of drawing the polygon.
    This change would also apply to the PolyPolygon function.

    Secondly, I want to use the gdi line and curve drawing functions such as Polyline, LineTo, MoveTo etc, and I note that these don't seem to be implemented in gdi.lua.
    I think I can do it, but I guess I'm hoping that you have plans to add these yourself. :)

    Any thoughts?

    Thanks,
    Garry.


  • 4
    Posts
    1668
    Views
    Log in to reply


  • ffi.new() has very rich semantics and already allows you to pass a table-of-tables to construct an array-of-structs. But it requires you to pass the length as the first argument. So I added a small extension to the VLA initializer so that it doesn't. It's at the end of util.lua and you can see all the ways you can use it in arrays_test.lua (check it out - some cases might surprise you) and it's also used in window.lua:MapWindowPoints. In short, you should do:

    function Polygon(hdc, points)
      local p, n = arrays.POINT(points)
      checknz(C.Polygon(hdc, p, n))
    end
    
    local p, n = Polygon(hdc, {{2, 3}, {4, 5}}) --alloc 2 points and init them
    local p, n = Polygon(hdc, 3, {2, 3}, {4, 5}) --alloc 3 points, init the first 2
    local p, n = Polygon(hdc, 5) --alloc 5 points, uninitialized (values are garbage, not zero)
    

    About implementing GDI, I don't wanna do it but you are welcome to add it yourself, the luaization utilities in util.lua should make it easy (I recommend reading about them and using them otherwise it will be very tedious and boring to bind all that stuff and you'll reinvent a lot of wheel in the process).

    For 2D graphics I recommend you take a look at cairo (CairoPanel and CairoPanel2 are 2 possible integrations for winapi -- they're used by cplayer. Warning: once you'll try cairo going back to GDI will feel painfully regressive (although I can understand if you don't want to carry the binary weight if your app is Windows-only).



  • I think the arrays constructor should be extended to allow you to pass a POINT[?] or POINT* cdata and a length, and just pass that through, just like the types constructor. This will allow the user control of the memory allocation as an option. Just a thought.



  • Thanks, I'll check all of that out.


4
Posts
1668
Views
Log in to reply

Internal error.

Oops! Looks like something went wrong!