summaryrefslogtreecommitdiffstats
path: root/fop-core/src
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2022-01-19 10:43:17 +0000
committerSimon Steiner <ssteiner@apache.org>2022-01-19 10:43:17 +0000
commit63c0ce941e58f3673a586527e1669639494ecf6e (patch)
tree3859f8aaf1fa792f8130d783131b24e1c1975255 /fop-core/src
parentbbd7343ba13043f8f78e175363037f052d648395 (diff)
downloadxmlgraphics-fop-63c0ce941e58f3673a586527e1669639494ecf6e.tar.gz
xmlgraphics-fop-63c0ce941e58f3673a586527e1669639494ecf6e.zip
FOP-3048: Resolve links across IF files
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1897194 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'fop-core/src')
-rw-r--r--fop-core/src/main/java/org/apache/fop/area/RenderPagesModel.java9
-rw-r--r--fop-core/src/main/java/org/apache/fop/render/intermediate/IFParser.java27
-rw-r--r--fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java11
-rw-r--r--fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java19
-rw-r--r--fop-core/src/test/java/org/apache/fop/events/EventProcessingTestCase.java6
-rw-r--r--fop-core/src/test/java/org/apache/fop/render/extensions/DocumentNavigationHandlerTestCase.java41
6 files changed, 88 insertions, 25 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/area/RenderPagesModel.java b/fop-core/src/main/java/org/apache/fop/area/RenderPagesModel.java
index b94a32b4b..91d8d4e22 100644
--- a/fop-core/src/main/java/org/apache/fop/area/RenderPagesModel.java
+++ b/fop-core/src/main/java/org/apache/fop/area/RenderPagesModel.java
@@ -191,15 +191,6 @@ public class RenderPagesModel extends AreaTreeModel {
protected void renderPage(PageViewport pageViewport) {
try {
renderer.renderPage(pageViewport);
- if (!pageViewport.isResolved()) {
- String[] idrefs = pageViewport.getIDRefs();
- for (String idref : idrefs) {
- AreaEventProducer eventProducer = AreaEventProducer.Provider.get(
- renderer.getUserAgent().getEventBroadcaster());
- eventProducer.unresolvedIDReferenceOnPage(this,
- pageViewport.getPageNumberString(), idref);
- }
- }
} catch (Exception e) {
AreaEventProducer eventProducer = AreaEventProducer.Provider.get(
renderer.getUserAgent().getEventBroadcaster());
diff --git a/fop-core/src/main/java/org/apache/fop/render/intermediate/IFParser.java b/fop-core/src/main/java/org/apache/fop/render/intermediate/IFParser.java
index 3745da00e..a75e61cf3 100644
--- a/fop-core/src/main/java/org/apache/fop/render/intermediate/IFParser.java
+++ b/fop-core/src/main/java/org/apache/fop/render/intermediate/IFParser.java
@@ -58,6 +58,7 @@ import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.render.intermediate.extensions.DocumentNavigationExtensionConstants;
import org.apache.fop.render.intermediate.extensions.DocumentNavigationHandler;
+import org.apache.fop.render.intermediate.extensions.GoToXYAction;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.ColorUtil;
@@ -164,6 +165,7 @@ public class IFParser implements IFConstants {
private Map<String, StructureTreeElement> structureTreeElements
= new HashMap<String, StructureTreeElement>();
+ private Map<String, GoToXYAction> unresolvedIds = new HashMap<>();
private class StructureTreeHandler extends DefaultHandler {
@@ -308,12 +310,24 @@ public class IFParser implements IFConstants {
.noStructureTreeInXML(this);
}
handled = startIFElement(localName, attributes);
+
+ if (EL_ID.equals(localName) && documentHandler.getDocumentNavigationHandler() != null) {
+ if (this.navParser == null) {
+ this.navParser = new DocumentNavigationHandler(
+ documentHandler.getDocumentNavigationHandler(),
+ structureTreeElements, unresolvedIds);
+ }
+ delegate = this.navParser;
+ delegateDepth++;
+ delegate.startDocument();
+ delegate.startElement(uri, localName, qName, attributes);
+ }
}
} else if (DocumentNavigationExtensionConstants.NAMESPACE.equals(uri)) {
if (this.navParser == null) {
this.navParser = new DocumentNavigationHandler(
this.documentHandler.getDocumentNavigationHandler(),
- structureTreeElements);
+ structureTreeElements, unresolvedIds);
}
delegate = this.navParser;
delegateDepth++;
@@ -410,6 +424,9 @@ public class IFParser implements IFConstants {
ElementHandler elementHandler = elementHandlers.get(localName);
if (elementHandler != null) {
try {
+ if (elementHandler instanceof DocumentHandler) {
+ addUnresolvedIds();
+ }
elementHandler.endElement();
} catch (IFException ife) {
handleIFException(ife);
@@ -425,6 +442,14 @@ public class IFParser implements IFConstants {
}
}
+ private void addUnresolvedIds() throws IFException {
+ for (GoToXYAction action : unresolvedIds.values()) {
+ if (action != null) {
+ documentHandler.getDocumentNavigationHandler().addResolvedAction(action);
+ }
+ }
+ }
+
// ============== Element handlers for the intermediate format =============
private interface ElementHandler {
diff --git a/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java b/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java
index 5a401b1a7..da010d21a 100644
--- a/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java
+++ b/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java
@@ -68,6 +68,7 @@ import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.AbstractTextArea;
+import org.apache.fop.area.inline.BasicLinkArea;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineArea;
@@ -95,7 +96,6 @@ import org.apache.fop.render.intermediate.extensions.GoToXYAction;
import org.apache.fop.render.intermediate.extensions.Link;
import org.apache.fop.render.intermediate.extensions.NamedDestination;
import org.apache.fop.render.intermediate.extensions.URIAction;
-import org.apache.fop.render.pdf.PDFEventProducer;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
@@ -427,9 +427,6 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
GoToXYAction action = (GoToXYAction)unfinishedGoTos.get(0);
noteGoToPosition(action, defaultPos);
}
- PDFEventProducer eventProducer = PDFEventProducer.Provider.get(
- getUserAgent().getEventBroadcaster());
- eventProducer.nonFullyResolvedLinkTargets(this, count);
// dysfunctional if pageref is null
}
}
@@ -981,6 +978,12 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
action.setStructureTreeElement(structElem);
Link link = new Link(action, ipRect);
this.deferredLinks.add(link);
+ } else if (ip instanceof BasicLinkArea) {
+ BasicLinkArea linkArea = (BasicLinkArea) ip;
+ String id = linkArea.getResolver().getIDRefs()[0];
+ action = getGoToActionForID(id, -1);
+ Link link = new Link(action, ipRect);
+ this.deferredLinks.add(link);
}
}
diff --git a/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java b/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java
index 69743708d..f654ef37e 100644
--- a/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java
+++ b/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java
@@ -38,6 +38,8 @@ import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.PageIndexContext;
import org.apache.fop.util.XMLUtil;
+import static org.apache.fop.render.intermediate.IFConstants.EL_ID;
+
/**
* ContentHandler that handles the IF document navigation namespace.
*/
@@ -46,9 +48,11 @@ public class DocumentNavigationHandler extends DefaultHandler
/** Logger instance */
protected static final Log log = LogFactory.getLog(DocumentNavigationHandler.class);
+ private static final String NAME = "name";
private StringBuffer content = new StringBuffer();
private Stack objectStack = new Stack();
+ private Map<String, GoToXYAction> unresolvedIds;
private IFDocumentNavigationHandler navHandler;
@@ -62,16 +66,27 @@ public class DocumentNavigationHandler extends DefaultHandler
* @param structureTreeElements the elements representing the structure of the document
*/
public DocumentNavigationHandler(IFDocumentNavigationHandler navHandler,
- Map<String, StructureTreeElement> structureTreeElements) {
+ Map<String, StructureTreeElement> structureTreeElements, Map<String, GoToXYAction> unresolvedIds) {
this.navHandler = navHandler;
assert structureTreeElements != null;
this.structureTreeElements = structureTreeElements;
+ this.unresolvedIds = unresolvedIds;
}
/** {@inheritDoc} */
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
boolean handled = false;
+ if (EL_ID.equals(localName)) {
+ String idref = attributes.getValue(NAME);
+ if (unresolvedIds.containsKey(idref)) {
+ GoToXYAction action = new GoToXYAction(idref);
+ action.setPageIndex(navHandler.getPageIndex());
+ action.setTargetLocation(new Point(0, 0));
+ unresolvedIds.put(idref, action);
+ }
+ handled = true;
+ }
if (NAMESPACE.equals(uri)) {
if (BOOKMARK_TREE.getLocalName().equals(localName)) {
if (!objectStack.isEmpty()) {
@@ -124,6 +139,7 @@ public class DocumentNavigationHandler extends DefaultHandler
final Point location;
if (pageIndex < 0) {
location = null;
+ unresolvedIds.put(id, null);
} else {
if (hasNavigation() && !inBookmark() && pageIndexRelative >= 0) {
int currentPageIndex = navHandler.getPageIndex();
@@ -136,6 +152,7 @@ public class DocumentNavigationHandler extends DefaultHandler
final int y = XMLUtil
.getAttributeAsInt(attributes, "y");
location = new Point(x, y);
+ unresolvedIds.remove(id);
}
action = new GoToXYAction(id, pageIndex, location,
new PageIndexRelative(pageIndex, pageIndexRelative));
diff --git a/fop-core/src/test/java/org/apache/fop/events/EventProcessingTestCase.java b/fop-core/src/test/java/org/apache/fop/events/EventProcessingTestCase.java
index 66ec43193..5e96883ec 100644
--- a/fop-core/src/test/java/org/apache/fop/events/EventProcessingTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/events/EventProcessingTestCase.java
@@ -106,12 +106,6 @@ public class EventProcessingTestCase {
}
@Test
- public void testArea() throws Exception {
- doTest("area.fo",
- AreaEventProducer.class.getName() + ".unresolvedIDReferenceOnPage");
- }
-
- @Test
public void testBookmarks() throws Exception {
doTest("bookmarks.fo",
AreaEventProducer.class.getName() + ".unresolvedIDReference");
diff --git a/fop-core/src/test/java/org/apache/fop/render/extensions/DocumentNavigationHandlerTestCase.java b/fop-core/src/test/java/org/apache/fop/render/extensions/DocumentNavigationHandlerTestCase.java
index 327f31aa5..1b8efd112 100644
--- a/fop-core/src/test/java/org/apache/fop/render/extensions/DocumentNavigationHandlerTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/render/extensions/DocumentNavigationHandlerTestCase.java
@@ -23,6 +23,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -30,7 +31,13 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
import org.junit.Assert;
import org.junit.Test;
@@ -45,11 +52,15 @@ import org.apache.xmlgraphics.util.QName;
import org.apache.fop.accessibility.StructureTreeElement;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.MimeConstants;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.pdf.PDFLinearizationTestCase;
import org.apache.fop.pdf.PDFVTTestCase;
import org.apache.fop.render.intermediate.IFContext;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFParser;
+import org.apache.fop.render.intermediate.IFUtil;
import org.apache.fop.render.intermediate.extensions.AbstractAction;
import org.apache.fop.render.intermediate.extensions.Bookmark;
import org.apache.fop.render.intermediate.extensions.BookmarkTree;
@@ -81,7 +92,7 @@ public class DocumentNavigationHandlerTestCase {
}
};
DocumentNavigationHandler navigationHandler = new DocumentNavigationHandler(pdfDocumentNavigationHandler,
- new HashMap<String, StructureTreeElement>());
+ new HashMap<String, StructureTreeElement>(), new HashMap<String, GoToXYAction>());
QName xy = DocumentNavigationExtensionConstants.GOTO_XY;
Attributes attributes = mock(Attributes.class);
when(attributes.getValue("page-index")).thenReturn("0");
@@ -96,6 +107,28 @@ public class DocumentNavigationHandlerTestCase {
}
@Test
+ public void testGotoXYMergedIF() throws Exception {
+ InputStream ifXml = getClass().getResourceAsStream("link.if.xml");
+ ByteArrayOutputStream pdf = iFToPDF(ifXml);
+ Assert.assertTrue(pdf.toString().contains("/S /GoTo"));
+ }
+
+ private ByteArrayOutputStream iFToPDF(InputStream is) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ FOUserAgent userAgent = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ Source src = new StreamSource(is);
+ IFDocumentHandler documentHandler
+ = userAgent.getRendererFactory().createDocumentHandler(userAgent, MimeConstants.MIME_PDF);
+ documentHandler.setResult(new StreamResult(out));
+ IFUtil.setupFonts(documentHandler);
+ IFParser parser = new IFParser();
+ Result res = new SAXResult(parser.getContentHandler(documentHandler, userAgent));
+ transformer.transform(src, res);
+ return out;
+ }
+
+ @Test
public void testGotoXYPrevousPage() throws SAXException, IFException, IOException {
FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
PDFDocumentHandler documentHandler = new PDFDocumentHandler(new IFContext(ua));
@@ -116,7 +149,7 @@ public class DocumentNavigationHandlerTestCase {
}
};
DocumentNavigationHandler navigationHandler = new DocumentNavigationHandler(pdfDocumentNavigationHandler,
- new HashMap<String, StructureTreeElement>());
+ new HashMap<String, StructureTreeElement>(), new HashMap<String, GoToXYAction>());
QName xy = DocumentNavigationExtensionConstants.GOTO_XY;
Attributes attributes = mock(Attributes.class);
when(attributes.getValue("page-index")).thenReturn("0");
@@ -150,7 +183,7 @@ public class DocumentNavigationHandlerTestCase {
PDFDocumentNavigationHandler pdfDocumentNavigationHandler = new PDFDocumentNavigationHandler(documentHandler);
DocumentNavigationHandler navigationHandler = new DocumentNavigationHandler(pdfDocumentNavigationHandler,
- new HashMap<String, StructureTreeElement>());
+ new HashMap<String, StructureTreeElement>(), new HashMap<String, GoToXYAction>());
QName xy = DocumentNavigationExtensionConstants.GOTO_XY;
Attributes attributes = mock(Attributes.class);
@@ -199,7 +232,7 @@ public class DocumentNavigationHandlerTestCase {
}
};
DocumentNavigationHandler navigationHandler = new DocumentNavigationHandler(pdfDocumentNavigationHandler,
- new HashMap<String, StructureTreeElement>());
+ new HashMap<String, StructureTreeElement>(), new HashMap<String, GoToXYAction>());
Attributes attributes = mock(Attributes.class);
when(attributes.getValue("page-index")).thenReturn("0");
when(attributes.getValue("x")).thenReturn("0");