View Issue Details

IDProjectCategoryView StatusLast Update
0016073ScribusPDFpublic2020-03-28 14:53
ReporterPontobart Assigned Tojghali  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version1.5.6.svn 
Target VersionFixed in Version1.5.6.svn 
Summary0016073: Fixing some clip handling issues in PDF import
DescriptionThe attached patch fixes the import of the file Option 5(1).pdf from https://bugs.scribus.net/view.php?id=15855 as far as I can see.

Currently the clipping path is using FPointArray which does not remember the fill rule to use as far as I see. This results in the clipping path operations not correctly tracking the rule to be applied. The patch uses QPainterPath to track the clip which also keeps track of the fill rule. Changes:

a) clip() and eoClip() now use the correct fill rule for the new path and correctly intersect it with the exisiting clip path.
b) fill() and eoFill() did not apply the clip at all. This is fixed.
c) For images we intersect the image area with the clip. The result is that some images do not span the whole page after being imported.

There are two issues that might/should be fixed in the future:
a) QPainterPath sometimes converts bezier curves into an approximation with line segments. See some of the boxes in Option 5(1).pdf
b) An empty clip path should be treated as nothing to print. However, currently an empty clip path is interpreted as no restriction at all. Instead for each new page the clip path should be initialized with the media box or crop box.
Steps To ReproduceStart scribus ../path/to/file/Option\ 5\(1\).pdf
TagsNo tags attached.
PatchYes

Activities

Pontobart

2020-03-25 20:04

reporter  

clipping_path_improvements.diff (15,820 bytes)
Index: scribus/plugins/import/pdf/slaoutput.cpp
===================================================================
--- scribus/plugins/import/pdf/slaoutput.cpp	(Revision 23535)
+++ scribus/plugins/import/pdf/slaoutput.cpp	(Arbeitskopie)
@@ -1298,8 +1298,7 @@
 	m_actPage = pageNum;
 	m_groupStack.clear();
 	pushGroup();
-	m_currentClipPath.resize(0);
-	m_currentClipPath.svgInit();
+	m_currentClipPath.clear();
 	m_clipPaths.clear();
 }
 
