dia r3904 - in trunk: . data plug-ins plug-ins/cairo



Author: hans
Date: Sat Mar  8 22:46:52 2008
New Revision: 3904
URL: http://svn.gnome.org/viewvc/dia?rev=3904&view=rev

Log:
2008-03-08  Hans Breuer  <hans breuer org>

	* plug-ins/cairo/diacairo-print.c : use the cairo renderer for
	integration with the Gtk+ print framework
	* plug-ins/cairo/diacairo.c : gtk-print implementation for paginated 
	output of PDF (bug #513226) and register for printing, also ... 
	  plug-ins/cairo/diacairo-renderer.c : ... split off the renderer
	implmentation in it's own file. Some tweaking for use in the
	print context.
	* plug-ins/cairo/diacairo.h : calback function to be registered
	in the menu (later to replace native printing?)
	* plug-ins/cairo/Makefile.am plug-ins/makefile.msc : adapted

	* data/display-ui.xml data/popup-ui.xml : more *ExtensionStart to 
	allow placement of plug-in function in all sub-menus. Above it is 
	used for "File/Print with Gtk+/cairo ..."

	* plug-ins/cairo/diacairo-interactive.c : also compile with Gtk+ < 2.8



Modified:
   trunk/ChangeLog
   trunk/data/display-ui.xml
   trunk/data/popup-ui.xml
   trunk/plug-ins/cairo/Makefile.am
   trunk/plug-ins/cairo/diacairo-interactive.c
   trunk/plug-ins/cairo/diacairo-print.c
   trunk/plug-ins/cairo/diacairo-renderer.c
   trunk/plug-ins/cairo/diacairo.c
   trunk/plug-ins/cairo/diacairo.h
   trunk/plug-ins/makefile.msc

Modified: trunk/data/display-ui.xml
==============================================================================
--- trunk/data/display-ui.xml	(original)
+++ trunk/data/display-ui.xml	Sat Mar  8 22:46:52 2008
@@ -14,6 +14,8 @@
 			<separator name="FileSep3" />
 			<menuitem name="FileClose" action="FileClose" />
 			<menuitem name="FileQuit" action="FileQuit" />
+			<separator name="FileSep4" />
+			<separator name="FileExtensionStart" />
 		</menu>
 		<menu name="Edit" action="Edit">
 			<menuitem name="EditUndo" action="EditUndo" />
@@ -28,10 +30,14 @@
 			<menuitem name="EditCopytext" action="EditCopytext" />
 			<menuitem name="EditCuttext" action="EditCuttext" />
 			<menuitem name="EditPastetext" action="EditPastetext" />
+			<separator name="EditSep3" />
+			<separator name="EditExtensionStart" />
 		</menu>
 		<menu name="Diagram" action="Diagram">
 			<menuitem name="DiagramProperties" action="DiagramProperties" />
 			<menuitem name="DiagramLayers" action="DiagramLayers" />
+			<separator name="DiagramSep1" />
+			<separator name="DIagramExtensionStart" />
 		</menu>
 		<menu name="View" action="View">
 			<menuitem name="ViewZoomin" action="ViewZoomin" />
@@ -63,6 +69,8 @@
 			<menuitem name="ViewNewview" action="ViewNewview" />
 			<menuitem name="ViewCloneview" action="ViewCloneview" />
 			<menuitem name="ViewRedraw" action="ViewRedraw" />
+			<separator name="ViewSep3" />
+			<separator name="ViewExtensionStart" />
 		</menu>
 		<menu name="Objects" action="Objects">
 			<menuitem name="ObjectsSendtoback" action="ObjectsSendtoback" />
@@ -113,6 +121,8 @@
 			<menu name="SelectBy" action="SelectBy">
 				<separator name="SelectByExtensionStart" />
 			</menu>
+			<separator name="SelectSep4" />
+			<separator name="SelectExtensionStart" />
 		</menu>
 		<menu name="Tools" action="Tools">
 			<menuitem name="ToolsModify" action="ToolsModify" />
@@ -133,6 +143,8 @@
 			<menuitem name="ToolsOutline" action="ToolsOutline" />
 			<separator name="ToolsSep1" />
 			<menuitem name="ToolsImage" action="ToolsImage" />
+			<separator name="ToolsSep2" />
+			<separator name="ToolsExtensionStart" />
 		</menu>
 		<menuitem name="InputMethods" action="InputMethods" />
 		<menu name="Dialogs" action="Dialogs">

Modified: trunk/data/popup-ui.xml
==============================================================================
--- trunk/data/popup-ui.xml	(original)
+++ trunk/data/popup-ui.xml	Sat Mar  8 22:46:52 2008
@@ -14,6 +14,8 @@
 			<separator name="FileSep3" />
 			<menuitem name="FileClose" action="FileClose" />
 			<menuitem name="FileQuit" action="FileQuit" />
+			<separator name="FileSep4" />
+			<separator name="FileExtensionStart" />
 		</menu>
 		<menu name="Edit" action="Edit">
 			<menuitem name="EditUndo" action="EditUndo" />
@@ -28,10 +30,14 @@
 			<menuitem name="EditCopytext" action="EditCopytext" />
 			<menuitem name="EditCuttext" action="EditCuttext" />
 			<menuitem name="EditPastetext" action="EditPastetext" />
+			<separator name="EditSep3" />
+			<separator name="EditExtensionStart" />
 		</menu>
 		<menu name="Diagram" action="Diagram">
 			<menuitem name="DiagramProperties" action="DiagramProperties" />
 			<menuitem name="DiagramLayers" action="DiagramLayers" />
+			<separator name="DiagramSep1" />
+			<separator name="DIagramExtensionStart" />
 		</menu>
 		<menu name="View" action="View">
 			<menuitem name="ViewZoomin" action="ViewZoomin" />
@@ -63,6 +69,8 @@
 			<menuitem name="ViewCloneview" action="ViewCloneview" />
 			<menuitem name="ViewShowall" action="ViewShowall" />
 			<menuitem name="ViewRedraw" action="ViewRedraw" />
+			<separator name="ViewSep3" />
+			<separator name="ViewExtensionStart" />
 		</menu>
 		<menu name="Objects" action="Objects">
 			<menuitem name="ObjectsSendtoback" action="ObjectsSendtoback" />
@@ -113,6 +121,8 @@
 			<menu name="SelectBy" action="SelectBy">
 				<separator name="SelectByExtensionStart" />
 			</menu>
+			<separator name="SelectSep4" />
+			<separator name="SelectExtensionStart" />
 		</menu>
 		<menu name="Tools" action="Tools">
 			<menuitem name="ToolsModify" action="ToolsModify" />
@@ -133,6 +143,8 @@
 			<menuitem name="ToolsOutline" action="ToolsOutline" />
 			<separator name="ToolsSep1" />
 			<menuitem name="ToolsImage" action="ToolsImage" />
+			<separator name="ToolsSep2" />
+			<separator name="ToolsExtensionStart" />
 		</menu>
 		<menuitem name="InputMethods" action="InputMethods" />
 		<menu name="Dialogs" action="Dialogs">

Modified: trunk/plug-ins/cairo/Makefile.am
==============================================================================
--- trunk/plug-ins/cairo/Makefile.am	(original)
+++ trunk/plug-ins/cairo/Makefile.am	Sat Mar  8 22:46:52 2008
@@ -3,6 +3,7 @@
 	diacairo.c \
 	diacairo.h \
 	diacairo-interactive.c \
+	diacairo-renderer.c \
 	diacairo-print.c 
 
 pkglib_LTLIBRARIES = libcairo_filter.la

Modified: trunk/plug-ins/cairo/diacairo-interactive.c
==============================================================================
--- trunk/plug-ins/cairo/diacairo-interactive.c	(original)
+++ trunk/plug-ins/cairo/diacairo-interactive.c	Sat Mar  8 22:46:52 2008
@@ -23,6 +23,7 @@
 #include "diacairo.h"
 
 #include <gdk/gdk.h>
+#include <gtk/gtkversion.h>
 
 #include "intl.h"
 #include "color.h"
@@ -224,7 +225,13 @@
   DiaCairoRenderer *base_renderer = DIA_CAIRO_RENDERER (self);
 
   g_return_if_fail (base_renderer->cr == NULL);
+#if GTK_CHECK_VERSION(2,8,0)
   base_renderer->cr = gdk_cairo_create(renderer->pixmap);
+#else
+  base_renderer->surface = cairo_image_surface_create (
+                             CAIRO_FORMAT_ARGB32, get_width_pixels (self), get_height_pixels (self));
+  base_renderer->cr = cairo_create (base_renderer->surface);
+#endif
 
   cairo_scale (base_renderer->cr, *renderer->zoom_factor, *renderer->zoom_factor);
   cairo_translate (base_renderer->cr, -renderer->visible->left, -renderer->visible->top);

Modified: trunk/plug-ins/cairo/diacairo-print.c
==============================================================================
--- trunk/plug-ins/cairo/diacairo-print.c	(original)
+++ trunk/plug-ins/cairo/diacairo-print.c	Sat Mar  8 22:46:52 2008
@@ -2,7 +2,7 @@
  * Copyright (C) 1998 Alexander Larsson
  *
  * diacairo-print.c -- Cairo/gtk+ based printing for dia
- * Copyright (C) 2007, Hans Breuer, <Hans Breuer Org>
+ * Copyright (C) 2008, Hans Breuer, <Hans Breuer Org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,5 +20,219 @@
  */
 
 #include "diacairo.h"
+#include "diacairo-print.h"
 
-#include <gtk/gtkprintoperation.h>
+#include "message.h"
+
+#if GTK_CHECK_VERSION (2,10,0)
+
+typedef struct _PrintData
+{
+  DiagramData *data;
+  DiaRenderer *renderer;
+} PrintData;
+
+static void
+count_objs(DiaObject *obj, DiaRenderer *renderer, int active_layer, guint *nobjs)
+{
+  (*nobjs)++;
+}
+
+/* Dia has it's own thing */
+static void
+_dia_to_gtk_page_setup (const DiagramData *data, GtkPageSetup *setup)
+{
+  GtkPaperSize *paper_size;
+  const double points_per_cm = 28.346457;
+  const PaperInfo *paper = &(data->paper);
+  int index = find_paper (paper->name);
+  if (index < 0)
+    index = get_default_paper ();
+  paper_size = gtk_paper_size_new_from_ppd (
+		 paper->name, paper->name, 
+                 get_paper_pswidth (index) * points_per_cm, 
+		 get_paper_psheight (index) * points_per_cm);
+
+  gtk_page_setup_set_orientation (setup, data->paper.is_portrait ?
+    GTK_PAGE_ORIENTATION_PORTRAIT : GTK_PAGE_ORIENTATION_LANDSCAPE);
+  gtk_page_setup_set_paper_size (setup, paper_size);
+
+  gtk_page_setup_set_left_margin (setup, data->paper.lmargin * 10, GTK_UNIT_MM);
+  gtk_page_setup_set_top_margin (setup, data->paper.tmargin * 10, GTK_UNIT_MM);
+  gtk_page_setup_set_right_margin (setup, data->paper.rmargin * 10, GTK_UNIT_MM);
+  gtk_page_setup_set_bottom_margin (setup, data->paper.bmargin * 10, GTK_UNIT_MM);
+  
+}
+
+static void
+begin_print (GtkPrintOperation *operation,
+             GtkPrintContext   *context,
+             PrintData         *print_data)
+{
+  DiaCairoRenderer *cairo_renderer;
+  g_return_if_fail (print_data->renderer != NULL);
+  cairo_renderer = DIA_CAIRO_RENDERER (print_data->renderer);
+  g_return_if_fail (cairo_renderer->cr == NULL);
+
+  cairo_renderer->cr = gtk_print_context_get_cairo_context (context);
+  cairo_renderer->dia = print_data->data;
+#if 0 /* needs some text size scaling ... */
+  cairo_renderer->layout = gtk_print_context_create_pango_layout (context);
+#endif
+
+  /* scaling - as usual I don't get it, or do I? */
+  cairo_renderer->scale = (
+      gtk_page_setup_get_paper_width (gtk_print_context_get_page_setup (context), GTK_UNIT_MM) 
+      - gtk_page_setup_get_left_margin( gtk_print_context_get_page_setup (context), GTK_UNIT_MM)
+      - gtk_page_setup_get_right_margin( gtk_print_context_get_page_setup (context), GTK_UNIT_MM)
+      ) / print_data->data->paper.width;
+  cairo_renderer->skip_show_page = TRUE;
+}
+
+static void
+draw_page (GtkPrintOperation *operation,
+	   GtkPrintContext *context,
+	   int page_nr,
+	   PrintData *print_data)
+{
+  Rectangle bounds;
+  int nobjs = 0;
+  DiagramData *data = print_data->data;
+  int x, y;
+  /* the effective sizes - dia already applied is_portrait */
+  double dp_width = data->paper.width;
+  double dp_height = data->paper.height;
+
+  DiaCairoRenderer *cairo_renderer;
+  g_return_if_fail (print_data->renderer != NULL);
+  cairo_renderer = DIA_CAIRO_RENDERER (print_data->renderer);
+
+  if (data->paper.fitto) {
+    x = page_nr % data->paper.fitwidth;
+    y = page_nr / data->paper.fitwidth;
+    
+    bounds.left = dp_width * x + data->extents.left;
+    bounds.top = dp_height * y + data->extents.top;
+    bounds.right = bounds.left + dp_width;
+    bounds.bottom = bounds.top + dp_height;
+  } else {
+    int nx = ceil((data->extents.right - data->extents.left) / dp_width);
+    int ny = ceil((data->extents.bottom - data->extents.top) / dp_height);
+    x = page_nr % nx;
+    y = page_nr / nx; 
+  }
+  bounds.left = dp_width * x + data->extents.left;
+  bounds.top = dp_height * y + data->extents.top;
+  bounds.right = bounds.left + dp_width;
+  bounds.bottom = bounds.top + dp_height;
+
+#if 0 /* calls begin/end of the given renderer */
+  /* count the number of objects in this region */
+  data_render(data, print_data->renderer, &bounds,
+              (ObjectRenderer) count_objs, &nobjs);
+  if (!nobjs)
+    return; /* not printing empty pages */
+#endif
+
+  /* setup a clipping rect */
+  {
+    GtkPageSetup *setup = gtk_print_context_get_page_setup (context);
+    double left = gtk_page_setup_get_left_margin (setup, GTK_UNIT_MM);
+    double top = gtk_page_setup_get_top_margin (setup, GTK_UNIT_MM);
+    double width = gtk_page_setup_get_paper_width (setup, GTK_UNIT_MM) 
+		   - left - gtk_page_setup_get_right_margin (setup, GTK_UNIT_MM);
+    double height = gtk_page_setup_get_paper_height (setup, GTK_UNIT_MM) 
+		    - top - gtk_page_setup_get_bottom_margin (setup, GTK_UNIT_MM);
+    cairo_save (cairo_renderer->cr);
+    /* we are still in the gtk-print coordinate system */
+#if 1
+    /* ... but apparently already transalted to top,left */
+    top = left = 0;
+#endif
+    cairo_rectangle (cairo_renderer->cr, left, top, width, height);
+    
+    cairo_clip (cairo_renderer->cr);
+  }
+
+  {
+    Rectangle extents = data->extents;
+
+    data->extents = bounds;
+    /* render only the region, FIXME: better way than modifying DiagramData ?  */
+    data_render(data, print_data->renderer, &bounds, NULL, NULL);
+    data->extents = extents;
+  }
+  cairo_restore (cairo_renderer->cr);
+}
+
+static void
+end_print (GtkPrintOperation *operation,
+           GtkPrintContext   *context,
+           PrintData         *print_data)
+{
+  g_object_unref (print_data->data);
+  g_object_unref (print_data->renderer);
+
+  g_free (print_data);
+}
+
+GtkPrintOperation *
+create_print_operation (DiagramData *data, const char *name)
+{
+  PrintData *print_data;
+  GtkPrintOperation *operation;
+  GtkPageSetup * setup;
+  int num_pages;
+
+  /* gets deleted in end_print */
+  print_data = g_new0 (PrintData, 1);
+  print_data->data = g_object_ref (data);
+  print_data->renderer = g_object_new (DIA_TYPE_CAIRO_RENDERER, NULL);
+  
+  operation = gtk_print_operation_new ();
+  
+  gtk_print_operation_set_job_name (operation, name);
+
+  setup = gtk_print_operation_get_default_page_setup (operation);
+  if (!setup)
+    setup = gtk_page_setup_new ();
+  _dia_to_gtk_page_setup (print_data->data, setup);
+  gtk_print_operation_set_default_page_setup (operation, setup);
+  g_object_unref (setup);
+
+  /* similar logic draw_page() but we need to set the total pages in advance */
+  if (data->paper.fitto) {
+    num_pages = data->paper.fitwidth * data->paper.fitheight;
+  } else {
+    int nx = ceil((data->extents.right - data->extents.left) / data->paper.width);
+    int ny = ceil((data->extents.bottom - data->extents.top) / data->paper.height);
+    num_pages = nx * ny;
+  }
+  gtk_print_operation_set_n_pages (operation, num_pages);
+
+  gtk_print_operation_set_unit (operation, GTK_UNIT_MM);
+
+  g_signal_connect (operation, "draw_page", G_CALLBACK (draw_page), print_data);
+  g_signal_connect (operation, "begin_print", G_CALLBACK (begin_print), print_data);
+  g_signal_connect (operation, "end_print", G_CALLBACK (end_print), print_data);
+  
+  return operation;
+}
+
+void
+cairo_print_callback (DiagramData *data,
+                      guint flags, /* further additions */
+                      void *user_data)
+{
+  GtkPrintOperation *op = create_print_operation (data, "diagram");
+  GtkPrintOperationResult res;
+  GError *error = NULL;
+  
+  res = gtk_print_operation_run (op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, &error);
+  if (GTK_PRINT_OPERATION_RESULT_ERROR == res) {
+    message_error (error->message);
+    g_error_free (error);
+  }
+}
+
+#endif /* Gtk+ 2.10 */

Modified: trunk/plug-ins/cairo/diacairo-renderer.c
==============================================================================
--- trunk/plug-ins/cairo/diacairo-renderer.c	(original)
+++ trunk/plug-ins/cairo/diacairo-renderer.c	Sat Mar  8 22:46:52 2008
@@ -73,17 +73,6 @@
 
 #include "diacairo.h"
 
-/*
-#define DEBUG_CAIRO
- */
-#ifdef DEBUG_CAIRO
-#  define DIAG_NOTE(action) action
-#  define DIAG_STATE(cr) { if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) g_print ("%s:%d, %s\n", __FILE__, __LINE__, cairo_status_string (cr)); }
-#else
-#  define DIAG_NOTE(action)
-#  define DIAG_STATE(cr)
-#endif
-
 /* 
  * render functions 
  */ 
@@ -92,7 +81,11 @@
 {
   DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
 
-  renderer->cr = cairo_create (renderer->surface);
+  if (renderer->surface)
+    renderer->cr = cairo_create (renderer->surface);
+  else
+    g_assert (renderer->cr);
+
   cairo_scale (renderer->cr, renderer->scale, renderer->scale);
   cairo_translate (renderer->cr, -renderer->dia->extents.left, -renderer->dia->extents.top);
 
@@ -129,7 +122,8 @@
                              1.0);
     }
 #ifdef HAVE_PANGOCAIRO_H
