git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1834850 13f79535-47bb-0310-9956-ffa450edef68pull/19/head
@@ -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); |
@@ -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); |
@@ -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, |
@@ -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(); |
@@ -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; | |||
@@ -90,6 +95,50 @@ public class DocumentNavigationHandlerTestCase { | |||
Assert.assertEquals(goToXYActions.get(0).getPageIndex(), currentPage); | |||
} | |||
@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(); |
@@ -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> |