Code

cairo ps output patch
authortheAdib <theAdib@users.sourceforge.net>
Wed, 9 May 2007 20:18:12 +0000 (20:18 +0000)
committertheAdib <theAdib@users.sourceforge.net>
Wed, 9 May 2007 20:18:12 +0000 (20:18 +0000)
src/extension/extension.h
src/extension/init.cpp
src/extension/internal/Makefile_insert
src/extension/internal/cairo-ps-out.cpp [new file with mode: 0644]
src/extension/internal/cairo-ps-out.h [new file with mode: 0644]
src/extension/internal/cairo-render-context.cpp
src/extension/internal/cairo-render-context.h

index 81629a2dcaa53b386c0579479c55907c9ef91536..dcd82372be8d98513efe60e4f3e2da2c5f0b89df 100644 (file)
@@ -43,6 +43,7 @@
 
 /** Defines the key for Postscript printing */
 #define SP_MODULE_KEY_PRINT_PS    "org.inkscape.print.ps"
+#define SP_MODULE_KEY_PRINT_CAIRO_PS   "org.inkscape.print.ps.cairo"
 /** Defines the key for PDF printing */
 #define SP_MODULE_KEY_PRINT_PDF    "org.inkscape.print.pdf"
 #define SP_MODULE_KEY_PRINT_CAIRO_PDF  "org.inkscape.print.pdf.cairo"
index ddbf308eecef18290b2a95b59d10d9fefa570eef..75f825f243d5d8f7508dc6b1945a3f61fb17f8b6 100644 (file)
@@ -41,6 +41,7 @@
 # include "internal/cairo-pdf-out.h"
 # include "internal/cairo-renderer-pdf-out.h"
 # include "internal/cairo-png-out.h"
+# include "internal/cairo-ps-out.h"
 #endif
 #include "internal/pov-out.h"
 #include "internal/odf.h"
@@ -121,6 +122,7 @@ init()
     Internal::CairoRendererPdfOutput::init();
     Internal::CairoRendererOutput::init();
     }
+    Internal::CairoPsOutput::init();
 #endif
 #ifdef WITH_GNOME_PRINT
     Internal::PrintGNOME::init();
index 7b5e9cc6d303aa60782c21569f9eb2f3ef4c61a0..6c4dc9556dfd6f6f5081062ecf6e4e64d2e16158 100644 (file)
@@ -31,6 +31,8 @@ extension_internal_libinternal_a_SOURCES =    \
        extension/internal/pdf-cairo.h \
        extension/internal/cairo-pdf-out.h      \
        extension/internal/cairo-pdf-out.cpp    \
+       extension/internal/cairo-ps-out.h       \
+       extension/internal/cairo-ps-out.cpp     \
        extension/internal/cairo-render-context.h       \
        extension/internal/cairo-render-context.cpp     \
        extension/internal/cairo-renderer.h \
diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp
new file mode 100644 (file)
index 0000000..8d062fa
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * A quick hack to use the Cairo renderer to write out a file.  This
+ * then makes 'save as...' PS.
+ *
+ * Authors:
+ *   Ted Gould <ted@gould.cx>
+ *   Ulf Erikson <ulferikson@users.sf.net>
+ *   Adib Taraben <theAdib@yahoo.com>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_CAIRO_PDF
+
+#include "cairo-ps-out.h"
+#include "cairo-render-context.h"
+#include "cairo-renderer.h"
+#include <print.h>
+#include "extension/system.h"
+#include "extension/print.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "display/nr-arena.h"
+#include "display/nr-arena-item.h"
+
+#include <libnr/n-art-bpath.h>
+
+#include "display/curve.h"
+#include "display/canvas-bpath.h"
+#include "sp-item.h"
+#include "style.h"
+#include "sp-root.h"
+#include "sp-shape.h"
+
+#include "io/sys.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+bool
+CairoPsOutput::check (Inkscape::Extension::Extension * module)
+{
+       return TRUE;
+}
+
+static bool
+ps_print_document_to_file(SPDocument *doc, gchar const *filename)
+{
+    CairoRenderer *renderer;
+    CairoRenderContext *ctx;
+
+    sp_document_ensure_up_to_date(doc);
+
+/* Start */
+    /* Create new arena */
+    SPItem *base = SP_ITEM(sp_document_root(doc));
+    NRArena *arena = NRArena::create();
+    unsigned dkey = sp_item_display_key_new(1);
+    NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
+    
+    /* Create renderer and context */
+    renderer = new CairoRenderer();
+    ctx = renderer->createContext();
+    bool ret = ctx->setPsTarget(filename);
+    if(ret) {
+        /* Render document */
+       ret = renderer->setupDocument(ctx, doc);
+       if (ret) {
+           renderer->renderItem(ctx, base);
+           ret = ctx->finish();
+       }
+    }
+    renderer->destroyContext(ctx);
+
+    /* Release arena */
+    sp_item_invoke_hide(base, dkey);
+    nr_arena_item_unref(root);
+    nr_object_unref((NRObject *) arena);
+/* end */
+    delete renderer;
+
+    return ret;
+}
+
+
+/**
+    \brief  This function calls the output module with the filename
+       \param  mod   unused
+       \param  doc   Document to be saved
+    \param  uri   Filename to save to (probably will end in .ps)
+*/
+void
+CairoPsOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
+{
+    Inkscape::Extension::Extension * ext;
+    unsigned int ret;
+
+    ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
+    if (ext == NULL)
+        return;
+
+       gchar * final_name;
+       final_name = g_strdup_printf("> %s", uri);
+       ret = ps_print_document_to_file(doc, final_name);
+       g_free(final_name);
+        
+       if (!ret)
+           throw Inkscape::Extension::Output::save_failed();
+
+       return;
+
+}
+
+/**
+       \brief   A function allocate a copy of this function.
+
+       This is the definition of Cairo PS out.  This function just
+       calls the extension system with the memory allocated XML that
+       describes the data.
+*/
+void
+CairoPsOutput::init (void)
+{
+       Inkscape::Extension::build_from_mem(
+               "<inkscape-extension>\n"
+                       "<name>Cairo PS Output</name>\n"
+                       "<id>org.inkscape.print.ps.cairo</id>\n"
+                       "<output>\n"
+                               "<extension>.ps</extension>\n"
+                "<mimetype>application/ps</mimetype>\n"
+                               "<filetypename>Cairo PS (*.ps)</filetypename>\n"
+                               "<filetypetooltip>PS File</filetypetooltip>\n"
+                       "</output>\n"
+               "</inkscape-extension>", new CairoPsOutput());
+
+       return;
+}
+
+} } }  /* namespace Inkscape, Extension, Implementation */
+
+#endif /* HAVE_CAIRO_PDF */
diff --git a/src/extension/internal/cairo-ps-out.h b/src/extension/internal/cairo-ps-out.h
new file mode 100644 (file)
index 0000000..27f7234
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * A quick hack to use the print output to write out a file.  This
+ * then makes 'save as...' PS.
+ *
+ * Authors:
+ *   Ted Gould <ted@gould.cx>
+ *   Ulf Erikson <ulferikson@users.sf.net>
+ *   Adib Taraben <theAdib@yahoo.com>
+ *
+ * Copyright (C) 2004-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef EXTENSION_INTERNAL_CAIRO_PS_OUT_H
+#define EXTENSION_INTERNAL_CAIRO_PS_OUT_H
+
+#include "extension/implementation/implementation.h"
+
+#ifdef HAVE_CAIRO_PDF
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+class CairoPsOutput : Inkscape::Extension::Implementation::Implementation {
+
+public:
+    bool check(Inkscape::Extension::Extension *module);
+    void save(Inkscape::Extension::Output *mod,
+              SPDocument *doc,
+              gchar const *uri);
+    static void init();
+};
+
+} } }  /* namespace Inkscape, Extension, Implementation */
+
+#endif /* HAVE_CAIRO_PDF */
+
+#endif /* !EXTENSION_INTERNAL_CAIRO_PS_OUT_H */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 47d38fa1d338e6ba39526feb1bdc14b3ad8a699d..b13b95643279d740e2458e421ce99d9b846abec3 100644 (file)
@@ -8,7 +8,7 @@
  *   Miklos Erdelyi <erdelyim@gmail.com>
  *
  * Copyright (C) 2006 Miklos Erdelyi
