summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2018-07-02 14:13:54 +0000
committerSimon Steiner <ssteiner@apache.org>2018-07-02 14:13:54 +0000
commitc28cc8e161b799f47000530cdf2779f6f2e7d735 (patch)
tree19abc0c414c723ca97c2bd1352ccfbc185574d96
parentee143ede26953cd06b1ac5ce7a49d38086c85e1c (diff)
downloadxmlgraphics-fop-c28cc8e161b799f47000530cdf2779f6f2e7d735.tar.gz
xmlgraphics-fop-c28cc8e161b799f47000530cdf2779f6f2e7d735.zip
FOP-2800: IF Links point to current page instead of earlier page
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1834850 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java10
-rw-r--r--fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java9
-rw-r--r--fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/GoToXYAction.java17
-rw-r--r--fop-core/src/test/java/org/apache/fop/pdf/PDFVTTestCase.java2
-rw-r--r--fop-core/src/test/java/org/apache/fop/render/extensions/DocumentNavigationHandlerTestCase.java49
-rw-r--r--fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-nav.xsd1
6 files changed, 80 insertions, 8 deletions
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 3ea7fc2cd..aeafc45a9 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
@@ -396,7 +396,7 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
this.documentMetadata = metadata.getMetadata();
}
- private GoToXYAction getGoToActionForID(String targetID, int pageIndex) {
+ private GoToXYAction getGoToActionForID(String targetID, final int pageIndex) {
// Already a GoToXY present for this target? If not, create.
GoToXYAction action = (GoToXYAction)actionSet.get(targetID);
//GoToXYAction action = (GoToXYAction)idGoTos.get(targetID);
@@ -407,10 +407,14 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
Point position = (Point)idPositions.get(targetID);
// can the GoTo already be fully filled in?
if (pageIndex >= 0 && position != null) {
- action = new GoToXYAction(targetID, pageIndex, position);
+ action = new GoToXYAction(targetID, pageIndex, position, new GoToXYAction.PageIndexRelative() {
+ public int getPageIndexRelative() {
+ return pageIndex - documentHandler.getContext().getPageIndex();
+ }
+ });
} else {
// Not complete yet, can't use getPDFGoTo:
- action = new GoToXYAction(targetID, pageIndex, null);
+ action = new GoToXYAction(targetID, pageIndex, null, null);
unfinishedGoTos.add(action);
}
action = (GoToXYAction)actionSet.put(action);
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 5221ad04b..c0b78d977 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
@@ -119,11 +119,12 @@ public class DocumentNavigationHandler extends DefaultHandler
} else {
String id = attributes.getValue("id");
int pageIndex = XMLUtil.getAttributeAsInt(attributes, "page-index");
+ final int pageIndexRelative = XMLUtil.getAttributeAsInt(attributes, "page-index-relative", 0);
final Point location;
if (pageIndex < 0) {
location = null;
} else {
- if (hasNavigation() && !inBookmark()) {
+ if (hasNavigation() && !inBookmark() && pageIndexRelative >= 0) {
int currentPageIndex = navHandler.getPageIndex();
if (currentPageIndex >= 0) {
pageIndex = currentPageIndex;
@@ -135,7 +136,11 @@ public class DocumentNavigationHandler extends DefaultHandler
.getAttributeAsInt(attributes, "y");
location = new Point(x, y);
}
- action = new GoToXYAction(id, pageIndex, location);
+ action = new GoToXYAction(id, pageIndex, location, new GoToXYAction.PageIndexRelative() {
+ public int getPageIndexRelative() {
+ return pageIndexRelative;
+ }
+ });
}
if (structureTreeElement != null) {
action.setStructureTreeElement(structureTreeElement);
diff --git a/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/GoToXYAction.java b/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/GoToXYAction.java
index 06dc4a5a7..6fdee58da 100644
--- a/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/GoToXYAction.java
+++ b/fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/GoToXYAction.java
@@ -33,6 +33,7 @@ import org.apache.fop.util.XMLUtil;
public class GoToXYAction extends AbstractAction implements DocumentNavigationExtensionConstants {
private int pageIndex = -1;
+ private PageIndexRelative pageIndexRelative;
private Point targetLocation;
/**
@@ -40,7 +41,7 @@ public class GoToXYAction extends AbstractAction implements DocumentNavigationEx
* @param id the identifier for this action
*/
public GoToXYAction(String id) {
- this(id, -1, null);
+ this(id, -1, null, null);
}
/**
@@ -51,7 +52,7 @@ public class GoToXYAction extends AbstractAction implements DocumentNavigationEx
* @param targetLocation the absolute location on the page (coordinates in millipoints),
* or null, if the position isn't known, yet
*/
- public GoToXYAction(String id, int pageIndex, Point targetLocation) {
+ public GoToXYAction(String id, int pageIndex, Point targetLocation, PageIndexRelative pageIndexRelative) {
setID(id);
if (pageIndex < 0 && targetLocation != null) {
throw new IllegalArgumentException(
@@ -59,6 +60,11 @@ public class GoToXYAction extends AbstractAction implements DocumentNavigationEx
}
setPageIndex(pageIndex);
setTargetLocation(targetLocation);
+ this.pageIndexRelative = pageIndexRelative;
+ }
+
+ public interface PageIndexRelative {
+ int getPageIndexRelative();
}
/**
@@ -147,6 +153,13 @@ public class GoToXYAction extends AbstractAction implements DocumentNavigationEx
atts.addAttribute("", "id", "id", XMLUtil.CDATA, getID());
atts.addAttribute("", "page-index", "page-index",
XMLUtil.CDATA, Integer.toString(pageIndex));
+ if (pageIndexRelative != null) {
+ int pageIndexRelativeInt = pageIndexRelative.getPageIndexRelative();
+ if (pageIndexRelativeInt < 0) {
+ atts.addAttribute("", "page-index-relative", "page-index-relative",
+ XMLUtil.CDATA, Integer.toString(pageIndexRelativeInt));
+ }
+ }
atts.addAttribute("", "x", "x", XMLUtil.CDATA,
Integer.toString(reportedTargetLocation.x));
atts.addAttribute("", "y", "y", XMLUtil.CDATA,
diff --git a/fop-core/src/test/java/org/apache/fop/pdf/PDFVTTestCase.java b/fop-core/src/test/java/org/apache/fop/pdf/PDFVTTestCase.java
index 63deaffba..312750f36 100644
--- a/fop-core/src/test/java/org/apache/fop/pdf/PDFVTTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/pdf/PDFVTTestCase.java
@@ -183,7 +183,7 @@ public class PDFVTTestCase {
throw new IOException(name + " not found " + firstObj);
}
- private String getObj(Collection<StringBuilder> objs, String x) {
+ public static String getObj(Collection<StringBuilder> objs, String x) {
for (StringBuilder s : objs) {
if (s.toString().contains(x)) {
return s.toString();
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 523da388f..327f31aa5 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
@@ -19,10 +19,13 @@
package org.apache.fop.render.extensions;
import java.awt.Dimension;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -43,6 +46,8 @@ import org.apache.fop.accessibility.StructureTreeElement;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
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.IFException;
import org.apache.fop.render.intermediate.extensions.AbstractAction;
@@ -91,6 +96,50 @@ public class DocumentNavigationHandlerTestCase {
}
@Test
+ public void testGotoXYPrevousPage() throws SAXException, IFException, IOException {
+ FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
+ PDFDocumentHandler documentHandler = new PDFDocumentHandler(new IFContext(ua));
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ documentHandler.setResult(new StreamResult(bos));
+ documentHandler.setFontInfo(new FontInfo());
+ documentHandler.startDocument();
+
+ documentHandler.startPage(0, "", "", new Dimension());
+ documentHandler.endPage();
+
+ documentHandler.startPage(1, "", "", new Dimension());
+ final List<GoToXYAction> goToXYActions = new ArrayList<GoToXYAction>();
+ PDFDocumentNavigationHandler pdfDocumentNavigationHandler = new PDFDocumentNavigationHandler(documentHandler) {
+ public void addResolvedAction(AbstractAction action) throws IFException {
+ super.addResolvedAction(action);
+ goToXYActions.add((GoToXYAction) action);
+ }
+ };
+ DocumentNavigationHandler navigationHandler = new DocumentNavigationHandler(pdfDocumentNavigationHandler,
+ new HashMap<String, StructureTreeElement>());
+ QName xy = DocumentNavigationExtensionConstants.GOTO_XY;
+ Attributes attributes = mock(Attributes.class);
+ when(attributes.getValue("page-index")).thenReturn("0");
+ when(attributes.getValue("page-index-relative")).thenReturn("-1");
+ when(attributes.getValue("x")).thenReturn("0");
+ when(attributes.getValue("y")).thenReturn("0");
+ navigationHandler.startElement(xy.getNamespaceURI(), xy.getLocalName(), null, attributes);
+ navigationHandler.endElement(xy.getNamespaceURI(), xy.getLocalName(), null);
+ documentHandler.endPage();
+ documentHandler.endDocument();
+
+ Assert.assertEquals(goToXYActions.get(0).getPageIndex(), 0);
+
+ Collection<StringBuilder> objs = PDFLinearizationTestCase.readObjs(
+ new ByteArrayInputStream(bos.toByteArray())).values();
+ String pages = PDFVTTestCase.getObj(objs, "/Type /Pages");
+ String action = PDFVTTestCase.getObj(objs, "/Type /Action");
+ String pageRef = action.split("\\[")[1].split(" /XYZ")[0];
+ Assert.assertTrue(pageRef.endsWith(" 0 R"));
+ Assert.assertTrue(pages.contains("/Kids [" + pageRef));
+ }
+
+ @Test
public void testGotoXYUniqueLinks() throws IFException, SAXException {
FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
PDFDocumentHandler documentHandler = new PDFDocumentHandler(new IFContext(ua));
diff --git a/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-nav.xsd b/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-nav.xsd
index ff6697cdf..49851f302 100644
--- a/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-nav.xsd
+++ b/fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-nav.xsd
@@ -106,6 +106,7 @@
<xs:complexType>
<xs:attributeGroup ref="nav:refDef"/>
<xs:attribute name="page-index" type="xs:int"/>
+ <xs:attribute name="page-index-relative" type="xs:int" use="optional"/>
<xs:attributeGroup ref="nav:posAtts"/>
</xs:complexType>
</xs:element>