[GRASS-CVS] markus: grass6/lib/cairodriver read.c, NONE, 1.1.2.1 read_bmp.c, NONE, 1.1.2.1 read_ppm.c, NONE, 1.1.2.1 write_bmp.c, NONE, 1.1.2.1 write_ppm.c, NONE, 1.1.2.1 Draw_bitmap.c, 1.1.2.1, 1.1.2.2 Graph.c, 1.1.2.1, 1.1.2.2 Makefile, 1.1.2.1, 1.1.2.2 Raster.c, 1.1.2.1, 1.1.2.2 cairodriver.h, 1.1.2.1, 1.1.2.2 write.c, 1.1.2.1, 1.1.2.2

grass at intevation.de grass at intevation.de
Fri Nov 23 05:47:15 EST 2007


Author: markus

Update of /grassrepository/grass6/lib/cairodriver
In directory doto:/tmp/cvs-serv11882

Modified Files:
      Tag: releasebranch_6_3
	Draw_bitmap.c Graph.c Makefile Raster.c cairodriver.h write.c 
Added Files:
      Tag: releasebranch_6_3
	read.c read_bmp.c read_ppm.c write_bmp.c write_ppm.c 
Log Message:
various fixes merged from HEAD

--- NEW FILE: read.c ---
#include "cairodriver.h"

void read_image(void)
{
	G_debug(1, "read_image");

	if (!cairo || !surface)
		return;

	if (file_type == FTYPE_PPM)
	{
		G_debug(1, "Reading image from %s", file_name);
		read_ppm();
	}
	else if (file_type == FTYPE_BMP)
	{
		G_debug(1, "Reading image from %s", file_name);
		read_bmp();
	}
#if CAIRO_HAS_PNG_FUNCTIONS
	else if (file_type == FTYPE_PNG)
	{
		cairo_surface_t *img_surf;
		G_debug(1, "Reading image from %s", file_name);

		img_surf = cairo_image_surface_create_from_png(file_name);
		if (!img_surf)
			return;

		cairo_save(cairo);
		cairo_set_source_surface(cairo, img_surf, 0, 0);
		cairo_paint(cairo);
		cairo_restore(cairo);

		cairo_surface_destroy(img_surf);
	}
#endif
	/* vector format files are written directly to file */

	modified = 0;
}

--- NEW FILE: read_bmp.c ---

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <grass/gis.h>
#include "cairodriver.h"

static unsigned int get_2(const unsigned char **q)
{
	const unsigned char *p = *q;
	unsigned int n = (p[0] << 0) | (p[1] << 8);
	*q += 2;
	return n;
}

static unsigned int get_4(const unsigned char **q)
{
	const unsigned char *p = *q;
	unsigned int n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
	*q += 4;
	return n;
}

static int read_bmp_header(const unsigned char *p)
{
	if (*p++ != 'B')
		return 0;
	if (*p++ != 'M')
		return 0;

	if (get_4(&p) != HEADER_SIZE + width * height * 4)
		return 0;

	get_4(&p);

	if (get_4(&p) != HEADER_SIZE)
		return 0;

	if (get_4(&p) != 40)
		return 0;

	if (get_4(&p) != width)
		return 0;
	if (get_4(&p) != -height)
		return 0;

	get_2(&p);
	if (get_2(&p) != 32)
		return 0;

	if (get_4(&p) != 0)
		return 0;
	if (get_4(&p) != width * height * 4)
		return 0;

	get_4(&p);
	get_4(&p);
	get_4(&p);
	get_4(&p);

	return 1;
}

void read_bmp(void)
{
	char header[HEADER_SIZE];
	FILE *input;
	int x, y;

	input = fopen(file_name, "rb");
	if (!input)
		G_fatal_error("cairo:: couldn't open input file %s", file_name);

	if (fread(header, sizeof(header), 1, input) != 1)
		G_fatal_error("cairo:: invalid input file %s", file_name);

	if (!read_bmp_header(header))
		G_fatal_error("cairo:: invalid BMP header for %s", file_name);

	fread(grid, stride, height, input);

	fclose(input);
}


