Skip to content

Commit 13be970

Browse files
committed
SVG: specify correct inheritance for attributes (including markers) and support percent stroke/fill-opacity
DEVSIX-8757
1 parent 448b6f3 commit 13be970

28 files changed

+181
-46
lines changed

svg/src/main/java/com/itextpdf/svg/SvgConstants.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,10 @@ public static final class Attributes extends CommonAttributeConstants {
829829
* Attribute defining the stroke linecap.
830830
*/
831831
public static final String STROKE_LINECAP = "stroke-linecap";
832+
/**
833+
* Attribute defining the stroke linejoin.
834+
*/
835+
public static final String STROKE_LINEJOIN = "stroke-linejoin";
832836

833837
/**
834838
* Attribute defining the stroke miterlimit.

svg/src/main/java/com/itextpdf/svg/css/impl/SvgAttributeInheritance.java

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

2525
import com.itextpdf.styledxmlparser.css.resolve.IStyleInheritance;
26-
import com.itextpdf.svg.SvgConstants;
26+
import com.itextpdf.svg.SvgConstants.Attributes;
2727

2828
import java.util.Arrays;
2929
import java.util.Collections;
@@ -36,30 +36,35 @@ This file is part of the iText (R) project.
3636
public class SvgAttributeInheritance implements IStyleInheritance {
3737

3838
/**
39-
* Set of inheritable SVG style attributes
40-
* in accordance with "http://www.w3schools.com/cssref/"
41-
* and "https://developer.mozilla.org/en-US/docs/Web/CSS/Reference"
39+
* Set of inheritable SVG style attributes in accordance with "https://www.w3.org/TR/SVG2/propidx.html".
4240
*/
4341
private static final Set<String> inheritableProperties = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
44-
45-
// clip-rule
46-
SvgConstants.Attributes.CLIP_RULE,
47-
48-
// fill
49-
SvgConstants.Attributes.FILL,
50-
51-
// fill-rule
52-
SvgConstants.Attributes.FILL_RULE,
53-
54-
// stroke
55-
SvgConstants.Attributes.STROKE,
56-
57-
// stroke-width
58-
SvgConstants.Attributes.STROKE_WIDTH,
59-
60-
// text-anchor
61-
SvgConstants.Attributes.TEXT_ANCHOR
62-
42+
// The following attributes haven't been supported in iText yet:
43+
// color-interpolation, color-rendering, glyph-orientation-vertical, image-rendering,
44+
// paint-order, pointer-events, shape-rendering, text-rendering.
45+
46+
// All the rest are either here or in com.itextpdf.styledxmlparser.css.resolve.CssInheritance
47+
Attributes.DIRECTION,
48+
// TODO DEVSIX-5890 Add Support to SVG dominant-baseline attribute
49+
Attributes.FILL,
50+
Attributes.FILL_OPACITY,
51+
Attributes.FILL_RULE,
52+
Attributes.MARKER,
53+
Attributes.MARKER_MID,
54+
Attributes.MARKER_END,
55+
Attributes.MARKER_START,
56+
Attributes.STROKE,
57+
Attributes.STROKE_DASHARRAY,
58+
Attributes.STROKE_DASHOFFSET,
59+
Attributes.STROKE_LINECAP,
60+
Attributes.STROKE_LINEJOIN,
61+
Attributes.STROKE_MITERLIMIT,
62+
Attributes.STROKE_OPACITY,
63+
Attributes.STROKE_WIDTH,
64+
Attributes.TEXT_ANCHOR,
65+
66+
// CLIP_RULE isn't from the spec above, but seems it's required according to some tests
67+
Attributes.CLIP_RULE
6368
)));
6469