- * 
+ *
  * Licensed under GNU GPL
  */
 
@@ -169,7 +169,7 @@ CairoRenderContext::setStateForStyle(SPStyle const *style)
 
 /**
  * \brief Creates a new render context which will be compatible with the given context's Cairo surface
- * 
+ *
  * \param width     width of the surface to be created
  * \param height    height of the surface to be created
  */
@@ -239,7 +239,90 @@ CairoRenderContext::setPdfTarget(gchar const *utf8_fn)
     gchar *local_fn = g_filename_from_utf8(utf8_fn,
                                            -1,  &bytesRead,  &bytesWritten, &error);
     gchar const *fn = local_fn;
-    
+
+    /* TODO: Replace the below fprintf's with something that does the right thing whether in
+    * gui or batch mode (e.g. --print=blah).  Consider throwing an exception: currently one of
+    * the callers (sp_print_document_to_file, "ret = mod->begin(doc)") wrongly ignores the
+    * return code.
+    */
+    if (fn != NULL) {
+        if (*fn == '|') {
+            fn += 1;
+            while (isspace(*fn)) fn += 1;
+#ifndef WIN32
+            osp = popen(fn, "w");
+#else
+            osp = _popen(fn, "w");
+#endif
+            if (!osp) {
+                fprintf(stderr, "inkscape: popen(%s): %s\n",
+                        fn, strerror(errno));
+                return false;
+            }
+            _stream = osp;
+        } else if (*fn == '>') {
+            fn += 1;
+            while (isspace(*fn)) fn += 1;
+            Inkscape::IO::dump_fopen_call(fn, "K");
+            osf = Inkscape::IO::fopen_utf8name(fn, "w+");
+            if (!osf) {
+                fprintf(stderr, "inkscape: fopen(%s): %s\n",
+                        fn, strerror(errno));
+                return false;
+            }
+            _stream = osf;
+        } else {
+            /* put cwd stuff in here */
+            gchar *qn = ( *fn
+                    ? g_strdup_printf("lpr -P %s", fn)  /* FIXME: quote fn */
+                : g_strdup("lpr") );
+#ifndef WIN32
+            osp = popen(qn, "w");
+#else
+            osp = _popen(qn, "w");
+#endif
+            if (!osp) {
+                fprintf(stderr, "inkscape: popen(%s): %s\n",
+                        qn, strerror(errno));
+                return false;
+            }
+            g_free(qn);
+            _stream = osp;
+        }
+    }
+
+    g_free(local_fn);
+
+    if (_stream) {
+        /* fixme: this is kinda icky */
+#if !defined(_WIN32) && !defined(__WIN32__)
+        (void) signal(SIGPIPE, SIG_IGN);
+#endif
+    }
+
+    return true;
+}
+
+bool
+CairoRenderContext::setPsTarget(gchar const *utf8_fn)
+{
+#ifndef CAIRO_HAS_PS_SURFACE
+    return false;
+#else
+    _target = CAIRO_SURFACE_TYPE_PS;
+    _vector_based_target = TRUE;
+#endif
+
+    FILE *osf = NULL;
+    FILE *osp = NULL;
+
+    gsize bytesRead = 0;
+    gsize bytesWritten = 0;
+    GError *error = NULL;
+    gchar *local_fn = g_filename_from_utf8(utf8_fn,
+                                           -1,  &bytesRead,  &bytesWritten, &error);
+    gchar const *fn = local_fn;
+
     /* TODO: Replace the below fprintf's with something that does the right thing whether in
     * gui or batch mode (e.g. --print=blah).  Consider throwing an exception: currently one of
     * the callers (sp_print_document_to_file, "ret = mod->begin(doc)") wrongly ignores the
@@ -299,7 +382,7 @@ CairoRenderContext::setPdfTarget(gchar const *utf8_fn)
         (void) signal(SIGPIPE, SIG_IGN);
 #endif
     }
-            
+
     return true;
 }
 
@@ -307,7 +390,7 @@ cairo_surface_t*
 CairoRenderContext::getSurface(void)
 {
     g_assert( _is_valid );
-    
+
     return _surface;
 }
 
@@ -385,7 +468,7 @@ CairoRenderContext::pushLayer(void)
 
     TRACE(("--pushLayer\n"));
     cairo_push_group(_cr);
-                
+
     // clear buffer
     if (!_vector_based_target) {
         cairo_save(_cr);
@@ -515,7 +598,7 @@ CairoRenderContext::popLayer(void)
                         guint32 *pixel = (guint32 *)row_data + i;
                         *pixel = ((((*pixel & 0x00ff0000) >> 16) * 13817 +
                                 ((*pixel & 0x0000ff00) >>  8) * 46518 +
-                                ((*pixel & 0x000000ff)      ) * 4688) * 
+                                ((*pixel & 0x000000ff)      ) * 4688) *
                                 int_opacity);
                     }
                 }
@@ -611,24 +694,24 @@ bool
 CairoRenderContext::finish(void)
 {
     g_assert( _is_valid );
-    
+
     if (_vector_based_target)
         cairo_show_page(_cr);
-    
+
     cairo_destroy(_cr);
     cairo_surface_destroy(_surface);
     _cr = NULL;
     _surface = NULL;
-    
+
     if (_layout)
         g_object_unref(_layout);
-    
+
     _is_valid = FALSE;
-    
+
     if (_vector_based_target) {
         /* Flush stream to be sure. */
         (void) fflush(_stream);
-    
+
         fclose(_stream);
         _stream = NULL;
     }
