Skip to content

Commit 08a1526

Browse files
authored
Upgrade PDFBox API to v2.0.8 (#333)
1 parent 095e142 commit 08a1526

File tree

99 files changed

+2788
-1116
lines changed

Some content is hidden

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

99 files changed

+2788
-1116
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.tom_roush.pdfbox">
4+
<uses-permission android:name="android.permission.INTERNET" />
45
</manifest>

library/src/androidTest/java/com/tom_roush/pdfbox/multipdf/PDFMergerUtilityTest.java

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,48 @@
2323
import java.io.File;
2424
import java.io.IOException;
2525

26+
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
2627
import com.tom_roush.pdfbox.io.MemoryUsageSetting;
2728
import com.tom_roush.pdfbox.pdmodel.PDDocument;
29+
import com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog;
30+
import com.tom_roush.pdfbox.pdmodel.PDPage;
31+
import com.tom_roush.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
32+
import com.tom_roush.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageFitDestination;
2833
import com.tom_roush.pdfbox.rendering.PDFRenderer;
29-
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
30-
31-
import org.junit.Before;
32-
import org.junit.Test;
3334

34-
import static org.junit.Assert.assertEquals;
35+
import junit.framework.TestCase;
3536

3637
/**
3738
* Test suite for PDFMergerUtility.
3839
*
3940
* @author Maruan Sahyoun (PDF files)
4041
* @author Tilman Hausherr (code)
4142
*/
42-
public class PDFMergerUtilityTest
43+
public class PDFMergerUtilityTest extends TestCase
4344
{
4445
final String SRCDIR = "pdfbox/input/merge";
4546
String TARGETTESTDIR;
4647
final int DPI = 96;
47-
Context testContext;
48+
private Context testContext;
4849

49-
@Before
50-
public void setUp() throws Exception
50+
@Override
51+
protected void setUp() throws Exception
5152
{
53+
super.setUp();
54+
5255
testContext = InstrumentationRegistry.getInstrumentation().getContext();
5356
PDFBoxResourceLoader.init(testContext);
5457
TARGETTESTDIR = testContext.getCacheDir() + "/pdfbox-test-output/merge/";
58+
5559
new File(TARGETTESTDIR).mkdirs();
5660
if (!new File(TARGETTESTDIR).exists())
5761
{
5862
throw new IOException("could not create output directory");
5963
}
6064
}
6165

66+
67+
6268
/**
6369
* Tests whether the merge of two PDF files with identically named but
6470
* different global resources works. The two PDF files have two fonts each
@@ -69,17 +75,18 @@ public void setUp() throws Exception
6975
*
7076
* @throws IOException if something goes wrong.
7177
*/
72-
@Test
7378
public void testPDFMergerUtility() throws IOException
7479
{
7580
checkMergeIdentical("PDFBox.GlobalResourceMergeTest.Doc01.decoded.pdf",
7681
"PDFBox.GlobalResourceMergeTest.Doc02.decoded.pdf",
77-
"GlobalResourceMergeTestResult.pdf", MemoryUsageSetting.setupMainMemoryOnly());
82+
"GlobalResourceMergeTestResult.pdf",
83+
MemoryUsageSetting.setupMainMemoryOnly());
7884

7985
// once again, with scratch file
8086
checkMergeIdentical("PDFBox.GlobalResourceMergeTest.Doc01.decoded.pdf",
8187
"PDFBox.GlobalResourceMergeTest.Doc02.decoded.pdf",
82-
"GlobalResourceMergeTestResult2.pdf", MemoryUsageSetting.setupTempFileOnly());
88+
"GlobalResourceMergeTestResult2.pdf",
89+
MemoryUsageSetting.setupTempFileOnly());
8390
}
8491

