Canvas Review
As announced by Murray already I am working for Openismus now. First task I got assigned was providing patches for some binding glitches in GooCanvas. Seems I complained too much about GooCanvas' code during that task. So Murray asked me to review GooCanvas, HippoCanvas and libccc to figure out which canvas would fit best for diagrams and reports in Glom.
As we have that nice canvas overview on the GNOME Wiki already, I added additional information to that wiki page. Thank you Emmanuele for updating the clutter records, btw.
HippoCanvas dropped out quickly for lacking printing support and more importantly for its boxed, HTML/CSS like layout. This approach doesn't seem to be flexible enough to support things like table relationship diagrams.
GooCanvas seems to be the most complete canvas, but it has some issues:
By provinding a function to pass a custom cairo context to the rendering routines its does only the trivial part of printing, but leaves pagination, which is the hard part of printing, to its users. Pagination usually is not trivial as you have to avoid splitting text lines and pictures on page boundaries:

Techniques to avoid this glichtes include moving of short paragraphs and pictures to the next page, cutting paragraphs and text at cell and line boundaries, rewrapping text and rescaling pictures. I could not find hooks for doing this in GooCanvas, so when using GooCanvas for Glom at least the hooks for such features would have to be added to that canvas.
As it seems grid fitting is implemented for tables only. This causes a blurry and unprofessional look. It also lowers rendering performance as unnecessary antialiasing and resampling operations have to be applied.
![]()
GooCanvas currently also has problems in its code architecture. Its data model structures are all public which puts quite some burden on maintainers willing to provide a stable API. This can be fixed easily as most/all of the fields exposed are be accessable by getters and setters.
A more serious problem is the optional model/view split which causes huge amounts of code duplication in GooCanvas. Currently GooCanvas gives you view items and model object, which in fact just are containers for the very same model data structure. View and model objects provide the same set of properties and methods to manipulate that shared data structure. This obviously is wrong: When there are view and model objects, all the model data should be stored in the model objects. At least there shouldn't be separate model data structures. The view objects should reference their model objects. But even that approach would be too complicated in my opinion, as in my opinion the canvas items itself are the model and the canvas, cell renderers, ... are the views. When the items have to store view specific data this issue should be handled internally (and not exposed to the user). I am pretty sure this change would reduce the lines of code GooCanvas needs by at least one third.
libccc is quite similiar to GooCanvas, which is not very suprising considering both want to provide a cairo based replacement for GNOME Canvas. libccc puts high emphasis on creating clean API and modern programming techiques. Usually this is a good thing, but considering the shear amount of other projects Sven is working on, it also directly leads to the biggest problem of libccc: Although being much older than GooCanvas 1), libccc has still lists "work in progress" for many features.
It is ahead of GooCanvas with its clean model/view separation. Beside the mandatory canvas widget the libraries provides additional view implementations like a GtkCellRenderer or a camera item (picture-in-picture). In addition to the features of GooCanvas it provides inline text editing and moves the burden of grid fitting from the canvas items to the views.
Conclusion
Without requiring printing support and high quality (pixel aligned) rendering the choice would be simple: Take GooCanvas, as it seems to be more complete. When if its feature matrix fits your needs, it's most reasonable to use this canvas widget.
Things shift when you figure out that you have add features. In that case GooCanvas' unnecessary code complexity hurts. You have to choose between investing alot of time on working with that complex and fragile code or convincing Damon (and the other people on the mailing list) of dropping the optional model/view split first - which also would need quite some time. Considering my weak mailing list discussion skills I'd most probably choose finishing libccc, instead of wasting that time on discussing and refactoring GooCanvas - but that's my personal opinion. People with better mailing list skills and better contact to Damon probably will vote different.
1) In opposition to common believe libccc really was started before GooCanvas. Sven demonstrated me libccc on 20C3 which was held in 2003, whereas GooCanvas was started in 2005.
HippoCanvas does have fixed-positioning layout available (you can add a child to a box that is fixed-positioned). Printing would be trivial since it already draws to Cairo.
However, for sure HippoCanvas is something you would not want to use unless you're prepared to hack on it, since it has only been evolved "as needed" for the apps using it (mugshot, bigboard, One Laptop Per Child). So if nobody needed a feature it's not there yet ;-)
The API certainly leans toward "mostly widget/html type things" with nonrectangular, fixed-position type things as the secondary case.
Havoc: Seems I really put HippoCanvas aside too early for not finding its fixed-position feature. Shame on me. Still it doesn't have fancy stuff like affine transformations - but I have to admit those really would not be needed for Glom.
Regarding printing: As I wrote in the article, printing takes more than just passing a custom cairo context to the rendering routines, so IMHO adding printing to HippoCanvas definitly would not be trivial: All the pagination code would have to be added. Yes, as long as you ignore fixed-positioned children, implementing pagination for HippoCanvas is much more trival, than for a canvas using an arbitrary scene graph as model. The boxed layout model greatly support pagination. As soon as you also want to consider fixed-positioned children things become complex.
I think this pagination stuff might be quite application-specific, but hopefully we can provide useful optional stuff if there are common needs. I guess I'll have a better idea of this after implementing it for Glom.
libccc look[s|ed] most promising, used it happily for long for geom (http://abulafia.fciencias.unam.mx/geom/)
Hi Mathias; I'm the developer of Geom, which mime just mentioned as an example application for libccc. I'm deeply interested in the development of libccc, and I'm hoping to be of some help if you decide to give the library a hand (as you mentioned it, Sven is very busy with like two million other projects).
Right now I'm insanely busy finishing my master thesis (that's the reason I haven't worked in Geom in two and a half months), but as soon as I've finished I will resume my hacking on it; and hacking in libccc is also in my wish list.
Hi Canek,
could you please share some experiences with libccc? I'm interrested in
- easy of use
- stability
- flexiblity
Thanks
You need to understand that I'm using just a very limited subset of libccc capabilities. With that in mind:
- I find the library very easy to use; much of the time the API just "makes sense", and generally things work as expected. The documentation (although not complete) is very good too.
- The library is very stable in x86; in amd64 the bug 460015 (http://bugzilla.gnome.org/show_bug.cg...) is a crasher, although I have a (very hackish) workaround.
- Given that I'm only using some very specific parts of the library, I don't know if I'm qualified to comment about the flexibility. However, the library is designed to be easily extensible.
Hope it helps.