Skip to content

Commit 08b437a

Browse files
committed
[RELEASE] iText 7 pdfSweep - 2.0.7
https://github.com/itext/i7j-pdfsweep/releases/tag/2.0.7 * release_branch_DEVSIX-5154: [RELEASE] pdfSweep 2.0.7 Add test for TextPosition Fix NPE in TextPositioning Add constructor of PdfDocument to try-with-resources [AFTER RELEASE] pdfSweep 2.0.6
2 parents 698d8f8 + 1af0d67 commit 08b437a

File tree

4 files changed

+150
-67
lines changed

4 files changed

+150
-67
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
<parent>
66
<groupId>com.itextpdf</groupId>
77
<artifactId>root</artifactId>
8-
<version>7.1.15</version>
8+
<version>7.1.16</version>
99
<relativePath />
1010
</parent>
1111

1212
<artifactId>cleanup</artifactId>
13-
<version>2.0.6</version>
13+
<version>2.0.7</version>
1414

1515
<name>pdfSweep</name>
1616
<description>Redact PDF documents. If you have to share PDFs with different departments or send them out of house, but they

src/main/java/com/itextpdf/pdfcleanup/TextPositioning.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,13 @@ class TextPositioning {
6767
private float[] tdShift;
6868
private Matrix tmShift;
6969

70-
private Float currLeading;
70+
private float currLeading = 0F;
7171

7272
/**
7373
* Get the current leading
7474
*/
7575
float getCurrLeading() {
76-
if (currLeading != null) {
77-
return (float) currLeading;
78-
}
79-
return 0f;
76+
return currLeading;
8077
}
8178

8279
void appendPositioningOperator(String operator, List<PdfObject> operands) {
@@ -168,7 +165,7 @@ private void writePositioningOperator(PdfCanvas canvas) {
168165
if (firstPositioningOperands != null) {
169166
if ("T*".equals(prevOperator)) {
170167
if (canvas.getGraphicsState().getLeading() != currLeading) {
171-
canvas.setLeading((float) currLeading);
168+
canvas.setLeading(currLeading);
172169
}
173170
}
174171
PdfCleanUpProcessor.writeOperands(canvas, firstPositioningOperands);
@@ -185,7 +182,7 @@ private void writeText(String operator, List<PdfObject> operands, PdfArray clean
185182
boolean newLineShowText = "'".equals(operator) || "\"".equals(operator);
186183
if (newLineShowText) {
187184
if (canvasGs.getLeading() != currLeading) {
188-
canvas.setLeading((float) currLeading);
185+
canvas.setLeading(currLeading);
189186
}
190187
// after new line operator, removed text shift doesn't matter
191188
removedTextShift = null;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2021 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is offered under a commercial and under the AGPL license.
7+
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
8+
9+
AGPL licensing:
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU Affero General Public License as published by
12+
the Free Software Foundation, either version 3 of the License, or
13+
(at your option) any later version.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU Affero General Public License for more details.
19+
20+
You should have received a copy of the GNU Affero General Public License
21+
along with this program. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
package com.itextpdf.pdfcleanup;
24+
25+
import com.itextpdf.io.font.constants.StandardFonts;
26+
import com.itextpdf.kernel.font.PdfFontFactory;
27+
import com.itextpdf.kernel.pdf.PdfArray;
28+
import com.itextpdf.kernel.pdf.PdfDocument;
29+
import com.itextpdf.kernel.pdf.PdfName;
30+
import com.itextpdf.kernel.pdf.PdfPage;
31+
import com.itextpdf.kernel.pdf.PdfWriter;
32+
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
33+
import com.itextpdf.test.ExtendedITextTest;
34+
import com.itextpdf.test.annotations.type.UnitTest;
35+
36+
import java.io.ByteArrayOutputStream;
37+
import java.io.IOException;
38+
import java.util.ArrayList;
39+
import org.junit.Assert;
40+
import org.junit.Test;
41+
import org.junit.experimental.categories.Category;
42+
43+
@Category(UnitTest.class)
44+
public class TextPositioningTest extends ExtendedITextTest {
45+
46+
public static final float EPS = 0.0001F;
47+
48+
@Test
49+
public void checkNoNpeThrowsInWritePositioningOperatorTest() throws IOException {
50+
PdfCanvas canvasForTest = createTestCanvas(1.0F);
51+
52+
TextPositioning textPositioning = new TextPositioning();
53+
try {
54+
textPositioning.appendPositioningOperator("T*", new ArrayList<>());
55+
textPositioning
56+
.writePositionedText("T*", new ArrayList<>(), new PdfArray(), canvasForTest);
57+
} catch (NullPointerException nullPointerException) {
58+
Assert.fail("We don't expect, that NPE will be thrown in this test!");
59+
}
60+
Assert.assertEquals(0.0, canvasForTest.getGraphicsState().getLeading(), EPS);
61+
}
62+
63+
@Test
64+
public void checkNoNpeThrowsInWritePositioningTextTest() throws IOException {
65+
PdfCanvas canvasForTest = createTestCanvas(2.0F);
66+
67+
TextPositioning textPositioning = new TextPositioning();
68+
try {
69+
textPositioning.appendPositioningOperator("'", new ArrayList<>());
70+
textPositioning.writePositionedText("'", new ArrayList<>(), new PdfArray(), canvasForTest);
71+
} catch (NullPointerException nullPointerException) {
72+
Assert.fail("We don't expect, that NPE will be thrown in this test!");
73+
}
74+
Assert.assertEquals(0.0, canvasForTest.getGraphicsState().getLeading(), EPS);
75+
}
76+
77+
private static PdfCanvas createTestCanvas(float canvasLeading) throws IOException {
78+
PdfDocument document = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()));
79+
PdfPage documentPage = document.addNewPage();
80+
PdfCanvas canvas = new PdfCanvas(documentPage);
81+
82+
canvas.setLeading(canvasLeading);
83+
canvas.setFontAndSize(PdfFontFactory.createFont(StandardFonts.COURIER), 14);
84+
return canvas;
85+
}
86+
}

src/test/java/com/itextpdf/pdfcleanup/util/CleanUpImagesCompareTool.java

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -210,75 +210,75 @@ private String compareImages(String outImage, String cmpImage, String difference
210210

211211
private Map<Integer, PageImageObjectsPaths > extractImagesFromPdf(String pdf, String outputPath)
212212
throws IOException, InterruptedException {
213-
PdfDocument pdfDoc = new PdfDocument(new PdfReader(pdf));
214-
Map<Integer, PageImageObjectsPaths > imageObjectDatas = new HashMap<>();
215-
216-
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
217-
PdfPage page = pdfDoc.getPage(i);
218-
PageImageObjectsPaths imageObjectData =
219-
new PageImageObjectsPaths (page.getPdfObject().getIndirectReference());
220-
Stack<ObjectPath.LocalPathItem> baseLocalPath = new Stack<ObjectPath.LocalPathItem>();
221-
222-
PdfResources pdfResources = page.getResources();
223-
if (pdfResources.getPdfObject().isIndirect()) {
224-
imageObjectData.addIndirectReference(pdfResources.getPdfObject().getIndirectReference());
225-
} else {
226-
baseLocalPath.push(new ObjectPath().new DictPathItem(PdfName.Resources));
227-
}
228-
229-
PdfDictionary xObjects = pdfResources.getResource(PdfName.XObject);
230-
if (xObjects == null) {
231-
continue;
232-
}
233-
234-
if (xObjects.isIndirect()) {
235-
imageObjectData.addIndirectReference(xObjects.getIndirectReference());
236-
baseLocalPath.clear();
237-
} else {
238-
baseLocalPath.push(new ObjectPath().new DictPathItem(PdfName.XObject));
239-
}
213+
try (PdfReader readerPdf = new PdfReader(pdf);
214+
PdfDocument pdfDoc = new PdfDocument(readerPdf)) {
215+
Map<Integer, PageImageObjectsPaths > imageObjectDatas = new HashMap<>();
216+
217+
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
218+
PdfPage page = pdfDoc.getPage(i);
219+
PageImageObjectsPaths imageObjectData =
220+
new PageImageObjectsPaths (page.getPdfObject().getIndirectReference());
221+
Stack<ObjectPath.LocalPathItem> baseLocalPath = new Stack<ObjectPath.LocalPathItem>();
222+
223+
PdfResources pdfResources = page.getResources();
224+
if (pdfResources.getPdfObject().isIndirect()) {
225+
imageObjectData.addIndirectReference(pdfResources.getPdfObject().getIndirectReference());
226+
} else {
227+
baseLocalPath.push(new ObjectPath().new DictPathItem(PdfName.Resources));
228+
}
240229

241-
boolean isPageToGsExtract = false;
242-
for (PdfName objectName : xObjects.keySet()) {
243-
if (!xObjects.get(objectName).isStream()
244-
|| !PdfName.Image.equals(xObjects.getAsStream(objectName).getAsName(PdfName.Subtype))) {
230+
PdfDictionary xObjects = pdfResources.getResource(PdfName.XObject);
231+
if (xObjects == null) {
245232
continue;
246233
}
247234

248-
PdfImageXObject pdfObject = new PdfImageXObject(xObjects.getAsStream(objectName));
249-
baseLocalPath.push(new ObjectPath().new DictPathItem(objectName));
250-
251-
if (!useGs) {
252-
String extension = pdfObject.identifyImageFileExtension();
253-
String fileName = outputPath + objectName + "_" + i + "." + extension;
254-
createImageFromPdfXObject(fileName, pdfObject);
235+
if (xObjects.isIndirect()) {
236+
imageObjectData.addIndirectReference(xObjects.getIndirectReference());
237+
baseLocalPath.clear();
255238
} else {
256-
isPageToGsExtract = true;
239+
baseLocalPath.push(new ObjectPath().new DictPathItem(PdfName.XObject));
257240
}
258241

259-
Stack<ObjectPath.LocalPathItem> reversedStack = new Stack<>();
260-
reversedStack.addAll(baseLocalPath);
261-
Stack<ObjectPath.LocalPathItem> resultStack = new Stack<>();
262-
resultStack.addAll(reversedStack);
263-
imageObjectData.addLocalPath(resultStack);
264-
baseLocalPath.pop();
265-
}
242+
boolean isPageToGsExtract = false;
243+
for (PdfName objectName : xObjects.keySet()) {
244+
if (!xObjects.get(objectName).isStream()
245+
|| !PdfName.Image.equals(xObjects.getAsStream(objectName).getAsName(PdfName.Subtype))) {
246+
continue;
247+
}
266248

267-
if (useGs && isPageToGsExtract) {
268-
String fileName = "Page_" + i + "-%03d.png";
269-
ghostscriptHelper.runGhostScriptImageGeneration(pdf, outputPath, fileName, String.valueOf(i));
270-
}
249+
PdfImageXObject pdfObject = new PdfImageXObject(xObjects.getAsStream(objectName));
250+
baseLocalPath.push(new ObjectPath().new DictPathItem(objectName));
271251

272-
ImageRenderListener listener = new ImageRenderListener();
273-
PdfCanvasProcessor parser = new PdfCanvasProcessor(listener);
274-
parser.processPageContent(page);
275-
ignoredImagesAreas.put(i, listener.getImageRectangles());
252+
if (!useGs) {
253+
String extension = pdfObject.identifyImageFileExtension();
254+
String fileName = outputPath + objectName + "_" + i + "." + extension;
255+
createImageFromPdfXObject(fileName, pdfObject);
256+
} else {
257+
isPageToGsExtract = true;
258+
}
276259

277-
imageObjectDatas.put(i, imageObjectData);
278-
}
260+
Stack<ObjectPath.LocalPathItem> reversedStack = new Stack<>();
261+
reversedStack.addAll(baseLocalPath);
262+
Stack<ObjectPath.LocalPathItem> resultStack = new Stack<>();
263+
resultStack.addAll(reversedStack);
264+
imageObjectData.addLocalPath(resultStack);
265+
baseLocalPath.pop();
266+
}
279267

280-
pdfDoc.close();
281-
return imageObjectDatas;
268+
if (useGs && isPageToGsExtract) {
269+
String fileName = "Page_" + i + "-%03d.png";
270+
ghostscriptHelper.runGhostScriptImageGeneration(pdf, outputPath, fileName, String.valueOf(i));
271+
}
272+
273+
ImageRenderListener listener = new ImageRenderListener();
274+
PdfCanvasProcessor parser = new PdfCanvasProcessor(listener);
275+
parser.processPageContent(page);
276+
ignoredImagesAreas.put(i, listener.getImageRectangles());
277+
278+
imageObjectDatas.put(i, imageObjectData);
279+
}
280+
return imageObjectDatas;
281+
}
282282
}
283283

284284
private void createImageFromPdfXObject(String imageFileName, PdfImageXObject imageObject)

0 commit comments

Comments
 (0)