/** \file * \brief Cairo IMAGERGB Driver * * See Copyright Notice in cd.h */ #include #include #include #include "cd.h" #include "cdcairo.h" #include "cdcairoctx.h" static char* get_stride_attrib(cdCtxCanvas* ctxcanvas) { static char data[100]; sprintf(data, "%d", cairo_image_surface_get_stride(cairo_get_target(ctxcanvas->cr))); return data; } static cdAttribute stride_attrib = { "STRIDE", NULL, get_stride_attrib }; static void set_write2png_attrib(cdCtxCanvas *ctxcanvas, char* data) { if (data) cairo_surface_write_to_png(cairo_get_target(ctxcanvas->cr), data); } static cdAttribute write2png_attrib = { "WRITE2PNG", set_write2png_attrib, NULL }; static char* get_data_attrib(cdCtxCanvas* ctxcanvas) { return (char*)ctxcanvas->rgb; } static cdAttribute data_attrib = { "RGBDATA", NULL, get_data_attrib }; static void cdkillcanvas (cdCtxCanvas *ctxcanvas) { if (!ctxcanvas->user_image) free(ctxcanvas->rgb); cdcairoKillCanvas(ctxcanvas); } static void cdcreatecanvas(cdCanvas* canvas, void* data) { cdCtxCanvas* ctxcanvas; cairo_surface_t *surface; int w = 0, h = 0, use_alpha = 0; float res = (float)3.78; unsigned char *rgb = NULL; char* str_data = (char*)data; char* res_ptr = NULL; cairo_format_t format = CAIRO_FORMAT_RGB24; /* Starting parameters */ if (str_data == NULL) return; if (strstr(str_data, "-a")) use_alpha = 1; res_ptr = strstr(str_data, "-r"); if (res_ptr) sscanf(res_ptr+2, "%g", &res); /* size and rgb */ #ifdef SunOS_OLD sscanf(str_data, "%dx%d %d", &w, &h, &rgb); #else sscanf(str_data, "%dx%d %p", &w, &h, &rgb); #endif if (w == 0 || h == 0) return; canvas->w = w; canvas->h = h; canvas->yres = res; canvas->xres = res; canvas->w_mm = ((double)w) / res; canvas->h_mm = ((double)h) / res; if (use_alpha) { canvas->bpp = 32; format = CAIRO_FORMAT_ARGB32; } else canvas->bpp = 24; /* fake value, image bpp is always 32 */ if (rgb) surface = cairo_image_surface_create_for_data(rgb, format, w, h, w*32); else surface = cairo_image_surface_create(format, canvas->w, canvas->h); /* Starting Cairo driver */ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface)); cairo_surface_destroy(surface); if (rgb) { ctxcanvas->user_image = 1; ctxcanvas->rgb = rgb; } else { ctxcanvas->user_image = 0; ctxcanvas->rgb = cairo_image_surface_get_data(cairo_get_target(ctxcanvas->cr)); /* fill with white */ /* transparent, this is the normal alpha coding */ cairo_set_source_rgba(ctxcanvas->cr, 1.0, 1.0, 1.0, 0.0); cairo_rectangle(ctxcanvas->cr, 0, 0, canvas->w, canvas->h); cairo_fill(ctxcanvas->cr); } cdRegisterAttribute(canvas, &stride_attrib); cdRegisterAttribute(canvas, &write2png_attrib); cdRegisterAttribute(canvas, &data_attrib); } static void cdinittable(cdCanvas* canvas) { cdcairoInitTable(canvas); canvas->cxKillCanvas = cdkillcanvas; } static cdContext cdCairoImageRGBContext = { CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_WRITEMODE | CD_CAP_PALETTE), CD_CTX_IMAGE, /* not a plus driver */ cdcreatecanvas, cdinittable, NULL, NULL }; cdContext* cdContextCairoImageRGB(void) { return &cdCairoImageRGBContext; }