Skip to content

Commit 8f1e347

Browse files
author
Dmitry Radchuk
committed
Fix not closed path in polygon, circle and ellipse
DEVSIX-2719, DEVSIX-3932
1 parent 9094fb0 commit 8f1e347

File tree

535 files changed

+103
-21
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

535 files changed

+103
-21
lines changed

svg/src/main/java/com/itextpdf/svg/renderers/impl/AbstractSvgNodeRenderer.java

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -319,21 +319,7 @@ void postDraw(SvgDrawContext context) {
319319
if (getParentClipPath() == null) {
320320
if (doFill && canElementFill()) {
321321
String fillRuleRawValue = getAttribute(SvgConstants.Attributes.FILL_RULE);
322-
323-
if (SvgConstants.Values.FILL_RULE_EVEN_ODD.equalsIgnoreCase(fillRuleRawValue)) {
324-
if (doStroke) {
325-
currentCanvas.eoFillStroke();
326-
} else {
327-
currentCanvas.eoFill();
328-
}
329-
} else {
330-
if (doStroke) {
331-
// TODO DEVSIX-8854 Draw SVG elements with transparent stroke in 2 steps
332-
currentCanvas.fillStroke();
333-
} else {
334-
currentCanvas.fill();
335-
}
336-
}
322+
doStrokeOrFill(fillRuleRawValue, currentCanvas);
337323
} else if (doStroke) {
338324
currentCanvas.stroke();
339325
} else {
@@ -360,6 +346,29 @@ void postDraw(SvgDrawContext context) {
360346
}
361347
}
362348

349+
/**
350+
* Do stroke or fill based on {@code doFill/doStroke} fields.
351+
*
352+
* @param fillRuleRawValue fill rule attribute value.
353+
* @param currentCanvas current canvas to draw on.
354+
*/
355+
void doStrokeOrFill(String fillRuleRawValue, PdfCanvas currentCanvas) {
356+
if (SvgConstants.Values.FILL_RULE_EVEN_ODD.equalsIgnoreCase(fillRuleRawValue)) {
357+
if (doStroke) {
358+
currentCanvas.eoFillStroke();
359+
} else {
360+
currentCanvas.eoFill();
361+
}
362+
} else {
363+
if (doStroke) {
364+
// TODO DEVSIX-8854 Draw SVG elements with transparent stroke in 2 steps
365+
currentCanvas.fillStroke();
366+
} else {
367+
currentCanvas.fill();
368+
}
369+
}
370+
}
371+
363372
/**
364373
* Operations to perform before drawing an element.
365374
* This includes setting stroke color and width, fill color.

svg/src/main/java/com/itextpdf/svg/renderers/impl/EllipseSvgNodeRenderer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,9 @@ public ISvgNodeRenderer createDeepCopy() {
117117
return copy;
118118
}
119119

120+
@Override
121+
void doStrokeOrFill(String fillRuleRawValue, PdfCanvas currentCanvas) {
122+
DrawUtils.doStrokeOrFillForClosedFigure(fillRuleRawValue, currentCanvas, doStroke);
123+
}
124+
120125
}

svg/src/main/java/com/itextpdf/svg/renderers/impl/PolygonSvgNodeRenderer.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ This file is part of the iText (R) project.
2323
package com.itextpdf.svg.renderers.impl;
2424

2525
import com.itextpdf.kernel.geom.Point;
26+
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
27+
import com.itextpdf.svg.SvgConstants;
2628
import com.itextpdf.svg.renderers.IMarkerCapable;
2729
import com.itextpdf.svg.renderers.ISvgNodeRenderer;
30+
import com.itextpdf.svg.utils.DrawUtils;
2831

2932
/**
3033
* {@link ISvgNodeRenderer} implementation for the <polygon> tag.
@@ -62,4 +65,9 @@ public ISvgNodeRenderer createDeepCopy() {
6265
deepCopyAttributesAndStyles(copy);
6366
return copy;
6467
}
68+
69+
@Override
70+
void doStrokeOrFill(String fillRuleRawValue, PdfCanvas currentCanvas) {
71+
DrawUtils.doStrokeOrFillForClosedFigure(fillRuleRawValue, currentCanvas, doStroke);
72+
}
6573
}

svg/src/main/java/com/itextpdf/svg/utils/DrawUtils.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ This file is part of the iText (R) project.
2323
package com.itextpdf.svg.utils;
2424

2525
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
26+
import com.itextpdf.svg.SvgConstants;
2627

2728
import java.util.List;
2829

@@ -53,4 +54,27 @@ public static void arc(final double x1, final double y1, final double x2, final
5354
}
5455
}
5556
}
57+
58+
/**
59+
* Perform stroke or fill operation for closed figure (e.g. Ellipse, Polygon, Circle).
60+
*
61+
* @param fillRuleRawValue fill rule (e.g. evenodd, nonzero)
62+
* @param currentCanvas canvas to draw on
63+
* @param doStroke if true, stroke operation will be performed, fill otherwise
64+
*/
65+
public static void doStrokeOrFillForClosedFigure(String fillRuleRawValue, PdfCanvas currentCanvas, boolean doStroke) {
66+
if (SvgConstants.Values.FILL_RULE_EVEN_ODD.equalsIgnoreCase(fillRuleRawValue)) {
67+
if (doStroke) {
68+
currentCanvas.closePathEoFillStroke();
69+
} else {
70+
currentCanvas.eoFill();
71+
}
72+
} else {
73+
if (doStroke) {
74+
currentCanvas.closePathFillStroke();
75+
} else {
76+
currentCanvas.fill();
77+
}
78+
}
79+
}
5680
}

svg/src/test/java/com/itextpdf/svg/renderers/impl/CircleNodeRendererIntegrationTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ public void circleSkewYTest() throws IOException, InterruptedException, java.io.
122122
}
123123