8592
/**
@@ -91,34 +98,77 @@ public void testPDFMergerUtility() throws IOException
9198
*/
9299
public void testJpegCcitt() throws IOException
93100
{
94-
checkMergeIdentical("jpegrgb.pdf", "multitiff.pdf", "JpegMultiMergeTestResult.pdf",
101+
checkMergeIdentical("jpegrgb.pdf",
102+
"multitiff.pdf",
103+
"JpegMultiMergeTestResult.pdf",
95104
MemoryUsageSetting.setupMainMemoryOnly());
96105

97106
// once again, with scratch file
98-
checkMergeIdentical("jpegrgb.pdf", "multitiff.pdf", "JpegMultiMergeTestResult.pdf",
107+
checkMergeIdentical("jpegrgb.pdf",
108+
"multitiff.pdf",
109+
"JpegMultiMergeTestResult.pdf",
99110
MemoryUsageSetting.setupTempFileOnly());
100111
}
101112

102113
// see PDFBOX-2893
103-
@Test
104114
public void testPDFMergerUtility2() throws IOException
105115
{
106116
checkMergeIdentical("PDFBox.GlobalResourceMergeTest.Doc01.pdf",
107117
"PDFBox.GlobalResourceMergeTest.Doc02.pdf",
108-
"GlobalResourceMergeTestResult.pdf", MemoryUsageSetting.setupMainMemoryOnly());
118+
"GlobalResourceMergeTestResult.pdf",
119+
MemoryUsageSetting.setupMainMemoryOnly());
109120

110121
// once again, with scratch file
111122
checkMergeIdentical("PDFBox.GlobalResourceMergeTest.Doc01.pdf",
112123
"PDFBox.GlobalResourceMergeTest.Doc02.pdf",
113-
"GlobalResourceMergeTestResult2.pdf", MemoryUsageSetting.setupTempFileOnly());
124+
"GlobalResourceMergeTestResult2.pdf",
125+
MemoryUsageSetting.setupTempFileOnly());
126+
}
127+
128+
/**
129+
* PDFBOX-3972: Test that OpenAction page destination isn't lost after merge.
130+
*
131+
* @throws IOException
132+
*/
133+
public void testPDFMergerOpenAction() throws IOException
134+
{
135+
PDDocument doc1 = new PDDocument();
136+
doc1.addPage(new PDPage());
137+
doc1.addPage(new PDPage());
138+
doc1.addPage(new PDPage());
139+
doc1.save(new File(TARGETTESTDIR,"MergerOpenActionTest1.pdf"));
140+
doc1.close();
141+
142+
PDDocument doc2 = new PDDocument();
143+
doc2.addPage(new PDPage());
144+
doc2.addPage(new PDPage());
145+
doc2.addPage(new PDPage());
146+
PDPageDestination dest = new PDPageFitDestination();
147+
dest.setPage(doc2.getPage(1));
148+
doc2.getDocumentCatalog().setOpenAction(dest);
149+
doc2.save(new File(TARGETTESTDIR,"MergerOpenActionTest2.pdf"));
150+
doc2.close();
151+
152+
PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
153+
pdfMergerUtility.addSource(new File(TARGETTESTDIR, "MergerOpenActionTest1.pdf"));
154+
pdfMergerUtility.addSource(new File(TARGETTESTDIR, "MergerOpenActionTest2.pdf"));
155+
pdfMergerUtility.setDestinationFileName(TARGETTESTDIR + "MergerOpenActionTestResult.pdf");
156+
pdfMergerUtility.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
157+
158+
PDDocument mergedDoc = PDDocument.load(new File(TARGETTESTDIR, "MergerOpenActionTestResult.pdf"));
159+
PDDocumentCatalog documentCatalog = mergedDoc.getDocumentCatalog();
160+
dest = (PDPageDestination) documentCatalog.getOpenAction();
161+
assertEquals(4, documentCatalog.getPages().indexOf(dest.getPage()));
162+
mergedDoc.close();
114163
}
115164