@@ -644,7 +727,7 @@ CairoRenderContext::transform(NRMatrix const *transform)
     cairo_matrix_t matrix;
     _initCairoMatrix(&matrix, transform);
     cairo_transform(_cr, &matrix);
-    
+
     // store new CTM
     getTransform(&_state->transform);
 }
@@ -653,7 +736,7 @@ void
 CairoRenderContext::setTransform(NRMatrix const *transform)
 {
     g_assert( _is_valid );
-    
+
     cairo_matrix_t matrix;
     _initCairoMatrix(&matrix, transform);
     cairo_set_matrix(_cr, &matrix);
@@ -702,9 +785,9 @@ void
 CairoRenderContext::popState(void)
 {
     g_assert( _is_valid );
-    
+
     cairo_restore(_cr);
-    
+
     g_free(_state_stack->data);
     _state_stack = g_slist_remove_link(_state_stack, _state_stack);
     _state = (CairoRenderState*)_state_stack->data;
@@ -726,13 +809,13 @@ cairo_pattern_t*
 CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver, NRRect const *pbox)
 {
     g_assert( SP_IS_PATTERN(paintserver) );
-        
+
     SPPattern *pat = SP_PATTERN (paintserver);
-    
+
     NRMatrix ps2user, pcs2dev;
     nr_matrix_set_identity(&ps2user);
     nr_matrix_set_identity(&pcs2dev);
-    
+
     double x = pattern_x(pat);
     double y = pattern_y(pat);
     double width = pattern_width(pat);
@@ -741,7 +824,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
     double bbox_height_scaler;
 
     TRACE(("%f x %f pattern\n", width, height));
-    
+
     if (pbox && pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
         //NR::Matrix bbox2user (pbox->x1 - pbox->x0, 0.0, 0.0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0);
         bbox_width_scaler = pbox->x1 - pbox->x0;
@@ -754,7 +837,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
         ps2user[4] = x;
         ps2user[5] = y;
     }
-    
+
     // apply pattern transformation
     NRMatrix pattern_transform(pattern_patternTransform(pat));
     nr_matrix_multiply(&ps2user, &ps2user, &pattern_transform);
@@ -762,7 +845,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
     // create pattern contents coordinate system
     if (pat->viewBox_set) {
         NRRect *view_box = pattern_viewBox(pat);
-        
+
         double x, y, w, h;
         double view_width, view_height;
         x = 0;
@@ -782,7 +865,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
         pcs2dev[0] = pbox->x1 - pbox->x0;
         pcs2dev[3] = pbox->y1 - pbox->y0;
     }
-    
+
     // calculate the size of the surface which has to be created
     // the scaling needs to be taken into account in the ctm after the pattern transformation
     NRMatrix temp;
@@ -817,11 +900,11 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
 
     pattern_ctx->setTransform(&pcs2dev);
     pattern_ctx->pushState();
-    
+
     // create arena and group
     NRArena *arena = NRArena::create();
     unsigned dkey = sp_item_display_key_new(1);
-    
+
     // show items and render them
     for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
         if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children
@@ -834,9 +917,9 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
             break; // do not go further up the chain if children are found
         }
     }