--- NEW FILE: read_ppm.c ---
#include "cairodriver.h"

void read_ppm(void)
{
	char *mask_name = G_store(file_name);
	FILE *input, *mask;
	int x, y;
	int i_width, i_height, maxval;

	input = fopen(file_name, "rb");
	if (!input)
		G_fatal_error("cairo: couldn't open input file %s", file_name);

	if (fscanf(input, "P6 %d %d %d", &i_width, &i_height, &maxval) != 3)
		G_fatal_error("cairo: invalid input file %s", file_name);

	fgetc(input);

	if (i_width != width || i_height != height)
		G_fatal_error(
			"cairo: input file has incorrect dimensions: expected: %dx%d got: %dx%d",
			width, height, i_width, i_height);

	mask_name[strlen(mask_name) - 2] = 'g';

	input = fopen(mask_name, "rb");
	if (!input)
		G_fatal_error("cairo: couldn't open input mask file %s", mask_name);

	if (fscanf(input, "P5 %d %d %d", &i_width, &i_height, &maxval) != 3)
		G_fatal_error("cairo: invalid input mask file %s", mask_name);

	fgetc(input);

	if (i_width != width || i_height != height)
		G_fatal_error(
			"cairo: input mask file has incorrect dimensions: expected: %dx%d got: %dx%d",
			width, height, i_width, i_height);

	G_free(mask_name);

	for (y = 0; y < height; y++)
	{
		unsigned int *row = (unsigned int *) (grid + y * stride);

		for (x = 0; x < width; x++)
		{
			int r = fgetc(input);
			int g = fgetc(input);
			int b = fgetc(input);
			int a = fgetc(mask);

			r = r * 255 / maxval;
			g = g * 255 / maxval;
			b = b * 255 / maxval;
			a = a * 255 / maxval;

			if (a > 0 && a < 0xFF)
			{
				r = r * a / 0xFF;
				g = g * a / 0xFF;
				b = b * a / 0xFF;
			}

			row[x] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
		}
	}

	fclose(input);
	fclose(mask);
}


--- NEW FILE: write_bmp.c ---

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <grass/gis.h>
#include "cairodriver.h"

static unsigned char *put_2(unsigned char *p, unsigned int n)
{
	*p++ = n & 0xFF;	n >>= 8;
	*p++ = n & 0xFF;
	return p;
}

static unsigned char *put_4(unsigned char *p, unsigned int n)
{
	*p++ = n & 0xFF;	n >>= 8;
	*p++ = n & 0xFF;	n >>= 8;
	*p++ = n & 0xFF;	n >>= 8;
	*p++ = n & 0xFF;
	return p;
}

static void make_bmp_header(unsigned char *p)
{
	*p++ = 'B';
	*p++ = 'M';

	p = put_4(p, HEADER_SIZE + width * height * 4);
	p = put_4(p, 0);
	p = put_4(p, HEADER_SIZE);

	p = put_4(p, 40);
	p = put_4(p, width);
	p = put_4(p, -height);
	p = put_2(p, 1);
	p = put_2(p, 32);
	p = put_4(p, 0);
	p = put_4(p, width * height * 4);
	p = put_4(p, 0);
	p = put_4(p, 0);
	p = put_4(p, 0);
	p = put_4(p, 0);
}

void write_bmp(void)
{
	char header[HEADER_SIZE];
	FILE *output;
	int x, y;

	output = fopen(file_name, "wb");
	if (!output)
		G_fatal_error("cairo: couldn't open output file %s", file_name);

	make_bmp_header(header);
	fwrite(header, sizeof(header), 1, output);

	fwrite(grid, stride, height, output);

	fclose(output);
}


--- NEW FILE: write_ppm.c ---
#include "cairodriver.h"

