2 * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include <libspectre/spectre.h>
27 #include "cairo-device.h"
43 dvi_cairo_draw_glyph (DviContext *dvi,
48 DviCairoDevice *cairo_device;
52 cairo_surface_t *surface;
54 cairo_device = (DviCairoDevice *) dvi->device.device_data;
58 isbox = (glyph->data == NULL || (dvi->params.flags & MDVI_PARAM_CHARBOXES));
60 x = - glyph->x + x0 + cairo_device->xmargin;
61 y = - glyph->y + y0 + cairo_device->ymargin;
65 surface = cairo_get_target (cairo_device->cr);
67 || x + w > cairo_image_surface_get_width (surface)
68 || y + h > cairo_image_surface_get_height (surface))
71 cairo_save (cairo_device->cr);
73 cairo_rectangle (cairo_device->cr,
74 x - cairo_device->xmargin,
75 y - cairo_device->ymargin,
77 cairo_stroke (cairo_device->cr);
79 cairo_translate (cairo_device->cr, x, y);
80 cairo_set_source_surface (cairo_device->cr,
81 (cairo_surface_t *) glyph->data,
83 cairo_paint (cairo_device->cr);
86 cairo_restore (cairo_device->cr);
90 dvi_cairo_draw_rule (DviContext *dvi,
97 DviCairoDevice *cairo_device;
100 cairo_device = (DviCairoDevice *) dvi->device.device_data;
102 color = cairo_device->fg;
104 cairo_save (cairo_device->cr);
106 cairo_set_line_width (cairo_device->cr,
107 cairo_get_line_width (cairo_device->cr) * cairo_device->scale);
108 cairo_set_source_rgb (cairo_device->cr,
109 ((color >> 16) & 0xff) / 255.,
110 ((color >> 8) & 0xff) / 255.,
111 ((color >> 0) & 0xff) / 255.);
113 cairo_rectangle (cairo_device->cr,
114 x + cairo_device->xmargin,
115 y + cairo_device->ymargin,
118 cairo_stroke (cairo_device->cr);
120 cairo_fill (cairo_device->cr);
123 cairo_restore (cairo_device->cr);
128 dvi_cairo_draw_ps (DviContext *dvi,
129 const char *filename,
135 DviCairoDevice *cairo_device;
136 unsigned char *data = NULL;
138 SpectreDocument *psdoc;
139 SpectreRenderContext *rc;
141 SpectreStatus status;
142 cairo_surface_t *image;
144 cairo_device = (DviCairoDevice *) dvi->device.device_data;
146 psdoc = spectre_document_new ();
147 spectre_document_load (psdoc, filename);
148 if (spectre_document_status (psdoc)) {
149 spectre_document_free (psdoc);
153 spectre_document_get_page_size (psdoc, &w, &h);
155 rc = spectre_render_context_new ();
156 spectre_render_context_set_scale (rc,
159 spectre_document_render_full (psdoc, rc, &data, &row_length);
160 status = spectre_document_status (psdoc);
162 spectre_render_context_free (rc);
163 spectre_document_free (psdoc);
166 g_warning ("Error rendering PS document %s: %s\n",
167 filename, spectre_status_to_string (status));
173 image = cairo_image_surface_create_for_data ((unsigned char *)data,
178 cairo_save (cairo_device->cr);
180 cairo_translate (cairo_device->cr,
181 x + cairo_device->xmargin,
182 y + cairo_device->ymargin);
183 cairo_set_source_surface (cairo_device->cr, image, 0, 0);
184 cairo_paint (cairo_device->cr);
186 cairo_restore (cairo_device->cr);
188 cairo_surface_destroy (image);
191 #endif /* HAVE_SPECTRE */
194 dvi_cairo_alloc_colors (void *device_data,
203 GdkColor color, color_fg, color_bg;
206 color_bg.red = (bg >> 16) & 0xff;
207 color_bg.green = (bg >> 8) & 0xff;
208 color_bg.blue = (bg >> 0) & 0xff;
210 color_fg.red = (fg >> 16) & 0xff;
211 color_fg.green = (fg >> 8) & 0xff;
212 color_fg.blue = (fg >> 0) & 0xff;
215 for (i = 0; i < npixels; i++) {
217 pow ((double)i / n, 1 / gamma) :
218 1 - pow ((double)(n - i) / n, -gamma);
220 color.red = frac * ((double)color_fg.red - color_bg.red) + color_bg.red;
221 color.green = frac * ((double)color_fg.green - color_bg.green) + color_bg.green;
222 color.blue = frac * ((double)color_fg.blue - color_bg.blue) + color_bg.blue;
224 pixels[i] = (color.red << 16) + (color.green << 8) + color.blue + 0xff000000;
231 dvi_cairo_create_image (void *device_data,
236 return cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
240 dvi_cairo_free_image (void *ptr)
242 cairo_surface_destroy ((cairo_surface_t *)ptr);
246 dvi_cairo_put_pixel (void *image, int x, int y, Ulong color)
248 cairo_surface_t *surface;
252 surface = (cairo_surface_t *) image;
254 rowstride = cairo_image_surface_get_stride (surface);
255 p = (guint32*) (cairo_image_surface_get_data (surface) + y * rowstride + x * 4);
261 dvi_cairo_set_color (void *device_data, Ulong fg, Ulong bg)
263 DviCairoDevice *cairo_device = (DviCairoDevice *) device_data;
265 cairo_device->fg = fg;
266 cairo_device->bg = bg;
271 mdvi_cairo_device_init (DviDevice *device)
273 device->device_data = g_new0 (DviCairoDevice, 1);
275 device->draw_glyph = dvi_cairo_draw_glyph;
276 device->draw_rule = dvi_cairo_draw_rule;
277 device->alloc_colors = dvi_cairo_alloc_colors;
278 device->create_image = dvi_cairo_create_image;
279 device->free_image = dvi_cairo_free_image;
280 device->put_pixel = dvi_cairo_put_pixel;
281 device->set_color = dvi_cairo_set_color;
283 device->draw_ps = dvi_cairo_draw_ps;
285 device->draw_ps = NULL;
287 device->refresh = NULL;
291 mdvi_cairo_device_free (DviDevice *device)
293 DviCairoDevice *cairo_device;
295 cairo_device = (DviCairoDevice *) device->device_data;
297 if (cairo_device->cr)
298 cairo_destroy (cairo_device->cr);
300 g_free (cairo_device);
304 mdvi_cairo_device_get_surface (DviDevice *device)
306 DviCairoDevice *cairo_device;
308 cairo_device = (DviCairoDevice *) device->device_data;
310 return cairo_surface_reference (cairo_get_target (cairo_device->cr));
314 mdvi_cairo_device_render (DviContext* dvi)
316 DviCairoDevice *cairo_device;
319 cairo_surface_t *surface;
322 static const cairo_user_data_key_t key;
324 cairo_device = (DviCairoDevice *) dvi->device.device_data;
326 if (cairo_device->cr)
327 cairo_destroy (cairo_device->cr);
329 page_width = dvi->dvi_page_w * dvi->params.conv + 2 * cairo_device->xmargin;
330 page_height = dvi->dvi_page_h * dvi->params.vconv + 2 * cairo_device->ymargin;
332 rowstride = page_width * 4;
333 pixels = (guchar *) g_malloc (page_height * rowstride);
334 memset (pixels, 0xff, page_height * rowstride);
336 surface = cairo_image_surface_create_for_data (pixels,
338 page_width, page_height,
340 cairo_surface_set_user_data (surface, &key,
341 pixels, (cairo_destroy_func_t)g_free);
343 cairo_device->cr = cairo_create (surface);
344 cairo_surface_destroy (surface);
346 mdvi_dopage (dvi, dvi->currpage);
350 mdvi_cairo_device_set_margins (DviDevice *device,
354 DviCairoDevice *cairo_device;
356 cairo_device = (DviCairoDevice *) device->device_data;
358 cairo_device->xmargin = xmargin;
359 cairo_device->ymargin = ymargin;
363 mdvi_cairo_device_set_scale (DviDevice *device,
366 DviCairoDevice *cairo_device;
368 cairo_device = (DviCairoDevice *) device->device_data;
370 cairo_device->scale = scale;