dia r3904 - in trunk: . data plug-ins plug-ins/cairo
- From: hans svn gnome org
- To: svn-commits-list gnome org
- Subject: dia r3904 - in trunk: . data plug-ins plug-ins/cairo
- Date: Sat, 8 Mar 2008 22:46:52 +0000 (GMT)
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]