void write_ppm(void)
{
	char *mask_name = G_store(file_name);
	FILE *output, *mask;
	int x, y;

	output = fopen(file_name, "wb");
	if (!output)
		G_fatal_error("cairo: couldn't open output file %s", file_name);

	mask_name[strlen(mask_name) - 2] = 'g';

	mask = fopen(mask_name, "wb");
	if (!mask)
		G_fatal_error("cairo: couldn't open mask file %s", mask_name);

	G_free(mask_name);

	fprintf(output, "P6\n%d %d\n255\n", width, height);
	fprintf(mask, "P5\n%d %d\n255\n", width, height);

	for (y = 0; y < height; y++)
	{
		const unsigned int *row = (const unsigned int *) (grid + y * stride);

		for (x = 0; x < width; x++)
		{
			unsigned int c = row[x];
			int a = (c >> 24) & 0xFF;
			int r = (c >> 16) & 0xFF;
			int g = (c >>  8) & 0xFF;
			int b = (c >>  0) & 0xFF;

			if (a > 0 && a < 0xFF)
			{
				r = r * 0xFF / a;
				g = g * 0xFF / a;
				b = b * 0xFF / a;
			}

			fputc((unsigned char) r, output);
			fputc((unsigned char) g, output);
			fputc((unsigned char) b, output);
			fputc((unsigned char) a, mask);
		}
	}

	fclose(output);
	fclose(mask);
}


Index: Draw_bitmap.c
===================================================================
RCS file: /grassrepository/grass6/lib/cairodriver/Draw_bitmap.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -d -r1.1.2.1 -r1.1.2.2
--- Draw_bitmap.c	24 Oct 2007 00:20:57 -0000	1.1.2.1
+++ Draw_bitmap.c	23 Nov 2007 10:47:12 -0000	1.1.2.2
@@ -1,5 +1,30 @@
 #include "cairodriver.h"
 
+static cairo_surface_t *fix_surface(cairo_surface_t *src)
+{
+	int width  = cairo_image_surface_get_width(src);
+	int height = cairo_image_surface_get_height(src);
+	int stride = cairo_image_surface_get_stride(src);
+	cairo_format_t format = cairo_image_surface_get_format(src);
+	unsigned char *data = cairo_image_surface_get_data(src);
+	cairo_surface_t *dst = cairo_image_surface_create(format, width, height);
+	int stride2 = cairo_image_surface_get_stride(dst);
+	unsigned char *data2 = cairo_image_surface_get_data(dst);
+	int i;
+
+	for (i = 0; i < height; i++)
+	{
+		void *p = data + i * stride;
+		void *q = data2 + i * stride2;
+		int n = stride < stride2 ? stride : stride2;
+
+		memcpy(q, p, n);
+	}
+
+	cairo_surface_destroy(src);
+	return dst;
+}
+
 void Cairo_draw_bitmap(int ncols, int nrows, int threshold, const unsigned char *buf)
 {
 	cairo_surface_t *surf;
@@ -11,6 +36,8 @@
 
 	if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS)
 		G_fatal_error("Cairo_draw_bitmap: Failed to create source");
+
+	surf = fix_surface(surf);
 
 	cairo_mask_surface(cairo, surf, cur_x, cur_y);
 

Index: Graph.c
===================================================================
RCS file: /grassrepository/grass6/lib/cairodriver/Graph.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -d -r1.1.2.1 -r1.1.2.2
--- Graph.c	24 Oct 2007 00:20:57 -0000	1.1.2.1
+++ Graph.c	23 Nov 2007 10:47:12 -0000	1.1.2.2
@@ -2,13 +2,30 @@
 #include <cairo-ps.h>
 #include <cairo-pdf.h>
 #include <cairo-svg.h>
+#include <cairo-xlib.h>
+
+#ifndef __MINGW32__
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#endif
+
+#if CAIRO_HAS_XLIB_SURFACE
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
 
 /* globals */
 char *file_name;
 int file_type;
-int width, height;
+int width, height, stride;
+unsigned char *grid;
 int modified;
 int auto_write;
+int mapped;
 
 /* background color */
 double bgcolor_r, bgcolor_g, bgcolor_b, bgcolor_a;
@@ -17,76 +34,190 @@
 cairo_surface_t *surface;
 cairo_t *cairo;
 
