Skip to content

Commit 954d61a

Browse files
committed
Process fillOpacity and strokeOpacity in GraphicsState Processor
DEVSIX-3719
1 parent c53ead2 commit 954d61a

File tree

4 files changed

+55
-9
lines changed

4 files changed

+55
-9
lines changed

kernel/src/main/java/com/itextpdf/kernel/pdf/canvas/parser/PdfCanvasProcessor.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,13 @@ This file is part of the iText (R) project.
9494
import com.itextpdf.kernel.pdf.colorspace.PdfSpecialCs;
9595

9696
import java.util.Objects;
97+
import com.itextpdf.kernel.pdf.extgstate.PdfExtGState;
9798
import org.slf4j.Logger;
9899
import org.slf4j.LoggerFactory;
99100

100101
import java.io.IOException;
101102
import java.lang.ref.WeakReference;
102-
import java.util.ArrayList;
103-
import java.util.Arrays;
104-
import java.util.Collection;
105-
import java.util.HashMap;
106-
import java.util.List;
107-
import java.util.Map;
108-
import java.util.Set;
109-
import java.util.Stack;
103+
import java.util.*;
110104

111105
import static com.itextpdf.kernel.pdf.canvas.PdfCanvasConstants.FillingRule;
112106

@@ -918,7 +912,6 @@ public void invoke(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfOb
918912
if (gsDic == null)
919913
throw new PdfException(PdfException._1IsAnUnknownGraphicsStateDictionary).setMessageParams(dictionaryName);
920914
}
921-
// at this point, all we care about is the FONT entry in the GS dictionary TODO merge the whole gs dictionary
922915
PdfArray fontParameter = gsDic.getAsArray(PdfName.Font);
923916
if (fontParameter != null) {
924917
PdfFont font = processor.getFont(fontParameter.getAsDictionary(0));
@@ -927,6 +920,8 @@ public void invoke(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfOb
927920
processor.getGraphicsState().setFont(font);
928921
processor.getGraphicsState().setFontSize(size);
929922
}
923+
PdfExtGState pdfExtGState = new PdfExtGState(gsDic.clone(Collections.singletonList(PdfName.Font)));
924+
processor.getGraphicsState().updateFromExtGState(pdfExtGState);
930925
}
931926
}
932927

kernel/src/test/java/com/itextpdf/kernel/pdf/canvas/parser/PdfCanvasProcessorTest.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ This file is part of the iText (R) project.
7070
import java.nio.file.Paths;
7171
import java.util.ArrayList;
7272
import java.util.List;
73+
import java.util.Map;
74+
import java.util.HashMap;
7375
import org.junit.Assert;
7476
import org.junit.Ignore;
7577
import org.junit.Rule;
@@ -108,6 +110,34 @@ public void contentStreamProcessorTest() throws IOException {
108110
Assert.assertEquals(expectedPageEventsLog, pageEventsLog.toString());
109111
}
110112

113+
@Test
114+
public void processGraphicsStateResourceOperatorFillOpacityTest() throws IOException {
115+
PdfDocument document = new PdfDocument(new PdfReader(sourceFolder + "transparentText.pdf"));
116+
Float expOpacity = 0.5f;
117+
118+
Map<String, Object> textRenderInfo = new HashMap<>();
119+
for (int i = 1; i <= document.getNumberOfPages(); ++i) {
120+
PdfPage page = document.getPage(i);
121+
PdfCanvasProcessor processor = new PdfCanvasProcessor(new RecordEveryTextRenderEvent(textRenderInfo));
122+
processor.processPageContent(page);
123+
}
124+
Assert.assertEquals("Expected fill opacity not found", expOpacity, textRenderInfo.get("FillOpacity"));
125+
}
126+
127+
@Test
128+
public void processGraphicsStateResourceOperatorStrokeOpacityTest() throws IOException {
129+
PdfDocument document = new PdfDocument(new PdfReader(sourceFolder + "hiddenText.pdf"));
130+
Float expOpacity = 0.0f;
131+
132+
Map<String, Object> textRenderInfo = new HashMap<>();
133+
for (int i = 1; i <= document.getNumberOfPages(); ++i) {
134+
PdfPage page = document.getPage(i);
135+
PdfCanvasProcessor processor = new PdfCanvasProcessor(new RecordEveryTextRenderEvent(textRenderInfo));
136+
processor.processPageContent(page);
137+
}
138+
Assert.assertEquals("Expected stroke opacity not found", expOpacity, textRenderInfo.get("StrokeOpacity"));
139+
}
140+
111141
@Test
112142
public void testClosingEmptyPath() throws IOException {
113143
String fileName = "closingEmptyPath.pdf";
@@ -301,4 +331,25 @@ public Set<EventType> getSupportedEvents() {
301331
return null;
302332
}
303333
}
334+
335+
private static class RecordEveryTextRenderEvent implements IEventListener {
336+
private Map<String, Object> map;
337+
338+
RecordEveryTextRenderEvent(Map<String, Object> map) {
339+
this.map = map;
340+
}
341+
342+
public void eventOccurred(IEventData data, EventType type) {
343+
if (data instanceof TextRenderInfo) {
344+
TextRenderInfo renderInfo = (TextRenderInfo) data;
345+
map.put("String", renderInfo.getPdfString().toUnicodeString());
346+
map.put("FillOpacity", renderInfo.getGraphicsState().getFillOpacity());
347+
map.put("StrokeOpacity", renderInfo.getGraphicsState().getStrokeOpacity());
348+
}
349+
}
350+
351+
public Set<EventType> getSupportedEvents() {
352+
return null;
353+
}
354+
}
304355
}

0 commit comments

Comments
 (0)