-    
+
     pattern_ctx->popState();
-    
+
     // setup a cairo_pattern_t
     cairo_surface_t *pattern_surface = pattern_ctx->getSurface();
     TEST(pattern_ctx->saveAsPng("pattern.png"));
@@ -848,9 +931,9 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
     _initCairoMatrix(&pattern_matrix, &ps2user);
     cairo_matrix_invert(&pattern_matrix);
     cairo_pattern_set_matrix(result, &pattern_matrix);
-    
+
     delete pattern_ctx;
-    
+
     // hide all items
     for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
         if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children
@@ -862,7 +945,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
             break; // do not go further up the chain if children are found
         }
     }
-    
+
     return result;
 }
 
@@ -872,11 +955,11 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
 {
     cairo_pattern_t *pattern = NULL;
     bool apply_bbox2user = FALSE;
-    
+
     if (SP_IS_LINEARGRADIENT (paintserver)) {
 
             SPLinearGradient *lg=SP_LINEARGRADIENT(paintserver);
-            
+
             sp_gradient_ensure_vector(SP_GRADIENT(lg)); // when exporting from commandline, vector is not built
 
             NR::Point p1 (lg->x1.computed, lg->y1.computed);
@@ -887,10 +970,10 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
                 p1 *= bbox2user;
                 p2 *= bbox2user;
             }
-            
+
             // create linear gradient pattern
             pattern = cairo_pattern_create_linear(p1[NR::X], p1[NR::Y], p2[NR::X], p2[NR::Y]);
-            
+
             // add stops
             for (gint i = 0; unsigned(i) < lg->vector.stops.size(); i++) {
                 float rgb[3];
@@ -908,7 +991,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
         double r = rg->r.computed;
         if (pbox && SP_GRADIENT(rg)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX)
             apply_bbox2user = true;
-        
+
         // create radial gradient pattern
         pattern = cairo_pattern_create_radial(f[NR::X], f[NR::Y], 0, c[NR::X], c[NR::Y], r);
 
@@ -924,7 +1007,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
     } else {
         return NULL;
     }
-        
+
     if (pattern && SP_IS_GRADIENT (paintserver)) {
         SPGradient *g = SP_GRADIENT(paintserver);
 
@@ -969,7 +1052,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
         cairo_matrix_invert(&pattern_matrix);   // because Cairo expects a userspace->patternspace matrix
         cairo_pattern_set_matrix(pattern, &pattern_matrix);
     }
-        
+
     return pattern;
 }
 
