Skip to content

Commit affac8f

Browse files
committed
Support stroke-opacity at layout level for text elements
DEVSIX-8774
1 parent a0ed6e3 commit affac8f

File tree

23 files changed

+352
-132
lines changed

23 files changed

+352
-132
lines changed

kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/PdfCanvas.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,9 +1514,6 @@ public PdfCanvas setMiterLimit(float miterLimit) {
15141514
*/
15151515
public PdfCanvas setLineDash(float phase) {
15161516
PdfArray dashPattern = getDashPatternArray(phase);
1517-
if (dashPattern == null) {
1518-
return this;
1519-
}
15201517
currentGs.setDashPattern(dashPattern);
15211518
contentStream.getOutputStream().writeByte('[').writeByte(']').writeSpace()
15221519
.writeFloat(phase).writeSpace()

layout/src/main/java/com/itextpdf/layout/ElementPropertyContainer.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,20 +604,62 @@ public T setTextRenderingMode(int textRenderingMode) {
604604
* The stroke color is the color of the outlines or edges of a shape.
605605
*
606606
* @return the current stroke color
607+
*
608+
* @deprecated in favour of {@link #getTransparentStrokeColor()} which should be renamed to {@code getStrokeColor}
609+
* after this method will be removed
607610
*/
611+
@Deprecated
608612
public Color getStrokeColor() {
609-
return this.<Color>getProperty(Property.STROKE_COLOR);
613+
return this.<TransparentColor>getProperty(Property.STROKE_COLOR).getColor();
614+
}
615+
616+
/**
617+
* Gets the stroke color for the current element.
618+
* The stroke color is the color of the outlines or edges of a shape.
619+
*
620+
* @return the current stroke color
621+
*/
622+
public TransparentColor getTransparentStrokeColor() {
623+
return this.<TransparentColor>getProperty(Property.STROKE_COLOR);
610624
}
611625

612626
/**
613627
* Sets the stroke color for the current element.
614628
* The stroke color is the color of the outlines or edges of a shape.
615629
*
616630
* @param strokeColor a new stroke color
617-
* @return this Element.
631+
*
632+
* @return this element
618633
*/
619634
public T setStrokeColor(Color strokeColor) {
620-
setProperty(Property.STROKE_COLOR, strokeColor);
635+
return setStrokeColor(strokeColor, 1f);
636+
}
637+
638+
/**
639+
* Sets the stroke color for the current element.
640+
* The stroke color is the color of the outlines or edges of a shape.
641+
*
642+
* @param strokeColor a {@link Color} for the stroke
643+
* @param opacity an opacity for the stroke color; a float between 0 and 1, where 1 stands for fully opaque color
644+
* and 0 - for fully transparent
645+
*
646+
* @return this element
647+
*/
648+
public T setStrokeColor(Color strokeColor, float opacity) {
649+
setProperty(Property.STROKE_COLOR, strokeColor != null ? new TransparentColor(strokeColor, opacity) : null);
650+
return (T) (Object) this;
651+
}
652+
653+
/**
654+
* Sets the stroke color for the current element.
655+
* The stroke color is the color of the outlines or edges of a shape.
656+
*
657+
* @param transparentColor a new stroke color with transparency
658+
*
659+
* @return this element
660+
*/
661+
public T setStrokeColor(TransparentColor transparentColor) {
662+
setProperty(Property.STROKE_COLOR, transparentColor);
621663
return (T) (Object) this;
622664
}
623665

layout/src/main/java/com/itextpdf/layout/renderer/TextRenderer.java

Lines changed: 146 additions & 113 deletions
Large diffs are not rendered by default.

layout/src/test/java/com/itextpdf/layout/TextWritingTest.java

Lines changed: 76 additions & 2 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.layout;
2424

2525
import com.itextpdf.io.font.constants.StandardFonts;
26+
import com.itextpdf.kernel.colors.Color;
2627
import com.itextpdf.kernel.colors.ColorConstants;
2728
import com.itextpdf.kernel.font.PdfFont;
2829
import com.itextpdf.kernel.font.PdfFontFactory;
@@ -131,6 +132,78 @@ public void textRenderingModeTest01() throws IOException, InterruptedException {
131132
Assertions.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
132133
}
133134

135+
@Test
136+
public void textStrokeTest() throws IOException, InterruptedException {
137+
String outFileName = destinationFolder + "textStrokeTest.pdf";
138+
String cmpFileName = sourceFolder + "cmp_textStrokeTest.pdf";
139+
try (PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
140+
Document document = new Document(pdfDocument)) {
141+
Text text1 = new Text("Red stroke text via color setter")
142+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.STROKE)
143+
.setStrokeColor(ColorConstants.RED)
144+
.setStrokeWidth(0.1f);
145+
document.add(new Paragraph().add(text1));
146+
147+
Text text2 = new Text("Red transparent stroke text via setter with 2 parameters")
148+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.STROKE)
149+
.setStrokeColor(ColorConstants.RED, 0.5f)
150+
.setStrokeWidth(0.1f);
151+
document.add(new Paragraph().add(text2));
152+
153+
Text text3 = new Text("Red transparent stroke text via transparent color setter")
154+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.STROKE)
155+
.setStrokeColor(new TransparentColor(ColorConstants.RED, 0.5f))
156+
.setStrokeWidth(0.1f);
157+
document.add(new Paragraph().add(text3));
158+
159+
Text text4 = new Text("Red transparent stroke text via transparent color property")
160+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.STROKE)
161+
.setStrokeWidth(0.1f);
162+
text4.setProperty(Property.STROKE_COLOR, new TransparentColor(ColorConstants.RED, 0.5f));
163+
document.add(new Paragraph().add(text4));
164+
165+
Text text5 = new Text("Red transparent stroke text via color property")
166+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.STROKE)
167+
.setStrokeWidth(0.1f);
168+
text5.setProperty(Property.STROKE_COLOR, ColorConstants.RED);
169+
document.add(new Paragraph().add(text5));
170+
}
171+
Assertions.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
172+
}
173+
174+
@Test
175+
public void textFillStrokeTest() throws IOException, InterruptedException {
176+
String outFileName = destinationFolder + "textFillStrokeTest.pdf";
177+
String cmpFileName = sourceFolder + "cmp_textFillStrokeTest.pdf";
178+
try (PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
179+
Document document = new Document(pdfDocument)) {
180+
Text text1 = new Text("Pink text with null stroke color (so font color is used)")
181+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE)
182+
.setFontColor(ColorConstants.PINK)
183+
.setStrokeColor((Color) null)
184+
.setStrokeWidth(2)
185+
.setFontSize(50);
186+
document.add(new Paragraph().add(text1));
187+
188+
Text text2 = new Text("Pink text with red half-transparent stroke")
189+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE)
190+
.setFontColor(ColorConstants.PINK)
191+
.setStrokeColor(ColorConstants.RED, 0.5f)
192+
.setStrokeWidth(2)
193+
.setFontSize(50);
194+
document.add(new Paragraph().add(text2));
195+
196+
Text text3 = new Text("Pink text with fully transparent stroke")
197+
.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE)
198+
.setFontColor(ColorConstants.PINK)
199+
.setStrokeColor(new TransparentColor(ColorConstants.RED, 0f))
200+
.setStrokeWidth(2)
201+
.setFontSize(50);
202+
document.add(new Paragraph().add(text3));
203+
}
204+
Assertions.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
205+
}
206+
134207
@Test
135208
public void leadingTest01() throws IOException, InterruptedException {
136209
String outFileName = destinationFolder + "leadingTest01.pdf";
@@ -365,12 +438,13 @@ public void strokedUnderlineTest() throws IOException, InterruptedException {
365438
.setDashPattern(new float[]{5, 5, 10, 5}, 5);
366439
p.setUnderline(underline);
367440

441+
TransparentColor strokeColor = new TransparentColor(ColorConstants.GREEN, 0.5f);
368442
Paragraph p2 = new Paragraph("Text with line-through and default underline.")
369443
.setFontSize(50).setStrokeWidth(1).setFontColor(ColorConstants.DARK_GRAY)
370-
.setStrokeColor(ColorConstants.GREEN);
444+
.setStrokeColor(strokeColor);
371445
Underline underline2 = new Underline(ColorConstants.DARK_GRAY, 0, 0.1f, 0, 0.3f,
372446
PdfCanvasConstants.LineCapStyle.BUTT)
373-
.setStrokeWidth(1).setStrokeColor(new TransparentColor(ColorConstants.GREEN));
447+
.setStrokeWidth(1).setStrokeColor(strokeColor);
374448
p2.setUnderline(underline2);
375449
p2.setUnderline();
376450

layout/src/test/java/com/itextpdf/layout/renderer/TextRendererIntegrationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ public void drawTextRenderingModeFillStrokeTest() {
968968
.setBackgroundColor(ColorConstants.YELLOW)
969969
.setWidth(10)
970970
.setStrokeWidth(1f)
971-
.setStrokeColor(null)
971+
.setStrokeColor((TransparentColor) null)
972972
.setBorder(new SolidBorder(1));
973973
paragraph.setNextRenderer(new TextRenderer(text) {
974974
@Override

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ void postDraw(SvgDrawContext context) {
328328
}
329329
} else {
330330
if (doStroke) {
331+
// TODO DEVSIX-8854 Draw SVG elements with transparent stroke in 2 steps
331332
currentCanvas.fillStroke();
332333
} else {
333334
currentCanvas.fill();
@@ -396,6 +397,7 @@ void applyFillAndStrokeProperties(FillProperties fillProperties, StrokePropertie
396397
currentCanvas.setLineWidth(strokeProperties.getWidth());
397398

398399
if (!CssUtils.compareFloats(strokeProperties.getOpacity(), 1f)) {
400+
// TODO DEVSIX-8854 Draw SVG elements with transparent stroke in 2 steps
399401
opacityGraphicsState.setStrokeOpacity(strokeProperties.getOpacity());
400402
}
401403
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,10 @@ private void applyTransform(SvgDrawContext context) {
143143

144144
private void applyGraphicsState(SvgDrawContext context) {
145145
SvgTextProperties textProperties = context.getSvgTextProperties();
146-
// TODO DEVSIX-8774 support stroke-opacity for text at layout level
147-
text.setFontColor(textProperties.getFillColor());
146+
text.setFontColor(textProperties.getFillColor(), textProperties.getFillOpacity());
148147
text.setStrokeWidth(textProperties.getLineWidth());
149-
text.setStrokeColor(textProperties.getStrokeColor());
148+
text.setStrokeColor(textProperties.getStrokeColor(), textProperties.getStrokeOpacity());
150149
text.setDashPattern(textProperties.getDashArray(), textProperties.getDashPhase());
151-
text.setOpacity(textProperties.getFillOpacity());
152150
text.setProperty(Property.UNDERLINE, textProperties.getTextDecoration());
153151
}
154152

0 commit comments

Comments
 (0)