@@ -1358,10 +1357,10 @@
 				PageItem *ite = m_doc->groupObjectsSelection(tmpSel);
 				if (ite)
 				{
-					FPointArray out = m_currentClipPath.copy();
-					out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
-					out.translate(-ite->xPos(), -ite->yPos());
-					ite->PoLine = out.copy();
+					QPainterPath clippath = m_currentClipPath;
+					clippath.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
+					clippath.translate(-ite->xPos(), -ite->yPos());
+					ite->PoLine.fromQPainterPath(clippath, true);
 					ite->ClipEdited = true;
 					ite->FrameType = 3;
 					ite->setTextFlowMode(PageItem::TextFlowDisabled);
@@ -1486,10 +1485,10 @@
 		ite->FrameType = 3;
 		if (checkClip())
 		{
-			FPointArray out = m_currentClipPath.copy();
-			out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
-			out.translate(-ite->xPos(), -ite->yPos());
-			ite->PoLine = out.copy();
+			QPainterPath clippath = m_currentClipPath;
+			clippath.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
+			clippath.translate(-ite->xPos(), -ite->yPos());
+			ite->PoLine.fromQPainterPath(clippath, true);
 			ite->ClipEdited = true;
 			ite->FrameType = 3;
 			ite->setTextFlowMode(PageItem::TextFlowDisabled);
@@ -1557,75 +1556,39 @@
 void SlaOutputDev::clip(GfxState *state)
 {
 //	qDebug() << "Clip";
-	const double *ctm;
-	ctm = state->getCTM();
-	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
-	QString output = convertPath(state->getPath());
-	if (output.isEmpty())
-		return;
-
-	FPointArray out;
-	out.parseSVG(output);
-	out.svgClosePath();
-	out.map(m_ctm);
-	if (checkClip())
-	{
-		QPainterPath pathN = out.toQPainterPath(true);
-		QPainterPath pathA = m_currentClipPath.toQPainterPath(true);
-		QPainterPath resultPath = pathA.intersected(pathN);
-		if (!resultPath.isEmpty())
-		{
-			FPointArray polyline;
-			polyline.resize(0);
-			polyline.fromQPainterPath(resultPath, true);
-			polyline.svgClosePath();
-			m_currentClipPath = polyline.copy();
-		}
-		else
-		{
-			m_currentClipPath.resize(0);
-			m_currentClipPath.svgInit();
-		}
-	}
-	else
-		m_currentClipPath = out.copy();
+	adjustClip(state, Qt::WindingFill);
 }
 
 void SlaOutputDev::eoClip(GfxState *state)
 {
 //	qDebug() << "EoClip";
-	const double *ctm;
-	ctm = state->getCTM();
+	adjustClip(state, Qt::OddEvenFill);
+}
+
+void SlaOutputDev::adjustClip(GfxState *state, Qt::FillRule fillRule)
+{
+	const double *ctm = state->getCTM();
 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
 	QString output = convertPath(state->getPath());
+	if (output.isEmpty())
+		return;
 	FPointArray out;
-	if (!output.isEmpty())
-	{
 		out.parseSVG(output);
 		out.svgClosePath();
 		out.map(m_ctm);
 		if (checkClip())
 		{
-			QPainterPath pathN = out.toQPainterPath(true);
-			QPainterPath pathA = m_currentClipPath.toQPainterPath(true);
-			QPainterPath resultPath = pathA.intersected(pathN);
-			if (!resultPath.isEmpty())
-			{
-				FPointArray polyline;
-				polyline.resize(0);
-				polyline.fromQPainterPath(resultPath, true);
-				polyline.svgClosePath();
-				m_currentClipPath = polyline.copy();
+		// "clip" (WindingFill) and "eoClip" (OddEvenFill) only the determine
+		// the fill rule of the new clipping path. The new clip should be the
+		// intersection of the old and new area. QPainterPath determines on
+		// its own which fill rule to use for the result. We should not loose
+		// this information.
+		QPainterPath pathN = out.toQPainterPath(false);
+		pathN.setFillRule(fillRule);
+		m_currentClipPath = pathN.intersected(m_currentClipPath);
 			}
 			else
-			{
-				m_currentClipPath.resize(0);
-				m_currentClipPath.svgInit();
-			}
-		}
-		else
-			m_currentClipPath = out.copy();
-	}
+		m_currentClipPath = out.toQPainterPath(false);
 }
 
 void SlaOutputDev::stroke(GfxState *state)
@@ -1723,51 +1686,17 @@
 void SlaOutputDev::fill(GfxState *state)
 {
 //	qDebug() << "Fill";
-	const double *ctm;
-	ctm = state->getCTM();
-	double xCoor = m_doc->currentPage()->xOffset();
-	double yCoor = m_doc->currentPage()->yOffset();
-	FPointArray out;
-	QString output = convertPath(state->getPath());
-	out.parseSVG(output);
-	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
-	out.map(m_ctm);
-	Coords = output;
-	FPoint wh = out.widthHeight();
-	if ((out.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)))
-	{
-		CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &CurrFillShade);
-		int z;
-		if (pathIsClosed)
-			z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None);
-		else
-			z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None);
-		PageItem* ite = m_doc->Items->at(z);
-		ite->PoLine = out.copy();
-		ite->ClipEdited = true;
-		ite->FrameType = 3;
-		ite->setFillShade(CurrFillShade);
-		ite->setLineShade(100);
-		ite->setFillEvenOdd(false);
-		ite->setFillTransparency(1.0 - state->getFillOpacity());
-		ite->setFillBlendmode(getBlendMode(state));
-		ite->setLineEnd(PLineEnd);
-		ite->setLineJoin(PLineJoin);
-		ite->setWidthHeight(wh.x(),wh.y());
-		ite->setTextFlowMode(PageItem::TextFlowDisabled);
-		m_doc->adjustItemSize(ite);
-		m_Elements->append(ite);
-		if (m_groupStack.count() != 0)
-		{
-			m_groupStack.top().Items.append(ite);
-			applyMask(ite);
-		}
-	}
+	createFillItem(state, Qt::WindingFill);
 }
 
 void SlaOutputDev::eoFill(GfxState *state)
 {
 //	qDebug() << "EoFill";
+	createFillItem(state, Qt::OddEvenFill);
+}
+
+void SlaOutputDev::createFillItem(GfxState *state, Qt::FillRule fillRule)
+{
 	const double *ctm;
 	ctm = state->getCTM();
 	double xCoor = m_doc->currentPage()->xOffset();
@@ -1777,9 +1706,15 @@
 	out.parseSVG(output);
 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
 	out.map(m_ctm);
+
+	// Clip the new path first and only add it if it is not empty.
+	QPainterPath path = out.toQPainterPath(false);
+	path.setFillRule(fillRule);
+	QPainterPath clippedPath = path.intersected(m_currentClipPath);
+
 	Coords = output;
-	FPoint wh = out.widthHeight();
-	if ((out.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)))
+	QRectF bbox = clippedPath.boundingRect();
+    if (!clippedPath.isEmpty() && !bbox.isNull())
 	{
 		CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &CurrFillShade);
 		int z;