-  renderer->layout = pango_cairo_create_layout (renderer->cr);
+  if (!renderer->layout)
+    renderer->layout = pango_cairo_create_layout (renderer->cr);
 #endif
 
   DIAG_STATE(renderer->cr)
@@ -142,9 +136,11 @@
 
   DIAG_NOTE(g_message( "end_render"));
  
-  cairo_show_page (renderer->cr);
+  if (!renderer->skip_show_page)
+    cairo_show_page (renderer->cr);
   DIAG_STATE(renderer->cr)
-  cairo_surface_destroy (renderer->surface);
+  if (renderer->surface)
+    cairo_surface_destroy (renderer->surface);
   DIAG_STATE(renderer->cr)
 }
 
@@ -958,289 +954,3 @@
   renderer_class->draw_rounded_rect = draw_rounded_rect;
   renderer_class->fill_rounded_rect = fill_rounded_rect;
 }
-
-typedef enum OutputKind
-{
-  OUTPUT_PS = 1,
-  OUTPUT_PNG,
-  OUTPUT_PNGA,
-  OUTPUT_PDF,
-  OUTPUT_WMF,
-  OUTPUT_EMF,
-  OUTPUT_CB,
-  OUTPUT_SVG
-} OutputKind;
-
-/* dia export funtion */
-static void
-export_data(DiagramData *data, const gchar *filename_utf8, 
-            const gchar *diafilename, void* user_data)
-{
-  DiaCairoRenderer *renderer;
-  FILE *file;
-  real width, height;
-  OutputKind kind = (OutputKind)user_data;
-  gchar* filename = g_locale_from_utf8 (filename_utf8, -1, NULL, NULL, NULL);
-
-  if (!filename) {
-    message_error(_("Can't convert output filename '%s' to locale encoding.\n"
-                    "Please choose a different name to save with cairo.\n"), 
-		  dia_message_filename(filename_utf8), strerror(errno));
-    return;
-  }
-  file = fopen(filename, "wb"); /* "wb" for binary! */
-
-  if (file == NULL) {
-    message_error(_("Can't open output file %s: %s\n"), 
-		  dia_message_filename(filename_utf8), strerror(errno));
-    return;
-  }
-  fclose (file);
-  renderer = g_object_new (DIA_TYPE_CAIRO_RENDERER, NULL);
-  renderer->dia = data; /* FIXME: not sure if this a good idea */
-  renderer->scale = 1.0;
-
-  switch (kind) {
-#ifdef CAIRO_HAS_PS_SURFACE
-  case OUTPUT_PS :
-    width  = data->paper.width * (72.0 / 2.54);
-    height = data->paper.height * (72.0 / 2.54);
-    renderer->scale = data->paper.scaling * (72.0 / 2.54);
-    DIAG_NOTE(g_message ("PS Surface %dx%d\n", (int)width, (int)height)); 
-    renderer->surface = cairo_ps_surface_create (filename,
-                                                 width, height); /*  in points? */
-    /* maybe we should increase the resolution here as well */
-    break;
-#endif  
-#if defined CAIRO_HAS_PNG_SURFACE || defined CAIRO_HAS_PNG_FUNCTIONS
-  case OUTPUT_PNGA :
-    renderer->with_alpha = TRUE;
-    /* fall through */
-  case OUTPUT_PNG :
-    /* quite arbitrary, but consistent with ../pixbuf ;-) */
-    renderer->scale = 20.0 * data->paper.scaling; 
-    width  = (data->extents.right - data->extents.left) * renderer->scale;
-    height = (data->extents.bottom - data->extents.top) * renderer->scale;
-
-    DIAG_NOTE(g_message ("PNG Surface %dx%d\n", (int)width, (int)height));
-    /* use case screwed by API shakeup. We need to special case */
-    renderer->surface = cairo_image_surface_create(
-						CAIRO_FORMAT_ARGB32,
-						(int)width, (int)height);
-    /* an extra refernce to make it survive end_render():cairo_surface_destroy() */
-    cairo_surface_reference(renderer->surface);
-    break;
-#endif
-#ifdef CAIRO_HAS_PDF_SURFACE
-  case OUTPUT_PDF :
-#define DPI 72.0 /* 600.0? */
-    /* I just don't get how the scaling is supposed to work, dpi versus page size ? */
-    renderer->scale = data->paper.scaling * (72.0 / 2.54);
-    width = data->paper.width * (72.0 / 2.54);
-    height = data->paper.height * (72.0 / 2.54);
-    DIAG_NOTE(g_message ("PDF Surface %dx%d\n", (int)width, (int)height));
-    renderer->surface = cairo_pdf_surface_create (filename,
-                                                  width, height);
-    cairo_surface_set_fallback_resolution (renderer->surface, DPI, DPI);
-#undef DPI
-    break;
-#endif
-#ifdef CAIRO_HAS_SVG_SURFACE
-  case OUTPUT_SVG :
-    /* quite arbitrary, but consistent with ../pixbuf ;-) */
-    renderer->scale = 20.0 * data->paper.scaling; 
-    width  = (data->extents.right - data->extents.left) * renderer->scale;
-    height = (data->extents.bottom - data->extents.top) * renderer->scale;
-    DIAG_NOTE(g_message ("SVG Surface %dx%d\n", (int)width, (int)height));
-    /* use case screwed by API shakeup. We need to special case */
-    renderer->surface = cairo_svg_surface_create(
-						filename,
-						(int)width, (int)height);
-    break;
-#endif
-  /* the default Cairo/win32 surface isn't able to do such ... */
-#ifdef CAIRO_HAS_WIN32X_SURFACE
-  case OUTPUT_EMF :
-    renderer->scale = 72.0;
-    renderer->surface = cairo_win32_surface_create (filename, NULL, CAIRO_WIN32_TARGET_EMF, 0, 0);
-    break;
-  case OUTPUT_WMF :
-    renderer->scale = 72.0;
-    renderer->surface = cairo_win32_surface_create (filename, NULL, CAIRO_WIN32_TARGET_WMF, 0, 0);
-    break;
-  case OUTPUT_CB :
-    /* just testing, does not create a file but puts content in the clpboard */
-    renderer->scale = 72.0;
-    renderer->surface = cairo_win32_surface_create (filename, NULL, CAIRO_WIN32_TARGET_CLIPBOARD, 0, 0);
-    break;
-#endif
-  default :
-    /* quite arbitrary, but consistent with ../pixbuf ;-) */
-    renderer->scale = 20.0 * data->paper.scaling; 
-    width  = (data->extents.right - data->extents.left) * renderer->scale;
-    height = (data->extents.bottom - data->extents.top) * renderer->scale;
-    DIAG_NOTE(g_message ("Image Surface %dx%d\n", (int)width, (int)height)); 
-    renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_A8, (int)width, (int)height);
-  }
-
-  /* use extents */
-  DIAG_NOTE(g_message("export_data extents %f,%f -> %f,%f", 
-            data->extents.left, data->extents.top, data->extents.right, data->extents.bottom));
-
-  data_render(data, DIA_RENDERER(renderer), NULL, NULL, NULL);
-#if defined CAIRO_HAS_PNG_FUNCTIONS
-  if (OUTPUT_PNGA == kind || OUTPUT_PNG == kind)
-    {
-      cairo_surface_write_to_png(renderer->surface, filename);
-      cairo_surface_destroy(renderer->surface);
-    }
-#endif
-  g_object_unref(renderer);
-}
-
-#ifdef CAIRO_HAS_PS_SURFACE
-static const gchar *ps_extensions[] = { "ps", NULL };
-static DiaExportFilter ps_export_filter = {
-    N_("Cairo PostScript"),
-    ps_extensions,
-    export_data,
-    (void*)OUTPUT_PS,
-    "cairo-ps" /* unique name */
-};
-#endif
-
-#ifdef CAIRO_HAS_PDF_SURFACE
-static const gchar *pdf_extensions[] = { "pdf", NULL };
-static DiaExportFilter pdf_export_filter = {
-    N_("Cairo Portable Document Format"),
-    pdf_extensions,
-    export_data,
-    (void*)OUTPUT_PDF,
-    "cairo-pdf"
-};
-#endif
-
-#ifdef CAIRO_HAS_SVG_SURFACE
-static const gchar *svg_extensions[] = { "svg", NULL };
-static DiaExportFilter svg_export_filter = {
-    N_("Cairo Scalable Vector Graphics"),
-    svg_extensions,
-    export_data,
-    (void*)OUTPUT_SVG,
-    "cairo-svg"
-};
-#endif
-
-static const gchar *png_extensions[] = { "png", NULL };
-static DiaExportFilter png_export_filter = {
-    N_("Cairo PNG"),
-    png_extensions,
-    export_data,
-    (void*)OUTPUT_PNG,
-    "cairo-png"
-};
-
-static DiaExportFilter pnga_export_filter = {
-    N_("Cairo PNG (with alpha)"),
-    png_extensions,
-    export_data,
-    (void*)OUTPUT_PNGA,
-    "cairo-alpha-png"
-};
-
-#ifdef CAIRO_HAS_WIN32X_SURFACE
-static const gchar *emf_extensions[] = { "wmf", NULL };
-static DiaExportFilter emf_export_filter = {
-    N_("Cairo WMF"),
-    emf_extensions,
-    export_data,
-    (void*)OUTPUT_EMF,
-    "cairo-emf"
-};
-
-static const gchar *wmf_extensions[] = { "wmf", NULL };
-static DiaExportFilter wmf_export_filter = {
-    N_("Cairo old WMF"),
-    wmf_extensions,
-    export_data,
-    (void*)OUTPUT_WMF,
-    "cairo-wmf"
-};
-
-static const gchar *cb_extensions[] = { "cb", NULL };
-static DiaExportFilter cb_export_filter = {
-    N_("Cairo Clipboard"),
-    cb_extensions,
-    export_data,
-    (void*)OUTPUT_CB,
-    "cairo-clipboard"
-};
-#endif /* CAIRO_HAS_WIN32X_SURFACE */
-
-static gboolean
-_plugin_can_unload (PluginInfo *info)
-{
-  /* Can't unlaod as long as we are giving away our types, e.g. dia_cairo_interactive_renderer_get_type () */
-  return FALSE;
-}
-
-static void
-_plugin_unload (PluginInfo *info)
-{
-#ifdef CAIRO_HAS_PS_SURFACE
-  filter_unregister_export(&ps_export_filter);
-#endif
-#ifdef CAIRO_HAS_PDF_SURFACE
-  filter_unregister_export(&pdf_export_filter);
-#endif
-#ifdef CAIRO_HAS_SVG_SURFACE
-  filter_unregister_export(&svg_export_filter);
-#endif
-#if defined CAIRO_HAS_PNG_SURFACE || defined CAIRO_HAS_PNG_FUNCTIONS
-  filter_unregister_export(&png_export_filter);
-  filter_unregister_export(&pnga_export_filter);
-#endif
-#ifdef CAIRO_HAS_WIN32X_SURFACE
-  filter_unregister_export(&emf_export_filter);
-  filter_unregister_export(&wmf_export_filter);
-  filter_unregister_export(&cb_export_filter);
-#endif
-}
-
-/* --- dia plug-in interface --- */
-
-DIA_PLUGIN_CHECK_INIT
-
-PluginInitResult
-dia_plugin_init(PluginInfo *info)
-{
-  if (!dia_plugin_info_init(info, "Cairo",
-                            _("Cairo based Rendering"),
-                            _plugin_can_unload,
-                            _plugin_unload))
-    return DIA_PLUGIN_INIT_ERROR;
-
-#ifdef CAIRO_HAS_PS_SURFACE
-  filter_register_export(&ps_export_filter);
-#endif
-#ifdef CAIRO_HAS_PDF_SURFACE
-  filter_register_export(&pdf_export_filter);
-#endif
-#ifdef CAIRO_HAS_SVG_SURFACE
-  filter_register_export(&svg_export_filter);
-#endif
-#if defined CAIRO_HAS_PNG_SURFACE || defined CAIRO_HAS_PNG_FUNCTIONS
-  filter_register_export(&png_export_filter);
-  filter_register_export(&pnga_export_filter);
-#endif
-#ifdef CAIRO_HAS_WIN32X_SURFACE
-  filter_register_export(&emf_export_filter);
-  filter_register_export(&wmf_export_filter);
-  filter_register_export(&cb_export_filter);
-#endif
-
-  /* FIXME: need to think about of proper way of registartion, see also app/display.c */
-  dia_cairo_interactive_renderer_get_type ();
-  
-  return DIA_PLUGIN_INIT_OK;
-}

