Aros/Developer/Cairo
There are currently two ports (1.5 and 1.12) of the Cairo graphics library. Both are located in the Aros contrib sources.
You'll find a quite recent version in "contrib/development/libs/cairo". It is a patch to Cairo version 1.12.0. This version builds into a static link library.
To compile the link library run the following commands in your Aros source directory:
make development-fontconfig
fc-cache
make development-cairo
This will build the dependencies and the Cairo and Pixman library.
Cairo 1.12 examples
[edit | edit source]Cairo 1.12, using directly the image surface (that processes everything in system memory) gives much faster results, say probably about 60% faster than the old 1.5.
Using the image surface, blit the rgba data to your custom area class in draw method, using cairo_image_get_data().
Cairo 1.5 examples
[edit | edit source]The Cairo version (1.5) in "contrib/gfx/libs/cairo/" is rather old. But in contrast to the other version it has the great advantage that it support Aros as a native backend. This means it comes with a function "cairo_aros_surface_create" that can render to Intuition RastPorts. First parameter was the pointer to the RastPort, the other parameters specified X/Y-offset, width and height. Also this port builds into a Aros shared library. In the Aros-Exec Archives you'll also find a static link library of Cairo that supports "cairo_aros_surface_create".
The old 1.5 version was entirely software-driven and it involved reads from the bitmap in video ram, which is highly inefficient.
The second example below shows a simple example of how native Aros surfaces are created and used.
Simple Cairo example that creates a PNG image
Compile with: gcc test.c -lcairo -lpixman -lfreetype2 -lfontconfig -liconv -lxml2 -lz -lpng
#include <cairo/cairo.h>
int main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 470, 80);
cr = cairo_create (surface);
cairo_select_font_face (cr, "DejaVu Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 50.0);
cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
cairo_move_to (cr, 50, 50);
cairo_show_text (cr, "Hello, AROS :-)");
cairo_destroy (cr);
cairo_surface_write_to_png (surface, "helloamiga.png");
cairo_surface_destroy (surface);
return 0;
}
Simple Cairo example using Aros native RastPort backend
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <cairo/cairo.h>
#include <cairo/cairo-aros.h>
#define WIDTH 400
#define HEIGHT 120
struct Window *appwin;
struct IntuitionBase *IntuitionBase;
cairo_surface_t *surface;
cairo_t *cr;
int main()
{
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0L);
if (IntuitionBase != NULL)
{
appwin = OpenWindowTags(NULL,
WA_Left, 100,
WA_Top, 100,
WA_Width, WIDTH,
WA_Height, HEIGHT,
WA_Title, "Cairo - AROS",
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW,
WA_Activate, TRUE,
WA_GimmeZeroZero, TRUE,
TAG_DONE);
surface = cairo_aros_surface_create (appwin->RPort, 0, 0, WIDTH, HEIGHT);
cr = cairo_create (surface);
cairo_select_font_face (cr, "DejaVu Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 50.0);
cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
cairo_move_to (cr, 50, 50);
cairo_show_text (cr, "Hello, AROS :-)");
if (appwin != NULL)
{
Wait(1L << appwin->UserPort->mp_SigBit);
CloseWindow(appwin);
}
}
if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase);
return 0;
}
References
[edit | edit source]Direct Access Functions
[edit | edit source]cairo_image_get_data() and other direct access functions are often misused by applications because they don't call cairo_surface_flush() and/or cairo_surface_mark_dirty() around the code which accesses the surface data directly. You must call cairo_surface_flush() before reading from or writing to the surface and that you must use cairo_surface_mark_dirty() after modifying it.
void modify_image_surface (cairo_surface_t *surface) { unsigned char *data; int width, height, stride; // flush to ensure all writing to the image was done cairo_surface_flush (surface); // modify the image data = cairo_image_surface_get_data (surface); width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); stride = cairo_image_surface_get_stride (surface); modify_image_data (data, width, height, stride); // mark the image dirty so Cairo clears its caches. cairo_surface_mark_dirty (surface); }
Cairo Library Calls
cairo_surface_create_similar cairo_surface_create_similar_image cairo_surface_create_for_rectangle cairo_surface_reference cairo_surface_destroy cairo_surface_status cairo_surface_finish cairo_surface_flush cairo_surface_get_device cairo_surface_get_font_options cairo_surface_get_content cairo_surface_mark_dirty cairo_surface_mark_dirty_rectangle cairo_surface_set_device_offset cairo_surface_get_device_offset cairo_surface_set_fallback_resolution cairo_surface_get_fallback_resolution cairo_surface_get_type cairo_surface_get_reference_count cairo_surface_set_user_data cairo_surface_get_user_data cairo_surface_copy_page cairo_surface_show_page cairo_surface_has_show_text_glyphs cairo_surface_set_mime_data cairo_surface_get_mime_data cairo_surface_supports_mime_type cairo_surface_map_to_image cairo_surface_unmap_image
cairo_device_reference cairo_device_destroy cairo_device_status cairo_device_finish cairo_device_flush cairo_device_get_type cairo_device_get_reference_count cairo_device_set_user_data cairo_device_get_user_data cairo_device_acquire cairo_device_release