116165
// checks that the result file of a merge has the same rendering as the two
117166
// source files
118167
private void checkMergeIdentical(String filename1, String filename2, String mergeFilename,
119-
MemoryUsageSetting memUsageSetting) throws IOException
168+
MemoryUsageSetting memUsageSetting)
169+
throws IOException
120170
{
121-
PDDocument srcDoc1 = PDDocument.load(testContext.getAssets().open(SRCDIR + "/" + filename1), (String) null);
171+
PDDocument srcDoc1 = PDDocument.load(testContext.getAssets().open(SRCDIR + "/" + filename1), (String)null);
122172
int src1PageCount = srcDoc1.getNumberOfPages();
123173
PDFRenderer src1PdfRenderer = new PDFRenderer(srcDoc1);
124174
Bitmap[] src1ImageTab = new Bitmap[src1PageCount];
@@ -128,7 +178,7 @@ private void checkMergeIdentical(String filename1, String filename2, String merg
128178
}
129179
srcDoc1.close();
130180

131-
PDDocument srcDoc2 = PDDocument.load(testContext.getAssets().open(SRCDIR + "/" + filename2), (String) null);
181+
PDDocument srcDoc2 = PDDocument.load(testContext.getAssets().open(SRCDIR + "/" + filename2), (String)null);
132182
int src2PageCount = srcDoc2.getNumberOfPages();
133183
PDFRenderer src2PdfRenderer = new PDFRenderer(srcDoc2);
134184
Bitmap[] src2ImageTab = new Bitmap[src2PageCount];
@@ -145,7 +195,7 @@ private void checkMergeIdentical(String filename1, String filename2, String merg
145195
pdfMergerUtility.mergeDocuments(memUsageSetting);
146196

147197
PDDocument mergedDoc
148-
= PDDocument.load(new File(TARGETTESTDIR, mergeFilename), (String) null);
198+
= PDDocument.load(new File(TARGETTESTDIR, mergeFilename), (String)null);
149199
PDFRenderer mergePdfRenderer = new PDFRenderer(mergedDoc);
150200
int mergePageCount = mergedDoc.getNumberOfPages();
151201
assertEquals(src1PageCount + src2PageCount, mergePageCount);
@@ -169,14 +219,13 @@ private void checkImagesIdentical(Bitmap bim1, Bitmap bim2)
169219
assertEquals(bim1.getWidth(), bim2.getWidth());
170220
int w = bim1.getWidth();
171221
int h = bim1.getHeight();
172-
173-
int[] bim1Pixels = new int[w * h];
174-
bim1.getPixels(bim1Pixels, 0, w, 0, 0, w, h);
175-
int[] bim2Pixels = new int[w * h];
176-
bim2.getPixels(bim2Pixels, 0, w, 0, 0, w, h);
177-
for (int pixelIdx = 0; pixelIdx < w * h; pixelIdx++)
222+
for (int i = 0; i < w; ++i)
178223
{
179-
assertEquals(bim1Pixels[pixelIdx], bim2Pixels[pixelIdx]);
224+
for (int j = 0; j < h; ++j)
225+
{
226+
assertEquals(bim1.getPixel(i, j), bim2.getPixel(i, j));
227+
}
180228
}
181229
}
230+
182231
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.tom_roush.pdfbox.pdfparser;
2+
3+
import android.content.Context;
4+
import android.util.Log;
5+
6+
import androidx.test.platform.app.InstrumentationRegistry;
7+
8+
import java.io.File;
9+
import java.io.FileOutputStream;
10+
import java.io.IOException;
11+
import java.io.InputStream;
12+
import java.net.URL;
13+
14+
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
15+
import com.tom_roush.pdfbox.io.IOUtils;
16+
import com.tom_roush.pdfbox.pdmodel.PDDocument;
17+
import com.tom_roush.pdfbox.rendering.PDFRenderer;
18+
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
22+
import static org.junit.Assert.assertEquals;
23+
24+
public class TestPDFParserInstrumentation
25+
{
26+
private Context testContext;
27+
28+
@Before
29+
public void setUp() throws IOException
30+
{
31+
testContext = InstrumentationRegistry.getInstrumentation().getContext();
32+
PDFBoxResourceLoader.init(testContext);
33+
}
34+
35+
/**
36+
* PDFBOX-3950: test parsing and rendering of truncated file with missing pages.
37+
*
38+
* @throws IOException
39+
*/
40+
@Test
41+
public void testPDFBox3950() throws IOException
42+
{
43+
File TARGETPDFDIR = new File(testContext.getCacheDir(), "pdfs");
44+
TARGETPDFDIR.mkdirs();
45+
File pdfFile = new File(testContext.getCacheDir(),
46+
"PDFBOX-3950-23EGDHXSBBYQLKYOKGZUOVYVNE675PRD.pdf");
47+
48+
if (!pdfFile.exists())
49+
{
50+
try
51+
{
52+
Log.i("PdfBox-Android", "PDF not cached, Downloading PDF for TestPDFParser.testPDFBox3950");
53+
InputStream pdfUrlStream = new URL(
54+
"https://issues.apache.org/jira/secure/attachment/12890042/23EGDHXSBBYQLKYOKGZUOVYVNE675PRD.pdf")
55+
.openStream();
56+
IOUtils.copy(pdfUrlStream, new FileOutputStream(pdfFile));
57+
}
58+
catch (Exception e)
59+
{
60+
Log.w("PdfBox-Android", "Unable to download test PDF. Skipping test TestPDFParser.testPDFBox3950");
61+
return;
62+
}
63+
}
64+
65+
PDDocument doc = PDDocument.load(pdfFile);
66+
assertEquals(4, doc.getNumberOfPages());
67+
PDFRenderer renderer = new PDFRenderer(doc);
68+
for (int i = 0; i < doc.getNumberOfPages(); ++i)
69+
{
70+
try
71+
{
72+
renderer.renderImage(i);
73+
}
74+
catch (IOException ex)
75+
{
76+
if (i == 3 && ex.getMessage().equals("Missing descendant font array"))
77+
{
78+
continue;
79+
}
80+
throw ex;
81+
}
82+
}
83+
doc.close();
84+
}
85+
}

library/src/androidTest/java/com/tom_roush/pdfbox/pdmodel/font/PDFontTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ private void testPDFBox3826checkFonts(byte[] byteArray, File fontFile) throws IO
143143
new PDFRenderer(doc).renderImage(0);
144144

145145
PDFTextStripper stripper = new PDFTextStripper();
146+
stripper.setLineSeparator("\n");
146147
String text = stripper.getText(doc);
147-
//Assert.assertEquals("testMultipleFontFileReuse1\r\ntestMultipleFontFileReuse2\r\ntestMultipleFontFileReuse3\r\n", text);
148+
Assert.assertEquals("testMultipleFontFileReuse1\ntestMultipleFontFileReuse2\ntestMultipleFontFileReuse3", text.trim());
148149

149150
doc.close();
150151
}