@@ -978,13 +1061,13 @@ CairoRenderContext::_setFillStyle(SPStyle const *const style, NRRect const *pbox
 {
     g_return_if_fail( style->fill.type == SP_PAINT_TYPE_COLOR
                       || style->fill.type == SP_PAINT_TYPE_PAINTSERVER );
-    
+
     float alpha = SP_SCALE24_TO_FLOAT(style->fill_opacity.value);
     if (_state->merge_opacity) {
         alpha *= _state->opacity;
         TRACE(("merged op=%f\n", alpha));
     }
-    
+
     if (style->fill.type == SP_PAINT_TYPE_COLOR) {
         float rgb[3];
         sp_color_get_rgb_floatv(&style->fill.value.color, rgb);
@@ -994,9 +1077,9 @@ CairoRenderContext::_setFillStyle(SPStyle const *const style, NRRect const *pbox
         g_assert( style->fill.type == SP_PAINT_TYPE_PAINTSERVER
                   || SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style))
                   || SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) );
-        
+
         cairo_pattern_t *pattern = _createPatternForPaintServer(SP_STYLE_FILL_SERVER(style), pbox, alpha);
-        
+
         if (pattern) {
             cairo_set_source(_cr, pattern);
             cairo_pattern_destroy(pattern);
@@ -1010,19 +1093,19 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, NRRect const *pbox)
     float alpha = SP_SCALE24_TO_FLOAT(style->stroke_opacity.value);
     if (_state->merge_opacity)
         alpha *= _state->opacity;
-    
+
     if (style->stroke.type == SP_PAINT_TYPE_COLOR) {
         float rgb[3];
         sp_color_get_rgb_floatv(&style->stroke.value.color, rgb);
-      
+
         cairo_set_source_rgba(_cr, rgb[0], rgb[1], rgb[2], alpha);
     } else {
         g_assert( style->fill.type == SP_PAINT_TYPE_PAINTSERVER
                   || SP_IS_GRADIENT(SP_STYLE_STROKE_SERVER(style))
                   || SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) );
-                
+
         cairo_pattern_t *pattern = _createPatternForPaintServer(SP_STYLE_STROKE_SERVER(style), pbox, alpha);
-        
+
         if (pattern) {
             cairo_set_source(_cr, pattern);
             cairo_pattern_destroy(pattern);
@@ -1036,7 +1119,7 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, NRRect const *pbox)
     } else {
        cairo_set_dash(_cr, NULL, 0, 0.0);      // disable dashing
     }
-    
+
     cairo_set_line_width(_cr, style->stroke_width.computed);
 
     // set line join type
@@ -1051,9 +1134,9 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, NRRect const *pbox)
        case SP_STROKE_LINEJOIN_BEVEL:
            join = CAIRO_LINE_JOIN_BEVEL;
            break;
-    }          
+    }
     cairo_set_line_join(_cr, join);
-    
+
     // set line cap type
     cairo_line_cap_t cap = CAIRO_LINE_CAP_BUTT;
     switch (style->stroke_linecap.computed) {
@@ -1066,7 +1149,7 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, NRRect const *pbox)
        case SP_STROKE_LINECAP_SQUARE:
            cap = CAIRO_LINE_CAP_SQUARE;
            break;
-    }          
+    }
     cairo_set_line_cap(_cr, cap);
     cairo_set_miter_limit(_cr, MAX(1, style->stroke_miterlimit.value));
 }
