Skip to content

Commit

Permalink
Upgrade PDFBox API to v2.0.21 (#404)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomRoush committed May 16, 2022
1 parent ad6b957 commit 3c6c526
Show file tree
Hide file tree
Showing 64 changed files with 2,072 additions and 775 deletions.
Expand Up @@ -18,6 +18,7 @@
package com.tom_roush.pdfbox.pdmodel.font;

import android.content.Context;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

Expand All @@ -28,10 +29,15 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import com.tom_roush.fontbox.ttf.TTFParser;
import com.tom_roush.fontbox.ttf.TrueTypeCollection;
import com.tom_roush.fontbox.ttf.TrueTypeFont;
import com.tom_roush.fontbox.util.autodetect.FontFileFinder;
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
import com.tom_roush.pdfbox.android.TestResourceGenerator;
import com.tom_roush.pdfbox.cos.COSName;
Expand Down Expand Up @@ -205,6 +211,53 @@ public void testPDFox4318() throws IOException
}
}

@Test
public void testFullEmbeddingTTC() throws IOException
{
FontFileFinder fff = new FontFileFinder();
TrueTypeCollection ttc = null;
for (URI uri : fff.find())
{
if (uri.getPath().endsWith(".ttc"))
{
File file = new File(uri);
Log.i("PdfBox-Android", "TrueType collection file: " + file);
ttc = new TrueTypeCollection(file);
break;
}
}
if (ttc == null)
{
Log.i("PdfBox-Android", "testFullEmbeddingTTC skipped, no .ttc files available");
return;
}

final List<String> names = new ArrayList<String>();
ttc.processAllFonts(new TrueTypeCollection.TrueTypeFontProcessor()
{
@Override
public void process(TrueTypeFont ttf) throws IOException
{
Log.i("PdfBox-Android", "TrueType font in collection: " + ttf.getName());
names.add(ttf.getName());
}
});

TrueTypeFont ttf = ttc.getFontByName(names.get(0)); // take the first one
Log.i("PdfBox-Android", "TrueType font used for test: " + ttf.getName());

try
{
PDType0Font.load(new PDDocument(), ttf, false);
}
catch (IOException ex)
{
Assert.assertEquals("Full embedding of TrueType font collections not supported", ex.getMessage());
return;
}
Assert.fail("should have thrown IOException");
}

