'Creating reusable templates in Cairo
I'm using Cairo (Cairomm in C++) with its PDF surface to create reports from JSON data, and would like a header and footer on each page I write. At the moment I am creating image surfaces as a template and copying the data to each new page, but I was thinking a more elegant method would be to have a method that returns a new Context for each page which writes to the same surface, pre-populated with the header and footer, that I can then call my drawing methods on.
To clarify, I am considering going from a method that returns an image surface with my header and footer (which I then copy to my PDF surface), to using a method that returns a new graphics context with the header and footer (but the same PDF surface) which I can write to directly.
The issue is that I am struggling to find any detailed documentation on whether there is a right or wrong way of templating in Cairo, and have never seen anyone use multiple contexts for it. Is there anything wrong with using multiple contexts on the same surface (assuming there is only one context per surface at a given time), and if so, is there a more correct way to apply layers to my surface other than using several image surfaces and copying data?
Solution 1:[1]
Is there anything wrong with using multiple contexts on the same surface (assuming there is only one context per surface at a given time),
Not really helpful, but: My gut feeling is "no, there is nothing wrong with it".
is there a more correct way to apply layers to my surface
I don't know about "more correct", but I would go with cairo_push_group() / cairo_pop_group() instead of an image surface. That way, your header/footer can still use vector operations on the resulting PDF instead of just "some pixels". Untested pseudo-code (sorry, pseudo-C, not pseudo-C++):
cairo_pattern_t * draw_header_to_pattern(cairo_t *cr) {
cairo_push_group_with_content(cr, CAIRO_CONTENT_COLOR_ALPHA);
// Code here to draw the header/footer
return cairo_pop_group(cr);
}
// To use this, create the pattern once:
cairo_pattern_t *template = draw_header_to_pattern(cr);
// Now, when starting a new page, draw the template
cairo_show_page(cr);
cairo_save(cr);
cairo_set_source(cr, template);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_paint(cr);
cairo_restore(cr);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Uli Schlachter |