@@ -1106,27 +1189,27 @@ CairoRenderContext::renderPath(NRBPath const *bpath, SPStyle const *style, NRRec
     if (style->fill.type != SP_PAINT_TYPE_NONE) {
         _setFillStyle(style, pbox);
         setBpath(bpath->path);
-        
+
         if (style->fill_rule.value == SP_WIND_RULE_EVENODD) {
             cairo_set_fill_rule(_cr, CAIRO_FILL_RULE_EVEN_ODD);
         } else {
             cairo_set_fill_rule(_cr, CAIRO_FILL_RULE_WINDING);
         }
-    
+
         if (style->stroke.type == SP_PAINT_TYPE_NONE)
             cairo_fill(_cr);
         else
             cairo_fill_preserve(_cr);
     }
-    
+
     if (style->stroke.type != SP_PAINT_TYPE_NONE) {
         _setStrokeStyle(style, pbox);
         if (style->fill.type == SP_PAINT_TYPE_NONE)
             setBpath(bpath->path);
 
-        cairo_stroke(_cr);    
+        cairo_stroke(_cr);
     }
-    
+
     if (need_layer)
         popLayer();
     else
@@ -1140,20 +1223,20 @@ CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsi
                                 NRMatrix const *image_transform, SPStyle const *style)
 {
     g_assert( _is_valid );
-    
+
     if (_render_mode == RENDER_MODE_CLIP)
         return true;
-    
+
     guchar* px_rgba = (guchar*)g_malloc(4 * w * h);
     if (!px_rgba)
         return false;
-    
+
     float opacity;
     if (_state->merge_opacity)
         opacity = _state->opacity;
     else
         opacity = 1.0;
-    
+
     // make a copy of the original pixbuf with premultiplied alpha
     // if we pass the original pixbuf it will get messed up
     for (unsigned i = 0; i < h; i++) {
@@ -1161,7 +1244,7 @@ CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsi
             guchar const *src = px + i * rs + j * 4;
             guint32 *dst = (guint32 *)(px_rgba + i * rs + j * 4);
             guchar r, g, b, alpha_dst;
-            
+
             // calculate opacity-modified alpha
             alpha_dst = src[3];
             if (opacity != 1.0 && _vector_based_target)
@@ -1171,23 +1254,23 @@ CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsi
             r = src[0]*alpha_dst/255;
             g = src[1]*alpha_dst/255;
             b = src[2]*alpha_dst/255;
-            
+
             *dst = (((alpha_dst) << 24) | (((r)) << 16) | (((g)) << 8) | (b));
        }
     }
-    
+
     cairo_surface_t *image_surface = cairo_image_surface_create_for_data(px_rgba, CAIRO_FORMAT_ARGB32, w, h, w * 4);
     if (cairo_surface_status(image_surface)) {
         TRACE(("Image surface creation failed:\n%s\n", cairo_status_to_string(cairo_surface_status(image_surface))));
        return false;
     }
-    
+
     // setup automatic freeing of the image data when destroying the surface
     static cairo_user_data_key_t key;
     cairo_surface_set_user_data(image_surface, &key, px_rgba, (cairo_destroy_func_t)g_free);
 
     cairo_save(_cr);
-    
+
     // scaling by width & height is not needed because it will be done by Cairo
     if (image_transform)
         transform(image_transform);
@@ -1205,11 +1288,11 @@ CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsi
         cairo_paint(_cr);
     else
         cairo_paint_with_alpha(_cr, opacity);
-    
+
     cairo_restore(_cr);
 
     cairo_surface_destroy(image_surface);
-    
+
     return true;
 }
 
@@ -1259,17 +1342,16 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, NRMatrix const *font_matrix
     double size = style->font_size.computed;
     PangoFcFont *fc_font = PANGO_FC_FONT(font);
     FcPattern *fc_pattern = fc_font->font_pattern;
-    
+
     cairo_save(_cr);
 
 #ifndef PANGO_ENABLE_BACKEND
-
     cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(fc_pattern);
     cairo_set_font_face(_cr, font_face);
-    
+
     if (FcPatternGetDouble(fc_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
         size = 12.0;
-    
+
     // set the given font matrix
     cairo_matrix_t matrix;
     _initCairoMatrix(&matrix, font_matrix);
@@ -1372,7 +1454,7 @@ CairoRenderContext::_concatTransform(cairo_t *cr, double xx, double yx, double x
 {
     cairo_matrix_t matrix;
 
-    cairo_matrix_init(&matrix, xx, yx, xy, yy, x0, y0); 
+    cairo_matrix_init(&matrix, xx, yx, xy, yy, x0, y0);
     cairo_transform(cr, &matrix);
 }
 
index 7659c3518162432456b476847ddc60178c83f7b7..424764358b9e20f037d21e73cd2fc198261b1696 100644 (file)
@@ -84,6 +84,7 @@ public:
     
     bool setImageTarget(cairo_format_t format);
     bool setPdfTarget(gchar const *utf8_fn);
+    bool setPsTarget(gchar const *utf8_fn);
 
     /** Creates the cairo_surface_t for the context with the
     given width, height and with the currently set target