Skip to content

Commit

Permalink
FOP-3136: Softmask dictionary preserved
Browse files Browse the repository at this point in the history
  • Loading branch information
simonsteiner1984 committed Aug 7, 2023
1 parent 5ee7efc commit b001a30
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 65 deletions.
6 changes: 1 addition & 5 deletions src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,6 @@ protected Object cloneForNewDocument(Object base) throws IOException {
return new PDFCloner(this, false).cloneForNewDocument(base);
}

protected Object cloneResourcesForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
return new PDFCloner(this, false).cloneResourcesForNewDocument(base, keyBase, exclude);
}

protected Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
return new PDFCloner(this, false).cloneForNewDocument(base, keyBase, exclude);
}
Expand Down Expand Up @@ -228,7 +224,7 @@ public Object createStreamFromPDFBoxPage(PDDocument sourceDoc, PDPage sourcePage

List<COSName> exclude = Arrays.asList(COSName.PATTERN);
PDFDictionary pageResources =
(PDFDictionary)cloneResourcesForNewDocument(srcPgResCosDict, srcPgResCosDict, exclude);
(PDFDictionary)cloneForNewDocument(srcPgResCosDict, srcPgResCosDict, exclude);

updateMergeFontInfo(pageResources, fontinfo);
updateXObj(srcPgResCosDict, pageResources);
Expand Down
18 changes: 4 additions & 14 deletions src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,7 @@ protected Object cloneForNewDocument(Object base, Object keyBase) throws IOExcep
return cloneForNewDocument(base, keyBase, Collections.EMPTY_LIST);
}

protected Object cloneResourcesForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
return cloneForNewDocument(base, keyBase, exclude, true);
}

protected Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
return cloneForNewDocument(base, keyBase, exclude, false);
}

