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 ||
59 (dvi->params.flags & MDVI_PARAM_CHARBOXES) ||
60 MDVI_GLYPH_ISEMPTY (glyph->data));
62 x = - glyph->x + x0 + cairo_device->xmargin;
63 y = - glyph->y + y0 + cairo_device->ymargin;
67 surface = cairo_get_target (cairo_device->cr);
69 || x + w > cairo_image_surface_get_width (surface)
70 || y + h > cairo_image_surface_get_height (surface))
73 cairo_save (cairo_device->cr);
75 cairo_rectangle (cairo_device->cr,
76 x - cairo_device->xmargin,
77 y - cairo_device->ymargin,
79 cairo_stroke (cairo_device->cr);
81 cairo_translate (cairo_device->cr, x, y);
82 cairo_set_source_surface (cairo_device->cr,
83 (cairo_surface_t *) glyph->data,
85 cairo_paint (cairo_device->cr);
88 cairo_restore (cairo_device->cr);
92 dvi_cairo_draw_rule (DviContext *dvi,
99 DviCairoDevice *cairo_device;
102 cairo_device = (DviCairoDevice *) dvi->device.device_data;
104 color = cairo_device->fg;
106 cairo_save (cairo_device->cr);
108 cairo_set_line_width (cairo_device->cr,
109 cairo_get_line_width (cairo_device->cr) * cairo_device->scale);
110 cairo_set_source_rgb (cairo_device->cr,
111 ((color >> 16) & 0xff) / 255.,
112 ((color >> 8) & 0xff) / 255.,
113 ((color >> 0) & 0xff) / 255.);
115 cairo_rectangle (cairo_device->cr,
116 x + cairo_device->xmargin,
117 y + cairo_device->ymargin,
120 cairo_stroke (cairo_device->cr);
122 cairo_fill (cairo_device->cr);
125 cairo_restore (cairo_device->cr);
130 dvi_cairo_draw_ps (DviContext *dvi,
131 const char *filename,
137 DviCairoDevice *cairo_device;
138 unsigned char *data = NULL;
140 SpectreDocument *psdoc;
141 SpectreRenderContext *rc;
143 SpectreStatus status;
144 cairo_surface_t *image;
146 cairo_device = (DviCairoDevice *) dvi->device.device_data;
148 psdoc = spectre_document_new ();
149 spectre_document_load (psdoc, filename);
150 if (spectre_document_status (psdoc)) {
151 spectre_document_free (psdoc);
155 spectre_document_get_page_size (psdoc, &w, &h);
157 rc = spectre_render_context_new ();
158 spectre_render_context_set_scale (rc,
161 spectre_document_render_full (psdoc, rc, &data, &row_length);
162 status = spectre_document_status (psdoc);
164 spectre_render_context_free (rc);
165 spectre_document_free (psdoc);
168 g_warning ("Error rendering PS document %s: %s\n",
169 filename, spectre_status_to_string (status));
175 image = cairo_image_surface_create_for_data ((unsigned char *)data,
180 cairo_save (cairo_device->cr);
182 cairo_translate (cairo_device->cr,
183 x + cairo_device->xmargin,
184 y + cairo_device->ymargin);
185 cairo_set_source_surface (cairo_device->cr, image, 0, 0);
186 cairo_paint (cairo_device->cr);
188 cairo_restore (cairo_device->cr);
190 cairo_surface_destroy (image);
193 #endif /* HAVE_SPECTRE */
196 dvi_cairo_alloc_colors (void *device_data,
205 GdkColor color, color_fg;
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 * color_fg.red;
220 color.green = frac * color_fg.green;
221 color.blue = frac * color_fg.blue;
224 pixels[i] = (alpha << 24) + (color.red << 16) + (color.green << 8) + color.blue;
231 dvi_cairo_create_image (void *device_data,
236 return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 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);
257 /* per cairo docs, must flush before modifying outside of cairo */
258 cairo_surface_flush(surface);
263 dvi_cairo_image_done (void *ptr)
265 cairo_surface_mark_dirty((cairo_surface_t *)ptr);
269 dvi_cairo_set_color (void *device_data, Ulong fg, Ulong bg)
271 DviCairoDevice *cairo_device = (DviCairoDevice *) device_data;
273 cairo_device->fg = fg;
274 cairo_device->bg = bg;
279 mdvi_cairo_device_init (DviDevice *device)
281 device->device_data = g_new0 (DviCairoDevice, 1);
283 device->draw_glyph = dvi_cairo_draw_glyph;
284 device->draw_rule = dvi_cairo_draw_rule;
285 device->alloc_colors = dvi_cairo_alloc_colors;
286 device->create_image = dvi_cairo_create_image;
287 device->free_image = dvi_cairo_free_image;
288 device->put_pixel = dvi_cairo_put_pixel;
289 device->image_done = dvi_cairo_image_done;
290 device->set_color = dvi_cairo_set_color;
292 device->draw_ps = dvi_cairo_draw_ps;
294 device->draw_ps = NULL;
296 device->refresh = NULL;
300 mdvi_cairo_device_free (DviDevice *device)
302 DviCairoDevice *cairo_device;
304 cairo_device = (DviCairoDevice *) device->device_data;
306 if (cairo_device->cr)
307 cairo_destroy (cairo_device->cr);
309 g_free (cairo_device);
313 mdvi_cairo_device_get_surface (DviDevice *device)
315 DviCairoDevice *cairo_device;
317 cairo_device = (DviCairoDevice *) device->device_data;
319 return cairo_surface_reference (cairo_get_target (cairo_device->cr));
323 mdvi_cairo_device_render (DviContext* dvi)
325 DviCairoDevice *cairo_device;
328 cairo_surface_t *surface;
330 cairo_device = (DviCairoDevice *) dvi->device.device_data;
332 if (cairo_device->cr)
333 cairo_destroy (cairo_device->cr);
335 page_width = dvi->dvi_page_w * dvi->params.conv + 2 * cairo_device->xmargin;
336 page_height = dvi->dvi_page_h * dvi->params.vconv + 2 * cairo_device->ymargin;
338 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
339 page_width, page_height);
341 cairo_device->cr = cairo_create (surface);
342 cairo_surface_destroy (surface);
344 cairo_set_source_rgb (cairo_device->cr, 1., 1., 1.);
345 cairo_paint (cairo_device->cr);
347 mdvi_dopage (dvi, dvi->currpage);
351 mdvi_cairo_device_set_margins (DviDevice *device,
355 DviCairoDevice *cairo_device;
357 cairo_device = (DviCairoDevice *) device->device_data;
359 cairo_device->xmargin = xmargin;
360 cairo_device->ymargin = ymargin;
364 mdvi_cairo_device_set_scale (DviDevice *device,
367 DviCairoDevice *cairo_device;
369 cairo_device = (DviCairoDevice *) device->device_data;
371 cairo_device->scale = scale;