Browse Source

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
pull/19/head
Simon Steiner 5 years ago
parent
commit
3a753d5418

+ 7
- 3
fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java View File

this.documentMetadata = metadata.getMetadata(); 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. // Already a GoToXY present for this target? If not, create.
GoToXYAction action = (GoToXYAction)actionSet.get(targetID); GoToXYAction action = (GoToXYAction)actionSet.get(targetID);
//GoToXYAction action = (GoToXYAction)idGoTos.get(targetID); //GoToXYAction action = (GoToXYAction)idGoTos.get(targetID);
Point position = (Point)idPositions.get(targetID); Point position = (Point)idPositions.get(targetID);
// can the GoTo already be fully filled in? // can the GoTo already be fully filled in?
if (pageIndex >= 0 && position != null) { 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 { } else {
// Not complete yet, can't use getPDFGoTo: // Not complete yet, can't use getPDFGoTo:
action = new GoToXYAction(targetID, pageIndex, null);
action = new GoToXYAction(targetID, pageIndex, null, null);
unfinishedGoTos.add(action); unfinishedGoTos.add(action);
} }
action = (GoToXYAction)actionSet.put(action); action = (GoToXYAction)actionSet.put(action);

+ 7
- 2
fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java View File

} else { } else {
String id = attributes.getValue("id"); String id = attributes.getValue("id");
int pageIndex = XMLUtil.getAttributeAsInt(attributes, "page-index"); int pageIndex = XMLUtil.getAttributeAsInt(attributes, "page-index");
final int pageIndexRelative = XMLUtil.getAttributeAsInt(attributes, "page-index-relative", 0);
final Point location; final Point location;
if (pageIndex < 0) { if (pageIndex < 0) {
location = null; location = null;
} else { } else {
if (hasNavigation() && !inBookmark()) {
if (hasNavigation() && !inBookmark() && pageIndexRelative >= 0) {
int currentPageIndex = navHandler.getPageIndex(); int currentPageIndex = navHandler.getPageIndex();
if (currentPageIndex >= 0) { if (currentPageIndex >= 0) {
pageIndex = currentPageIndex; pageIndex = currentPageIndex;
.getAttributeAsInt(attributes, "y"); .getAttributeAsInt(attributes, "y");
location = new Point(x, 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) { if (structureTreeElement != null) {
action.setStructureTreeElement(structureTreeElement); action.setStructureTreeElement(structureTreeElement);

+ 15
- 2
fop-core/src/main/java/org/apache/fop/render/intermediate/extensions/GoToXYAction.java View File

public class GoToXYAction extends AbstractAction implements DocumentNavigationExtensionConstants { public class GoToXYAction extends AbstractAction implements DocumentNavigationExtensionConstants {


private int pageIndex = -1; private int pageIndex = -1;
private PageIndexRelative pageIndexRelative;
private Point targetLocation; private Point targetLocation;


/** /**
* @param id the identifier for this action * @param id the identifier for this action
*/ */
public GoToXYAction(String id) { public GoToXYAction(String id) {
this(id, -1, null);
this(id, -1, null, null);
} }


/** /**
* @param targetLocation the absolute location on the page (coordinates in millipoints), * @param targetLocation the absolute location on the page (coordinates in millipoints),
* or null, if the position isn't known, yet * 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); setID(id);
if (pageIndex < 0 && targetLocation != null) { if (pageIndex < 0 && targetLocation != null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
} }
setPageIndex(pageIndex); setPageIndex(pageIndex);
setTargetLocation(targetLocation); setTargetLocation(targetLocation);
this.pageIndexRelative = pageIndexRelative;
}

public interface PageIndexRelative {
int getPageIndexRelative();
} }


/** /**
atts.addAttribute("", "id", "id", XMLUtil.CDATA, getID()); atts.addAttribute("", "id", "id", XMLUtil.CDATA, getID());
atts.addAttribute("", "page-index", "page-index", atts.addAttribute("", "page-index", "page-index",
XMLUtil.CDATA, Integer.toString(pageIndex)); 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, atts.addAttribute("", "x", "x", XMLUtil.CDATA,
Integer.toString(reportedTargetLocation.x)); Integer.toString(reportedTargetLocation.x));
atts.addAttribute("", "y", "y", XMLUtil.CDATA, atts.addAttribute("", "y", "y", XMLUtil.CDATA,

+ 1
- 1
fop-core/src/test/java/org/apache/fop/pdf/PDFVTTestCase.java View File

throw new IOException(name + " not found " + firstObj); 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) { for (StringBuilder s : objs) {
if (s.toString().contains(x)) { if (s.toString().contains(x)) {
return s.toString(); return s.toString();

+ 49
- 0
fop-core/src/test/java/org/apache/fop/render/extensions/DocumentNavigationHandlerTestCase.java View File

package org.apache.fop.render.extensions; package org.apache.fop.render.extensions;


import java.awt.Dimension; import java.awt.Dimension;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.FopFactory;
import org.apache.fop.fonts.FontInfo; 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.IFContext;
import org.apache.fop.render.intermediate.IFException; import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.extensions.AbstractAction; import org.apache.fop.render.intermediate.extensions.AbstractAction;
Assert.assertEquals(goToXYActions.get(0).getPageIndex(), currentPage); 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 @Test
public void testGotoXYUniqueLinks() throws IFException, SAXException { public void testGotoXYUniqueLinks() throws IFException, SAXException {
FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent(); FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();

+ 1
- 0
fop/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-nav.xsd View File

<xs:complexType> <xs:complexType>
<xs:attributeGroup ref="nav:refDef"/> <xs:attributeGroup ref="nav:refDef"/>
<xs:attribute name="page-index" type="xs:int"/> <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:attributeGroup ref="nav:posAtts"/>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>

Loading…
Cancel
Save