@@ -1788,17 +1723,20 @@
 		else
 			z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None);
 		PageItem* ite = m_doc->Items->at(z);
-		ite->PoLine = out.copy();
+		ite->PoLine.fromQPainterPath(clippedPath, true);
 		ite->ClipEdited = true;
 		ite->FrameType = 3;
 		ite->setFillShade(CurrFillShade);
 		ite->setLineShade(100);
-		ite->setFillEvenOdd(true);
+		// Only the new path has to be interpreted according to fillRule. QPainterPath
+		// could decide to create a final path according to the other rule. Thus
+		// we have to set this from the final path.
+		ite->setFillEvenOdd(clippedPath.fillRule() == Qt::OddEvenFill);
 		ite->setFillTransparency(1.0 - state->getFillOpacity());
 		ite->setFillBlendmode(getBlendMode(state));
 		ite->setLineEnd(PLineEnd);
 		ite->setLineJoin(PLineJoin);
-		ite->setWidthHeight(wh.x(),wh.y());
+		ite->setWidthHeight(bbox.width(),bbox.height());
 		ite->setTextFlowMode(PageItem::TextFlowDisabled);
 		m_doc->adjustItemSize(ite);
 		m_Elements->append(ite);
@@ -1812,6 +1750,7 @@
 
 GBool SlaOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax)
 {
+//	qDebug() << "SlaOutputDev::axialShadedFill";
 	double GrStartX;
 	double GrStartY;
 	double GrEndX;
@@ -1884,16 +1823,16 @@
 	PageItem* ite = m_doc->Items->at(z);
 	if (checkClip())
 	{
-		FPointArray out = m_currentClipPath.copy();
+		QPainterPath out = m_currentClipPath;
 		out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
 		out.translate(-ite->xPos(), -ite->yPos());
-		ite->PoLine = out.copy();
+		ite->PoLine.fromQPainterPath(out, true);
+		ite->setFillEvenOdd(out.fillRule() == Qt::OddEvenFill);
 	}
 	ite->ClipEdited = true;
 	ite->FrameType = 3;
 	ite->setFillShade(CurrFillShade);
 	ite->setLineShade(100);
-	ite->setFillEvenOdd(false);
 	ite->setFillTransparency(1.0 - state->getFillOpacity());
 	ite->setFillBlendmode(getBlendMode(state));
 	ite->setLineEnd(PLineEnd);
@@ -1924,6 +1863,7 @@
 
 GBool SlaOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax)
 {
+//	qDebug() << "SlaOutputDev::radialShadedFill";
 	double GrStartX;
 	double GrStartY;
 	double GrEndX;
@@ -2004,16 +1944,16 @@
 	PageItem* ite = m_doc->Items->at(z);
 	if (checkClip())
 	{
-		FPointArray out = m_currentClipPath.copy();
+		QPainterPath out = m_currentClipPath;
 		out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
 		out.translate(-ite->xPos(), -ite->yPos());
-		ite->PoLine = out.copy();
+		ite->PoLine.fromQPainterPath(out, true);
+		ite->setFillEvenOdd(out.fillRule() == Qt::OddEvenFill);
 	}
 	ite->ClipEdited = true;
 	ite->FrameType = 3;
 	ite->setFillShade(CurrFillShade);
 	ite->setLineShade(100);
-	ite->setFillEvenOdd(false);
 	ite->setFillTransparency(1.0 - state->getFillOpacity());
 	ite->setFillBlendmode(getBlendMode(state));
 	ite->setLineEnd(PLineEnd);
@@ -2044,6 +1984,7 @@
 
 GBool SlaOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading)
 {
+//	qDebug() << "SlaOutputDev::gouraudTriangleShadedFill";
 	double xCoor = m_doc->currentPage()->xOffset();
 	double yCoor = m_doc->currentPage()->yOffset();
 	double xmin, ymin, xmax, ymax;
@@ -2123,7 +2064,7 @@
 
 GBool SlaOutputDev::patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading)
 {
-//	qDebug() << "mesh shaded fill";
+//	qDebug() << "SlaOutputDev::patchMeshShadedFill";
 	double xCoor = m_doc->currentPage()->xOffset();
 	double yCoor = m_doc->currentPage()->yOffset();
 	double xmin, ymin, xmax, ymax;
@@ -2272,6 +2213,7 @@
 
 GBool SlaOutputDev::tilingPatternFill(GfxState *state, Gfx * /*gfx*/, Catalog *cat, Object *str, POPPLER_CONST_070 double *pmat, int paintType, int tilingType, Dict *resDict, POPPLER_CONST_070 double *mat, POPPLER_CONST_070 double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep)
 {
+//	qDebug() << "SlaOutputDev::tilingPatternFill";
 	PDFRectangle box;
 	Gfx *gfx;
 	QString id;
@@ -2360,16 +2302,16 @@
 	ite = m_doc->Items->at(z);
 	if (checkClip())
 	{
-		FPointArray out = m_currentClipPath.copy();
+		QPainterPath out = m_currentClipPath;
 		out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
 		out.translate(-ite->xPos(), -ite->yPos());
-		ite->PoLine = out.copy();
+		ite->PoLine.fromQPainterPath(out, true);
+		ite->setFillEvenOdd(out.fillRule() == Qt::OddEvenFill);
 	}
 	ite->ClipEdited = true;
 	ite->FrameType = 3;
 	ite->setFillShade(CurrFillShade);
 	ite->setLineShade(100);
-	ite->setFillEvenOdd(false);
 	ite->setFillTransparency(1.0 - state->getFillOpacity());
 	ite->setFillBlendmode(getBlendMode(state));
 	ite->setLineEnd(PLineEnd);
@@ -2700,6 +2642,17 @@
 		torigin = m_ctm.map(QPointF(0, 1));
 	}
 
+	// Determine the visible area of the picture after clipping it. If it is empty, no item
+	// needs to be created.
+	QPainterPath outline;
+	outline.addRect(0, 0, 1, 1);
+	outline = m_ctm.map(outline);
+	if (!m_currentClipPath.isEmpty())
+		outline = outline.intersected(m_currentClipPath);
+
+	if ((inPattern == 0) && (outline.isEmpty() || outline.boundingRect().isNull()))
+		return;
+
     // Determine the width and height of the image by undoing the rotation part
 	// of the CTM and applying the result to the unit square.
 	QTransform without_rotation; 
@@ -2798,20 +2751,15 @@
 		}
 		delete tempFile;
 	}
