Blame utils/viewer-cairo.c

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
}