-int Cairo_Graph_set(int argc, char **argv)
+static void init_cairo(void);
+static int ends_with(const char *string, const char *suffix);
+static void map_file(void);
+
+#if CAIRO_HAS_XLIB_SURFACE
+static int init_xlib(void)
 {
-	char *c;
+	Display *dpy;
+	Drawable win;
+	unsigned long xid;
+	XVisualInfo templ;
+	XVisualInfo *vinfo;
+	int count;
+	Window root;
+	unsigned int depth;
+	int si;
+	unsigned int ui;
+	Visual *visual;
+	char *p;
 
-	G_gisinit("Cairo driver");
-	G_debug(1, "Cairo_Graph_set");
+	p = getenv("GRASS_CAIRO_DRAWABLE");
+	if (!p || sscanf(p, "%li", &xid) != 1)
+		G_fatal_error("invalid Drawable XID: %s", p);
+	win = xid;
+
+	dpy = XOpenDisplay(NULL);
+	if (!dpy)
+		G_fatal_error("Unable to open display");
+
+	p = getenv("GRASS_CAIRO_VISUAL");
+	if (!p || sscanf(p, "%li", &xid) != 1)
+		G_fatal_error("invalid Visual XID: %s", p);
+	templ.visualid = xid;
+
+	vinfo = XGetVisualInfo(dpy, VisualIDMask, &templ, &count);
+	if (!vinfo || !count)
+		G_fatal_error("Unable to obtain visual");
+	visual = vinfo[0].visual;
+
+	if (!XGetGeometry(dpy, win, &root, &si, &si, &width, &height, &ui, &depth))
+		G_fatal_error("Unable to query drawable");
+
+	surface = cairo_xlib_surface_create(dpy, win, visual, width, height);
+
+	if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
+		G_fatal_error("Failed to initialize Xlib surface");
+
+	cairo = cairo_create(surface);
+
+	file_name = "<X11>";
+	file_type = FTYPE_X11;
+
+	screen_right = screen_left + width;
+	screen_bottom = screen_top + height;
+
+	return 0;
+}
+#endif
+
+static int init_file(void)
+{
+	int do_read = 0;
+	int do_map = 0;
+	char *p;
 
 	/* set image properties */
 	width = screen_right - screen_left;
 	height = screen_bottom - screen_top;
-
-	/* TODO: find out why G_getenv doesn't work */
+	stride = width * 4;
 
 	/* get file name */
-	c = getenv("GRASS_CAIROFILE");
-	if (!c || strlen(c) == 0)
-		c = DEFAULT_FILE_NAME;
+	p = getenv("GRASS_CAIROFILE");
+	if (!p || strlen(p) == 0)
+		p = DEFAULT_FILE_NAME;
 
-	file_name = c;
-	G_message("CAIRO: collecting to file: %s\n GRASS_WIDTH=%d, GRASS_HEIGHT=%d", file_name, width, height);
+	file_name = p;
 
 	/* get file type (from extension) */
-	if (ends_with(c, ".png"))
+	if (file_type == FTYPE_X11)
+		; /* skip */
+	else if (ends_with(file_name, ".ppm"))
+		file_type = FTYPE_PPM;
+	else if (ends_with(file_name, ".bmp"))
+		file_type = FTYPE_BMP;
+#if CAIRO_HAS_PNG_FUNCTIONS
+	else if (ends_with(file_name, ".png"))
 		file_type = FTYPE_PNG;
+#endif
 #if CAIRO_HAS_PDF_SURFACE
-	else if (ends_with(c, ".pdf"))
+	else if (ends_with(file_name, ".pdf"))
 		file_type = FTYPE_PDF;
 #endif
 #if CAIRO_HAS_PS_SURFACE
-	else if (ends_with(c, ".ps"))
+	else if (ends_with(file_name, ".ps"))
 		file_type = FTYPE_PS;
 #endif
 #if CAIRO_HAS_SVG_SURFACE
-	else if (ends_with(c, ".svg"))
+	else if (ends_with(file_name, ".svg"))
 		file_type = FTYPE_SVG;
 #endif
 	else
-		G_fatal_error("Unknown file extension: %s", c);
-	G_debug(1, "File type: %s (%d)", c, file_type);
+		G_fatal_error("Unknown file extension: %s", p);
+	G_debug(1, "File type: %s (%d)", file_name, file_type);
 
-	c = getenv("GRASS_AUTO_WRITE");
-	auto_write = c && strcmp(c, "TRUE") == 0;
+	p = getenv("GRASS_CAIRO_MAPPED");
+	do_map = p && strcmp(p, "TRUE") == 0 && ends_with(file_name, ".bmp");
+
+	p = getenv("GRASS_CAIRO_READ");
+	do_read = p && strcmp(p, "TRUE") == 0;
+
+	if (do_read && access(file_name, 0) != 0)
+		do_read = 0;
+
+	G_message("cairo: collecting to file: %s,\n     GRASS_WIDTH=%d, GRASS_HEIGHT=%d",
+		  file_name, width, height);
+
+	if (do_read && do_map)
+		map_file();
+
+	if (!mapped)
+	{
+		grid = G_malloc(height * stride);
+		init_cairo();
+	}
+
+	if (!do_read)
+	{
+		Cairo_Erase();
+		modified = 1;
+	}
+
+	if (do_read && !mapped)
+		read_image();
+
+	if (do_map && !mapped)
+	{
+		write_image();
+		map_file();
+	}
+
+	return 0;
+}
+
+int Cairo_Graph_set(int argc, char **argv)
+{
+	char *p;
+
+	G_gisinit("Cairo driver");
+	G_debug(1, "Cairo_Graph_set");
 
 	/* get background color */
-	c = getenv("GRASS_BACKGROUNDCOLOR");
-	if (c && *c)
+	p = getenv("GRASS_BACKGROUNDCOLOR");
+	if (p && *p)
 	{
 		unsigned int red, green, blue;
 
-		if (sscanf(c, "%02x%02x%02x", &red, &green, &blue) == 3)
+		if (sscanf(p, "%02x%02x%02x", &red, &green, &blue) == 3)
 		{
 			bgcolor_r = CAIROCOLOR(red);
 			bgcolor_g = CAIROCOLOR(green);
 			bgcolor_b = CAIROCOLOR(blue);
 		}
 		else
-			G_fatal_error("Unknown background color: %s", c);
+			G_fatal_error("Unknown background color: %s", p);
 	}
 	else
 		bgcolor_r = bgcolor_g = bgcolor_b = 1.0;
 
 	/* get background transparency setting */
-	c = getenv("GRASS_TRANSPARENT");
-	if (c && strcmp(c, "TRUE") == 0)
+	p = getenv("GRASS_TRANSPARENT");
+	if (p && strcmp(p, "TRUE") == 0)
 		bgcolor_a = 0.0;
 	else
 		bgcolor_a = 1.0;
 
-	init_cairo();
-	return 0;
+	p = getenv("GRASS_AUTO_WRITE");
+	auto_write = p && strcmp(p, "TRUE") == 0;
+
+#if CAIRO_HAS_XLIB_SURFACE
+	p = getenv("GRASS_CAIRO_DRAWABLE");
+	if (p)
+		return init_xlib();
+#endif
+	return init_file();
 }
 
 void Cairo_Graph_close(void)