library/src/main/java/com/tom_roush/fontbox/cff/CFFParser.java

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -83,37 +83,7 @@ public List<CFFFont> parse(byte[] bytes) throws IOException
8383
// try to determine which kind of font we have
8484
if (TAG_OTTO.equals(firstTag))
8585
{
86-
// this is OpenType font containing CFF data
87-
// so find CFF tag
88-
short numTables = input.readShort();
89-
@SuppressWarnings("unused")
90-
short searchRange = input.readShort();
91-
@SuppressWarnings("unused")
92-
short entrySelector = input.readShort();
93-
@SuppressWarnings("unused")
94-
short rangeShift = input.readShort();
95-
96-
boolean cffFound = false;
97-
for (int q = 0; q < numTables; q++)
98-
{
99-
String tagName = readTagName(input);
100-
@SuppressWarnings("unused")
101-
long checksum = readLong(input);
102-
long offset = readLong(input);
103-
long length = readLong(input);
104-
if (tagName.equals("CFF "))
105-
{
106-
cffFound = true;
107-
byte[] bytes2 = new byte[(int) length];
108-
System.arraycopy(bytes, (int) offset, bytes2, 0, bytes2.length);
109-
input = new CFFDataInput(bytes2);
110-
break;
111-
}
112-
}
113-
if (!cffFound)
114-
{
115-
throw new IOException("CFF tag not found in this OpenType font.");
116-
}
86+
input = createTaggedCFFDataInput(input, bytes);
11787
}
11888
else if (TAG_TTCF.equals(firstTag))
11989
{
@@ -150,6 +120,33 @@ else if (TAG_TTFONLY.equals(firstTag))
150120
return fonts;
151121
}
152122

123+
private CFFDataInput createTaggedCFFDataInput(CFFDataInput input, byte[] bytes) throws IOException
124+
{
125+
// this is OpenType font containing CFF data
126+
// so find CFF tag
127+
short numTables = input.readShort();
128+
@SuppressWarnings("unused")
129+
short searchRange = input.readShort();
130+
@SuppressWarnings("unused")
131+
short entrySelector = input.readShort();
132+
@SuppressWarnings("unused")
133+
short rangeShift = input.readShort();
134+
for (int q = 0; q < numTables; q++)
135+
{
136+
String tagName = readTagName(input);
137+
@SuppressWarnings("unused")
138+
long checksum = readLong(input);
139+
long offset = readLong(input);
140+
long length = readLong(input);
141+
if ("CFF ".equals(tagName))
142+
{
143+
byte[] bytes2 = Arrays.copyOfRange(bytes, (int) offset, (int) (offset + length));
144+
return new CFFDataInput(bytes2);
145+
}
146+
}
147+
throw new IOException("CFF tag not found in this OpenType font.");
148+
}
149+
153150
private static String readTagName(CFFDataInput input) throws IOException
154151
{
155152
byte[] b = input.readBytes(4);

0 commit comments

Comments
 (0)