124124
@Test
125-
// TODO: DEVSIX-3932 update cmp_ after fix
126125
public void circleWithBigStrokeWidthTest() throws IOException, InterruptedException, java.io.IOException {
127126
convertAndCompare(sourceFolder, destinationFolder, "circleWithBigStrokeWidth");
128127
}

svg/src/test/java/com/itextpdf/svg/renderers/impl/EllipseSvgNodeRendererIntegrationTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ public void parseParametersAndCalculateCoordinatesWithBetterPrecisionEllipseTest
171171
}
172172

173173
@Test
174-
// TODO: DEVSIX-3932 update cmp_ after fix
175174
public void ellipseWithBigStrokeWidthTest() throws IOException, InterruptedException, java.io.IOException {
176175
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "ellipseWithBigStrokeWidth");
177176
}

svg/src/test/java/com/itextpdf/svg/renderers/impl/LinearGradientSvgNodeRendererTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@ public static void beforeClass() {
4747
ITextTest.createOrClearDestinationFolder(destinationFolder);
4848
}
4949

50-
// TODO: DEVSIX-3932 update cmp_ after fix
5150
@Test
5251
public void circleTest() throws IOException, InterruptedException, java.io.IOException {
5352
convertAndCompare(sourceFolder, destinationFolder, "circle");
5453
}
5554

56-
// TODO: DEVSIX-3932 update cmp_ after fix
5755
@Test
5856
public void ellipseTest() throws IOException, InterruptedException, java.io.IOException {
5957
convertAndCompare(sourceFolder, destinationFolder, "ellipse");
@@ -241,7 +239,6 @@ public void arcInsideOtherEllipticalArcTest() throws IOException, InterruptedExc
241239
convertAndCompare(sourceFolder, destinationFolder, "arcInsideOtherEllipticalArc");
242240
}
243241

244-
// TODO: DEVSIX-3932 update cmp_ after fix
245242
@Test
246243
public void polygonTest() throws IOException, InterruptedException, java.io.IOException {
247244
convertAndCompare(sourceFolder, destinationFolder, "polygon");

svg/src/test/java/com/itextpdf/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ public void markerInPolylineElementTest() throws IOException, InterruptedExcepti
127127
}
128128

129129
@Test
130-
// TODO: update when DEVSIX-2719 will be closed
131130
public void markerInPolygonElementTest() throws IOException, InterruptedException {
132131
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "markerInPolygonElement");
133132
}

svg/src/test/java/com/itextpdf/svg/renderers/impl/PathSvgNodeRendererTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,4 +478,9 @@ public void patternHrefTransitivePresAR1Test() throws IOException, InterruptedEx
478478
public void patternHrefTransitivePresAR2Test() throws IOException, InterruptedException {
479479
convertAndCompareSinglePage(sourceFolder, destinationFolder, "patternHrefTransitivePresAR2", properties);
480480
}
481+
482+
@Test
483+
public void closedPathIsCutTest() throws IOException, InterruptedException {
484+
convertAndCompareSinglePage(sourceFolder, destinationFolder, "closedPathIsCutTest", properties);
485+
}
481486
}

svg/src/test/java/com/itextpdf/svg/renderers/impl/PolygonSvgNodeRendererTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,14 @@ public void connectPointsWithSameYCoordinateTest() {
182182
Assertions.assertEquals(expectedPoints.get(x), attributePoints.get(x));
183183
}
184184
}
185+
186+
@Test
187+
public void polygonIsNotCutTest() throws IOException, InterruptedException {
188+
convertAndCompareSinglePage(sourceFolder, destinationFolder, "polygonIsNotCutTest");
189+
}
190+
191+
@Test
192+
public void polygonIsNotCutEvenOddTest() throws IOException, InterruptedException {
193+
convertAndCompareSinglePage(sourceFolder, destinationFolder, "polygonIsNotCutEvenOddTest");
194+
}
185195
}

0 commit comments

Comments
 (0)