Vector Graphics via Cairo

BlitzMax Forums/BlitzMax Programming/Vector Graphics via Cairo

taxlerendiosk(Posted 2005) [#1]
Cairo is an open-source rendering layer for vector graphics. I've been working on a BlitzMax wrapper, and so far have got it mostly working, rendering direct to Pixmap buffers.

However...

1) I'm currently using a Cairo DLL I found on the web somewhere rather than compiled-in code. Obviously I'd need to work out how to do this properly to make it cross-platform.

2) There is no support for any actual file format (e.g. SVG). I don't know whether it should be written in BlitzMax using a third-party XML module or what.

Is anyone else interested in this? It's not a complete system yet which is why I haven't released any code, I've hit a wall on both these issues and I dunno if enough people would really use it to make it worthwhile anyway. Is anyone else planning anything with Vector gfx at the moment?


Wiebo(Posted 2005) [#2]
Yes, I am working on some stuff with vectors... I've got most of my engine done though.. I'm interested in Cairo though, to see what it can do.


TartanTangerine (was Indiepath)(Posted 2005) [#3]
I've designed a function to draw glowing lines. It looks really quite nice. Basically it's a textured line function so you could texture it with anything, I chose a glow texture :D



But I suspect you mean something else when you say "VEctor Graphics"


taxlerendiosk(Posted 2005) [#4]
Yeah - cool effect though - vector graphics as in shapes made of lines and bezier curves, with fills including gradient and other effects. The reason I'd like it is to do a cartoony graphic adventure (a la Day of the Tentacle) with compact high-resolution graphics that would take up far more space as bitmaps (prerendered at run-time, not directly rendered frame-by-frame).


DocFritz(Posted 2005) [#5]
I'd be interested in Vectorgraphics too, but isn't it very slow if it renders to a Pixmap which you have to draw? Is there a possibility to Render it directly to Backbuffer?

@Indiepath
I'd like to see it in the Code-Archives, because I need excactly what you coded: A textured line. I'd also be glad if you could mail the code to mail@... ;)


taxlerendiosk(Posted 2005) [#6]
I was actually assuming that THAT would be too slow, which is why I was planning to prerender to Pixmaps as the game (or more likely each scene) is loaded and load the pixmaps into images, and then draw the images normally as the game is actually running (a bit like the way people used to have to draw rotated images in Blitz2D). If it *is* actually feasible to render in realtime to the backbuffer, I'd certainly be interested in trying to implement that too.


ImaginaryHuman(Posted 2005) [#7]
If you are only going to be loading the graphics and rendering them as storage and then turning them into images, it sounds like it'd work okay. Otherwise you'd be having to use DrawPixmap which is slower. I would think, though, that if you wanted to manipulate your vector graphics, like it if were a typeface or something you wanted to stretch and change and do things with (otherwise, why bother having it be vector-based?), you could render it directly with OpenGL or whatever and it should be pretty fast. If you can convert it to polygons or something.


taxlerendiosk(Posted 2005) [#8]
(otherwise, why bother having it be vector-based?)

For space reasons. I could render a tiny file (compared to JPEG/PNG equivalent) into a high-quality 1280x1024 cartoony background. Plus it could dynamically render to lower resolutions and not look as blurry.


MrCredo(Posted 2005) [#9]
@denzilquixode

i started few weeks also with using CAIRO-Library... But i gived up...

I was not able to compile the C-source-codes. But than i found a current DLL (at GTK-project)... i added a PNG-Lib to this sources and some more needed libs... but this LIBRARY do not work...

I testet with drawing at Win32-HDC - and had no luck...

I grab also a sample-code that render graphic to a PNG-Image - but this code generate only empty PNG's...

i don't know why, but this library do not work...
(i had DLL and all functions-access without problems. But nothing happen... :-/ )

can you publish your working stuff?


taxlerendiosk(Posted 2005) [#10]
I don't have anywhere to host it so I emailed it. Rename it from .zipp to .zip (Gmail blocks me from sending executables - apparently even DLLs - inside zip files but this seems like a workaround).


MrCredo(Posted 2005) [#11]
hm cairo was designed for highspeed realtime applications... hm...


Dreamora(Posted 2005) [#12]
But BM not for realtime texture modification.


MrCredo(Posted 2005) [#13]
yahoo.........

i found my "BUG"
i do not know that i should call "cairo_stroke" after i draw something... but now how to clear graphics???? hmmmm...

NOW - i can create a window with api-commands and get a HDC-handle from it

After this i load dynamicaly cairo.DLL and call some DLL-functions to draw graphics... i do not tested yet how fast this it... but i hope this is fast... :-)

at the moment i need to create a custom module for creating windows... but i hope that in future (with GUI-support) we do not need this...


Haramanai(Posted 2006) [#14]
So what happend? Did anyone of you finished the Cairo wrapper?


taxlerendiosk(Posted 2006) [#15]
I never overcame the problems with it and didn't develop any further, sorry. You can download the project as far I got it from http://malxode.com/CairoMax.zip - please feel free to develop on it further.


Haramanai(Posted 2006) [#16]
Thanks denzilquixode.
I had e-mailed you too. Now I the e-mail must go directly to the Garbage collector.


taxlerendiosk(Posted 2006) [#17]
Actually, your email is what alerted me - I don't check the forums all that often.


Haramanai(Posted 2006) [#18]
Can you point some of the problems?


taxlerendiosk(Posted 2006) [#19]
As I said in the first post, the first is the fact it relies on a DLL (and I can't even remember where I got the one in that zip from, now - it wasn't from a standard official package, I had to hunt around on the 'net for a suitable one). Secondly it requires you to do everything "by hand", no support for actual vector formats like SVG. Apart from that it should be working - though the TCairo wrapper object may be incomplete.


Brucey(Posted 2006) [#20]
Good day....

I downloaded denzils' CairoMax stuff and now have the examples running on Win32 using the latest Cairo (1.0.4) source.

Will probably need some work to make it all cross-platform, and turned into a proper module, but for an afternoon's hacking it'll do for now.

SVG integration would be nice indeed, I think...


FlameDuck(Posted 2006) [#21]
I think someone (Warpy?) did an SVG loader for the original BlitzBasic. Together with MaXML, can't imagine porting it would be that much of a challenge.

BTW, Brucey - thought of releasing the source to the Eclipse plug-in, if you're not going to develop it further? I know quite a few people who would be interested in carrying on the torch / co-developing it.


Haramanai(Posted 2006) [#22]
LibSvg-Cairo is what we need to run Svg thru Cairo.
I have no expirience of c and no lack compiling the source of this lib so I can take the dll.
Also all those days I am diging in the internet to find a pre-compiled Libsvg-cairo I have no luck.
Also the libsvg-cairo in CVS have many improvments comparing the 0.1.6 vertion.


taxlerendiosk(Posted 2006) [#23]
Great work Brucey! Drove me mad trying to get that to work.

I was just thinking what the best thing to aim for in the final module, to make it easy and "Blitzy". How about having an extended Pixmap type (TCairoPixmap or something) with methods to open and close a Cairo context on it, all the "manual" Cairo commands as methods, and a PasteSVG method that lets you stamp pre-defined shapes on (with optional parameters for position, scale, etc.)? It's not as simple as adding LoadImage support for SVG since a vector image has no definite edges, scale etc unlike bitmap.


Brucey(Posted 2006) [#24]
*Finally* got it working with Freetype fonts on Win32 (it defaults to using the windows system for fonts).
Me thinks it would be best to use the same on all platforms, hence my trying to get FT working.

Maybe someone can help me with some information on how one is able to make specific #defines for the various platforms.
As it stands, you would normally run ./configure which modifies config.h for the platform, enabling and disabling certain #defines for the build.
Rather than that, it would be much tidier to have a config.h that will have the options setup for the 3 platforms, which are used at build time.


Oh, and I managed to get the libsvg stuff for cairo (from cvs) compiled.... which also required me to choose either expat or libxml as the xml loader. So I now also have a libxml module.... *sigh*
Not that I've tried using it yet... I just have it compiling. And hacked together at that... Looks like it was written with linux in mind, so I had to borrow some code from glib to make things build.

It may well be easier to take that svg loader and munge something together with the cairo module... we shall see.

Summary of modules : (I don't like using Pub.xxxxx as it is messy to re-install modules whenever a new version of Max is released)
BaH.Cairo
BaH.Libxml
BaH.svg
BaH.Fontconfig (for Cairo's FT stuff)

Apart from denzil's cairo API bits, the modules don't have any max entry-points (yet)... They are just there to fill dependencies..


denzil, I think making it more Blitzy would be a good idea, although it is working pretty well as you made it so far..

:-)


Brucey(Posted 2006) [#25]
Have done some more work on Cairo.

It's now a proper module, and I've renamed the main type, TCairoPixmap, extending TPixmap.
You can create an instance of TCairoPixmap as you would a pixmap:
Local cairo:TCairoPixmap = TCairoPixmap.Create(256,256,PF_BGRA8888)

do some stuff to the context
cairo.SetLineWidth(5)
' draw an arc of 360 degrees (a circle) with radius 125.
cairo.arc(128, 128, 125, 0, 360)
' set draw color to yellow
cairo.SetSourceRGB(1, 1, 0)
' fix fill color to current
cairo.FillPreserve()
' set draw color to black
cairo.SetSourceRGB(0, 0, 0)
' draw it
cairo.Stroke()
' destroy context and resources
cairo.Destroy()

and get the resulting image...
Local image:TImage = LoadImage(cairo)

Have also puffed out the documentation a tad using the cairo API docs as a base. It's almost as well documented as TPixmap now ;-)

denzil, I've sent you a copy of the module. Lemme know what you think, and where we might be able to improve on it....

:o)

<edit>
Still haven't got around to testing it on Mac or Linux yet, so consider this win32 only for now until we can make sure it compiles up okay on the other platforms....
</edit>


taxlerendiosk(Posted 2006) [#26]
I've replied - having some problems getting it to compile. I've been looking through the source and docs though and it's looking really good otherwise.


Wiebo(Posted 2006) [#27]
Sounds cool! Where can I get it? :)


Brucey(Posted 2006) [#28]
I've got it working now on Linux.
All the demos look the same, which is probably a good thing ;-)

There's one small issue with getting it running on all platforms at the moment, and that is because the Freetype module requires an Import added to it (the source is there, it is simply not using compiling in a particular function).
I've asked Mark if he can add this officially.... (not a lot of code to change, me thinks!)

And I would also like to get it up and running on OSX too. I might have a hack at it later today... :-)


MrCredo(Posted 2006) [#29]
this lib should added to blitzmax-modules...


Haramanai(Posted 2006) [#30]
Do we have any news?


Brucey(Posted 2006) [#31]
Hallo :-)

I suppose this should be in a topic of its own, but anyhow...

You can download the cairo max module from My Modules Repository.

It uses the latest Cairo (1.1.6), and also includes a module for fontconfig (no max API, just the compiled code), since it requires fontconfig to get at the FreeType API.
Comes fully documented with some examples to get you started.
It is currently borked on Mac, so this is only really good for win32 and Linux, until we can get the graphics issues sorted.

I see there is better svg support in 1.1.6 so will have to look into that. The only issue there would then be that cairo would end up being dependent on my libxml2 module (not that that in itself is such a bad thing, I suppose :-p )
...

Anyhoo... lemme know how you get on. All feedback is appreciated.

Denzil. I haven't done anything with those ideas you mailed me about yet. Just upgraded and got everything working nicely.
Lots of potential here I think for improvements :-)


Brucey(Posted 2006) [#32]
.. I'm going to have a look at making a libsvg module this weekend.. with the idea that you could then load a .svg file and display it in Max (via the Cairo module)...

If I make it a separate module, then Cairo is libxml free.
However, there is also a build option in Cairo to *export* svg, which, if compiled in, would require libxml....

heh... wish me luck :-p


assari(Posted 2006) [#33]
Just downloaded and tried your module. Works a treat.
Thanks for sharing. Good job


Wiebo(Posted 2006) [#34]
This looks very interesting. Thanks man!


Haramanai(Posted 2006) [#35]
Top stuff man.
Great.
No dll just code. Top.

I will go and play (learn).

And another thing. I vote you to be beta tester.


Haramanai(Posted 2006) [#36]
Have you found a way to clear cairo and start painting again?
I cannot find a way to get cairo in a loop so I cannot create any drawing tool.

[Edit]
Ok I found a way to do it. I am just using the Functions and not the methods. TCairoPixmap it's not so good idea after all as Cairo it's supossed to draw on a surface. I think that the wrapper must stay at the most low level of the actual API and not get changed for the more stiled typing of the commands.
And the best is to provide the functions that are nessasery to optimize the Cairo Objects for BMax like CreateFromPixMap Function to create and get the pointer of the new surface that you created.
And some for the Matrix to bypass the trick of MemAlloc(64 * 6) . Overall functions to keep the compartibility between BlitMax and Cairo.
Just my opinion. I will continue playing as the wrapper after all looks great.


Beaker(Posted 2006) [#37]
Looks good so far. I don't think all demos work correctly here:
text.bmx - just displays a white screen.
clock.bmx - just displays a circle and a single line at 3 o'clock (no text or other lines).


Haramanai(Posted 2006) [#38]
Yes the this demos don't run ok.
I just said that TCairoPixmap it's not good. cause as I am reading the API docs and I if you read them you will find out that Cairo_t it's something like the drawing tools and Surfaces are the surface( paper ) that you will draw on it.
Anyway I started to add the docs of the API on the original functions. I finished the cairo_t.
Brucey what you think?


Brucey(Posted 2006) [#39]
Interesting...

I've had the demos working fine on win32 (win2k) and linux (ubunto 5.10 and Fedora Core 4 - different machines). All seemed to perform in the same way for both platforms.

As far as I can tell with the docs, a surface is simple something that stuff gets rendered to, be it a bitmap in memory or a postscript file.
As it stands at the moment, we have it running on top of a Pixmap, onto which the Cairo context is set to render.

I thought it was useful to take away some of the hoops from the user that you'd have to jump through were you working in C. Isn't this the BlitzMax way? - to make it easy for Joe Coder to use, without having to know too much.

:-)


Brucey(Posted 2006) [#40]
Anyhoo... while I'm here, I thought I'd mention a new module available on my site - libsvg.

It plugs into the Cairo module to allow loading and rendering of .svg files through the Cairo API.
You can do all the usual manipulation you would on standard Cairo drawing methods, against the loaded SVG.

You will need the Cairo and libxml modules to use this one.

Note: This is licensed under LGPL 2. So is a little bit restrictive... sorry.

Anyways, enjoy :-)


Brucey(Posted 2006) [#41]
The latest Cairo adds a Clear() method which will clear down an area with the specified colors - just a convenience method really.
This appears to be the way the Cairo author says to do it too... which is interesting...

:-)


taxlerendiosk(Posted 2006) [#42]
Stellar work again Brucey, libsvg seems to work fine here. But it looks like you can only load from disk, is there any chance of loading IncBin'd SVGs? What about zlib compression that your xml module supports, does that already work in SVGs?

Re TCairoPixmap. As far as I can tell the only reason to go back to a separate TCairo context object is if we're planning to eventually support surfaces for other things, like straight to DX/OpenGL buffers. If we do do that I think we should still have a TCairoPixmap but one that just has a cairo:TCairo field and CreateCairo()/DestroyCairo() methods, and then you'd do, like, cpixmap.cairo.Stroke() instead of cpixmap.Stroke().


Brucey(Posted 2006) [#43]
denzil, thanks.

I don't see that it would be impossible for the loading of inc-bin'd SVGs...
Haven't tried a compressed xml yet... assuming it just passes the raw xml to libxml, I don't see why not.

I just wanted to get it up and running first... then tweaks and enhancements can follow on from there :-)

Okay.. .have updated fontconfig module so that it handles win32 font-dir locations better at runtime. Thanks to Chris C. for the useful comments with regards that issue :-)
That should fix the demos that use text.... (obviously, if I'd coded the demos so that they checked if the font-stuff had worked first before trying to use it, I suppose it wouldn't have looked so cack.... - the moral of the story being... if a method returns a success-status value, you should probably check to see it actually was succesful)..

Enjoy :-)


Haramanai(Posted 2006) [#44]
I played with cairo a lot. Great module but the over all speed that I can get it's 17 fps at a machine of 2ghz 512 ram.
Well I am trying to make a realtime aplication but this looks like it's not possible with only Cairo Module. What it's needed it's a Glitz module that will be connected with cairo module.


Brucey have you checked Glitz? looks like the only way to play with vector graphics in realltime.


Brucey(Posted 2006) [#45]
Don't hold your breath... glitz has absolutely *no* documentation... so it'll take a while to get my head around it....

:o)