Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ repositories {
}
...
dependencies {
implementation 'com.github.ainceborn:PdfBox-Android-3:3.0.2'
implementation 'com.github.ainceborn:PdfBox-Android-3:3.0.3'
}
```

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=1024m -Dkotlin.daemon.jvm.opti
org.gradle.parallel=true
org.gradle.caching=true

VERSION_NAME=3.0.2
VERSION_NAME=3.0.3
VERSION_CODE=1

ANDROID_BUILD_MIN_SDK_VERSION=26
Expand Down
1 change: 1 addition & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ android {
minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
versionName project.VERSION_NAME
buildConfigField 'String', 'VERSION_NAME', "\"${project.VERSION_NAME}\""
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-proguard-rules.txt'
}
Expand Down
9 changes: 9 additions & 0 deletions library/src/main/java/com/ainceborn/PdfBoxInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.ainceborn;

import com.ainceborn.pdfbox.BuildConfig;

public class PdfBoxInfo {
public static String getVersionName() {
return BuildConfig.VERSION_NAME;
}
}
10 changes: 7 additions & 3 deletions library/src/main/java/com/ainceborn/fontbox/ttf/TTFParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,19 @@ FontHeaders parseTableHeaders(TTFDataStream raf) throws IOException
// panose = os2WindowsMetricsTable.getPanose();
outHeaders.setOs2Windows(font.getOS2Windows());

boolean isOTFAndPostScript;
boolean isOTFAndPostScript = false;
if (font instanceof OpenTypeFont && ((OpenTypeFont) font).isPostScript())
{
isOTFAndPostScript = true;
if (((OpenTypeFont) font).isSupportedOTF())
{
isOTFAndPostScript = true;
font.readTableHeaders(CFFTable.TAG, outHeaders); // calls CFFTable.readHeaders();
}
else
{
outHeaders.setError("OpenType fonts using CFF2 outlines are not supported");
return outHeaders;
}
}
else if (!(font instanceof OpenTypeFont) && font.tables.containsKey(CFFTable.TAG))
{
Expand All @@ -281,7 +286,6 @@ else if (!(font instanceof OpenTypeFont) && font.tables.containsKey(CFFTable.TAG
}
else
{
isOTFAndPostScript = false;
TTFTable gcid = font.getTableMap().get("gcid");
if (gcid != null && gcid.getLength() >= FontHeaders.BYTES_GCID)
{
Expand Down
129 changes: 58 additions & 71 deletions library/src/main/java/com/ainceborn/pdfbox/cos/COSArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ public COSArray()
public COSArray(List<? extends COSObjectable> cosObjectables)
{
this(
cosObjectables.stream()
.map(co -> co == null ? null : co.getCOSObject())
.collect(Collectors.toCollection(ArrayList::new)),
true
cosObjectables.stream()
.map(co -> co == null ? null : co.getCOSObject())
.collect(Collectors.toCollection(ArrayList::new)),
true
);
}

Expand All @@ -82,18 +82,9 @@ private COSArray(ArrayList<COSBase> cosObjects, boolean direct)
*/
public void add(COSBase object)
{
if ((object instanceof COSDictionary || object instanceof COSArray) && !object.isDirect()
&& object.getKey() != null)
{
COSObject cosObject = new COSObject(object, object.getKey());
objects.add(cosObject);
getUpdateState().update(cosObject);
}
else
{
objects.add(object);
getUpdateState().update(object);
}
COSBase objectToAdd = maybeWrap(object);
objects.add(objectToAdd);
getUpdateState().update(objectToAdd);
}

/**
Expand All @@ -120,18 +111,9 @@ public void add( COSObjectable object )
*/
public void add( int i, COSBase object)
{
if ((object instanceof COSDictionary || object instanceof COSArray) && !object.isDirect()
&& object.getKey() != null)
{
COSObject cosObject = new COSObject(object, object.getKey());
objects.add(i, cosObject);
getUpdateState().update(cosObject);
}
else
{
objects.add(i, object);
getUpdateState().update(object);
}
COSBase objectToAdd = maybeWrap(object);
objects.add(i, objectToAdd);
getUpdateState().update(objectToAdd);
}

/**
Expand Down Expand Up @@ -185,14 +167,16 @@ public void addAll( Collection<COSBase> objectsList )
*
* @param objectList The list of objects to add.
*/
public void addAll( COSArray objectList )
public void addAll(COSArray objectList)
{
if( objectList != null )
if (objectList == null)
{
if (objects.addAll(objectList.objects))
{
getUpdateState().update(objectList);
}
return;
}

if (objects.addAll(objectList.objects))
{
getUpdateState().update(objectList);
}
}

Expand All @@ -217,20 +201,11 @@ public void addAll( int i, Collection<COSBase> objectList )
* @param index zero based index into array.
* @param object The object to set.
*/
public void set( int index, COSBase object)
public void set(int index, COSBase object)
{
if ((object instanceof COSDictionary || object instanceof COSArray) && !object.isDirect()
&& object.getKey() != null)
{
COSObject cosObject = new COSObject(object, object.getKey());
objects.set(index, cosObject);
getUpdateState().update(cosObject);
}
else
{
objects.set(index, object);
getUpdateState().update(object);
}
COSBase objectToAdd = maybeWrap(object);
objects.set(index, objectToAdd);
getUpdateState().update(objectToAdd);
}

/**
Expand Down Expand Up @@ -617,7 +592,6 @@ public void growToSize( int size, COSBase object )
while( size() < size )
{
add( object );
getUpdateState().update(object);
}
getUpdateState().update();
}
Expand Down Expand Up @@ -800,65 +774,78 @@ public COSUpdateState getUpdateState()

/**
* Collects all indirect objects numbers within this COSArray and all included dictionaries. It is used to avoid
* mixed up object numbers when importing an existing page to another pdf.
* overlapping object numbers when importing an existing page to another pdf.
*
* Expert use only. You might run into an endless recursion if choosing a wrong starting point.
*
* @param indirectObjects a collection of already found indirect objects.
*
*/
public void getIndirectObjectKeys(Collection<COSObjectKey> indirectObjects)
protected Collection<COSObjectKey> resetObjectKeys(Collection<COSObjectKey> indirectObjects)
{
if (indirectObjects == null)
{
return;
return indirectObjects;
}
COSObjectKey key = getKey();
if (key != null)
{
// avoid endless recursions
if (indirectObjects.contains(key))
{
return;
}
else
{
indirectObjects.add(key);
return indirectObjects;
}
indirectObjects.add(key);
// reset key
setKey(null);
}

for (COSBase cosBase : objects)
{
if (cosBase == null)
{
continue;
}
COSObjectKey cosBaseKey = cosBase.getKey();
if (cosBaseKey != null && indirectObjects.contains(cosBaseKey))
COSObjectKey indirectObjectKey = cosBase instanceof COSObject ? cosBase.getKey() : null;
if (indirectObjectKey != null)
{
continue;
}
if (cosBase instanceof COSObject)
{
// dereference object
cosBase = ((COSObject) cosBase).getObject();
if (indirectObjects.contains(indirectObjectKey))
{
continue;
}
// dereference object first
COSBase dereferencedObject = ((COSObject) cosBase).getObject();
// reset key
cosBase.setKey(null);
cosBase = dereferencedObject;
}
if (cosBase instanceof COSDictionary)
{
// descend to included dictionary to collect all included indirect objects
((COSDictionary) cosBase).getIndirectObjectKeys(indirectObjects);
// descend to included dictionary to reset all included indirect objects
((COSDictionary) cosBase).resetObjectKeys(indirectObjects);
}
else if (cosBase instanceof COSArray)
{
// descend to included array to collect all included indirect objects
((COSArray) cosBase).getIndirectObjectKeys(indirectObjects);
// descend to included array to reset all included indirect objects
((COSArray) cosBase).resetObjectKeys(indirectObjects);
}
else if (cosBaseKey != null)
else if (indirectObjectKey != null)
{
// add key for all indirect objects other than COSDictionary/COSArray
indirectObjects.add(cosBaseKey);
indirectObjects.add(indirectObjectKey);
}
}
return indirectObjects;
}

// wrap indirect objects
private COSBase maybeWrap(COSBase object)
{
COSBase objectToAdd = object;
if ((object instanceof COSDictionary || object instanceof COSArray) && !object.isDirect()
&& object.getKey() != null)
{
objectToAdd = new COSObject(object, object.getKey());
}
return objectToAdd;
}
}
62 changes: 39 additions & 23 deletions library/src/main/java/com/ainceborn/pdfbox/cos/COSDictionary.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -1424,64 +1425,79 @@ public COSUpdateState getUpdateState()
return updateState;
}

/**
* Reset all object keys to avoid overlapping numbers when saving the new pdf.
*/
public void resetImportedObjectKeys()
{
resetObjectKeys(new HashSet<>()).clear();
}

/**
* Collects all indirect objects numbers within this dictionary and all included dictionaries. It is used to avoid
* mixed up object numbers when importing an existing page to another pdf.
* overlapping object numbers when importing an existing page to another pdf.
*
* Expert use only. You might run into an endless recursion if choosing a wrong starting point.
*
* @param indirectObjects a collection of already found indirect objects.
*
*/
public void getIndirectObjectKeys(Collection<COSObjectKey> indirectObjects)
protected Collection<COSObjectKey> resetObjectKeys(Collection<COSObjectKey> indirectObjects)
{
if (indirectObjects == null)
{
return;
return indirectObjects;
}
COSObjectKey key = getKey();
if (key != null)
{
// avoid endless recursions
if (indirectObjects.contains(key))
{
return;
}
else
{
indirectObjects.add(key);
return indirectObjects;
}
indirectObjects.add(key);
// reset object key
setKey(null);
}
for (Map.Entry<COSName, COSBase> entry : items.entrySet())
{
COSBase cosBase = entry.getValue();
COSObjectKey cosBaseKey = cosBase != null ? cosBase.getKey() : null;
// avoid endless recursions
if (COSName.PARENT.equals(entry.getKey())
|| (cosBaseKey != null && indirectObjects.contains(cosBaseKey)))
{
continue;
}
if (cosBase instanceof COSObject)
COSObjectKey indirectObjectKey = cosBase instanceof COSObject ? cosBase.getKey() : null;
if (indirectObjectKey != null)
{
// dereference object
// avoid endless recursions
if (indirectObjects.contains(indirectObjectKey))
{
continue;
}
// dereference object first
cosBase = ((COSObject) cosBase).getObject();
// reset object key
entry.getValue().setKey(null);
}
if (cosBase instanceof COSDictionary)
{
// descend to included dictionary to collect all included indirect objects
((COSDictionary) cosBase).getIndirectObjectKeys(indirectObjects);
COSName entryKey = entry.getKey();
// descend to included dictionary to reset all included indirect objects
// skip PARENT and P references to avoid recursions
if (!COSName.PARENT.equals(entryKey) && !COSName.P.equals(entryKey))
{
((COSDictionary) cosBase).resetObjectKeys(indirectObjects);
}
}
else if (cosBase instanceof COSArray)
{
// descend to included array to collect all included indirect objects
((COSArray) cosBase).getIndirectObjectKeys(indirectObjects);
// descend to included array to reset all included indirect objects
((COSArray) cosBase).resetObjectKeys(indirectObjects);
}
else if (cosBaseKey != null)
else if (indirectObjectKey != null)
{
// add key for all indirect objects other than COSDictionary/COSArray
indirectObjects.add(cosBaseKey);
indirectObjects.add(indirectObjectKey);
}
}
return indirectObjects;
}

}
Loading
Loading