Skip to content

Commit 07a241a

Browse files
author
Dmitry Radchuk
committed
Support display:none and visibility:hidden for svg elements except text
DEVSIX-8753
1 parent 69e07f1 commit 07a241a

File tree

49 files changed

+391
-2
lines changed

Some content is hidden

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

49 files changed

+391
-2
lines changed

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ public final void draw(SvgDrawContext context) {
142142
PdfCanvas currentCanvas = context.getCurrentCanvas();
143143

144144
if (this.attributesAndStyles != null) {
145+
if (isHidden()) {
146+
return;
147+
}
148+
145149
String transformString = this.attributesAndStyles.get(SvgConstants.Attributes.TRANSFORM);
146150

147151
if (transformString != null && !transformString.isEmpty()) {
@@ -274,6 +278,16 @@ protected void deepCopyAttributesAndStyles(ISvgNodeRenderer deepCopy) {
274278
*/
275279
protected abstract void doDraw(SvgDrawContext context);
276280

281+
/**
282+
* Check if this renderer should draw the element based on its attributes (e.g. visibility/display)
283+
*
284+
* @return true if element won't be drawn, false otherwise
285+
*/
286+
protected boolean isHidden() {
287+
return CommonCssConstants.NONE.equals(this.attributesAndStyles.get(CommonCssConstants.DISPLAY))
288+
|| CommonCssConstants.HIDDEN.equals(this.attributesAndStyles.get(CommonCssConstants.VISIBILITY));
289+
}
290+
277291
/**
278292
* Gets parent {@link ClipPathSvgNodeRenderer} if it exists or {@code null} otherwise.
279293
*
@@ -518,7 +532,11 @@ private TransparentColor getColorFromAttributeValue(SvgDrawContext context, Stri
518532
Color resolvedColor = null;
519533
float resolvedOpacity = 1;
520534
normalizedName = normalizedName.substring(1);
521-
final ISvgNodeRenderer colorRenderer = context.getNamedObject(normalizedName);
535+
ISvgNodeRenderer colorRenderer = context.getNamedObject(normalizedName);
536+
if (colorRenderer instanceof AbstractSvgNodeRenderer
537+
&& ((AbstractSvgNodeRenderer)colorRenderer).isHidden()) {
538+
colorRenderer = null;
539+
}
522540
if (colorRenderer instanceof ISvgPaintServer) {
523541
if (colorRenderer.getParent() == null) {
524542
colorRenderer.setParent(this);
@@ -585,6 +603,9 @@ private boolean drawInClipPath(SvgDrawContext context) {
585603
if (template instanceof ClipPathSvgNodeRenderer) {
586604
// Clone template to avoid muddying the state
587605
ClipPathSvgNodeRenderer clipPath = (ClipPathSvgNodeRenderer) template.createDeepCopy();
606+
if (clipPath.isHidden()) {
607+
return false;
608+
}
588609
// Resolve parent inheritance
589610
SvgNodeRendererInheritanceResolver.applyInheritanceToSubTree(this, clipPath, context.getCssContext());
590611
clipPath.setClippedRenderer(this);

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ This file is part of the iText (R) project.
2525
import com.itextpdf.kernel.geom.NoninvertibleTransformException;
2626
import com.itextpdf.kernel.geom.Rectangle;
2727
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
28+
import com.itextpdf.styledxmlparser.css.CommonCssConstants;
2829
import com.itextpdf.svg.logs.SvgLogMessageConstant;
2930
import com.itextpdf.svg.renderers.ISvgNodeRenderer;
3031
import com.itextpdf.svg.renderers.SvgDrawContext;
@@ -69,6 +70,10 @@ protected void doDraw(SvgDrawContext context) {
6970

7071
PdfCanvas currentCanvas = context.getCurrentCanvas();
7172
for (ISvgNodeRenderer child : getChildren()) {
73+
if (child instanceof AbstractSvgNodeRenderer
74+
&& ((AbstractSvgNodeRenderer) child).isHidden()) {
75+
continue;
76+
}
7277
currentCanvas.saveState();
7378

7479
child.setParent(this);
@@ -116,4 +121,10 @@ public void drawClippedRenderer(SvgDrawContext context) {
116121
public void setClippedRenderer(AbstractSvgNodeRenderer clippedRenderer) {
117122
this.clippedRenderer = clippedRenderer;
118123
}
124+
125+
@Override
126+
protected boolean isHidden() {
127+
return CommonCssConstants.NONE.equals(this.attributesAndStyles.get(CommonCssConstants.DISPLAY))
128+
&& !CommonCssConstants.HIDDEN.equals(this.attributesAndStyles.get(CommonCssConstants.VISIBILITY));
129+
}
119130
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ This file is part of the iText (R) project.
2929
import com.itextpdf.kernel.geom.AffineTransform;
3030
import com.itextpdf.kernel.geom.Point;
3131
import com.itextpdf.kernel.geom.Rectangle;
32+
import com.itextpdf.styledxmlparser.css.CommonCssConstants;
3233
import com.itextpdf.svg.SvgConstants.Attributes;
3334
import com.itextpdf.svg.renderers.ISvgNodeRenderer;
3435
import com.itextpdf.svg.renderers.SvgDrawContext;
@@ -94,6 +95,11 @@ public Rectangle getObjectBoundingBox(SvgDrawContext context) {
9495
return null;
9596
}
9697

98+
@Override
99+
protected boolean isHidden() {
100+
return CommonCssConstants.NONE.equals(this.attributesAndStyles.get(CommonCssConstants.DISPLAY));
101+
}
102+
97103
// TODO: DEVSIX-4136 opacity is not supported now.
98104
// The opacity should be equal to 'parentOpacity * stopRenderer.getStopOpacity() * stopColor[3]'
99105
private List<GradientColorStop> parseStops(float parentOpacity) {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ This file is part of the iText (R) project.
2525
import com.itextpdf.kernel.geom.AffineTransform;
2626
import com.itextpdf.kernel.geom.Point;
2727
import com.itextpdf.kernel.geom.Rectangle;
28+
import com.itextpdf.styledxmlparser.css.CommonCssConstants;
2829
import com.itextpdf.styledxmlparser.css.util.CssDimensionParsingUtils;
2930
import com.itextpdf.styledxmlparser.css.util.CssTypesValidationUtils;
3031
import com.itextpdf.styledxmlparser.css.util.CssUtils;
@@ -77,6 +78,11 @@ public Rectangle getObjectBoundingBox(SvgDrawContext context) {
7778
return null;
7879
}
7980

81+
@Override
82+
protected boolean isHidden() {
83+
return CommonCssConstants.HIDDEN.equals(this.attributesAndStyles.get(CommonCssConstants.VISIBILITY));
84+
}
85+
8086
@Override
8187
void preDraw(SvgDrawContext context) {
8288
super.preDraw(context);

svg/src/test/java/com/itextpdf/svg/css/VisibilityTest.java

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,107 @@ public static void beforeClass() {
4141
}
4242

4343
@Test
44-
//TODO DEVSIX-8753: update cmp file after supporting
4544
public void visibilityDiffValuesTest() throws IOException, InterruptedException {
4645
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibility");
4746
}
47+
48+
@Test
49+
public void visibilityDiffValuesTest2() throws IOException, InterruptedException {
50+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibility2");
51+
}
52+
53+
@Test
54+
public void visibilityHiddenInLinearGradientTest() throws IOException, InterruptedException {
55+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInLinearGradient");
56+
}
57+
58+
@Test
59+
public void visibilityHiddenInMarkerTest() throws IOException, InterruptedException {
60+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInMarker");
61+
}
62+
63+
@Test
64+
public void visibilityHiddenInGTest() throws IOException, InterruptedException {
65+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInG");
66+
}
67+
68+
@Test
69+
public void visibilityHiddenInUseTest() throws IOException, InterruptedException {
70+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInUse");
71+
}
72+
73+
@Test
74+
public void visibilityHiddenInDefsTest() throws IOException, InterruptedException {
75+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInDefs");
76+
}
77+
78+
@Test
79+
public void visibilityHiddenInPatternTest() throws IOException, InterruptedException {
80+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInPattern");
81+
}
82+
83+
@Test
84+
public void visibilityHiddenInClipPathTest() throws IOException, InterruptedException {
85+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInClipPath");
86+
}
87+
88+
@Test
89+
public void visibilityHiddenInClipPathWithUseTest() throws IOException, InterruptedException {
90+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInClipPathWithUse");
91+
}
92+
93+
@Test
94+
public void visibilityHiddenInSymbolTest() throws IOException, InterruptedException {
95+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"visibilityHiddenInSymbol");
96+
}
97+
98+
@Test
99+
public void displayNoneInLinearGradientTest() throws IOException, InterruptedException {
100+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInLinearGradient");
101+
}
102+
103+
@Test
104+
public void displayNoneInMarkerTest() throws IOException, InterruptedException {
105+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInMarker");
106+
}
107+
108+
@Test
109+
public void displayNoneInGTest() throws IOException, InterruptedException {
110+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInG");
111+
}
112+
113+
@Test
114+
public void displayNoneInG2Test() throws IOException, InterruptedException {
115+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInG2");
116+
}
117+
118+
@Test
119+
public void displayNoneInUseTest() throws IOException, InterruptedException {
120+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInUse");
121+
}
122+
123+
@Test
124+
public void displayNoneInDefsTest() throws IOException, InterruptedException {
125+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInDefs");
126+
}
127+
128+
@Test
129+
public void displayNoneInPatternTest() throws IOException, InterruptedException {
130+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInPattern");
131+
}
132+
133+
@Test
134+
public void displayNoneInSymbolTest() throws IOException, InterruptedException {
135+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInSymbol");
136+
}
137+
138+
@Test
139+
public void displayNoneInClipPathTest() throws IOException, InterruptedException {
140+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInClipPath");
141+
}
142+
143+
@Test
144+
public void displayNoneInClipPathWithUseTest() throws IOException, InterruptedException {
145+
convertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER,"displayNoneInClipPathWithUse");
146+
}
48147
}
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)