@@ -107,15 +238,17 @@
 	}
 }
 
-void init_cairo(void)
+static void init_cairo(void)
 {
 	G_debug(1, "init_cairo");
 
 	/* create cairo surface */
 	switch (file_type)
 	{
+	case FTYPE_PPM:
+	case FTYPE_BMP:
 	case FTYPE_PNG:
-		surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+		surface = (cairo_surface_t *) cairo_image_surface_create_for_data(grid, CAIRO_FORMAT_ARGB32, width, height, stride);
 		break;
 #if CAIRO_HAS_PDF_SURFACE
 	case FTYPE_PDF:
@@ -141,15 +274,44 @@
 		G_fatal_error("Failed to initialize Cairo surface");
 
 	cairo = cairo_create(surface);
-
-	Cairo_Erase();
 }
 
 /* Returns TRUE if string ends with suffix (case insensitive) */
-int ends_with(const char *string, const char *suffix)
+static int ends_with(const char *string, const char *suffix)
 {
 	if (strlen(string) < strlen(suffix))
 		return FALSE;
 
 	return G_strcasecmp(suffix, string + strlen(string) - strlen(suffix)) == 0;
 }
+
+static void map_file(void)
+{
+#ifndef __MINGW32__
+	size_t size = HEADER_SIZE + width * height * sizeof(unsigned int);
+	void *ptr;
+	int fd;
+
+	fd = open(file_name, O_RDWR);
+	if (fd < 0)
+		return;
+
+	ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t ) 0);
+	if (ptr == MAP_FAILED)
+		return;
+
+	if (grid)
+	{
+		cairo_destroy(cairo);
+		cairo_surface_destroy(surface);
+		G_free(grid);
+	}
+	grid = (char *) ptr + HEADER_SIZE;
+	init_cairo();
+
+	close(fd);
+
+	mapped = 1;
+#endif
+}
+

