1/* viewer-cairo.c: Common code for Cairo-based viewers
2 *
3 * Copyright (C) 1999,2004,2005 Red Hat, Inc.
4 * Copyright (C) 2001 Sun Microsystems
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21#include "config.h"
22
23#include "viewer-cairo.h"
24#include "viewer-render.h"
25
26#include <cairo.h>
27
28#include <string.h>
29
30
31
32#ifdef HAVE_CAIRO_XLIB
33#ifdef HAVE_XFT
34#include "viewer-x.h"
35#include <cairo-xlib.h>
36
37static cairo_surface_t *
38cairo_x_view_iface_create_surface (gpointer instance,
39 gpointer surface,
40 int width,
41 int height)
42{
43 XViewer *x = (XViewer *)instance;
44 Drawable drawable = (Drawable) surface;
45
46 return cairo_xlib_surface_create (x->display, drawable,
47 DefaultVisual (x->display, x->screen),
48 width, height);
49}
50
51static void
52cairo_x_view_iface_paint_background (gpointer instance G_GNUC_UNUSED,
53 cairo_t *cr)
54{
55 cairo_set_source_rgb (cr, 1, 1, 1);
56 cairo_paint (cr);
57
58 if (opt_bg_set)
59 {
60 cairo_set_source_rgba (cr,
61 opt_bg_color.red / 65535.,
62 opt_bg_color.green / 65535.,
63 opt_bg_color.blue / 65535.,
64 opt_bg_alpha / 65535.);
65 cairo_paint (cr);
66 }
67}
68
69static CairoViewerIface cairo_x_viewer_iface = {
70 &x_viewer,
71 cairo_x_view_iface_create_surface,
72 cairo_x_view_iface_paint_background
73};
74#endif /* HAVE_XFT */
75#endif /* HAVE_CAIRO_XLIB */
76
77
78
79
80static cairo_surface_t *
81cairo_view_iface_create_surface (gpointer instance,
82 gpointer surface,
83 int width,
84 int height)
85{
86 return cairo_surface_reference (surface);
87}
88
89
90
91static gpointer
92cairo_image_view_create (const PangoViewer *klass G_GNUC_UNUSED)
93{
94 return NULL;
95}
96
97static void
98cairo_image_view_destroy (gpointer instance G_GNUC_UNUSED)
99{
100}
101
102static gpointer
103cairo_image_view_create_surface (gpointer instance,
104 int width,
105 int height)
106{
107 cairo_t *cr;
108 cairo_surface_t *surface;
109
110 /* TODO: Be smarter about format? */
111 surface = cairo_image_surface_create (format: CAIRO_FORMAT_ARGB32, width, height);
112
113 cr = cairo_create (target: surface);
114 cairo_set_source_rgb (cr, red: 1.0, green: 1.0, blue: 1.0);
115 cairo_paint (cr);
116 cairo_destroy (cr);
117
118 return surface;
119}
120
121static void
122cairo_image_view_destroy_surface (gpointer instance,
123 gpointer surface)
124{
125 cairo_surface_destroy (surface);
126}
127
128const PangoViewer cairo_image_viewer = {
129 "CairoImage",
130 NULL,
131 NULL,
132 cairo_image_view_create,
133 cairo_image_view_destroy,
134 NULL,
135 cairo_image_view_create_surface,
136 cairo_image_view_destroy_surface,
137 NULL,
138 NULL,
139 NULL,
140 NULL,
141 NULL
142};
143
144static void
145cairo_image_view_iface_paint_background (gpointer instance G_GNUC_UNUSED,
146 cairo_t *cr)
147{
148 cairo_set_source_rgb (cr, red: 1, green: 1, blue: 1);
149 cairo_paint (cr);
150
151 if (opt_bg_set)
152 {
153 cairo_set_operator (cr, op: CAIRO_OPERATOR_SOURCE);
154 cairo_set_source_rgba (cr,
155 red: opt_bg_color.red / 65535.,
156 green: opt_bg_color.green / 65535.,
157 blue: opt_bg_color.blue / 65535.,
158 alpha: opt_bg_alpha / 65535.);
159 cairo_paint (cr);
160 }
161}
162
163static CairoViewerIface cairo_image_viewer_iface = {
164 &cairo_image_viewer,
165 cairo_view_iface_create_surface,
166 cairo_image_view_iface_paint_background
167};
168
169
170
171
172#ifdef CAIRO_HAS_SVG_SURFACE
173# include <cairo-svg.h>
174#endif
175#ifdef CAIRO_HAS_PDF_SURFACE
176# include <cairo-pdf.h>
177#endif
178#ifdef CAIRO_HAS_PS_SURFACE
179# include <cairo-ps.h>
180# if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,6,0)
181# define HAS_EPS 1
182
183static cairo_surface_t *
184_cairo_eps_surface_create (const char *filename,
185 double width,
186 double height)
187{
188 cairo_surface_t *surface;
189
190 surface = cairo_ps_surface_create (filename, width_in_points: width, height_in_points: height);
191 cairo_ps_surface_set_eps (surface, TRUE);
192
193 return surface;
194}
195
196# else
197# undef HAS_EPS
198# endif
199#endif
200
201typedef cairo_surface_t *(*CairoVectorFileCreateFunc) (const char *filename,
202 double width,
203 double height);
204
205typedef struct
206{
207 const char *filename;
208 CairoVectorFileCreateFunc constructor;
209} CairoVectorViewer;
210
211static gpointer
212cairo_vector_view_create (const PangoViewer *klass G_GNUC_UNUSED)
213{
214 const char *extension = NULL;
215 CairoVectorFileCreateFunc constructor = NULL;
216
217 if (opt_output)
218 {
219 extension = strrchr (s: opt_output, c: '.');
220 if (extension)
221 extension++; /* skip the dot */
222 }
223
224 if (!extension)
225 return NULL;
226
227 if (0)
228 {}
229 #ifdef CAIRO_HAS_SVG_SURFACE
230 else if (0 == g_ascii_strcasecmp (s1: extension, s2: "svg"))
231 constructor = cairo_svg_surface_create;
232 #endif
233 #ifdef CAIRO_HAS_PDF_SURFACE
234 else if (0 == g_ascii_strcasecmp (s1: extension, s2: "pdf"))
235 constructor = cairo_pdf_surface_create;
236 #endif
237 #ifdef CAIRO_HAS_PS_SURFACE
238 else if (0 == g_ascii_strcasecmp (s1: extension, s2: "ps"))
239 constructor = cairo_ps_surface_create;
240 #ifdef HAS_EPS
241 else if (0 == g_ascii_strcasecmp (s1: extension, s2: "eps"))
242 constructor = _cairo_eps_surface_create;
243 #endif
244 #endif
245
246 if (constructor)
247 {
248 CairoVectorViewer *instance;
249
250 instance = g_slice_new (CairoVectorViewer);
251
252 /* save output filename and unset it such that the viewer layer
253 * doesn't try to save to file.
254 */
255 instance->filename = opt_output;
256 opt_output = NULL;
257
258 instance->constructor = constructor;
259
260 /* Fix dpi on 72. That's what cairo vector surfaces are. */
261 opt_dpi = 72;
262
263 return instance;
264 }
265
266 return NULL;
267}
268
269static void
270cairo_vector_view_destroy (gpointer instance G_GNUC_UNUSED)
271{
272 CairoVectorViewer *c = (CairoVectorViewer *) instance;
273
274 g_slice_free (CairoVectorViewer, c);
275}
276
277static gpointer
278cairo_vector_view_create_surface (gpointer instance,
279 int width,
280 int height)
281{
282 CairoVectorViewer *c = (CairoVectorViewer *) instance;
283 cairo_surface_t *surface;
284
285 surface = c->constructor (c->filename, width, height);
286
287 /*cairo_surface_set_fallback_resolution (surface, fallback_resolution_x, fallback_resolution_y);*/
288
289 return surface;
290}
291
292static void
293cairo_vector_view_destroy_surface (gpointer instance,
294 gpointer surface)
295{
296 /* TODO: check for errors */
297 cairo_surface_destroy (surface);
298}
299
300const PangoViewer cairo_vector_viewer = {
301 "CairoFile",
302 NULL,
303 NULL,
304 cairo_vector_view_create,
305 cairo_vector_view_destroy,
306 NULL,
307 cairo_vector_view_create_surface,
308 cairo_vector_view_destroy_surface,
309 NULL,
310 NULL,
311 NULL,
312 NULL,
313 NULL
314};
315
316static void
317cairo_vector_view_iface_paint_background (gpointer instance G_GNUC_UNUSED,
318 cairo_t *cr)
319{
320 if (opt_bg_set)
321 {
322 cairo_set_operator (cr, op: CAIRO_OPERATOR_SOURCE);
323 cairo_set_source_rgba (cr,
324 red: opt_bg_color.red / 65535.,
325 green: opt_bg_color.green / 65535.,
326 blue: opt_bg_color.blue / 65535.,
327 alpha: opt_bg_alpha / 65535.);
328 cairo_paint (cr);
329 }
330}
331
332static CairoViewerIface cairo_vector_viewer_iface = {
333 &cairo_vector_viewer,
334 cairo_view_iface_create_surface,
335 cairo_vector_view_iface_paint_background
336};
337
338
339
340gpointer
341cairo_viewer_iface_create (const CairoViewerIface **iface)
342{
343 gpointer ret;
344
345 *iface = &cairo_vector_viewer_iface;
346 ret = (*iface)->backend_class->create ((*iface)->backend_class);
347 if (ret)
348 return ret;
349
350#ifdef HAVE_CAIRO_XLIB
351#ifdef HAVE_XFT
352 if (opt_display)
353 {
354 *iface = &cairo_x_viewer_iface;
355 return (*iface)->backend_class->create ((*iface)->backend_class);
356 }
357#endif /* HAVE_XFT */
358#endif /* HAVE_CAIRO_XLIB */
359
360 *iface = &cairo_image_viewer_iface;
361 return (*iface)->backend_class->create ((*iface)->backend_class);
362}
363
364void
365cairo_viewer_add_options (GOptionGroup *group G_GNUC_UNUSED)
366{
367}
368

source code of gtk/subprojects/pango/utils/viewer-cairo.c