Code

patch to fix multiple ps and pdf problems by Ulf Erikson
authorbuliabyak <buliabyak@users.sourceforge.net>
Sat, 1 Jul 2006 20:57:59 +0000 (20:57 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Sat, 1 Jul 2006 20:57:59 +0000 (20:57 +0000)
share/extensions/pdf_output.inx.txt
share/extensions/pdf_output_via_gs_on_win32.inx.txt
share/extensions/ps2pdf.sh
src/extension/internal/pdf-out.cpp
src/extension/internal/pdf.cpp
src/extension/internal/pdf.h
src/extension/internal/ps.cpp

index 1ed6eafb188d3c3207b4d0e70fed3bac27b1ddfb..3e2b4f4910c6e437a6456e17c8a199134d4e4a2d 100644 (file)
@@ -1,13 +1,13 @@
 <inkscape-extension>
     <_name>PDF Output</_name>
-    <id>org.inkscape.output.pdf</id>
-    <dependency type="extension">org.inkscape.output.ps.via_gs</dependency>
+    <id>org.inkscape.output.pdf.via_gs</id>
+    <dependency type="extension">org.inkscape.output.ps</dependency>
     <dependency type="executable" location="extensions">ps2pdf.sh</dependency>
     <dependency type="executable">ps2pdf</dependency>
     <output>
         <extension>.pdf</extension>
         <mimetype>image/x-portable-document-format</mimetype>
-        <_filetypename>Adobe PDF (*.pdf)</_filetypename>
+        <_filetypename>Adobe PDF via postscript (*.pdf)</_filetypename>
         <_filetypetooltip>Adobe Portable Document Format</_filetypetooltip>
     </output>
     <script>
index 50e63ced84f11eb06bac917cdef7e2d355dd2881..ae10a048e7c6bc2daddd6daf65f78ce59aef7fba 100644 (file)
@@ -14,7 +14,7 @@ that they get into the tarball
     <output>
         <extension>.pdf</extension>
         <mimetype>image/x-portable-document-format</mimetype>
-        <_filetypename>Adobe PDF (*.pdf)</_filetypename>
+        <_filetypename>Adobe PDF via postscript (*.pdf)</_filetypename>
         <_filetypetooltip>Adobe Portable Document Format</_filetypetooltip>
     </output>
     <script>
index 86daa96bc42eed5a051dbb79c333df34c73a8c98..1b7c4cfa38e4c95d6851a7b56f84f884c73c6226 100755 (executable)
@@ -1,2 +1,10 @@
 #! /bin/sh
-exec ps2pdf "$1" - 2> /dev/null
+
+params=`grep "^%%DocumentMedia:" "$1" | head -n 1 | awk '{  if (NF==7) { if ($2!="plain") print "-sPAPERSIZE=" $2; else print "-dDEVICEWIDTHPOINTS=" $3 " -dDEVICEHEIGHTPOINTS=" $4; } }'`
+
+if [ "x${params}x" == "xx" ]
+then 
+        params=`grep "^%%BoundingBox:" "$1" | head -n 1 | awk '{ print "-dDEVICEWIDTHPOINTS=" $4 " -dDEVICEHEIGHTPOINTS=" $5; }'`
+fi
+
+exec ps2pdf $params "$1" - 2> /dev/null
index 370855fe684e59b97c815cd8ca14efbc1dc4064d..5cf859161167fcac71e2dfcfed03f09fab4cc2b8 100644 (file)
@@ -101,17 +101,11 @@ PdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar
     if (ext == NULL)\r
         return;\r
 \r
-    bool old_textToPath  = ext->get_param_bool("textToPath");\r
-    bool new_val         = mod->get_param_bool("textToPath");\r
-    ext->set_param_bool("textToPath", new_val);\r
-\r
        gchar * final_name;\r
        final_name = g_strdup_printf("> %s", uri);\r
        pdf_print_document_to_file(doc, final_name);\r
        g_free(final_name);\r
 \r
-    ext->set_param_bool("textToPath", old_textToPath);\r
-\r
        return;\r
 }\r
 \r
@@ -129,7 +123,6 @@ PdfOutput::init (void)
                "<inkscape-extension>\n"\r
                        "<name>PDF Output</name>\n"\r
                        "<id>org.inkscape.output.pdf</id>\n"\r
-                       "<param name=\"textToPath\" gui-text=\"Text to Path\" type=\"boolean\">true</param>\n"\r
                        "<output>\n"\r
                                "<extension>.pdf</extension>\n"\r
                                "<mimetype>application/pdf</mimetype>\n"\r