Index: Makefile
===================================================================
RCS file: /grassrepository/grass6/lib/cairodriver/Makefile,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -d -r1.1.2.1 -r1.1.2.2
--- Makefile	24 Oct 2007 00:20:57 -0000	1.1.2.1
+++ Makefile	23 Nov 2007 10:47:12 -0000	1.1.2.2
@@ -29,7 +29,12 @@
 	Raster.o	\
 	Respond.o	\
 	Color.o		\
-	write.o
+	read.o		\
+	read_bmp.o	\
+	read_ppm.o	\
+	write.o		\
+	write_bmp.o	\
+	write_ppm.o
 
 include $(MODULE_TOPDIR)/include/Make/Lib.make
 

Index: Raster.c
===================================================================
RCS file: /grassrepository/grass6/lib/cairodriver/Raster.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -d -r1.1.2.1 -r1.1.2.2
--- Raster.c	24 Oct 2007 00:20:57 -0000	1.1.2.1
+++ Raster.c	23 Nov 2007 10:47:12 -0000	1.1.2.2
@@ -18,19 +18,21 @@
 
 	/* TODO: are top and left swapped? */
 
-	src_r = s[0][1];
-	src_b = s[1][1];
 	src_l = s[0][0];
+	src_r = s[0][1];
 	src_t = s[1][0];
-	dst_r = d[0][1];
-	dst_b = d[1][1];
+	src_b = s[1][1];
+
+	src_w = src_r - src_l;
+	src_h = src_b - src_t;
+
 	dst_l = d[0][0];
+	dst_r = d[0][1];
 	dst_t = d[1][0];
+	dst_b = d[1][1];
 
-	src_h = src_b - src_t + 1;
-	src_w = src_r - src_l + 1;
-	dst_h = dst_b - dst_t + 1;
-	dst_w = dst_r - dst_l + 1;
+	dst_w = dst_r - dst_l;
+	dst_h = dst_b - dst_t;
 
 	G_debug(1, " src (TBLR): %d %d %d %d, dst (TBLR) %d %d %d %d",
 		src_t, src_b, src_l, src_r, dst_t, dst_b, dst_l, dst_r);