private void testPDFBox3826checkFonts(byte[] byteArray, File fontFile) throws IOException
{
PDDocument doc = PDDocument.load(byteArray);
Expand Down
Expand Up @@ -24,24 +24,23 @@
import java.io.File;
import java.io.IOException;

import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
import com.tom_roush.pdfbox.pdmodel.PDDocument;
import com.tom_roush.pdfbox.rendering.TestRendering;
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MultilineFieldsTest
public class MultilineFieldsInstrumentationTest
{
private static File OUT_DIR;
private static final String IN_DIR = "pdfbox/com/tom_roush/pdfbox/pdmodel/interactive/form";
private static final String NAME_OF_PDF = "MultilineFields.pdf";
private static final String TEST_VALUE =
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " +
"sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam";
private static final String TEST_VALUE = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " +
"sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam";

Context testContext;
private Context testContext;

private PDDocument document;
private PDAcroForm acroForm;
Expand All @@ -51,7 +50,6 @@ public void setUp() throws IOException
{
testContext = InstrumentationRegistry.getInstrumentation().getContext();
PDFBoxResourceLoader.init(testContext);
System.out.println("Working Directory = " + System.getProperty("user.dir"));
document = PDDocument.load(testContext.getAssets().open(IN_DIR + "/" + NAME_OF_PDF));
acroForm = document.getDocumentCatalog().getAcroForm();
OUT_DIR = new File(testContext.getCacheDir(), "pdfbox-test-output");
Expand Down Expand Up @@ -110,4 +108,5 @@ public void tearDown() throws IOException
{
document.close();
}

}
Expand Up @@ -284,6 +284,20 @@ public void testFlattenPDFBox4788() throws IOException
flattenAndCompare(sourceUrl, targetFileName);
}

/**
* PDFBOX-4889: appearance streams with empty /BBox.
*
* @throws IOException
*/
@Test
public void testFlattenPDFBox4889() throws IOException
{
String sourceUrl = "https://issues.apache.org/jira/secure/attachment/13005793/f1040sb%20test.pdf";
String targetFileName = "PDFBOX-4889.pdf";

flattenAndCompare(sourceUrl, targetFileName);
}

/*
* Flatten and compare with generated image samples.
*/
Expand Down
20 changes: 8 additions & 12 deletions library/src/main/java/com/tom_roush/fontbox/cmap/CMapParser.java
Expand Up @@ -16,6 +16,7 @@
*/
package com.tom_roush.fontbox.cmap;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -122,27 +123,27 @@ public CMap parse(InputStream input) throws IOException

if (previousToken != null)
{
if (op.op.equals("usecmap"))
if (op.op.equals("usecmap") && previousToken instanceof LiteralName)
{
parseUsecmap((LiteralName) previousToken, result);
}
else if (op.op.equals("begincodespacerange"))
else if (op.op.equals("begincodespacerange") && previousToken instanceof Number)
{
parseBegincodespacerange((Number) previousToken, cmapStream, result);
}
else if (op.op.equals("beginbfchar"))
else if (op.op.equals("beginbfchar") && previousToken instanceof Number)
{
parseBeginbfchar((Number) previousToken, cmapStream, result);
}
else if (op.op.equals("beginbfrange"))
else if (op.op.equals("beginbfrange") && previousToken instanceof Number)
{
parseBeginbfrange((Number) previousToken, cmapStream, result);
}
else if (op.op.equals("begincidchar"))
else if (op.op.equals("begincidchar") && previousToken instanceof Number)
{
parseBegincidchar((Number) previousToken, cmapStream, result);
}
else if (op.op.equals("begincidrange"))
else if (op.op.equals("begincidrange") && previousToken instanceof Integer)
{
parseBegincidrange((Integer) previousToken, cmapStream, result);
}
Expand Down Expand Up @@ -452,12 +453,7 @@ protected InputStream getExternalCMap(String name) throws IOException
return PDFBoxResourceLoader.getStream("com/tom_roush/fontbox/resources/cmap/" + name);
}

InputStream is = getClass().getResourceAsStream("/com/tom_roush/fontbox/resources/cmap/" + name);
if (is == null)
{
throw new IOException("Error: Could not find referenced cmap stream " + name);
}
return is;
return new BufferedInputStream(getClass().getResourceAsStream("/com/tom_roush/fontbox/resources/cmap/" + name));
}