private Object cloneForNewDocument(Object base, Object keyBase, Collection exclude, boolean rename)
throws IOException {
if (base == null) {
return null;
}
Expand Down Expand Up @@ -110,7 +101,7 @@ private Object cloneForNewDocument(Object base, Object keyBase, Collection exclu
} else if (base instanceof COSStream) {
return readCOSStream((COSStream) base, keyBase);
} else if (base instanceof COSDictionary) {
return readCOSDictionary((COSDictionary) base, keyBase, exclude, rename);
return readCOSDictionary((COSDictionary) base, keyBase, exclude);
} else if (base instanceof COSName) {
PDFName newName = new PDFName(((COSName)base).getName());
return cacheClonedObject(keyBase, newName);
Expand Down Expand Up @@ -151,17 +142,16 @@ protected Object readCOSObject(COSObject object, Collection exclude) throws IOEx
return obj;
}

private PDFDictionary readCOSDictionary(COSDictionary dic, Object keyBase, Collection exclude, boolean rename)
throws IOException {
private PDFDictionary readCOSDictionary(COSDictionary dic, Object keyBase, Collection exclude) throws IOException {
PDFDictionary newDict = new PDFDictionary();
cacheClonedObject(keyBase, newDict);
for (Map.Entry<COSName, COSBase> e : dic.entrySet()) {
if (!exclude.contains(e.getKey())) {
String name = e.getKey().getName();
if (rename && adapter.uniqueName != null) {
if (adapter.uniqueName != null) {
name = adapter.uniqueName.getName(e.getKey());
}
newDict.put(name, cloneForNewDocument(e.getValue(), e.getValue(), exclude, true));
newDict.put(name, cloneForNewDocument(e.getValue(), e.getValue(), exclude));
}
}
return newDict;
Expand Down
1 change: 1 addition & 0 deletions src/java/org/apache/fop/render/pdf/pdfbox/UniqueName.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ private List<COSName> getResourceNames(COSDictionary sourcePageResources, List<C
}
}
}
resourceNames.remove(COSName.S);
return resourceNames;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ public class PDFBoxAdapterTestCase {
protected static final String PATTERN = "pattern.pdf";
protected static final String PATTERN2 = "pattern2.pdf";
protected static final String FORMROTATED = "formrotated.pdf";
protected static final String SOFTMASK = "softmask-min.pdf";

private static PDFPage getPDFPage(PDFDocument doc) {
final Rectangle2D r = new Rectangle2D.Double();
Expand Down Expand Up @@ -554,16 +553,21 @@ public Map<Integer, URI> getImages() {
}

private void loadPage(PDFDocument pdfdoc, String src) throws IOException {
PDDocument doc = load(src);
loadPage(pdfdoc, doc);
}

private PDFPage loadPage(PDFDocument pdfdoc, PDDocument doc) throws IOException {
PDFPage pdfpage = getPDFPage(pdfdoc);
pdfdoc.assignObjectNumber(pdfpage);
pdfpage.setDocument(pdfdoc);
PDFBoxAdapter adapter = new PDFBoxAdapter(pdfpage, new HashMap<>(), new HashMap<Integer, PDFArray>());
PDDocument doc = load(src);
PDPage page = doc.getPage(0);
PDFArray targetPageMediaBox = new PDFArray(0d, 0d, 100d, 100d);
adapter.createStreamFromPDFBoxPage(doc, page, "key", new AffineTransform(), targetPageMediaBox, null,
new Rectangle());
doc.close();
return pdfpage;
}

@Test
Expand Down Expand Up @@ -625,53 +629,11 @@ public void testPDFBoxImageHandlerTransformPatternMatrix() throws Exception {
Assert.assertTrue(baseObjectStringDef.contains(
"COSName{Matrix}:"
+ "COSArray{"
+ "COSFloat{53.885883};COSFloat{0.0};1;"
+ "COSFloat{-26.496819};COSFloat{72.74594};COSFloat{-20.860199};"
+ "COSFloat{53.885883};COSFloat{0.0};1;"
+ "COSFloat{-26.496819};COSFloat{72.74594};COSFloat{-20.860199};"
+ "};"));
}

/**
* Only page resources names should be de-collisioned - this tests that deeper COSNames are preserved.
* @throws Exception On exception.
*/
@Test
public void testPDFBoxImageHandlerPreserveNames() throws Exception {
ImageInfo imgi = new ImageInfo("a", "b");
PDDocument srcPDFDoc = load(SOFTMASK);
ImagePDF srcImagePDF = new ImagePDF(imgi, srcPDFDoc);
PDFDocument targetPDFDoc = new PDFDocument("");
PDFPage targetPDFPage = getPDFPage(targetPDFDoc);
targetPDFPage.setDocument(targetPDFDoc);
PDFGState g = new PDFGState();
targetPDFDoc.assignObjectNumber(g);
targetPDFPage.addGState(g);

PDFContentGenerator con = new PDFContentGenerator(targetPDFDoc, null, null);
FOUserAgent mockedAgent = mock(FOUserAgent.class);
when(mockedAgent.isAccessibilityEnabled()).thenReturn(false);
when(mockedAgent.getPDFObjectCache()).thenReturn(new SoftMapCache(true));
PDFRenderingContext c = new PDFRenderingContext(mockedAgent, con, targetPDFPage, null);
c.setPageNumbers(new HashMap<Integer, PDFArray>());
Rectangle destRect = new Rectangle(0, 0, 637920, 850320);
PDFBoxImageHandler pdfBoxImageHandler = new PDFBoxImageHandler();
pdfBoxImageHandler.handleImage(c, srcImagePDF, destRect);

// Drill down into doc and check that the soft mask dictionary has been preserved.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
c.getGenerator().getDocument().output(bos);
String docString = bos.toString("UTF-8");

Assert.assertTrue(docString.contains("2 0 obj\n"
+ "<<\n"
+ " /S /Transparency\n"
+ " /CS /DeviceCMYK\n"
+ " /Type /Group\n"
+ " /I false\n"
+ " /K false\n"
+ ">>\n"
+ "endobj"));
}

@Test
public void testPDFCache() throws IOException {
LoadPDFWithCache loadPDFWithCache = new LoadPDFWithCache();
Expand Down Expand Up @@ -984,4 +946,17 @@ public void testMergeAnnotsTree() throws Exception {
+ "/T (Fullname1)\n"
+ ">>"));
}

@Test
public void testPreservePropertyNames() throws Exception {
PDDocument doc = load(CFF1);
COSDictionary properties = new COSDictionary();
properties.setItem(COSName.S, COSName.S);
doc.getPage(0).getResources().getCOSObject().setItem(COSName.PROPERTIES, properties);
PDFDocument pdfdoc = new PDFDocument("");
PDFPage page = loadPage(pdfdoc, doc);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
page.getPDFResources().output(bos);
Assert.assertTrue(bos.toString("UTF-8").contains("/Properties << /S /S >>"));
}
}
Binary file not shown.

0 comments on commit b001a30

Please sign in to comment.