@@ -48,7 +50,7 @@
 	int n, int row,
 	const unsigned char *red, const unsigned char *grn, const unsigned char *blu, const unsigned char *nul)
 {
-	unsigned int *dst = (unsigned int *) src_data + row * (src_stride >> 2);
+	unsigned int *dst = (unsigned int *) (src_data + (row - src_t) * src_stride);
 	int i;
 
 	G_debug(3, "Cairo_scaled_raster: %d %d", n, row);
@@ -74,8 +76,9 @@
 
 	/* paint source surface onto dstination (scaled) */
 	cairo_save(cairo);
+	cairo_translate(cairo, dst_l, dst_t);
 	cairo_scale(cairo, (double) dst_w / (double) src_w, (double) dst_h / (double) src_h);
-	cairo_set_source_surface(cairo, src_surf, dst_l, dst_t);
+	cairo_set_source_surface(cairo, src_surf, 0, 0);
 	cairo_paint(cairo);
 	cairo_restore(cairo);
 

Index: cairodriver.h
===================================================================
RCS file: /grassrepository/grass6/lib/cairodriver/cairodriver.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -d -r1.1.2.1 -r1.1.2.2
--- cairodriver.h	24 Oct 2007 00:20:57 -0000	1.1.2.1
+++ cairodriver.h	23 Nov 2007 10:47:12 -0000	1.1.2.2
@@ -14,28 +14,35 @@
 
 #define DEFAULT_FILE_NAME "map.png"
 
+#define HEADER_SIZE 54
+
 /* Scale for converting colors from [0..255] to cairo's [0.0..1.0] */
 #define COLORSCALE (1.0/255.0)
 #define CAIROCOLOR(a) (((double)(a))*COLORSCALE)
 
 /* File types */
 #define FTYPE_UNKNOWN 0
-#define FTYPE_PNG 1
-#define FTYPE_PDF 2
-#define FTYPE_PS  3
-#define FTYPE_SVG 4
+#define FTYPE_PPM 1
+#define FTYPE_BMP 2
+#define FTYPE_PNG 3
+#define FTYPE_PDF 4
+#define FTYPE_PS  5
+#define FTYPE_SVG 6
+#define FTYPE_X11 7
 
 extern cairo_surface_t *surface;
 extern cairo_t *cairo;
 
 extern char *file_name;
 extern int file_type;
-extern int width, height;
+extern int width, height, stride;
+extern unsigned char *grid;
 extern int clip_left, clip_right, clip_top, clip_bottom;
 extern int auto_write;
 extern double bgcolor_r, bgcolor_g, bgcolor_b, bgcolor_a;
 extern int modified;
 extern int auto_write;
+extern int mapped;
 
 extern const struct driver *Cairo_Driver(void);
 
@@ -60,11 +67,13 @@
 extern void Cairo_Polyline_abs(const int*, const int*, int);
 extern void Cairo_Respond(void);
 
-/* Graph.c */
-extern void init_cairo(void);
-extern int ends_with(const char*, const char*);
-
+/* read.c */
+extern void read_image(void);
+extern void read_ppm(void);
+extern void read_bmp(void);
 /* write.c */
 extern void write_image(void);
+extern void write_ppm(void);
+extern void write_bmp(void);
 
 #endif /* __CAIRODRIVER_H__ */

Index: write.c
===================================================================
RCS file: /grassrepository/grass6/lib/cairodriver/write.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -d -r1.1.2.1 -r1.1.2.2
--- write.c	24 Oct 2007 00:20:57 -0000	1.1.2.1
+++ write.c	23 Nov 2007 10:47:12 -0000	1.1.2.2
@@ -1,5 +1,10 @@
 #include "cairodriver.h"
 
+#if CAIRO_HAS_XLIB_SURFACE
+#include <X11/Xlib.h>
+#include <cairo-xlib.h>
+#endif
+
 void write_image(void)
 {
 	G_debug(1, "write_image");
@@ -7,15 +12,37 @@
 	if (!modified)
 		return;
 
-	if (cairo && surface)
+	if (mapped)
+		return;
+
+	if (!cairo || !surface)
+		return;
+
+	if (file_type == FTYPE_PPM)
 	{
-		if (file_type == FTYPE_PNG)
-		{
-			G_debug(1, "Writing image to %s", file_name);
-			cairo_surface_write_to_png(surface, file_name);
-		}
-		/* vector format files are written directly to file */
+		G_debug(1, "Writing image to %s", file_name);
+		write_ppm();
 	}
+	else if (file_type == FTYPE_BMP)
+	{
+		G_debug(1, "Writing image to %s", file_name);
+		write_bmp();
+	}
+#if CAIRO_HAS_PNG_FUNCTIONS
+	else if (file_type == FTYPE_PNG)
+	{
+		G_debug(1, "Writing image to %s", file_name);
+		cairo_surface_write_to_png(surface, file_name);
+	}
+#endif
+#if CAIRO_HAS_XLIB_SURFACE
+	else if (file_type == FTYPE_X11)
+	{
+		XFlush(cairo_xlib_surface_get_display(surface));
+	}
+#endif
+	/* vector format files are written directly to file */
 
 	modified = 0;
 }
+




More information about the grass-commit mailing list