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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <gdk/gdkcolor.h>
23 #include <libspectre/spectre.h>
26 #include "cairo-device.h"
42 dvi_cairo_draw_glyph (DviContext *dvi,
47 DviCairoDevice *cairo_device;
51 cairo_surface_t *surface;
53 cairo_device = (DviCairoDevice *) dvi->device.device_data;
57 isbox = (glyph->data == NULL || (dvi->params.flags & MDVI_PARAM_CHARBOXES));
59 x = - glyph->x + x0 + cairo_device->xmargin;
60 y = - glyph->y + y0 + cairo_device->ymargin;
64 surface = cairo_get_target (cairo_device->cr);
66 || x + w > cairo_image_surface_get_width (surface)
67 || y + h > cairo_image_surface_get_height (surface))
70 cairo_save (cairo_device->cr);
72 cairo_rectangle (cairo_device->cr,
73 x - cairo_device->xmargin,
74 y - cairo_device->ymargin,
76 cairo_stroke (cairo_device->cr);
78 cairo_translate (cairo_device->cr, x, y);
79 cairo_set_source_surface (cairo_device->cr,
80 (cairo_surface_t *) glyph->data,
82 cairo_paint (cairo_device->cr);
85 cairo_restore (cairo_device->cr);
89 dvi_cairo_draw_rule (DviContext *dvi,
96 DviCairoDevice *cairo_device;
99 cairo_device = (DviCairoDevice *) dvi->device.device_data;
101 color = cairo_device->fg;
103 cairo_save (cairo_device->cr);
105 cairo_set_line_width (cairo_device->cr,
106 cairo_get_line_width (cairo_device->cr) * cairo_device->scale);
107 cairo_set_source_rgb (cairo_device->cr,
108 ((color >> 16) & 0xff) / 255.,
109 ((color >> 8) & 0xff) / 255.,
110 ((color >> 0) & 0xff) / 255.);
112 cairo_rectangle (cairo_device->cr,
113 x + cairo_device->xmargin,
114 y + cairo_device->ymargin,
117 cairo_stroke (cairo_device->cr);
119 cairo_fill (cairo_device->cr);
122 cairo_restore (cairo_device->cr);
127 dvi_cairo_draw_ps (DviContext *dvi,
128 const char *filename,
134 DviCairoDevice *cairo_device;
135 unsigned char *data = NULL;
137 SpectreDocument *psdoc;
138 SpectreRenderContext *rc;
140 SpectreStatus status;
141 cairo_surface_t *image;
143 cairo_device = (DviCairoDevice *) dvi->device.device_data;
145 psdoc = spectre_document_new ();
146 spectre_document_load (psdoc, filename);
147 if (spectre_document_status (psdoc)) {
148 spectre_document_free (psdoc);
152 spectre_document_get_page_size (psdoc, &w, &h);
154 rc = spectre_render_context_new ();
155 spectre_render_context_set_scale (rc,
158 spectre_document_render_full (psdoc, rc, &data, &row_length);
159 status = spectre_document_status (psdoc);
161 spectre_render_context_free (rc);
162 spectre_document_free (psdoc);
165 g_warning ("Error rendering PS document %s: %s\n",
166 filename, spectre_status_to_string (status));
172 image = cairo_image_surface_create_for_data ((unsigned char *)data,
177 cairo_save (cairo_device->cr);
179 cairo_translate (cairo_device->cr,
180 x + cairo_device->xmargin,
181 y + cairo_device->ymargin);
182 cairo_set_source_surface (cairo_device->cr, image, 0, 0);
183 cairo_paint (cairo_device->cr);
185 cairo_restore (cairo_device->cr);
187 cairo_surface_destroy (image);
190 #endif /* HAVE_SPECTRE */
193 dvi_cairo_alloc_colors (void *device_data,
202 GdkColor color, color_fg, color_bg;
205 color_bg.red = (bg >> 16) & 0xff;
206 color_bg.green = (bg >> 8) & 0xff;
207 color_bg.blue = (bg >> 0) & 0xff;
209 color_fg.red = (fg >> 16) & 0xff;
210 color_fg.green = (fg >> 8) & 0xff;
211 color_fg.blue = (fg >> 0) & 0xff;
214 for (i = 0; i < npixels; i++) {
216 pow ((double)i / n, 1 / gamma) :
217 1 - pow ((double)(n - i) / n, -gamma);
219 color.red = frac * ((double)color_fg.red - color_bg.red) + color_bg.red;
220 color.green = frac * ((double)color_fg.green - color_bg.green) + color_bg.green;
221 color.blue = frac * ((double)color_fg.blue - color_bg.blue) + color_bg.blue;
223 pixels[i] = (color.red << 16) + (color.green << 8) + color.blue + 0xff000000;
230 dvi_cairo_create_image (void *device_data,
235 return cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
239 dvi_cairo_free_image (void *ptr)
241 cairo_surface_destroy ((cairo_surface_t *)ptr);
245 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 = cairo_image_surface_get_data (surface) + y * rowstride + x * 4;
257 p[2] = (color >> 16) & 0xff;
258 p[1] = (color >> 8) & 0xff;
259 p[0] = (color >> 0) & 0xff;
263 dvi_cairo_set_color (void *device_data, Ulong fg, Ulong bg)
265 DviCairoDevice *cairo_device = (DviCairoDevice *) device_data;
267 cairo_device->fg = fg;
268 cairo_device->bg = bg;
273 mdvi_cairo_device_init (DviDevice *device)
275 device->device_data = g_new0 (DviCairoDevice, 1);
277 device->draw_glyph = dvi_cairo_draw_glyph;
278 device->draw_rule = dvi_cairo_draw_rule;
279 device->alloc_colors = dvi_cairo_alloc_colors;
280 device->create_image = dvi_cairo_create_image;
281 device->free_image = dvi_cairo_free_image;
282 device->put_pixel = dvi_cairo_put_pixel;
283 device->set_color = dvi_cairo_set_color;
285 device->draw_ps = dvi_cairo_draw_ps;
287 device->draw_ps = NULL;
289 device->refresh = NULL;
293 mdvi_cairo_device_free (DviDevice *device)
295 DviCairoDevice *cairo_device;
297 cairo_device = (DviCairoDevice *) device->device_data;
299 if (cairo_device->cr)
300 cairo_destroy (cairo_device->cr);
302 g_free (cairo_device);
306 mdvi_cairo_device_get_surface (DviDevice *device)
308 DviCairoDevice *cairo_device;
310 cairo_device = (DviCairoDevice *) device->device_data;
312 return cairo_surface_reference (cairo_get_target (cairo_device->cr));
316 mdvi_cairo_device_render (DviContext* dvi)
318 DviCairoDevice *cairo_device;
321 cairo_surface_t *surface;
324 static const cairo_user_data_key_t key;
326 cairo_device = (DviCairoDevice *) dvi->device.device_data;
328 if (cairo_device->cr)
329 cairo_destroy (cairo_device->cr);
331 page_width = dvi->dvi_page_w * dvi->params.conv + 2 * cairo_device->xmargin;
332 page_height = dvi->dvi_page_h * dvi->params.vconv + 2 * cairo_device->ymargin;
334 rowstride = page_width * 4;
335 pixels = (gchar *) g_malloc (page_height * rowstride);
336 memset (pixels, 0xff, page_height * rowstride);
338 surface = cairo_image_surface_create_for_data (pixels,
340 page_width, page_height,
342 cairo_surface_set_user_data (surface, &key,
343 pixels, (cairo_destroy_func_t)g_free);
345 cairo_device->cr = cairo_create (surface);
346 cairo_surface_destroy (surface);
348 mdvi_dopage (dvi, dvi->currpage);
352 mdvi_cairo_device_set_margins (DviDevice *device,
356 DviCairoDevice *cairo_device;
358 cairo_device = (DviCairoDevice *) device->device_data;
360 cairo_device->xmargin = xmargin;
361 cairo_device->ymargin = ymargin;
365 mdvi_cairo_device_set_scale (DviDevice *device,
368 DviCairoDevice *cairo_device;
370 cairo_device = (DviCairoDevice *) device->device_data;
372 cairo_device->scale = scale;