-	if ((checkClip()) && (inPattern == 0))
+	if (inPattern == 0)
 	{
-		FPointArray out = m_currentClipPath.copy();
+		outline.translate(xCoor - ite->xPos(), yCoor - ite->yPos());
+		// Undo the rotation of the clipping path as it is rotated together with the iamge.
 		QTransform mm;
 		mm.rotate(-ite->rotation());
-		out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
-		out.translate(-ite->xPos(), -ite->yPos());
-		// Undo the rotation of the clipping path as it is rotated together with the iamge.
-		for (int i = 0; i != out.size(); ++i)
-		{
-			QPointF p = mm.map(out.pointQF(i));
-			out.setPoint(i, p.x(), p.y());
-		}
-		ite->PoLine = out.copy();
+		outline = mm.map(outline);
+		ite->PoLine.fromQPainterPath(outline, true);
+		ite->setFillEvenOdd(outline.fillRule() == Qt::OddEvenFill);
 		ite->ClipEdited = true;
 		ite->FrameType = 3;
 		ite->setTextFlowMode(PageItem::TextFlowDisabled);
@@ -3536,6 +3484,7 @@
 
 QString SlaOutputDev::convertPath(POPPLER_CONST_083 GfxPath *path)
 {
+//	qDebug() << "SlaOutputDev::convertPath";
 	if (! path)
 		return QString();
 
@@ -3798,10 +3747,10 @@
 bool SlaOutputDev::checkClip()
 {
 	bool ret = false;
-	if (m_currentClipPath.count() != 0)
+	if (!m_currentClipPath.isEmpty())
 	{
-		FPoint wh = m_currentClipPath.widthHeight();
-		if ((wh.x() > 0) && (wh.y() > 0))
+		QRectF bbox = m_currentClipPath.boundingRect();
+		if ((bbox.width() > 0) && (bbox.height() > 0))
 			ret = true;
 	}
 	return ret;
Index: scribus/plugins/import/pdf/slaoutput.h
===================================================================
--- scribus/plugins/import/pdf/slaoutput.h	(Revision 23535)
+++ scribus/plugins/import/pdf/slaoutput.h	(Arbeitskopie)
@@ -296,6 +296,14 @@
 	QString UnicodeParsedString(const std::string& s1);
 	bool checkClip();
 
+	// Intersect the current clip path with the new path in state where filled areas
+	// are interpreted according to fillRule.
+	void adjustClip(GfxState *state, Qt::FillRule fillRule);
+
+	// Take the current path of state and interpret it according to fillRule,
+	// intersect it with the clipping path and create a new pageitem for it.
+	void createFillItem(GfxState *state, Qt::FillRule fillRule);
+
 	void createImageFrame(QImage& image, GfxState *state, int numColorComponents);
 
 	bool pathIsClosed {false};
@@ -308,8 +316,15 @@
 	QVector<double> DashValues;
 	double DashOffset {0.0};
 	QString Coords;
-	FPointArray m_currentClipPath;
-	QStack<FPointArray> m_clipPaths;
+	// The currently visible area. If it is empty, everything is visible.
+	// QPainterPath has the drawback that it sometimes approximates Bezier curves
+	// by line segments for numerical stability. If available, a better class
+	// should be used. However, it is important that the used class knows which
+	// areas are covered and does not rely on external information about the fill
+	// rule to use.
+	QPainterPath m_currentClipPath;
+	QStack<QPainterPath> m_clipPaths;
+
 	struct groupEntry
 	{
 		QList<PageItem*> Items;

jghali

2020-03-26 00:31

administrator   ~0047456

Niiice! Thanks. I've applied your patch with a slight modification in order to remove usage of QPainterPath::clear(). This function has been introduced in Qt 5.13 and at this point we support Qt 5.11.

jghali

2020-03-26 01:30

administrator   ~0047460

It seems there is something wrong tho with the added test for image visible area in SlaOutputDev::createImageFrame():
QPainterPath outline;
outline.addRect(0, 0, 1, 1);
outline = m_ctm.map(outline);
if (!m_currentClipPath.isEmpty())
    outline = outline.intersected(m_currentClipPath);

if ((inPattern == 0) && (outline.isEmpty() || outline.boundingRect().isNull()))
    return;

This test apparently prevent some images to be imported correctly. Take for example the sample file of issue 0015865. These lines prevent the image at the top of the page to be correctly imported. Without these lines, import would be correct.

Pontobart

2020-03-26 07:33

reporter   ~0047462

It a quick glance this looks like a bug in Qt.

I have printed the clip, the outline and the intersection:

m_currentClipPath: QPainterPath: Element count=5
-> MoveTo(x=52.436, y=84.1364)
-> LineTo(x=349.348, y=63.3732)
-> LineTo(x=364.92, y=286.057)
-> LineTo(x=68.0084, y=306.82)
-> LineTo(x=52.436, y=84.1364)
Qt::OddEvenFill

outline: QPainterPath: Element count=5
-> MoveTo(x=68.0065, y=306.792)
-> LineTo(x=364.88, y=286.031)
-> LineTo(x=349.31, y=63.3758)
-> LineTo(x=52.436, y=84.1364)
-> LineTo(x=68.0065, y=306.792)
Qt::OddEvenFill

intersection: QPainterPath: Element count=0

There are small diffferences in the coordinates, but the intersection should be the large area and not empty. I'll try to take a look later.

jghali

2020-03-26 11:43

administrator   ~0047466

It seems there are also clipping issues when importing PDF such as this one.

15818_gradient_transparency_group_disappear.pdf (29,179 bytes)

jghali

2020-03-26 12:33

administrator   ~0047467

Astonishingly using:
outline = m_currentClipPath.intersected(outline);
instead of:
outline = outline.intersected(m_currentClipPath);
seems to work better...

Pontobart

2020-03-26 13:43

reporter   ~0047470

This is a bug in QPainterPath:
https://bugreports.qt.io/browse/QTBUG-83102

Seems like an alternative is necessary.

Pontobart

2020-03-26 21:59

reporter   ~0047476

This one reverts the additional clip in createImageFrame and should make the file from 0015865 work.

The other file needs a deeper look. The handling of masks is not yet correct.

do_not_clip_imagees_on_outline.diff (1,229 bytes)
Index: scribus/plugins/import/pdf/slaoutput.cpp
===================================================================
--- scribus/plugins/import/pdf/slaoutput.cpp	(Revision 23539)
+++ scribus/plugins/import/pdf/slaoutput.cpp	(Arbeitskopie)
@@ -2642,17 +2642,6 @@
 		torigin = m_ctm.map(QPointF(0, 1));
 	}
 
-	// Determine the visible area of the picture after clipping it. If it is empty, no item
-	// needs to be created.
-	QPainterPath outline;
-	outline.addRect(0, 0, 1, 1);
-	outline = m_ctm.map(outline);
-	if (!m_currentClipPath.isEmpty())
-		outline = m_currentClipPath.intersected(outline);
-
-	if ((inPattern == 0) && (outline.isEmpty() || outline.boundingRect().isNull()))
-		return;
-
     // Determine the width and height of the image by undoing the rotation part
 	// of the CTM and applying the result to the unit square.
 	QTransform without_rotation; 
@@ -2751,8 +2740,10 @@
 		}
 		delete tempFile;
 	}
-	if (inPattern == 0)
+
+	if (checkClip() && (inPattern == 0))
 	{
+		QPainterPath outline = m_currentClipPath;
 		outline.translate(xCoor - ite->xPos(), yCoor - ite->yPos());
 		// Undo the rotation of the clipping path as it is rotated together with the iamge.
 		QTransform mm;

jghali

2020-03-28 12:15

administrator   ~0047479

Here is as requested on irc the sla which was used to create 15818_gradient_transparency_group_disappear.pdf

15818_gradient_transparency_group_disappear.sla (33,310 bytes)

jghali

2020-03-28 13:53

administrator   ~0047480

Last edited: 2020-03-28 14:53

View 2 revisions

With r23538, the file from 0015865 already works as well as several other test files I have in my possession. So I'm tempted to leave the code as is for now despite that potential QPainterPath::intersected() issue. If you look at the other sample attached to 0015865, swimming-howto.pdf, it is also now correctly imported and reverting to the old code would now cause somewhat a regression.

Issue History

Date Modified Username Field Change
2020-03-25 20:04 Pontobart New Issue
2020-03-25 20:04 Pontobart File Added: clipping_path_improvements.diff
2020-03-26 00:31 jghali Assigned To => jghali
2020-03-26 00:31 jghali Status new => resolved
2020-03-26 00:31 jghali Resolution open => fixed
2020-03-26 00:31 jghali Fixed in Version => 1.5.6.svn
2020-03-26 00:31 jghali Note Added: 0047456
2020-03-26 01:30 jghali Note Added: 0047460
2020-03-26 07:33 Pontobart Note Added: 0047462
2020-03-26 11:43 jghali File Added: 15818_gradient_transparency_group_disappear.pdf
2020-03-26 11:43 jghali Note Added: 0047466
2020-03-26 12:33 jghali Note Added: 0047467
2020-03-26 13:43 Pontobart Note Added: 0047470
2020-03-26 21:59 Pontobart File Added: do_not_clip_imagees_on_outline.diff
2020-03-26 21:59 Pontobart Note Added: 0047476
2020-03-28 12:15 jghali File Added: 15818_gradient_transparency_group_disappear.sla
2020-03-28 12:15 jghali Note Added: 0047479
2020-03-28 13:53 jghali Note Added: 0047480
2020-03-28 14:53 jghali Note Edited: 0047480 View Revisions