6570
@Override

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,15 @@ private TransparentColor getColorFromAttributeValue(SvgDrawContext context, Stri
532532
private float getOpacityByAttributeName(String attributeName, float generalOpacity) {
533533
float opacity = generalOpacity;
534534

535-
String opacityValue = getAttribute(attributeName);
536-
if (opacityValue != null && !SvgConstants.Values.NONE.equalsIgnoreCase(opacityValue)) {
537-
opacity *= Float.valueOf(opacityValue);
535+
String opacityStr = getAttribute(attributeName);
536+
if (opacityStr != null && !SvgConstants.Values.NONE.equalsIgnoreCase(opacityStr)) {
537+
float opacityValue;
538+
if (CssTypesValidationUtils.isPercentageValue(opacityStr)) {
539+
opacityValue = CssDimensionParsingUtils.parseRelativeValue(opacityStr, 1f);
540+
} else {
541+
opacityValue = Float.valueOf(opacityStr);
542+
}
543+
opacity *= opacityValue;
538544
}
539545
return opacity;
540546
}

svg/src/test/java/com/itextpdf/svg/renderers/OpacityTest.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ This file is part of the iText (R) project.
2424

2525
import com.itextpdf.test.ITextTest;
2626

27+
import java.io.IOException;
2728
import org.junit.jupiter.api.Assertions;
2829
import org.junit.jupiter.api.BeforeAll;
29-
import org.junit.jupiter.api.Test;
3030
import org.junit.jupiter.api.Tag;
31-
import java.io.IOException;
31+
import org.junit.jupiter.api.Test;
3232

3333
@Tag("IntegrationTest")
3434
public class OpacityTest extends SvgIntegrationTest {
@@ -63,19 +63,16 @@ public void testRGBA() throws IOException, InterruptedException {
6363
}
6464

6565
@Test
66-
//TODO DEVSIX-2678
67-
public void testFillOpacityWithComma() throws IOException, InterruptedException {
66+
//TODO DEVSIX-2678 SVG: Displaying invalid value of fill-opacity incorrectly
67+
public void testFillOpacityWithComma() {
6868
Assertions.assertThrows(NumberFormatException.class,
6969
() -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithComma")
7070
);
7171
}
7272

7373
@Test
74-
//TODO DEVSIX-2678
7574
public void testFillOpacityWithPercents() throws IOException, InterruptedException {
76-
Assertions.assertThrows(NumberFormatException.class,
77-
() -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithPercents")
78-
);
75+
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithPercents");
7976
}
8077

8178
@Test
@@ -93,11 +90,8 @@ public void testStrokeOpacityWithComma() throws IOException, InterruptedExceptio
9390
}
9491

9592
@Test
96-
//TODO DEVSIX-2679
9793
public void testStrokeOpacityWithPercents() throws IOException, InterruptedException {
98-
Assertions.assertThrows(NumberFormatException.class,
99-
() -> convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testStrokeOpacityWithPercents")
100-
);
94+
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testStrokeOpacityWithPercents");
10195
}
10296

10397
@Test

svg/src/test/java/com/itextpdf/svg/renderers/StrokeTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,19 +133,19 @@ public void strokeObjectsOverlap1Test() throws IOException, InterruptedException
133133
}
134134

135135
@Test
136-
//TODO DEVSIX-7338: Update cmp file
136+
//TODO DEVSIX-7338: SVG stroke on group applied incorrectly
137137
public void strokeObjectsOverlap2Test() throws IOException, InterruptedException {
138138
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "strokeOnGroup2");
139139
}
140140

141141
@Test
142-
//TODO DEVSIX-7338: Update cmp file
142+
//TODO DEVSIX-7338: SVG stroke on group applied incorrectly
143143
public void strokeObjectsOverlap3Test() throws IOException, InterruptedException {
144144
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "strokeOnGroupNoInsideStroke");
145145
}
146146

147147
@Test
148-
//TODO DEVSIX-7338: Update cmp file
148+
//TODO DEVSIX-7338: SVG stroke on group applied incorrectly
149149
public void strokeObjectsOverlap4Test() throws IOException, InterruptedException {
150150
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "strokeOnGroupNoInsideStroke2");
151151
}

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ This file is part of the iText (R) project.
3232
import java.io.IOException;
3333
import org.junit.jupiter.api.BeforeAll;
3434
import org.junit.jupiter.api.BeforeEach;
35-
import org.junit.jupiter.api.Test;
3635
import org.junit.jupiter.api.Tag;
36+
import org.junit.jupiter.api.Test;
3737

3838
@Tag("IntegrationTest")
3939
public class MarkerSvgNodeRendererIntegrationTest extends SvgIntegrationTest {
@@ -317,4 +317,24 @@ public void deformationWhenRotationAndPreserveAspectRationNoneTest() throws IOEx
317317
public void markerParentElementTest() throws IOException, InterruptedException {
318318
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "markerParentElement");
319319
}
320+
321+
@Test
322+
public void markerDefinedInStyleTest() throws IOException, InterruptedException {
323+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "markerDefinedInStyle");
324+
}
325+
326+
@Test
327+
public void markerOnGroupTest() throws IOException, InterruptedException {
328+
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOnGroup");
329+
}
330+
331+
@Test
332+
public void markerOnSvgTest() throws IOException, InterruptedException {
333+
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOnSvg");
334+
}
335+
336+
@Test
337+
public void markerOnSymbolTest() throws IOException, InterruptedException {
338+
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOnSymbol");
339+
}
320340
}

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

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

129129
@Test
130-
// TODO DEVSIX-2258 Processing of stroke attribute is not currently correct supported
131130
public void opacityAttributeTest() throws IOException, InterruptedException {
132131
convertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "opacityAttrTest");
133132
}

0 commit comments

Comments
 (0)