private Object parseNextToken(PushbackInputStream is) throws IOException
Expand Down
Expand Up @@ -37,19 +37,26 @@ public class CodespaceRange
* &lt;8140&gt; to &lt;9FFC&gt; defines a rectangular range. The high byte has to be within 0x81 and 0x9F and the
* low byte has to be within 0x40 and 0xFC
*
* @param startBytes
* @param endBytes
*/
public CodespaceRange(byte[] startBytes, byte[] endBytes)
{
if (startBytes.length != endBytes.length)
byte[] correctedStartBytes = startBytes;
if (startBytes.length != endBytes.length && startBytes.length == 1 && startBytes[0] == 0)
{
correctedStartBytes = new byte[endBytes.length];
}
else if (startBytes.length != endBytes.length)
{
throw new IllegalArgumentException(
"The start and the end values must not have different lengths.");
}
start = new int[startBytes.length];
start = new int[correctedStartBytes.length];
end = new int[endBytes.length];
for (int i = 0; i < startBytes.length; i++)
for (int i = 0; i < correctedStartBytes.length; i++)
{
start[i] = startBytes[i] & 0xFF;
start[i] = correctedStartBytes[i] & 0xFF;
end[i] = endBytes[i] & 0xFF;
}
codeLength = endBytes.length;
Expand Down
10 changes: 10 additions & 0 deletions library/src/main/java/com/tom_roush/fontbox/pfb/PfbParser.java
Expand Up @@ -140,11 +140,21 @@ private void parsePfb(final byte[] pfb) throws IOException
size += in.read() << 8;
size += in.read() << 16;
size += in.read() << 24;
if (size < 0)
{
throw new IOException("PFB record size is negative: " + size);
}
lengths[records] = size;
if (pointer >= pfbdata.length)
{
throw new EOFException("attempted to read past EOF");
}
if (size > pfbdata.length - pointer)
{
throw new IOException("PFB record size (" + size +
") doesn't fit in buffer, position: " + pointer +
", total length: " + pfbdata.length);
}
int got = in.read(pfbdata, pointer, size);
if (got < 0)
{
Expand Down
Expand Up @@ -148,24 +148,37 @@ private void invalidate() throws IOException
@Override
public int read(byte[] b, int off, int len) throws IOException
{
int leftover = bufend - bufpos;
if (len <= leftover)
{
System.arraycopy(buffer, bufpos, b, off, len);
bufpos += len;
return len;
}
System.arraycopy(buffer, bufpos, b, off, leftover);
bufpos += leftover;
if (fillBuffer() > 0)
int curLen = len; // length of what is left to read (shrinks)
int curOff = off; // offset where to put read data (grows)
int totalRead = 0;

while (true)
{
int bytesRead = read(b, off + leftover, len - leftover);
if (bytesRead > 0)
int leftover = bufend - bufpos;
if (curLen <= leftover)
{
System.arraycopy(buffer, bufpos, b, curOff, curLen);
bufpos += curLen;
return totalRead + curLen;
}
// curLen > leftover, we need to read more than what remains in buffer
System.arraycopy(buffer, bufpos, b, curOff, leftover);
totalRead += leftover;
bufpos += leftover;
if (fillBuffer() > 0)
{
curOff += leftover;
curLen -= leftover;
}
else
{
leftover += bytesRead;
if (totalRead == 0)
{
return -1;
}
return totalRead;
}
}
return leftover > 0 ? leftover : -1;
}

/**
Expand Down
Expand Up @@ -402,7 +402,7 @@ private Collection<LangSysTable> getLangSysTables(String scriptTag)
*
* @param langSysTables The {@code LangSysTable}s indicating {@code FeatureRecord}s to search
* for
* @param enabledFeatures An optional whitelist of feature tags ({@code null} to allow all)
* @param enabledFeatures An optional list of feature tags ({@code null} to allow all)
* @return The indicated {@code FeatureRecord}s
*/
private List<FeatureRecord> getFeatureRecords(Collection<LangSysTable> langSysTables,
Expand Down Expand Up @@ -510,16 +510,16 @@ private int doLookup(LookupTable lookupTable, int gid)

/**
* Apply glyph substitutions to the supplied gid. The applicable substitutions are determined by
* the {@code scriptTags} which indicate the language of the gid, and by the
* {@code enabledFeatures} which acts as a whitelist.
* the {@code scriptTags} which indicate the language of the gid, and by the list of
* {@code enabledFeatures}.
*
* To ensure that a single gid isn't mapped to multiple substitutions, subsequent invocations
* with the same gid will return the same result as the first, regardless of script or enabled
* features.
*
* @param gid GID
* @param scriptTags Script tags applicable to the gid (see {@link OpenTypeScript})
* @param enabledFeatures Whitelist of features to apply
* @param enabledFeatures list of features to apply
*/
public int getSubstitution(int gid, String[] scriptTags, List<String> enabledFeatures)
{
Expand Down
Expand Up @@ -152,7 +152,7 @@ public class OS2WindowsMetricsTable extends TTFTable
* <p>For Restricted License embedding to take effect, it must be the only level of embedding
* selected.
*/
public static final short FSTYPE_RESTRICTED = 0x0001;
public static final short FSTYPE_RESTRICTED = 0x0002;

/**
* Preview and Print embedding: the font may be embedded, and temporarily loaded on the
Expand Down
Expand Up @@ -18,6 +18,7 @@

import android.util.Log;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
Expand Down Expand Up @@ -222,21 +223,13 @@ public final class OpenTypeScript
{
if (PDFBoxResourceLoader.isReady())
{
input = PDFBoxResourceLoader.getStream(path);
input = new BufferedInputStream(PDFBoxResourceLoader.getStream(path));
}
else
{
// Fallback
input = OpenTypeScript.class.getResourceAsStream(path);
}
if (input != null)
{
parseScriptsFile(input);
}
else
{
Log.w("PdfBox-Android", "Could not find '" + path + "', mirroring char map will be empty: ");
input = new BufferedInputStream(OpenTypeScript.class.getResourceAsStream(path));
}
parseScriptsFile(input);
}
catch (IOException e)
{
Expand Down

0 comments on commit 3c6c526

Please sign in to comment.