Modified: trunk/plug-ins/cairo/diacairo.c
==============================================================================
--- trunk/plug-ins/cairo/diacairo.c	(original)
+++ trunk/plug-ins/cairo/diacairo.c	Sat Mar  8 22:46:52 2008
@@ -72,892 +72,7 @@
 #include "plug-ins.h"
 
 #include "diacairo.h"
-
-/*
-#define DEBUG_CAIRO
- */
-#ifdef DEBUG_CAIRO
-#  define DIAG_NOTE(action) action
-#  define DIAG_STATE(cr) { if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) g_print ("%s:%d, %s\n", __FILE__, __LINE__, cairo_status_string (cr)); }
-#else
-#  define DIAG_NOTE(action)
-#  define DIAG_STATE(cr)
-#endif
-
-/* 
- * render functions 
- */ 
-static void
-begin_render(DiaRenderer *self)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  renderer->cr = cairo_create (renderer->surface);
-  cairo_scale (renderer->cr, renderer->scale, renderer->scale);
-  cairo_translate (renderer->cr, -renderer->dia->extents.left, -renderer->dia->extents.top);
-
-  /* clear background */
-  if (renderer->with_alpha)
-    {
-      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_SOURCE);
-      cairo_set_source_rgba (renderer->cr,
-                             renderer->dia->bg_color.red, 
-                             renderer->dia->bg_color.green, 
-                             renderer->dia->bg_color.blue,
-                             0.0);
-    }
-  else
-    {
-      cairo_set_source_rgba (renderer->cr,
-                             renderer->dia->bg_color.red, 
-                             renderer->dia->bg_color.green, 
-                             renderer->dia->bg_color.blue,
-                             1.0);
-    }
-  cairo_rectangle (renderer->cr, 
-                   renderer->dia->extents.left, renderer->dia->extents.top,
-                   renderer->dia->extents.right, renderer->dia->extents.bottom);
-  cairo_fill (renderer->cr);
-  if (renderer->with_alpha)
-    {
-      /* restore to default drawing */
-      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_OVER);
-      cairo_set_source_rgba (renderer->cr,
-                             renderer->dia->bg_color.red, 
-                             renderer->dia->bg_color.green, 
-                             renderer->dia->bg_color.blue,
-                             1.0);
-    }
-#ifdef HAVE_PANGOCAIRO_H
-  renderer->layout = pango_cairo_create_layout (renderer->cr);
-#endif
-
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-end_render(DiaRenderer *self)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  DIAG_NOTE(g_message( "end_render"));
- 
-  cairo_show_page (renderer->cr);
-  DIAG_STATE(renderer->cr)
-  cairo_surface_destroy (renderer->surface);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-set_linewidth(DiaRenderer *self, real linewidth)
-{  
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  DIAG_NOTE(g_message("set_linewidth %f", linewidth));
-
-  cairo_set_line_width (renderer->cr, linewidth);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-set_linecaps(DiaRenderer *self, LineCaps mode)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  DIAG_NOTE(g_message("set_linecaps %d", mode));
-
-  switch(mode) {
-  case LINECAPS_BUTT:
-    cairo_set_line_cap (renderer->cr, CAIRO_LINE_CAP_BUTT);
-    break;
-  case LINECAPS_ROUND:
-    cairo_set_line_cap (renderer->cr, CAIRO_LINE_CAP_ROUND);
-    break;
-  case LINECAPS_PROJECTING:
-    cairo_set_line_cap (renderer->cr, CAIRO_LINE_CAP_SQUARE); /* ?? */
-    break;
-  default:
-    message_error("DiaCairoRenderer : Unsupported caps mode specified!\n");
-  }
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-set_linejoin(DiaRenderer *self, LineJoin mode)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  DIAG_NOTE(g_message("set_join %d", mode));
-
-  switch(mode) {
-  case LINEJOIN_MITER:
-    cairo_set_line_join (renderer->cr, CAIRO_LINE_JOIN_MITER);
-    break;
-  case LINEJOIN_ROUND:
-    cairo_set_line_join (renderer->cr, CAIRO_LINE_JOIN_ROUND);
-    break;
-  case LINEJOIN_BEVEL:
-    cairo_set_line_join (renderer->cr, CAIRO_LINE_JOIN_BEVEL);
-    break;
-  default:
-    message_error("DiaCairoRenderer : Unsupported join mode specified!\n");
-  }
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-set_linestyle(DiaRenderer *self, LineStyle mode)
-{
-  /* dot = 10% of len */
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  double dash[6];
-
-  DIAG_NOTE(g_message("set_linestyle %d", mode));
-
-  /* line type */
-  switch (mode) {
-  case LINESTYLE_SOLID:
-    cairo_set_dash (renderer->cr, NULL, 0, 0);
-    break;
-  case LINESTYLE_DASHED:
-    dash[0] = renderer->dash_length;
-    dash[1] = renderer->dash_length;
-    cairo_set_dash (renderer->cr, dash, 2, 0);
-    break;
-  case LINESTYLE_DASH_DOT:
-    dash[0] = renderer->dash_length;
-    dash[1] = renderer->dash_length * 0.45;
-    dash[2] = renderer->dash_length * 0.1;
-    dash[3] = renderer->dash_length * 0.45;
-    cairo_set_dash (renderer->cr, dash, 4, 0);
-    break;
-  case LINESTYLE_DASH_DOT_DOT:
-    dash[0] = renderer->dash_length;
-    dash[1] = renderer->dash_length * (0.8/3);
-    dash[2] = renderer->dash_length * 0.1;
-    dash[3] = renderer->dash_length * (0.8/3);
-    dash[4] = renderer->dash_length * 0.1;
-    dash[5] = renderer->dash_length * (0.8/3);
-    cairo_set_dash (renderer->cr, dash, 6, 0);
-    break;
-  case LINESTYLE_DOTTED:
-    dash[0] = renderer->dash_length * 0.1;
-    dash[1] = renderer->dash_length * 0.1;
-    cairo_set_dash (renderer->cr, dash, 2, 0);
-    break;
-  default:
-    message_error("DiaCairoRenderer : Unsupported line style specified!\n");
-  }
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-set_dashlength(DiaRenderer *self, real length)
-{  
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  DIAG_NOTE(g_message("set_dashlength %f", length));
-
-  renderer->dash_length = length;
-}
-
-static void
-set_fillstyle(DiaRenderer *self, FillStyle mode)
-{
-  DIAG_NOTE(g_message("set_fillstyle %d", mode));
-
-  switch(mode) {
-  case FILLSTYLE_SOLID:
-    /* FIXME: how to set _no_ pattern ?
-      * cairo_set_pattern (renderer->cr, NULL);
-      */
-    break;
-  default:
-    message_error("DiaCairoRenderer : Unsupported fill mode specified!\n");
-  }
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-set_font(DiaRenderer *self, DiaFont *font, real height)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  DiaFontStyle style = dia_font_get_style (font);
-
-  PangoFontDescription *pfd = pango_font_description_copy (dia_font_get_description (font));
-  const char *family_name;
-  DIAG_NOTE(g_message("set_font %f %s", height, dia_font_get_family(font)));
-
-#ifdef HAVE_PANGOCAIRO_H
-  /* select font and size */
-  pango_font_description_set_size (pfd, (int)(height * 0.7 * PANGO_SCALE)); /* same magic factor as in lib/font.c */
-  pango_layout_set_font_description (renderer->layout, pfd);
-  pango_font_description_free (pfd);
-#else
-  family_name = dia_font_get_family(font);
-
-  cairo_select_font_face (
-      renderer->cr,
-      family_name,
-      DIA_FONT_STYLE_GET_SLANT(style) == DIA_FONT_NORMAL ? CAIRO_FONT_SLANT_NORMAL : CAIRO_FONT_SLANT_ITALIC,
-      DIA_FONT_STYLE_GET_WEIGHT(style) < DIA_FONT_MEDIUM ? CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD); 
-  cairo_set_font_size (renderer->cr, height * 0.7); /* same magic factor as in lib/font.c */
-#endif
-
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-draw_line(DiaRenderer *self, 
-          Point *start, Point *end, 
-          Color *color)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  DIAG_NOTE(g_message("draw_line %f,%f -> %f, %f", 
-            start->x, start->y, end->x, end->y));
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-  cairo_move_to (renderer->cr, start->x, start->y);
-  cairo_line_to (renderer->cr, end->x, end->y);
-  cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-draw_polyline(DiaRenderer *self, 
-              Point *points, int num_points, 
-              Color *color)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  int i;
-
-  DIAG_NOTE(g_message("draw_polyline n:%d %f,%f ...", 
-            num_points, points->x, points->y));
-
-  g_return_if_fail(1 < num_points);
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-
-  cairo_new_path (renderer->cr);
-  /* point data */
-  cairo_move_to (renderer->cr, points[0].x, points[0].y);
-  for (i = 1; i < num_points; i++)
-    {
-      cairo_line_to (renderer->cr, points[i].x, points[i].y);
-    }
-  cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-_polygon(DiaRenderer *self, 
-         Point *points, int num_points, 
-         Color *color,
-         gboolean fill)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  int i;
-
-  DIAG_NOTE(g_message("%s_polygon n:%d %f,%f ...",
-            fill ? "fill" : "draw",
-            num_points, points->x, points->y));
-
-  g_return_if_fail(1 < num_points);
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-
-  cairo_new_path (renderer->cr);
-  /* point data */
-  cairo_move_to (renderer->cr, points[0].x, points[0].y);
-  for (i = 1; i < num_points; i++)
-    {
-      cairo_line_to (renderer->cr, points[i].x, points[i].y);
-    }
-  cairo_line_to (renderer->cr, points[0].x, points[0].y);
-  cairo_close_path (renderer->cr);
-  if (fill)
-    cairo_fill (renderer->cr);
-  else
-    cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-draw_polygon(DiaRenderer *self, 
-             Point *points, int num_points, 
-             Color *color)
-{
-  _polygon (self, points, num_points, color, FALSE);
-}
-
-static void
-fill_polygon(DiaRenderer *self, 
-             Point *points, int num_points, 
-             Color *color)
-{
-  _polygon (self, points, num_points, color, TRUE);
-}
-
-static void
-_rect(DiaRenderer *self, 
-      Point *ul_corner, Point *lr_corner,
-      Color *color,
-      gboolean fill)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-
-  DIAG_NOTE(g_message("%s_rect %f,%f -> %f,%f", 
-            fill ? "fill" : "draw",
-            ul_corner->x, ul_corner->y, lr_corner->x, lr_corner->y));
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-  
-  cairo_rectangle (renderer->cr, 
-                   ul_corner->x, ul_corner->y, 
-                   lr_corner->x - ul_corner->x, lr_corner->y - ul_corner->y);
-
-  if (fill)
-    cairo_fill (renderer->cr);
-  else
-    cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-draw_rect(DiaRenderer *self, 
-          Point *ul_corner, Point *lr_corner,
-          Color *color)
-{
-  _rect (self, ul_corner, lr_corner, color, FALSE);
-}
-
-static void
-fill_rect(DiaRenderer *self, 
-          Point *ul_corner, Point *lr_corner,
-          Color *color)
-{
-  _rect (self, ul_corner, lr_corner, color, TRUE);
-}
-
-static void
-draw_arc(DiaRenderer *self, 
-	 Point *center,
-	 real width, real height,
-	 real angle1, real angle2,
-	 Color *color)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  Point start;
-  double a1, a2;
-
-  DIAG_NOTE(g_message("draw_arc %fx%f <%f,<%f", 
-            width, height, angle1, angle2));
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-
-  /* Dia and Cairo don't agree on arc definitions, so it needs
-   * to be converted, i.e. mirrored at the x axis
-   */
-  cairo_new_path (renderer->cr);
-  start.x = center->x + (width / 2.0)  * cos((M_PI / 180.0) * angle1);
-  start.y = center->y - (height / 2.0) * sin((M_PI / 180.0) * angle1);
-  cairo_move_to (renderer->cr, start.x, start.y);
-  a1 = - (angle1 / 180.0) * G_PI;
-  a2 = - (angle2 / 180.0) * G_PI;
-  /* FIXME: to handle width != height some cairo_scale/cairo_translate would be needed */
-  cairo_arc_negative (renderer->cr, center->x, center->y, 
-                      width > height ? height / 2.0 : width / 2.0, /* FIXME 2nd radius */
-                      a1, a2);
-  cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-fill_arc(DiaRenderer *self, 
-         Point *center,
-         real width, real height,
-         real angle1, real angle2,
-         Color *color)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  Point start;
-  double a1, a2;
-
-  DIAG_NOTE(g_message("draw_arc %fx%f <%f,<%f", 
-            width, height, angle1, angle2));
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-  
-  cairo_new_path (renderer->cr);
-  start.x = center->x + (width / 2.0)  * cos((M_PI / 180.0) * angle1);
-  start.y = center->y - (height / 2.0) * sin((M_PI / 180.0) * angle1);
-  cairo_move_to (renderer->cr, center->x, center->y);
-  cairo_line_to (renderer->cr, start.x, start.y);
-  a1 = - (angle1 / 180.0) * G_PI;
-  a2 = - (angle2 / 180.0) * G_PI;
-  /* FIXME: to handle width != height some cairo_scale/cairo_translate would be needed */
-  cairo_arc_negative (renderer->cr, center->x, center->y, 
-                      width > height ? height / 2.0 : width / 2.0, /* FIXME 2nd radius */
-                      a1, a2);
-  cairo_line_to (renderer->cr, center->x, center->y);
-  cairo_close_path (renderer->cr);
-  cairo_fill (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-_ellipse(DiaRenderer *self, 
-         Point *center,
-         real width, real height,
-         Color *color,
-         gboolean fill)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  double co;
-
-  DIAG_NOTE(g_message("%s_ellipse %fx%f center @ %f,%f", 
-            fill ? "fill" : "draw", width, height, center->x, center->y));
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-  
-  /* FIXME: how to make a perfect ellipse from a bezier ? */
-  co = sqrt(pow(width,2)/4 + pow(height,2)/4);
-
-  cairo_new_path (renderer->cr);
-  cairo_move_to (renderer->cr,
-                 center->x, center->y - height/2);
-  cairo_curve_to (renderer->cr,
-                  center->x + co, center->y - height/2,
-                  center->x + co, center->y + height/2,
-                  center->x, center->y + height/2);
-  cairo_curve_to (renderer->cr,
-                  center->x - co, center->y + height/2,
-                  center->x - co, center->y - height/2,
-                  center->x, center->y - height/2);
-  if (fill)
-    cairo_fill (renderer->cr);
-  else
-    cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-draw_ellipse(DiaRenderer *self, 
-             Point *center,
-             real width, real height,
-             Color *color)
-{
-  _ellipse (self, center, width, height, color, FALSE);
-}
-
-static void
-fill_ellipse(DiaRenderer *self, 
-             Point *center,
-             real width, real height,
-             Color *color)
-{
-  _ellipse (self, center, width, height, color, TRUE);
-}
-
-static void
-_bezier(DiaRenderer *self, 
-        BezPoint *points,
-        int numpoints,
-        Color *color,
-        gboolean fill)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  int i;
-
-  DIAG_NOTE(g_message("%s_bezier n:%d %fx%f ...", 
-            fill ? "fill" : "draw", numpoints, points->p1.x, points->p1.y));
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-
-  cairo_new_path (renderer->cr);
-  for (i = 0; i < numpoints; i++)
-  {
-    switch (points[i].type)
-    {
-    case BEZ_MOVE_TO:
-      cairo_move_to (renderer->cr, points[i].p1.x, points[i].p1.y);
-      break;
-    case BEZ_LINE_TO:
-      cairo_line_to (renderer->cr, points[i].p1.x, points[i].p1.y);
-      break;
-    case BEZ_CURVE_TO:
-      cairo_curve_to (renderer->cr, 
-                      points[i].p1.x, points[i].p1.y,
-                      points[i].p2.x, points[i].p2.y,
-                      points[i].p3.x, points[i].p3.y);
-      break;
-    default :
-      g_assert_not_reached ();
-    }
-  }
-
-  if (fill)
-    cairo_fill (renderer->cr);
-  else
-    cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-draw_bezier(DiaRenderer *self, 
-            BezPoint *points,
-            int numpoints,
-            Color *color)
-{
-  _bezier (self, points, numpoints, color, FALSE);
-}
-
-static void
-fill_bezier(DiaRenderer *self, 
-            BezPoint *points,
-            int numpoints,
-            Color *color)
-{
-  _bezier (self, points, numpoints, color, TRUE);
-}
-
-static void
-draw_string(DiaRenderer *self,
-            const char *text,
-            Point *pos, Alignment alignment,
-            Color *color)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  cairo_text_extents_t extents;
-  double x = 0, y = 0;
-  int len = strlen(text);
-  PangoRectangle logical_rect;
-
-  DIAG_NOTE(g_message("draw_string(%d) %f,%f %s", 
-            len, pos->x, pos->y, text));
-
-  if (len < 1) return; /* shouldn't this be handled by Dia's core ? */
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-#ifdef HAVE_PANGOCAIRO_H
-  /* alignment calculation done by pangocairo? */
-  pango_layout_set_alignment (renderer->layout, alignment == ALIGN_CENTER ? PANGO_ALIGN_CENTER :
-                                                alignment == ALIGN_RIGHT ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT);
-  pango_layout_set_text (renderer->layout, text, len);
-  {
-    PangoLayoutIter *iter = pango_layout_get_iter(renderer->layout);
-    int bline = pango_layout_iter_get_baseline(iter);
-    /* although we give the alignment above we need to adjust the start point */
-    PangoRectangle extents;
-    int shift;
-    pango_layout_iter_get_line_extents (iter, NULL, &extents);
-    shift = alignment == ALIGN_CENTER ? PANGO_RBEARING(extents)/2 :
-            alignment == ALIGN_RIGHT ? PANGO_RBEARING(extents) : 0;
-    cairo_move_to (renderer->cr, pos->x - (double)shift / PANGO_SCALE, pos->y - (double)bline / PANGO_SCALE);
-    pango_layout_iter_free (iter);
-  }
-  pango_cairo_show_layout (renderer->cr, renderer->layout);
-#else
-  /* using the 'toy API' */
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-  cairo_text_extents (renderer->cr,
-                      text,
-                      &extents);
-
-  y = pos->y; /* ?? */
-
-  switch (alignment) {
-  case ALIGN_LEFT:
-    x = pos->x;
-    break;
-  case ALIGN_CENTER:
-    x = pos->x - extents.width / 2 + +extents.x_bearing;
-    break;
-  case ALIGN_RIGHT:
-    x = pos->x - extents.width + extents.x_bearing;
-    break;
-  }
-
-  cairo_move_to (renderer->cr, x, y);
-  cairo_show_text (renderer->cr, text);
-#endif
-
-  DIAG_STATE(renderer->cr)
-}
-
-static void
-draw_image(DiaRenderer *self,
-           Point *point,
-           real width, real height,
-           DiaImage image)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  cairo_surface_t *surface;
-  guint8 *data;
-  int w = dia_image_width(image);
-  int h = dia_image_height(image);
-  int rs = dia_image_rowstride(image);
-
-  DIAG_NOTE(g_message("draw_image %fx%f [%d(%d),%d] @%f,%f", 
-            width, height, w, rs, h, point->x, point->y));
-
-  if (dia_image_rgba_data (image))
-    {
-      const guint8 *p1 = dia_image_rgba_data (image);
-      /* we need to make a copy to rearrange channels 
-       * (also need to use malloc, cause Cairo insists to free() it)
-       */
-      guint8 *p2 = data = g_malloc (h * rs);
-      int i;
-
-      for (i = 0; i < (h * rs) / 4; i++)
-        {
-#  if G_BYTE_ORDER == G_LITTLE_ENDIAN
-          p2[0] = p1[2]; /* b */
-          p2[1] = p1[1]; /* g */
-          p2[2] = p1[0]; /* r */
-          p2[3] = p1[3]; /* a */
-#  else
-          p2[3] = p1[2]; /* b */
-          p2[2] = p1[1]; /* g */
-          p2[1] = p1[0]; /* r */
-          p2[0] = p1[3]; /* a */
-#  endif
-          p1+=4;
-          p2+=4;
-        }
-
-      surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, w, h, rs);
-    }
-  else
-    {
-      guint8 *p, *p2;
-      guint8 *p1 = data = dia_image_rgb_data (image);
-      /* need to copy to be owned by cairo/pixman, urgh.
-       * Also cairo wants RGB24 32 bit aligned
-       */
-      int x, y;
-
-      p = p2 = g_malloc(h*w*4);
-      for (y = 0; y < h; y++)
-        {
-          for (x = 0; x < w; x++)
-            {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-              /* apparently BGR is required */
-              p2[x*4  ] = p1[x*3+2];
-              p2[x*4+1] = p1[x*3+1];
-              p2[x*4+2] = p1[x*3  ];
-              p2[x*4+3] = 0x80; /* should not matter */
-#else
-              p2[x*4+3] = p1[x*3+2];
-              p2[x*4+2] = p1[x*3+1];
-              p2[x*4+1] = p1[x*3  ];
-              p2[x*4+0] = 0x80; /* should not matter */
-#endif
-            }
-          p2 += (w*4);
-          p1 += rs;
-        }
-      surface = cairo_image_surface_create_for_data (p, CAIRO_FORMAT_RGB24, w, h, w*4);
-      g_free (data);
-      data = p;
-    }
-  cairo_save (renderer->cr);
-  cairo_translate (renderer->cr, point->x, point->y);
-  cairo_scale (renderer->cr, width/w, height/h);
-  cairo_move_to (renderer->cr, 0.0, 0.0);
-  /* maybe just the second set_filter is required */
-#if 0
-  cairo_surface_set_filter (renderer->surface, CAIRO_FILTER_BEST);
-  cairo_surface_set_filter (surface, CAIRO_FILTER_BEST);
-#endif
-  cairo_set_source_surface (renderer->cr, surface, 0.0, 0.0);
-  cairo_paint (renderer->cr);
-  cairo_restore (renderer->cr);
-  cairo_surface_destroy (surface);
-
-  g_free (data);
-
-  DIAG_STATE(renderer->cr);
-}
-
-static void 
-_rounded_rect (DiaRenderer *self,
-               Point *topleft, Point *bottomright,
-               Color *color, real radius,
-               gboolean fill)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
-  real r2;
-
-  radius = MIN(radius, (bottomright->x - topleft->x)/2);
-  radius = MIN(radius, (bottomright->y - topleft->y)/2);
-  r2 = radius/2;
-
-  DIAG_NOTE(g_message("%s_rounded_rect %f,%f -> %f,%f, %f", 
-            fill ? "fill" : "draw",
-            topleft->x, topleft->y, bottomright->x, bottomright->y, radius));
-
-  cairo_set_source_rgba (renderer->cr, color->red, color->green, color->blue, 1.0);
-
-  cairo_new_path (renderer->cr);
-  cairo_move_to (renderer->cr,
-                 topleft->x + radius, topleft->y);
-
-  /* corners are _not_ control points, but halfway */
-  cairo_line_to  (renderer->cr,
-                  bottomright->x - radius, topleft->y);
-  cairo_curve_to (renderer->cr,
-                  bottomright->x - r2, topleft->y, bottomright->x, topleft->y + r2,
-                  bottomright->x, topleft->y + radius);
-  cairo_line_to  (renderer->cr,
-                  bottomright->x, bottomright->y - radius);
-  cairo_curve_to (renderer->cr,
-                  bottomright->x, bottomright->y - r2, bottomright->x - r2, bottomright->y,
-                  bottomright->x - radius, bottomright->y);
-  cairo_line_to  (renderer->cr,
-                  topleft->x + radius, bottomright->y);
-  cairo_curve_to (renderer->cr,
-                  topleft->x + r2, bottomright->y, topleft->x, bottomright->y - r2,
-                  topleft->x, bottomright->y - radius);
-  cairo_line_to  (renderer->cr,
-                  topleft->x, topleft->y + radius); 
-  cairo_curve_to (renderer->cr,
-                  topleft->x, topleft->y + r2, topleft->x + r2, topleft->y,
-                  topleft->x + radius, topleft->y);
-  if (fill)
-    cairo_fill (renderer->cr);
-  else
-    cairo_stroke (renderer->cr);
-  DIAG_STATE(renderer->cr)
-}
-
-static void 
-draw_rounded_rect (DiaRenderer *renderer,
-                   Point *topleft, Point *bottomright,
-                   Color *color, real radius)
-{
-  _rounded_rect (renderer, topleft, bottomright, color, radius, FALSE);
-}
-
-static void 
-fill_rounded_rect (DiaRenderer *renderer,
-                   Point *topleft, Point *bottomright,
-                   Color *color, real radius)
-{
-  _rounded_rect (renderer, topleft, bottomright, color, radius, TRUE);
-}
-
-/* gobject boiler plate */
-static void cairo_renderer_init (DiaCairoRenderer *r, void *p);
-static void cairo_renderer_class_init (DiaCairoRendererClass *klass);
-
-static gpointer parent_class = NULL;
-
-GType
-dia_cairo_renderer_get_type (void)
-{
-  static GType object_type = 0;
-
-  if (!object_type)
-    {
-      static const GTypeInfo object_info =
-      {
-        sizeof (DiaCairoRendererClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) cairo_renderer_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (DiaCairoRenderer),
-        0,              /* n_preallocs */
-	(GInstanceInitFunc)cairo_renderer_init /* init */
-      };
-
-      object_type = g_type_register_static (DIA_TYPE_RENDERER,
-                                            "DiaCairoRenderer",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
-}
-
-static void
-cairo_renderer_init (DiaCairoRenderer *renderer, void *p)
-{
-  /*
-   * Initialize fields where 0 init isn't good enough. Bug #151716
-   * appears to show that we are sometimes called to render a line
-   * without setting the linestyle first. Probably a bug elsewhere
-   * but it's this plug-in which hangs ;)
-   */
-  renderer->dash_length = 1.0;
-  renderer->scale = 1.0;
-}
-
-static void
-cairo_renderer_finalize (GObject *object)
-{
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (object);
-
-  cairo_destroy (renderer->cr);
-#ifdef HAVE_PANGOCAIRO_H
-  if (renderer->layout)
-    g_object_unref (renderer->layout);  
-#endif
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-cairo_renderer_class_init (DiaCairoRendererClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  DiaRendererClass *renderer_class = DIA_RENDERER_CLASS (klass);
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = cairo_renderer_finalize;
-
-  /* renderer members */
-  renderer_class->begin_render = begin_render;
-  renderer_class->end_render   = end_render;
-
-  renderer_class->set_linewidth  = set_linewidth;
-  renderer_class->set_linecaps   = set_linecaps;
-  renderer_class->set_linejoin   = set_linejoin;
-  renderer_class->set_linestyle  = set_linestyle;
-  renderer_class->set_dashlength = set_dashlength;
-  renderer_class->set_fillstyle  = set_fillstyle;
-
-  renderer_class->set_font  = set_font;
-
-  renderer_class->draw_line    = draw_line;
-  renderer_class->fill_polygon = fill_polygon;
-  renderer_class->draw_rect    = draw_rect;
-  renderer_class->fill_rect    = fill_rect;
-  renderer_class->draw_arc     = draw_arc;
-  renderer_class->fill_arc     = fill_arc;
-  renderer_class->draw_ellipse = draw_ellipse;
-  renderer_class->fill_ellipse = fill_ellipse;
-
-  renderer_class->draw_string  = draw_string;
-  renderer_class->draw_image   = draw_image;
-
-  /* medium level functions */
-  renderer_class->draw_rect = draw_rect;
-  renderer_class->draw_polyline  = draw_polyline;
-  renderer_class->draw_polygon   = draw_polygon;
-
-  renderer_class->draw_bezier   = draw_bezier;
-  renderer_class->fill_bezier   = fill_bezier;
-
-  /* highest level functions */
-  renderer_class->draw_rounded_rect = draw_rounded_rect;
-  renderer_class->fill_rounded_rect = fill_rounded_rect;
-}
+#include "diacairo-print.h"
 
 typedef enum OutputKind
 {
@@ -1098,6 +213,32 @@
   g_object_unref(renderer);
 }
 
+static void
+export_print_data (DiagramData *data, const gchar *filename_utf8, 
+                   const gchar *diafilename, void* user_data)
+{
+  OutputKind kind = (OutputKind)user_data;
+#if GTK_CHECK_VERSION (2,10,0)
+  GtkPrintOperation *op = create_print_operation (data, filename_utf8);
+  GtkPrintOperationResult res;
+  GError *error = NULL;
+
+# ifdef CAIRO_HAS_PDF_SURFACE
+  /* as of this writing the only format Gtk+ supports here is PDF */
+  g_assert (OUTPUT_PDF == kind);
+# endif
+  
+  gtk_print_operation_set_export_filename (op, filename_utf8);
+  res = gtk_print_operation_run (op, GTK_PRINT_OPERATION_ACTION_EXPORT, NULL, &error);
+  if (GTK_PRINT_OPERATION_RESULT_ERROR == res) {
+    message_error (error->message);
+    g_error_free (error);
+  }
+#else
+  message_error (_("Printing with Gtk+(cairo) requires at least version 2.10."));
+#endif
+}
+
 #ifdef CAIRO_HAS_PS_SURFACE
 static const gchar *ps_extensions[] = { "ps", NULL };
 static DiaExportFilter ps_export_filter = {
@@ -1114,7 +255,11 @@
 static DiaExportFilter pdf_export_filter = {
     N_("Cairo Portable Document Format"),
     pdf_extensions,
+# if GTK_CHECK_VERSION (2,10,0)
+    export_print_data,
+# else
     export_data,
+# endif
     (void*)OUTPUT_PDF,
     "cairo-pdf"
 };
@@ -1177,6 +322,16 @@
 };
 #endif /* CAIRO_HAS_WIN32X_SURFACE */
 
+#if GTK_CHECK_VERSION (2,10,0)
+static DiaCallbackFilter cb_gtk_print = {
+    "GtkCairoPrintAction",
+    N_("Print via Gtk+/cairo ..."),
+    "/DisplayMenu/File/FileExtensionStart",
+    cairo_print_callback,
+    (void*)OUTPUT_PDF
+};
+#endif
+
 static gboolean
 _plugin_can_unload (PluginInfo *info)
 {
@@ -1239,6 +394,10 @@
   filter_register_export(&cb_export_filter);
 #endif
 
+#if GTK_CHECK_VERSION (2,10,0)
+  filter_register_callback (&cb_gtk_print);
+#endif
+
   /* FIXME: need to think about of proper way of registartion, see also app/display.c */
   dia_cairo_interactive_renderer_get_type ();
   

Modified: trunk/plug-ins/cairo/diacairo.h
==============================================================================
--- trunk/plug-ins/cairo/diacairo.h	(original)
+++ trunk/plug-ins/cairo/diacairo.h	Sat Mar  8 22:46:52 2008
@@ -22,6 +22,17 @@
 #include <cairo.h>
 #include "diarenderer.h"
 
+/*
+#define DEBUG_CAIRO
+ */
+#ifdef DEBUG_CAIRO
+#  define DIAG_NOTE(action) action
+#  define DIAG_STATE(cr) { if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) g_print ("%s:%d, %s\n", __FILE__, __LINE__, cairo_status_string (cr)); }
+#else
+#  define DIAG_NOTE(action)
+#  define DIAG_STATE(cr)
+#endif
+
 /* --- the renderer base class --- */
 G_BEGIN_DECLS
 
@@ -40,14 +51,15 @@
 {
   DiaRenderer parent_instance;
 
-  cairo_t *cr;
-  cairo_surface_t *surface;
+  cairo_t *cr; /**< if NULL it gest created from the surface */
+  cairo_surface_t *surface; /**< can be NULL to use the provived cr */
  
   double dash_length;
   DiagramData *dia;
 
   real scale;
   gboolean with_alpha;
+  gboolean skip_show_page; /**< when using for print avoid the internal show_page */
   
   /** caching the font description from set_font */
   PangoLayout *layout;

Modified: trunk/plug-ins/makefile.msc
==============================================================================
--- trunk/plug-ins/makefile.msc	(original)
+++ trunk/plug-ins/makefile.msc	Sat Mar  8 22:46:52 2008
@@ -51,6 +51,7 @@
 OBJECTS = \
 	diacairo.obj \
 	diacairo-interactive.obj \
+	diacairo-renderer.obj \
 	diacairo-print.obj
 !ENDIF
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]