index c85be3b56dfc7b27e68e0ce7d170421517b32cfa..0951d97f2b34006e22cc76b7b0b73948b47e41de 100644 (file)
@@ -74,10 +74,14 @@ PrintPDF::PrintPDF() :
     _dpi(72),\r
     _bitmap(false)\r
 {\r
+    _num_alphas = 10;\r
+    _pushed_alphas = (float*) malloc(_num_alphas*sizeof(float));\r
 }\r
 \r
 PrintPDF::~PrintPDF(void)\r
 {\r
+    free(_pushed_alphas);\r
+\r
     /* fixme: should really use pclose for popen'd streams */\r
     if (_stream) fclose(_stream);\r
 \r
@@ -233,6 +237,9 @@ PrintPDF::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
     FILE *osf = NULL;\r
     FILE *osp = NULL;\r
 \r
+    _curr_alpha = 0;\r
+    _pushed_alphas[_curr_alpha] = 1.0;\r
+\r
     gsize bytesRead = 0;\r
     gsize bytesWritten = 0;\r
     GError *error = NULL;\r
@@ -473,6 +480,31 @@ PrintPDF::bind(Inkscape::Extension::Print *mod, NRMatrix const *transform, float
                  << transform->c[4] << " "\r
                  << transform->c[5] << " cm\n";\r
 \r
+    if (opacity!=1.0) {\r
+        float alpha = opacity * _pushed_alphas[_curr_alpha];\r
+\r
+        fprintf(stderr, "bind: opacity=%f, pushed=%f, alpha=%f\n",\r
+                opacity, _pushed_alphas[_curr_alpha], alpha);\r
+        \r
+        _curr_alpha++;\r
+        if (_curr_alpha >= _num_alphas) {\r
+            _num_alphas = _num_alphas*2;\r
+            _pushed_alphas = (float *) realloc(_pushed_alphas, _num_alphas*sizeof(float));\r
+        }\r
+        _pushed_alphas[_curr_alpha] = alpha;\r
+        \r
+        PdfObject *pdf_alpha = pdf_file->begin_resource(pdf_extgstate);\r
+        *pdf_alpha << "<< /Type /ExtGState\n";\r
+        *pdf_alpha << "   /ca " << alpha << "\n";\r
+        *pdf_alpha << "   /AIS false\n";\r
+        *pdf_alpha << ">>\n";\r
+        \r
+        *page_stream << pdf_alpha->get_name()\r
+                     << " gs\n";\r
+        \r
+        pdf_file->end_resource(pdf_alpha);\r
+    }\r
+\r
     return 1;\r
 }\r
 \r
@@ -482,6 +514,8 @@ PrintPDF::release(Inkscape::Extension::Print *mod)
     if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned.\r
     if (_bitmap) return 0;\r
 \r
+    _curr_alpha--;\r
+\r
     *page_stream << "Q\n";\r
 \r
     return 1;\r
@@ -507,23 +541,25 @@ PrintPDF::print_fill_alpha(SVGOStringStream &/*os*/, SPStyle const *const style,
     \r
     if (style->fill.type == SP_PAINT_TYPE_COLOR) {\r
         float alpha = 1.0;\r
-        \r
-        if (style->opacity.set)\r
-            alpha *= SP_SCALE24_TO_FLOAT(style->opacity.value);\r
-        \r
-        if (style->fill_opacity.set)\r
-            alpha *= SP_SCALE24_TO_FLOAT(style->fill_opacity.value);\r
+        alpha *= SP_SCALE24_TO_FLOAT(style->fill_opacity.value);\r
 \r
         if (alpha != 1.0) {\r
             PdfObject *pdf_alpha = pdf_file->begin_resource(pdf_extgstate);\r
             *pdf_alpha << "<< /Type /ExtGState\n";\r
-            *pdf_alpha << "   /ca " << alpha << "\n";\r
+            *pdf_alpha << "   /ca " << alpha*_pushed_alphas[_curr_alpha] << "\n";\r
             *pdf_alpha << "   /AIS false\n";\r
             *pdf_alpha << ">>\n";\r
             \r
             *page_stream << pdf_alpha->get_name()\r
                          << " gs\n";\r
             \r
+            \r
+        fprintf(stderr, "print_fill_alpha: opacity=%f, fill-opacity=%f, pushed_alphas=%f ==> %f\n",\r
+                SP_SCALE24_TO_FLOAT(style->opacity.value),\r
+                SP_SCALE24_TO_FLOAT(style->fill_opacity.value),\r
+                _pushed_alphas[_curr_alpha],\r
+                alpha*_pushed_alphas[_curr_alpha]);\r
+\r
             pdf_file->end_resource(pdf_alpha);\r
         }\r
     } else {\r
@@ -550,12 +586,12 @@ PrintPDF::print_fill_alpha(SVGOStringStream &/*os*/, SPStyle const *const style,
                 alpha *= lg->vector.stops[i].opacity;\r
             }\r
             \r
-            if (alpha != 1.0 || style->opacity.set) {\r
+            if (alpha != 1.0) {\r
                 PdfObject *pdf_gstate = pdf_file->begin_resource(pdf_extgstate);\r
                 *pdf_gstate << "<< /Type /ExtGState\n";\r
                 \r
-                if (style->opacity.set) {\r
-                    *pdf_gstate << "   /ca " << SP_SCALE24_TO_FLOAT(style->opacity.value) << "\n";\r
+                if (_pushed_alphas[_curr_alpha] != 1.0) {\r
+                    *pdf_gstate << "   /ca " << _pushed_alphas[_curr_alpha] << "\n";\r
                     *pdf_gstate << "   /AIS false\n";\r
                 }\r
                 \r
@@ -679,12 +715,12 @@ PrintPDF::print_fill_alpha(SVGOStringStream &/*os*/, SPStyle const *const style,
                 alpha *= rg->vector.stops[i].opacity;\r
             }\r
 \r
-            if (alpha != 1.0 || style->opacity.set) {\r
+            if (alpha != 1.0) {\r
                 PdfObject *pdf_gstate = pdf_file->begin_resource(pdf_extgstate);\r
                 *pdf_gstate << "<< /Type /ExtGState\n";\r
                 \r
-                if (style->opacity.set) {\r
-                    *pdf_gstate << "   /ca " << SP_SCALE24_TO_FLOAT(style->opacity.value) << "\n";\r
+                if (_pushed_alphas[_curr_alpha] != 1.0) {\r
+                    *pdf_gstate << "   /ca " << _pushed_alphas[_curr_alpha] << "\n";\r
                     *pdf_gstate << "   /AIS false\n";\r
                 }\r
                 \r
@@ -914,17 +950,12 @@ PrintPDF::print_stroke_style(SVGOStringStream &os, SPStyle const *style)
     *page_stream << rgb[0] << " " << rgb[1] << " " << rgb[2] << " RG\n";\r
         \r
     float alpha = 1.0;\r
-\r
-    if (style->opacity.set)\r
-        alpha *= SP_SCALE24_TO_FLOAT(style->opacity.value);\r
-        \r
-    if (style->stroke_opacity.set)\r
-        alpha *= SP_SCALE24_TO_FLOAT(style->stroke_opacity.value);\r
+    alpha *= SP_SCALE24_TO_FLOAT(style->stroke_opacity.value);\r
 \r
     if (alpha != 1.0) {\r
         PdfObject *pdf_alpha = pdf_file->begin_resource(pdf_extgstate);\r
         *pdf_alpha << "<< /Type /ExtGState\n";\r
-        *pdf_alpha << "   /CA " << alpha << "\n";\r
+        *pdf_alpha << "   /CA " << alpha*_pushed_alphas[_curr_alpha] << "\n";\r
         *pdf_alpha << "   /AIS false\n";\r
         *pdf_alpha << ">>\n";\r
         \r
@@ -937,8 +968,7 @@ PrintPDF::print_stroke_style(SVGOStringStream &os, SPStyle const *style)
     // invalid PS-lines such as "[0.0000000 0.0000000] 0.0000000 setdash", which should be "[] 0 setdash",\r
     // we first check if all components of stroke_dash.dash are 0.\r
     bool LineSolid = true;\r
-    if (style->stroke_dasharray_set &&\r
-        style->stroke_dash.n_dash   &&\r
+    if (style->stroke_dash.n_dash   &&\r
         style->stroke_dash.dash       )\r
     {\r
         int i = 0;\r
@@ -966,9 +996,9 @@ PrintPDF::print_stroke_style(SVGOStringStream &os, SPStyle const *style)
     *page_stream << style->stroke_width.computed << " w\n";\r
     *page_stream << style->stroke_linejoin.computed << " j\n";\r
     *page_stream << style->stroke_linecap.computed << " J\n";\r
-    if (style->stroke_miterlimit.set) {\r
-        *page_stream << style->stroke_miterlimit.value << " M\n";\r
-    }\r
+    *page_stream <<\r
+        ( style->stroke_miterlimit.value > 1 ?\r
+          style->stroke_miterlimit.value : 1 ) << " M\n";\r
 }\r
 \r
 \r
index 0273f9835b5527eed579f3952915826a1af3e94e..0ceda7cafa1969f5c13b2bc4540e55df986d49fb 100644 (file)
@@ -35,6 +35,9 @@ class PrintPDF : public Inkscape::Extension::Implementation::Implementation {
     PdfFile   *pdf_file;\r
     PdfObject *doc_info;\r
     PdfObject *page_stream;\r
+    float *_pushed_alphas;\r
+    int _num_alphas;\r
+    int _curr_alpha;\r
     unsigned short _dpi;\r
     bool _bitmap;\r
     std::set<std::string> _latin1_encoded_fonts;\r
index a72b88461804a76801932a9fe0a6c0cbc7ec869d..c3289ccd6245446f2a3bb6f45070cd3d781a84d8 100644 (file)
@@ -385,6 +385,10 @@ PrintPS::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
                << d.x0 << " "
                << (_height - d.y0) << " "
                << d.x1 << "\n";
+            os << "%%DocumentMedia: plain "
+               << (int) ceil(_height) << " "
+               << (int) ceil(_width) << " "
+               << "0 () ()\n";
         } else {
             os << "%%Orientation: Portrait\n";
             os << "%%BoundingBox: " << (int) d.x0 << " "
@@ -395,6 +399,10 @@ PrintPS::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
                << d.y0 << " "
                << d.x1 << " "
                << d.y1 << "\n";
+            os << "%%DocumentMedia: plain "
+               << (int) ceil(_width) << " "
+               << (int) ceil(_height) << " "
+               << "0 () ()\n";
         }
 
         os << "%%EndComments\n";
@@ -656,8 +664,7 @@ PrintPS::print_stroke_style(SVGOStringStream &os, SPStyle const *style)
     // invalid PS-lines such as "[0.0000000 0.0000000] 0.0000000 setdash", which should be "[] 0 setdash",
     // we first check if all components of stroke_dash.dash are 0.
     bool LineSolid = true;
-    if (style->stroke_dasharray_set &&
-        style->stroke_dash.n_dash   &&
+    if (style->stroke_dash.n_dash   &&
         style->stroke_dash.dash       )
     {
         int i = 0;
@@ -784,44 +791,6 @@ PrintPS::image(Inkscape::Extension::Print *mod, guchar *px, unsigned int w, unsi
     if (_bitmap) return 0;
 
     return print_image(_stream, px, w, h, rs, transform);
-#if 0
-    fprintf(_stream, "gsave\n");
-    fprintf(_stream, "/rowdata %d string def\n", 3 * w);
-    fprintf(_stream, "[%g %g %g %g %g %g] concat\n",
-            transform->c[0],
-            transform->c[1],
-            transform->c[2],
-            transform->c[3],
-            transform->c[4],
-            transform->c[5]);
-    fprintf(_stream, "%d %d 8 [%d 0 0 -%d 0 %d]\n", w, h, w, h, h);
-    fprintf(_stream, "{currentfile rowdata readhexstring pop}\n");
-    fprintf(_stream, "false 3 colorimage\n");
-
-    for (unsigned int r = 0; r < h; r++) {
-        guchar *s;
-        unsigned int c0, c1, c;
-        s = px + r * rs;
-        for (c0 = 0; c0 < w; c0 += 24) {
-            c1 = MIN(w, c0 + 24);
-            for (c = c0; c < c1; c++) {
-                static char const xtab[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
-                fputc(xtab[s[0] >> 4], _stream);
-                fputc(xtab[s[0] & 0xf], _stream);
-                fputc(xtab[s[1] >> 4], _stream);
-                fputc(xtab[s[1] & 0xf], _stream);
-                fputc(xtab[s[2] >> 4], _stream);
-                fputc(xtab[s[2] & 0xf], _stream);
-                s += 4;
-            }
-            fputs("\n", _stream);
-        }
-    }
-
-    fprintf(_stream, "grestore\n");
-
-    return 0;
-#endif
 }
 
 char const *
@@ -1142,85 +1111,87 @@ PrintPS::print_image(FILE *ofp, guchar *px, unsigned int width, unsigned int hei
     Inkscape::SVGOStringStream os;
 
     os << "gsave\n";
+
     os << "[" << transform->c[0] << " "
        << transform->c[1] << " "
        << transform->c[2] << " "
        << transform->c[3] << " "
        << transform->c[4] << " "
        << transform->c[5] << "] concat\n";
-    os << width << " " << height << " 8 ["
-       << width << " 0 0 -" << height << " 0 " << height << "]\n";
-
 
     /* Write read image procedure */
-    os << "% Strings to hold RGB-samples per scanline\n";
-    os << "/rstr " << width << " string def\n";
-    os << "/gstr " << width << " string def\n";
-    os << "/bstr " << width << " string def\n";
-    os << "{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}\n";
-    os << "{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}\n";
-    os << "{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}\n";
-    os << "true 3\n";
+    os << "<<\n";
+    os << "  /ImageType 3\n";
+    os << "  /InterleaveType 1\n";
+
+    os << "  /MaskDict\n";
+    os << "  <<\n";
+    os << "    /ImageType 1\n";
+    os << "    /Width " << width << "\n";
+    os << "    /Height " << height << "\n";
+    os << "    /ImageMatrix "
+       << "[" << transform->c[0] << " "
+       << transform->c[1] << " "
+       << transform->c[2] << " "
+       << transform->c[3] << " "
+       << 0 << " "
+       << height << "]\n";
+    os << "    /BitsPerComponent 8\n";
+    os << "    /Decode [1 0]\n";
+    os << "  >>\n";
+
+    os << "  /DataDict\n";
+    os << "  <<\n";
+    os << "    /ImageType 1\n";
+    os << "    /Width " << width << "\n";
+    os << "    /Height " << height << "\n";
+    os << "    /ImageMatrix "
+       << "[" << transform->c[0] << " "
+       << transform->c[1] << " "
+       << transform->c[2] << " "
+       << transform->c[3] << " "
+       << 0 << " "
+       << height << "]\n";
+    os << "    /DataSource currentfile /ASCII85Decode filter\n";
+    os << "    /BitsPerComponent 8\n";
+    os << "    /Decode [0 1 0 1 0 1]\n";
+    os << "  >>\n";
+
+    os << ">>\n";
 
     /* Allocate buffer for packbits data. Worst case: Less than 1% increase */
-    guchar *const packb = (guchar *)g_malloc((width * 105)/100+2);
-    guchar *const plane = (guchar *)g_malloc(width);
+    guchar *const packb = (guchar *)g_malloc((4*width * 105)/100+2);
+    guchar *const plane = (guchar *)g_malloc(4*width);
 
-    /* ps_begin_data(ofp); */
-    os << "colorimage\n";
-
-/*#define GET_RGB_TILE(begin)                   \
- *  {int scan_lines;                                                    \
- *    scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i); \
- *    gimp_pixel_rgn_get_rect(&pixel_rgn, begin, 0, i, width, scan_lines); \
- *    src = begin; }
- */
+    os << "image\n";
 
+    ascii85_init();
+    
     for (unsigned i = 0; i < height; i++) {
-        /* if ((i % tile_height) == 0) GET_RGB_TILE(data); */ /* Get more data */
         guchar const *const src = px + i * rs;
 
-        /* Iterate over RGB */
-        for (int rgb = 0; rgb < 3; rgb++) {
-            guchar const *src_ptr = src + rgb;
-            guchar *plane_ptr = plane;
-            for (unsigned j = 0; j < width; j++) {
-                *(plane_ptr++) = *src_ptr;
-                src_ptr += 4;
-            }
-
-            int nout;
-            compress_packbits(width, plane, &nout, packb);
-
-            ascii85_init();
-            ascii85_nout(nout, packb, os);
-            ascii85_out(128, os); /* Write EOD of RunLengthDecode filter */
-            ascii85_done(os);
+        guchar const *src_ptr = src;
+        guchar *plane_ptr = plane;
+        for (unsigned j = 0; j < width; j++) {
+            *(plane_ptr++) = *(src_ptr+3);
+            *(plane_ptr++) = *(src_ptr+0);
+            *(plane_ptr++) = *(src_ptr+1);
+            *(plane_ptr++) = *(src_ptr+2);
+            src_ptr += 4;
         }
+        
+        ascii85_nout(4*width, plane, os);
     }
-    /* ps_end_data(ofp); */
-
-#if 0
-    fprintf(ofp, "showpage\n");
-    g_free(data);
-#endif
+    ascii85_done(os);
 
     g_free(packb);
     g_free(plane);
 
-#if 0
-    if (ferror(ofp)) {
-        g_message(_("write error occurred"));
-        return (FALSE);
-    }
-#endif
-
     os << "grestore\n";
 
     fprintf(ofp, "%s", os.str().c_str());
 
     return 0;
-//#undef GET_RGB_TILE
 }
 
 bool