View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0007500 | Scribus | public | 2008-10-15 22:31 | 2016-01-14 01:20 | |
Reporter | pspencer | Assigned To | fschmid | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | Linux | OS | Fedora | OS Version | 8 |
Product Version | 1.3.5svn | ||||
Fixed in Version | 1.3.5svn | ||||
Summary | 0007500: Documents with Render Frames Result in PDF Files With Invalid Closepath Operators | ||||
Description | When you export to PDF a document containing a render frame, the render frame is not visible when you view the PDF in Adobe Reader or Ghostscript. When you view it with XPDF/Evince, the error message "Error: No current point in closepath" is generated, but the document is viewable just fine. The problem seems to be with the code in pdflib_core.cpp that attempts to clip the embedded pdf. It contains many occurrences of code similar to PutPage(SetClipPath(ite)); PutPage("h\nW*\nn\n"); If ite is empty, the first PutPage outputs the empty string. The second PutPage generates the pdf commands "h", "W*", and "n" -- and "h" is apparently not a valid operator when no current point has been set. I don't know why it's not valid, since the PostScript equivalent operator "closepath" is permitted (and does nothing) in the absence of a current point, but apparently it's not, and causes Adobe Reader to choke on the whole object. I would suggest moving the generation of "h" -- and perhaps of the other operators too -- to inside the SetClipPath routine, where they would be output conditionally on a path having been built. The attached patch implements this as follows (but will require some checking for typos etc. due to the sheer number of similar lines involved): (1) It adds an extra QString argument, opPath, to the SetClipPath, SetClipPathImage, and SetClipPathArray routines. (2) It modifies each of those routines as follows: - Upon completion of the loop through the list, the "h" operator is added but ONLY if nPath is false (meaning a path segment has begun but is not yet closed). And, for the routines that take the optional "poly" argument, the "h" is added only when "poly && ! nPath". - Finally, if the routine produced code at all, it appends the opPath text, but if it has just generated the empty string, the opPath text is omitted. (3) It changes each call to one of those routines, passing the appropriate opPath. For example, the lines PutPage(SetClipPath(ite)); PutPage("h\nW*\nn\n"); are replaced with PutPage(SetClipPath(ite, "W*\nn\n") I think this is probably the cleanest and safest way to solve the problem but I am completely new to Scribus so there may be a better solution. | ||||
Tags | No tags attached. | ||||
Patch | |||||
2008-10-15 22:31
|
scribus-pdf.patch (15,779 bytes)
--- Scribus/scribus/pdflib_core.cpp.badpdf 2008-10-14 14:01:51.000000000 -0400 +++ Scribus/scribus/pdflib_core.cpp 2008-10-15 17:03:41.000000000 -0400 @@ -1870,18 +1870,15 @@ } else { - PutPage(SetClipPath(ite)); - PutPage("h\nf*\n"); + PutPage(SetClipPath(ite, "f*\n")); } } PutPage("q\n"); if (ite->imageClip.size() != 0) { - PutPage(SetClipPathImage(ite)); - PutPage("h\nW*\nn\n"); + PutPage(SetClipPathImage(ite, "W*\nn\n")); } - PutPage(SetClipPath(ite)); - PutPage("h\nW*\nn\n"); + PutPage(SetClipPath(ite, "W*\nn\n")); if (ite->imageFlippedH()) PutPage("-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n"); if (ite->imageFlippedV()) @@ -1899,8 +1896,7 @@ PutPage(PDF_TransparenzStroke(ite)); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - PutPage(SetClipPath(ite)); - PutPage("h\nS\n"); + PutPage(SetClipPath(ite, "S\n")); } else { @@ -1910,8 +1906,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { PutPage(setStrokeMulti(&ml[it])); - PutPage(SetClipPath(ite)); - PutPage("h\nS\n"); + PutPage(SetClipPath(ite, "S\n")); } } } @@ -1961,8 +1956,7 @@ PutPage("/"+ShName+" gs\n"); } PutPage(putColor(ite->lineColor(), ite->lineShade(), true)); - PutPage(SetClipPathArray(&arrow)); - PutPage("h\nf*\n"); + PutPage(SetClipPathArray(&arrow,"f*\n")); } if (ite->endArrowIndex() != 0) { @@ -1982,8 +1976,7 @@ PutPage("/"+ShName+" gs\n"); } PutPage(putColor(ite->lineColor(), ite->lineShade(), true)); - PutPage(SetClipPathArray(&arrow)); - PutPage("h\nf*\n"); + PutPage(SetClipPathArray(&arrow, "f*\n")); } break; case PageItem::ItemType1: @@ -2001,8 +1994,7 @@ { if (ite->fillColor() != CommonStrings::None) { - PutPage(SetClipPath(ite)); - PutPage("h\nf*\n"); + PutPage(SetClipPath(ite, "f*\n")); } } if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) @@ -2011,8 +2003,7 @@ PutPage(PDF_TransparenzStroke(ite)); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - PutPage(SetClipPath(ite)); - PutPage("h\nS\n"); + PutPage(SetClipPath(ite,"S\n")); } else { @@ -2022,8 +2013,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { PutPage(setStrokeMulti(&ml[it])); - PutPage(SetClipPath(ite)); - PutPage("h\nS\n"); + PutPage(SetClipPath(ite, "S\n")); } } } @@ -2044,8 +2034,7 @@ { if (ite->fillColor() != CommonStrings::None) { - PutPage(SetClipPath(ite)); - PutPage("h\nf*\n"); + PutPage(SetClipPath(ite, "f*\n")); } } } @@ -2055,8 +2044,7 @@ PutPage(PDF_TransparenzStroke(ite)); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - PutPage(SetClipPath(ite, false)); - PutPage("S\n"); + PutPage(SetClipPath(ite, "S\n", false)); } else { @@ -2066,8 +2054,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { PutPage(setStrokeMulti(&ml[it])); - PutPage(SetClipPath(ite, false)); - PutPage("S\n"); + PutPage(SetClipPath(ite, "S\n", false)); } } } @@ -2098,8 +2085,7 @@ PutPage("/"+ShName+" gs\n"); } PutPage(putColor(ite->lineColor(), ite->lineShade(), true)); - PutPage(SetClipPathArray(&arrow)); - PutPage("h\nf*\n"); + PutPage(SetClipPathArray(&arrow, "f*\n")); break; } } @@ -2130,8 +2116,7 @@ PutPage("/"+ShName+" gs\n"); } PutPage(putColor(ite->lineColor(), ite->lineShade(), true)); - PutPage(SetClipPathArray(&arrow)); - PutPage("h\nf*\n"); + PutPage(SetClipPathArray(&arrow, "f*\n")); break; } } @@ -2149,8 +2134,7 @@ PutPage(PDF_TransparenzStroke(ite)); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - PutPage(SetClipPath(ite, false)); - PutPage("S\n"); + PutPage(SetClipPath(ite, "S\n", false)); } else { @@ -2160,8 +2144,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { PutPage(setStrokeMulti(&ml[it])); - PutPage(SetClipPath(ite, false)); - PutPage("S\n"); + PutPage(SetClipPath(ite, "S\n", false)); } } } @@ -2522,8 +2505,7 @@ // PutPage(EncString("("+docTitle+")",ObjCounter)+" Tj\nET\n"); painter1.addText( QPointF(0.0,0.0), infoFont, docTitle ); textPath.fromQPainterPath(painter1); - PutPage(SetClipPathArray(&textPath, true)); - PutPage("h\nf*\n"); + PutPage(SetClipPathArray(&textPath, "f*\n", true)); PutPage("Q\n"); QDate d = QDate::currentDate(); QString docDate = tr("Date:")+" "+d.toString(Qt::TextDate); @@ -2535,8 +2517,7 @@ // PutPage(EncString("("+ tr("Date:")+" "+d.toString(Qt::TextDate)+")",ObjCounter)+" Tj\nET\n"); painter2.addText( QPointF(0.0,0.0), infoFont, docDate ); textPath.fromQPainterPath(painter2); - PutPage(SetClipPathArray(&textPath, true)); - PutPage("h\nf*\n"); + PutPage(SetClipPathArray(&textPath, "f*\n", true)); PutPage("Q\n"); } } @@ -2859,8 +2840,7 @@ mm.rotate(ite->rotation()); cl.map( mm ); ite->PoLine = cl; - PutPage(SetClipPath(ite)); - PutPage("h W* n\n"); + PutPage(SetClipPath(ite, "W* n\n")); groupStack.push(ite->groupsLastItem); ite->PoLine = clb.copy(); continue; @@ -2958,8 +2938,7 @@ mm.rotate(ite->rotation()); cl.map( mm ); ite->PoLine = cl; - grcon += SetClipPath(ite); - grcon += "h W* n\n"; + grcon += SetClipPath(ite, "W* n\n"); groupStack.push(ite->groupsLastItem); groupStackS.push(ite); if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= 14)) @@ -3415,18 +3394,15 @@ } else { - tmp += SetClipPath(ite); - tmp += "h\nf*\n"; + tmp += SetClipPath(ite, "f*\n"); } } tmp += "q\n"; if (ite->imageClip.size() != 0) { - tmp += SetClipPathImage(ite); - tmp += "h\nW*\nn\n"; + tmp += SetClipPathImage(ite, "W*\nn"); } - tmp += SetClipPath(ite); - tmp += "h\nW*\nn\n"; + tmp += SetClipPath(ite, "W*\nn\n"); if (ite->imageFlippedH()) tmp += "-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n"; if (ite->imageFlippedV()) @@ -3444,8 +3420,7 @@ tmp += PDF_TransparenzStroke(ite); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - tmp += SetClipPath(ite); - tmp += "h\nS\n"; + tmp += SetClipPath(ite, "S\n"); } else { @@ -3455,8 +3430,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { tmp += setStrokeMulti(&ml[it]); - tmp += SetClipPath(ite); - tmp += "h\nS\n"; + tmp += SetClipPath(ite, "S\n"); } } } @@ -3483,8 +3457,7 @@ } else { - tmp += SetClipPath(ite); - tmp += "h\nf*\n"; + tmp += SetClipPath(ite, "f*\n"); } } tmp += "q\n"; @@ -3500,8 +3473,7 @@ tmp += PDF_TransparenzStroke(ite); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - tmp += SetClipPath(ite); - tmp += "h\nS\n"; + tmp += SetClipPath(ite, "S\n"); } else { @@ -3511,8 +3483,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { tmp += setStrokeMulti(&ml[it]); - tmp += SetClipPath(ite); - tmp += "h\nS\n"; + tmp += SetClipPath(ite, "S\n"); } } } @@ -3560,8 +3531,7 @@ tmp += "/"+ShName+" gs\n"; } tmp += putColor(ite->lineColor(), ite->lineShade(), true); - tmp += SetClipPathArray(&arrow); - tmp += "h\nf*\n"; + tmp += SetClipPathArray(&arrow, "f*\n"); } if (ite->endArrowIndex() != 0) { @@ -3581,8 +3551,7 @@ tmp += "/"+ShName+" gs\n"; } tmp += putColor(ite->lineColor(), ite->lineShade(), true); - tmp += SetClipPathArray(&arrow); - tmp += "h\nf*\n"; + tmp += SetClipPathArray(&arrow, "f*\n"); } break; case PageItem::ItemType1: @@ -3600,11 +3569,7 @@ { if (ite->fillColor() != CommonStrings::None) { - tmp += SetClipPath(ite); - if (ite->fillRule) - tmp += "h\nf*\n"; - else - tmp += "h\nf\n"; + tmp += SetClipPath(ite, (ite->fillRule ? "f*\n" : "f\n")); } } if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) @@ -3613,8 +3578,7 @@ tmp += PDF_TransparenzStroke(ite); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - tmp += SetClipPath(ite); - tmp += "h\nS\n"; + tmp += SetClipPath(ite, "S\n"); } else { @@ -3624,8 +3588,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { tmp += setStrokeMulti(&ml[it]); - tmp += SetClipPath(ite); - tmp += "h\nS\n"; + tmp += SetClipPath(ite, "S\n"); } } } @@ -3646,8 +3609,7 @@ { if (ite->fillColor() != CommonStrings::None) { - tmp += SetClipPath(ite); - tmp += "h\nf*\n"; + tmp += SetClipPath(ite, "f*\n"); } } } @@ -3657,8 +3619,7 @@ tmp += PDF_TransparenzStroke(ite); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - tmp += SetClipPath(ite, false); - tmp += "S\n"; + tmp += SetClipPath(ite, "S\n", false); } else { @@ -3668,8 +3629,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { tmp += setStrokeMulti(&ml[it]); - tmp += SetClipPath(ite, false); - tmp += "S\n"; + tmp += SetClipPath(ite, "S\n", false); } } } @@ -3700,8 +3660,7 @@ tmp += "/"+ShName+" gs\n"; } tmp += putColor(ite->lineColor(), ite->lineShade(), true); - tmp += SetClipPathArray(&arrow); - tmp += "h\nf*\n"; + tmp += SetClipPathArray(&arrow, "f*\n"); break; } } @@ -3732,8 +3691,7 @@ tmp += "/"+ShName+" gs\n"; } tmp += putColor(ite->lineColor(), ite->lineShade(), true); - tmp += SetClipPathArray(&arrow); - tmp += "h\nf*\n"; + tmp += SetClipPathArray(&arrow, "f*\n"); break; } } @@ -3751,8 +3709,7 @@ tmp += PDF_TransparenzStroke(ite); if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0)) { - tmp += SetClipPath(ite, false); - tmp += "S\n"; + tmp += SetClipPath(ite, "S\n", false); } else { @@ -3762,8 +3719,7 @@ if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0)) { tmp += setStrokeMulti(&ml[it]); - tmp += SetClipPath(ite, false); - tmp += "S\n"; + tmp += SetClipPath(ite, "S\n", false); } } } @@ -4352,8 +4308,7 @@ mm.rotate(embedded->rotation()); cl.map( mm ); embedded->PoLine = cl; - tmp2 += SetClipPath(embedded); - tmp2 += "h W* n\n"; + tmp2 += SetClipPath(embedded, "W* n\n"); groupStack.push(embedded->groupsLastItem); embedded->PoLine = clb.copy(); continue; @@ -4886,7 +4841,7 @@ return tmp; } -QString PDFLibCore::SetClipPathImage(PageItem *ite) +QString PDFLibCore::SetClipPathImage(PageItem *ite, const QString &pathOp) { QString tmp(""); if (ite->imageClip.size() > 3) @@ -4896,7 +4851,7 @@ { if (ite->imageClip.point(poi).x() > 900000) { - tmp += "h\n"; + if (! nPath) tmp += "h\n"; nPath = true; continue; } @@ -4920,11 +4875,13 @@ tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" c\n"; } } + if (! nPath) tmp += "h\n"; } + if (tmp.length()) tmp += pathOp; return tmp; } -QString PDFLibCore::SetClipPath(PageItem *ite, bool poly) +QString PDFLibCore::SetClipPath(PageItem *ite, const QString &pathOp, bool poly) { QString tmp(""); if (ite->PoLine.size() > 3) @@ -4934,7 +4891,7 @@ { if (ite->PoLine.point(poi).x() > 900000) { - if (poly) + if (poly && ! nPath) tmp += "h\n"; nPath = true; continue; @@ -4959,11 +4916,13 @@ tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" c\n"; } } + if (poly && ! nPath) tmp += "h\n"; } + if (tmp.length()) tmp += pathOp; return tmp; } -QString PDFLibCore::SetClipPathArray(FPointArray *ite, bool poly) +QString PDFLibCore::SetClipPathArray(FPointArray *ite, const QString &pathOp, bool poly) { QString tmp(""); if (ite->size() > 3) @@ -4973,7 +4932,7 @@ { if (ite->point(poi).x() > 900000) { - if (poly) + if (poly && ! nPath) tmp += "h\n"; nPath = true; continue; @@ -4998,7 +4957,9 @@ tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" c\n"; } } + if (poly && ! nPath) tmp += "h\n"; } + if (tmp.length()) tmp += pathOp; return tmp; } @@ -5044,8 +5005,7 @@ mm.rotate(item->rotation()); cl.map( mm ); item->PoLine = cl; - tmp2 += SetClipPath(item); - tmp2 += "h W* n\n"; + tmp2 += SetClipPath(item, "W* n\n"); groupStack.push(item->groupsLastItem); item->PoLine = clb.copy(); continue; @@ -5250,11 +5210,7 @@ Patterns.insert("Pattern"+currItem->pattern()+QString::number(ResCount), patObject); QString tmp = "/Pattern cs\n"; tmp += "/Pattern"+currItem->pattern()+QString::number(ResCount)+" scn\n"; - tmp += SetClipPath(currItem); - if (currItem->fillRule) - tmp += "h\nf*\n"; - else - tmp += "h\nf\n"; + tmp += SetClipPath(currItem, (currItem->fillRule ? "f*\n" : "f\n")); ResCount++; output = tmp; return true; @@ -5391,7 +5347,7 @@ } PutDoc(">>\n"); QString stre = ""; - stre += "q\n"+SetClipPath(currItem)+"h\nW* n\n"+"/"+ShName+" sh\nQ\n"; + stre += "q\n"+SetClipPath(currItem, "W* n\n")+"/"+ShName+" sh\nQ\n"; if (Options.Compress) stre = CompressStr(&stre); PutDoc("/Length "+QString::number(stre.length())+"\n"); @@ -5603,8 +5559,7 @@ tmp += "q\n"; if ((Options.Version >= 14) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1))) tmp += "/"+TRes+" gs\n"; - tmp += SetClipPath(currItem); - tmp += "h\nW* n\n"; + tmp += SetClipPath(currItem, "W* n\n"); tmp += "/"+ShName+" sh\nQ\n"; } return tmp; --- Scribus/scribus/pdflib_core.h.badpdf 2008-10-14 14:01:50.000000000 -0400 +++ Scribus/scribus/pdflib_core.h 2008-10-15 17:01:51.000000000 -0400 @@ -104,9 +104,9 @@ QString FitKey(const QString & pass); QString setStrokeMulti(struct SingleLine *sl); - QString SetClipPathArray(FPointArray *ite, bool poly = true); - QString SetClipPathImage(PageItem *ite); - QString SetClipPath(PageItem *ite, bool poly = true); + QString SetClipPathArray(FPointArray *ite, const QString& pathOp, bool poly = true); + QString SetClipPathImage(PageItem *ite, const QString& pathOp); + QString SetClipPath(PageItem *ite, const QString& pathOp, bool poly = true); QString SetColor(const QString& farbe, double Shade); QString SetColor(const ScColor& farbe, double Shade); QString SetGradientColor(const QString& farbe, double Shade); |
|
This was fixed with committs r12698 and r12700. The whole issue was the fact that the render frames didn't get correctly initialized during creation. Now they have always correct clipping paths. Another issue was the fact that the PDF's generated by pdftex are needing a correct default graphics state (stroke & fill color set to black, linewidth = 1 etc..) in the PDF. |
Date Modified | Username | Field | Change |
---|---|---|---|
2008-10-15 22:31 | pspencer | New Issue | |
2008-10-15 22:31 | pspencer | File Added: scribus-pdf.patch | |
2008-10-16 07:34 | fschmid | Note Added: 0020445 | |
2008-10-16 07:34 | fschmid | Status | new => resolved |
2008-10-16 07:34 | fschmid | Fixed in Version | => 1.3.5svn |
2008-10-16 07:34 | fschmid | Resolution | open => fixed |
2008-10-16 07:34 | fschmid | Assigned To | => fschmid |
2008-12-10 16:26 | mhanski | Relationship added | child of 0007647 |
2008-12-11 22:26 | cbradney | Status | resolved => closed |
2016-01-14 01:20 | JLuc | Relationship added | related to 0013654 |