|
Packit |
0ec9dd |
/* viewer-cairo.c: Common code for Cairo-based viewers
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* Copyright (C) 1999,2004,2005 Red Hat, Inc.
|
|
Packit |
0ec9dd |
* Copyright (C) 2001 Sun Microsystems
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This library is free software; you can redistribute it and/or
|
|
Packit |
0ec9dd |
* modify it under the terms of the GNU Library General Public
|
|
Packit |
0ec9dd |
* License as published by the Free Software Foundation; either
|
|
Packit |
0ec9dd |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
0ec9dd |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
0ec9dd |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
0ec9dd |
* Library General Public License for more details.
|
|
Packit |
0ec9dd |
*
|
|
Packit |
0ec9dd |
* You should have received a copy of the GNU Library General Public
|
|
Packit |
0ec9dd |
* License along with this library; if not, write to the
|
|
Packit |
0ec9dd |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit |
0ec9dd |
* Boston, MA 02111-1307, USA.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
#include "config.h"
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#include "viewer-cairo.h"
|
|
Packit |
0ec9dd |
#include "viewer-render.h"
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#include <cairo.h>
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#include <string.h>
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#ifdef HAVE_CAIRO_XLIB
|
|
Packit |
0ec9dd |
#ifdef HAVE_XFT
|
|
Packit |
0ec9dd |
#include "viewer-x.h"
|
|
Packit |
0ec9dd |
#include <cairo-xlib.h>
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static cairo_surface_t *
|
|
Packit |
0ec9dd |
cairo_x_view_iface_create_surface (gpointer instance,
|
|
Packit |
0ec9dd |
gpointer surface,
|
|
Packit |
0ec9dd |
int width,
|
|
Packit |
0ec9dd |
int height)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
XViewer *x = (XViewer *)instance;
|
|
Packit |
0ec9dd |
Drawable drawable = (Drawable) surface;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return cairo_xlib_surface_create (x->display, drawable,
|
|
Packit |
0ec9dd |
DefaultVisual (x->display, x->screen),
|
|
Packit |
0ec9dd |
width, height);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cairo_x_view_iface_paint_background (gpointer instance G_GNUC_UNUSED,
|
|
Packit |
0ec9dd |
cairo_t *cr)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_set_source_rgb (cr, 1, 1, 1);
|
|
Packit |
0ec9dd |
cairo_paint (cr);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (opt_bg_set)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_set_source_rgba (cr,
|
|
Packit |
0ec9dd |
opt_bg_color.red / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_color.green / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_color.blue / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_alpha / 65535.);
|
|
Packit |
0ec9dd |
cairo_paint (cr);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static CairoViewerIface cairo_x_viewer_iface = {
|
|
Packit |
0ec9dd |
&x_viewer,
|
|
Packit |
0ec9dd |
cairo_x_view_iface_create_surface,
|
|
Packit |
0ec9dd |
cairo_x_view_iface_paint_background
|
|
Packit |
0ec9dd |
};
|
|
Packit |
0ec9dd |
#endif /* HAVE_XFT */
|
|
Packit |
0ec9dd |
#endif /* HAVE_CAIRO_XLIB */
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static cairo_surface_t *
|
|
Packit |
0ec9dd |
cairo_view_iface_create_surface (gpointer instance,
|
|
Packit |
0ec9dd |
gpointer surface,
|
|
Packit |
0ec9dd |
int width,
|
|
Packit |
0ec9dd |
int height)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
return cairo_surface_reference (surface);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static gpointer
|
|
Packit |
0ec9dd |
cairo_image_view_create (const PangoViewer *klass G_GNUC_UNUSED)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
return NULL;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cairo_image_view_destroy (gpointer instance G_GNUC_UNUSED)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static gpointer
|
|
Packit |
0ec9dd |
cairo_image_view_create_surface (gpointer instance,
|
|
Packit |
0ec9dd |
int width,
|
|
Packit |
0ec9dd |
int height)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_t *cr;
|
|
Packit |
0ec9dd |
cairo_surface_t *surface;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* TODO: Be smarter about format? */
|
|
Packit |
0ec9dd |
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cr = cairo_create (surface);
|
|
Packit |
0ec9dd |
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
|
Packit |
0ec9dd |
cairo_paint (cr);
|
|
Packit |
0ec9dd |
cairo_destroy (cr);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return surface;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cairo_image_view_destroy_surface (gpointer instance,
|
|
Packit |
0ec9dd |
gpointer surface)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_surface_destroy (surface);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
const PangoViewer cairo_image_viewer = {
|
|
Packit |
0ec9dd |
"CairoImage",
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
cairo_image_view_create,
|
|
Packit |
0ec9dd |
cairo_image_view_destroy,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
cairo_image_view_create_surface,
|
|
Packit |
0ec9dd |
cairo_image_view_destroy_surface,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL
|
|
Packit |
0ec9dd |
};
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cairo_image_view_iface_paint_background (gpointer instance G_GNUC_UNUSED,
|
|
Packit |
0ec9dd |
cairo_t *cr)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_set_source_rgb (cr, 1, 1, 1);
|
|
Packit |
0ec9dd |
cairo_paint (cr);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (opt_bg_set)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
|
Packit |
0ec9dd |
cairo_set_source_rgba (cr,
|
|
Packit |
0ec9dd |
opt_bg_color.red / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_color.green / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_color.blue / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_alpha / 65535.);
|
|
Packit |
0ec9dd |
cairo_paint (cr);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static CairoViewerIface cairo_image_viewer_iface = {
|
|
Packit |
0ec9dd |
&cairo_image_viewer,
|
|
Packit |
0ec9dd |
cairo_view_iface_create_surface,
|
|
Packit |
0ec9dd |
cairo_image_view_iface_paint_background
|
|
Packit |
0ec9dd |
};
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#ifdef CAIRO_HAS_SVG_SURFACE
|
|
Packit |
0ec9dd |
# include <cairo-svg.h>
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
#ifdef CAIRO_HAS_PDF_SURFACE
|
|
Packit |
0ec9dd |
# include <cairo-pdf.h>
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
#ifdef CAIRO_HAS_PS_SURFACE
|
|
Packit |
0ec9dd |
# include <cairo-ps.h>
|
|
Packit |
0ec9dd |
# if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,6,0)
|
|
Packit |
0ec9dd |
# define HAS_EPS 1
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static cairo_surface_t *
|
|
Packit |
0ec9dd |
_cairo_eps_surface_create (const char *filename,
|
|
Packit |
0ec9dd |
double width,
|
|
Packit |
0ec9dd |
double height)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_surface_t *surface;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
surface = cairo_ps_surface_create (filename, width, height);
|
|
Packit |
0ec9dd |
cairo_ps_surface_set_eps (surface, TRUE);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return surface;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
# else
|
|
Packit |
0ec9dd |
# undef HAS_EPS
|
|
Packit |
0ec9dd |
# endif
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
typedef cairo_surface_t *(*CairoVectorFileCreateFunc) (const char *filename,
|
|
Packit |
0ec9dd |
double width,
|
|
Packit |
0ec9dd |
double height);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
typedef struct
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
const char *filename;
|
|
Packit |
0ec9dd |
CairoVectorFileCreateFunc constructor;
|
|
Packit |
0ec9dd |
} CairoVectorViewer;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static gpointer
|
|
Packit |
0ec9dd |
cairo_vector_view_create (const PangoViewer *klass G_GNUC_UNUSED)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
const char *extension = NULL;
|
|
Packit |
0ec9dd |
CairoVectorFileCreateFunc constructor = NULL;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (opt_output)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
extension = strrchr (opt_output, '.');
|
|
Packit |
0ec9dd |
if (extension)
|
|
Packit |
0ec9dd |
extension++; /* skip the dot */
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (!extension)
|
|
Packit |
0ec9dd |
return NULL;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (0)
|
|
Packit |
0ec9dd |
;
|
|
Packit |
0ec9dd |
#ifdef CAIRO_HAS_SVG_SURFACE
|
|
Packit |
0ec9dd |
else if (0 == g_ascii_strcasecmp (extension, "svg"))
|
|
Packit |
0ec9dd |
constructor = cairo_svg_surface_create;
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
#ifdef CAIRO_HAS_PDF_SURFACE
|
|
Packit |
0ec9dd |
else if (0 == g_ascii_strcasecmp (extension, "pdf"))
|
|
Packit |
0ec9dd |
constructor = cairo_pdf_surface_create;
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
#ifdef CAIRO_HAS_PS_SURFACE
|
|
Packit |
0ec9dd |
else if (0 == g_ascii_strcasecmp (extension, "ps"))
|
|
Packit |
0ec9dd |
constructor = cairo_ps_surface_create;
|
|
Packit |
0ec9dd |
#ifdef HAS_EPS
|
|
Packit |
0ec9dd |
else if (0 == g_ascii_strcasecmp (extension, "eps"))
|
|
Packit |
0ec9dd |
constructor = _cairo_eps_surface_create;
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (constructor)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
CairoVectorViewer *instance;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
instance = g_slice_new (CairoVectorViewer);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* save output filename and unset it such that the viewer layer
|
|
Packit |
0ec9dd |
* doesn't try to save to file.
|
|
Packit |
0ec9dd |
*/
|
|
Packit |
0ec9dd |
instance->filename = opt_output;
|
|
Packit |
0ec9dd |
opt_output = NULL;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
instance->constructor = constructor;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* Fix dpi on 72. That's what cairo vector surfaces are. */
|
|
Packit |
0ec9dd |
opt_dpi = 72;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return instance;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return NULL;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cairo_vector_view_destroy (gpointer instance G_GNUC_UNUSED)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
CairoVectorViewer *c = (CairoVectorViewer *) instance;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_slice_free (CairoVectorViewer, c);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static gpointer
|
|
Packit |
0ec9dd |
cairo_vector_view_create_surface (gpointer instance,
|
|
Packit |
0ec9dd |
int width,
|
|
Packit |
0ec9dd |
int height)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
CairoVectorViewer *c = (CairoVectorViewer *) instance;
|
|
Packit |
0ec9dd |
cairo_surface_t *surface;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
surface = c->constructor (c->filename, width, height);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/*cairo_surface_set_fallback_resolution (surface, fallback_resolution_x, fallback_resolution_y);*/
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return surface;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cairo_vector_view_destroy_surface (gpointer instance,
|
|
Packit |
0ec9dd |
gpointer surface)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
/* TODO: check for errors */
|
|
Packit |
0ec9dd |
cairo_surface_destroy (surface);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
const PangoViewer cairo_vector_viewer = {
|
|
Packit |
0ec9dd |
"CairoFile",
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
cairo_vector_view_create,
|
|
Packit |
0ec9dd |
cairo_vector_view_destroy,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
cairo_vector_view_create_surface,
|
|
Packit |
0ec9dd |
cairo_vector_view_destroy_surface,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL,
|
|
Packit |
0ec9dd |
NULL
|
|
Packit |
0ec9dd |
};
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
cairo_vector_view_iface_paint_background (gpointer instance G_GNUC_UNUSED,
|
|
Packit |
0ec9dd |
cairo_t *cr)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
if (opt_bg_set)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
|
Packit |
0ec9dd |
cairo_set_source_rgba (cr,
|
|
Packit |
0ec9dd |
opt_bg_color.red / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_color.green / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_color.blue / 65535.,
|
|
Packit |
0ec9dd |
opt_bg_alpha / 65535.);
|
|
Packit |
0ec9dd |
cairo_paint (cr);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static CairoViewerIface cairo_vector_viewer_iface = {
|
|
Packit |
0ec9dd |
&cairo_vector_viewer,
|
|
Packit |
0ec9dd |
cairo_view_iface_create_surface,
|
|
Packit |
0ec9dd |
cairo_vector_view_iface_paint_background
|
|
Packit |
0ec9dd |
};
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
gpointer
|
|
Packit |
0ec9dd |
cairo_viewer_iface_create (const CairoViewerIface **iface)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
gpointer ret;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
*iface = &cairo_vector_viewer_iface;
|
|
Packit |
0ec9dd |
ret = (*iface)->backend_class->create ((*iface)->backend_class);
|
|
Packit |
0ec9dd |
if (ret)
|
|
Packit |
0ec9dd |
return ret;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#ifdef HAVE_CAIRO_XLIB
|
|
Packit |
0ec9dd |
#ifdef HAVE_XFT
|
|
Packit |
0ec9dd |
if (opt_display)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
*iface = &cairo_x_viewer_iface;
|
|
Packit |
0ec9dd |
return (*iface)->backend_class->create ((*iface)->backend_class);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
#endif /* HAVE_XFT */
|
|
Packit |
0ec9dd |
#endif /* HAVE_CAIRO_XLIB */
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
*iface = &cairo_image_viewer_iface;
|
|
Packit |
0ec9dd |
return (*iface)->backend_class->create ((*iface)->backend_class);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
void
|
|
Packit |
0ec9dd |
cairo_viewer_add_options (GOptionGroup *group G_GNUC_UNUSED)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
}
|