[cairo-commit] cairo/src cairo_png_surface.c,NONE,1.1 cairo.h,1.46,1.47 cairo-features.h.in,1.3,1.4
Olivier Andrieu
commit at pdx.freedesktop.org
Mon Aug 15 11:12:59 PDT 2005
Committed by: oandrieu
Update of /cvs/cairo/cairo/src
In directory pdx:/tmp/cvs-serv14562/src
Modified Files:
cairo.h cairo-features.h.in
Added Files:
cairo_png_surface.c
Log Message:
Add PNG backend (cairo_set_target_png and cairo_png_surface_create).
--- NEW FILE: cairo_png_surface.c ---
#include <png.h>
#include "cairoint.h"
static const cairo_surface_backend_t cairo_png_surface_backend;
void
cairo_set_target_png (cairo_t *cr,
FILE *file,
cairo_format_t format,
int width,
int height)
{
cairo_surface_t *surface;
surface = cairo_png_surface_create (file, format,
width, height);
if (surface == NULL) {
cr->status = CAIRO_STATUS_NO_MEMORY;
return;
}
cairo_set_target_surface (cr, surface);
/* cairo_set_target_surface takes a reference, so we must destroy ours */
cairo_surface_destroy (surface);
}
typedef struct cairo_png_surface {
cairo_surface_t base;
/* PNG-specific fields */
FILE *file;
png_structp png_w;
png_infop png_i;
cairo_image_surface_t *image;
} cairo_png_surface_t;
static void
_cairo_png_surface_erase (cairo_png_surface_t *surface);
cairo_surface_t *
cairo_png_surface_create (FILE *file,
cairo_format_t format,
int width,
int height)
{
cairo_png_surface_t *surface;
time_t now = time (NULL);
png_time png_time;
if (format == CAIRO_FORMAT_A8 ||
format == CAIRO_FORMAT_A1 ||
file == NULL)
return NULL;
surface = malloc (sizeof (cairo_png_surface_t));
if (surface == NULL)
goto failure;
_cairo_surface_init (&surface->base, &cairo_png_surface_backend);
surface->png_w = NULL;
surface->png_i = NULL;
surface->image = (cairo_image_surface_t *)
cairo_image_surface_create (format, width, height);
if (surface->image == NULL)
goto failure;
_cairo_png_surface_erase (surface);
surface->file = file;
surface->png_w = png_create_write_struct (PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
if (surface->png_w == NULL)
goto failure;
surface->png_i = png_create_info_struct (surface->png_w);
if (surface->png_i == NULL)
goto failure;
if (setjmp (png_jmpbuf (surface->png_w)))
goto failure;
png_init_io (surface->png_w, surface->file);
switch (format) {
case CAIRO_FORMAT_ARGB32:
png_set_IHDR (surface->png_w, surface->png_i,
width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
break;
case CAIRO_FORMAT_RGB24:
png_set_IHDR (surface->png_w, surface->png_i,
width, height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
break;
}
png_convert_from_time_t (&png_time, now);
png_set_tIME (surface->png_w, surface->png_i, &png_time);
png_write_info (surface->png_w, surface->png_i);
switch (format) {
case CAIRO_FORMAT_ARGB32:
png_set_bgr (surface->png_w);
break;
case CAIRO_FORMAT_RGB24:
png_set_filler (surface->png_w, 0, PNG_FILLER_AFTER);
png_set_bgr (surface->png_w);
break;
}
return &surface->base;
failure:
if (surface) {
if (surface->image)
cairo_surface_destroy (&surface->image->base);
if (surface->png_i)
png_destroy_write_struct (&surface->png_w, &surface->png_i);
else if (surface->png_w)
png_destroy_write_struct (&surface->png_w, NULL);
free (surface);
}
return NULL;
}
static cairo_surface_t *
_cairo_png_surface_create_similar (void *abstract_src,
cairo_format_t format,
int width,
int height)
{
return NULL;
}
static void
_cairo_png_surface_destroy (void *abstract_surface)
{
cairo_png_surface_t *surface = abstract_surface;
int i;
png_byte *row;
if (setjmp (png_jmpbuf (surface->png_w)))
goto failure;
row = surface->image->data;
for (i=0; i < surface->image->height; i++) {
png_write_row (surface->png_w, row);
row += surface->image->stride;
}
png_write_end (surface->png_w, surface->png_i);
failure:
png_destroy_write_struct (&surface->png_w, &surface->png_i);
cairo_surface_destroy (&surface->image->base);
free (surface);
}
static void
_cairo_png_surface_erase (cairo_png_surface_t *surface)
{
cairo_color_t transparent;
_cairo_color_init (&transparent);
_cairo_color_set_rgb (&transparent, 0., 0., 0.);
_cairo_color_set_alpha (&transparent, 0.);
_cairo_surface_fill_rectangle (&surface->image->base,
CAIRO_OPERATOR_SRC,
&transparent,
0, 0,
surface->image->width,
surface->image->height);
}
static double
_cairo_png_surface_pixels_per_inch (void *abstract_surface)
{
return 96.0;
}
static cairo_image_surface_t *
_cairo_png_surface_get_image (void *abstract_surface)
{
cairo_png_surface_t *surface = abstract_surface;
cairo_surface_reference (&surface->image->base);
return surface->image;
}
static cairo_status_t
_cairo_png_surface_set_image (void *abstract_surface,
cairo_image_surface_t *image)
{
cairo_png_surface_t *surface = abstract_surface;
if (image == surface->image)
return CAIRO_STATUS_SUCCESS;
/* XXX: Need to call _cairo_image_surface_set_image here, but it's
not implemented yet. */
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_status_t
_cairo_png_surface_set_matrix (void *abstract_surface,
cairo_matrix_t *matrix)
{
cairo_png_surface_t *surface = abstract_surface;
return _cairo_image_surface_set_matrix (surface->image, matrix);
}
static cairo_status_t
_cairo_png_surface_set_filter (void *abstract_surface,
cairo_filter_t filter)
{
cairo_png_surface_t *surface = abstract_surface;
return _cairo_image_surface_set_filter (surface->image, filter);
}
static cairo_status_t
_cairo_png_surface_set_repeat (void *abstract_surface,
int repeat)
{
cairo_png_surface_t *surface = abstract_surface;
return _cairo_image_surface_set_repeat (surface->image, repeat);
}
static cairo_int_status_t
_cairo_png_surface_composite (cairo_operator_t operator,
cairo_surface_t *generic_src,
cairo_surface_t *generic_mask,
void *abstract_dst,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_png_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t operator,
const cairo_color_t *color,
cairo_rectangle_t *rects,
int num_rects)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_png_surface_composite_trapezoids (cairo_operator_t operator,
cairo_surface_t *generic_src,
void *abstract_dst,
int x_src,
int y_src,
cairo_trapezoid_t *traps,
int num_traps)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_png_surface_copy_page (void *abstract_surface)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_int_status_t
_cairo_png_surface_show_page (void *abstract_surface)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static const cairo_surface_backend_t cairo_png_surface_backend = {
_cairo_png_surface_create_similar,
_cairo_png_surface_destroy,
_cairo_png_surface_pixels_per_inch,
_cairo_png_surface_get_image,
_cairo_png_surface_set_image,
_cairo_png_surface_set_matrix,
_cairo_png_surface_set_filter,
_cairo_png_surface_set_repeat,
_cairo_png_surface_composite,
_cairo_png_surface_fill_rectangles,
_cairo_png_surface_composite_trapezoids,
_cairo_png_surface_copy_page,
_cairo_png_surface_show_page
};
Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -C2 -d -r1.46 -r1.47
*** a/cairo.h 18 Feb 2004 02:47:34 -0000 1.46
--- b/cairo.h 24 Feb 2004 20:28:49 -0000 1.47
***************
*** 103,106 ****
--- 103,119 ----
#endif /* CAIRO_HAS_PS_SURFACE */
+ #ifdef CAIRO_HAS_PNG_SURFACE
+
+ #include <stdio.h>
+
+ void
+ cairo_set_target_png (cairo_t *cr,
+ FILE *file,
+ cairo_format_t format,
+ int width,
+ int height);
+
+ #endif /* CAIRO_HAS_PNG_SURFACE */
+
#ifdef CAIRO_HAS_XLIB_SURFACE
***************
*** 668,671 ****
--- 681,696 ----
#endif /* CAIRO_HAS_PS_SURFACE */
+ #ifdef CAIRO_HAS_PNG_SURFACE
+
+ /* PNG-surface functions */
+
+ cairo_surface_t *
+ cairo_png_surface_create (FILE *file,
+ cairo_format_t format,
+ int width,
+ int height);
+
+ #endif /* CAIRO_HAS_PNG_SURFACE */
+
#ifdef CAIRO_HAS_XLIB_SURFACE
Index: cairo-features.h.in
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-features.h.in,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** a/cairo-features.h.in 3 Feb 2004 07:24:14 -0000 1.3
--- b/cairo-features.h.in 24 Feb 2004 20:28:49 -0000 1.4
***************
*** 31,34 ****
--- 31,36 ----
#define @PS_SURFACE_FEATURE@
+ #define @PNG_SURFACE_FEATURE@
+
#define @XLIB_SURFACE_FEATURE@
More information about the cairo-commit
mailing list