diff options
-rw-r--r-- | src/java/org/apache/fop/area/BookmarkData.java | 33 | ||||
-rw-r--r-- | status.xml | 3 | ||||
-rw-r--r-- | test/layoutengine/standard-testcases/bookmarks_2.xml | 68 |
3 files changed, 95 insertions, 9 deletions
diff --git a/src/java/org/apache/fop/area/BookmarkData.java b/src/java/org/apache/fop/area/BookmarkData.java index 30bd704b1..07290824e 100644 --- a/src/java/org/apache/fop/area/BookmarkData.java +++ b/src/java/org/apache/fop/area/BookmarkData.java @@ -19,11 +19,13 @@ package org.apache.fop.area; +import java.util.Collection; +import java.util.Iterator; import java.util.List; -import java.util.HashMap; +import java.util.Map; -import org.apache.fop.fo.pagination.bookmarks.BookmarkTree; import org.apache.fop.fo.pagination.bookmarks.Bookmark; +import org.apache.fop.fo.pagination.bookmarks.BookmarkTree; /** * An instance of this class is either a PDF bookmark-tree and @@ -31,6 +33,7 @@ import org.apache.fop.fo.pagination.bookmarks.Bookmark; * child bookmark-items under it. */ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable { + private List subData = new java.util.ArrayList(); // bookmark-title for this fo:bookmark @@ -46,7 +49,7 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable private PageViewport pageRef = null; // unresolved idrefs by this bookmark and child bookmarks below it - private HashMap unresolvedIDRefs = new HashMap(); + private Map unresolvedIDRefs = new java.util.HashMap(); /** * Create a new bookmark data object. @@ -79,9 +82,17 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable bookmarkTitle = bookmark.getBookmarkTitle(); bShow = bookmark.showChildItems(); this.idRef = bookmark.getInternalDestination(); - unresolvedIDRefs.put(idRef, this); } + private void putUnresolved(String id, BookmarkData bd) { + List refs = (List)unresolvedIDRefs.get(id); + if (refs == null) { + refs = new java.util.ArrayList(); + unresolvedIDRefs.put(id, refs); + } + refs.add(bd); + } + /** * Create a new bookmark data root object. * This constructor is called by the AreaTreeParser when the @@ -128,10 +139,10 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable public void addSubData(BookmarkData sub) { subData.add(sub); if (sub.pageRef == null || sub.pageRef.equals("")) { - unresolvedIDRefs.put(sub.getIDRef(), sub); + putUnresolved(sub.getIDRef(), sub); String[] ids = sub.getIDRefs(); for (int count = 0; count < ids.length; count++) { - unresolvedIDRefs.put(ids[count], sub); + putUnresolved(ids[count], sub); } } } @@ -212,9 +223,13 @@ public class BookmarkData extends AbstractOffDocumentItem implements Resolvable */ public void resolveIDRef(String id, List pages) { if (!id.equals(idRef)) { - BookmarkData bd = (BookmarkData) unresolvedIDRefs.get(id); - if (bd != null) { - bd.resolveIDRef(id, pages); + Collection refs = (Collection)unresolvedIDRefs.get(id); + if (refs != null) { + Iterator iter = refs.iterator(); + while (iter.hasNext()) { + BookmarkData bd = (BookmarkData)iter.next(); + bd.resolveIDRef(id, pages); + } unresolvedIDRefs.remove(id); } } else { diff --git a/status.xml b/status.xml index 6e165d998..172869f60 100644 --- a/status.xml +++ b/status.xml @@ -28,6 +28,9 @@ <changes> <release version="FOP Trunk"> + <action context="Code" dev="JM" type="fix" fixes-bug="37993"> + Bugfix: allow multiple bookmarks to point at the same destination. + </action> <action context="Code" dev="JM" type="fix" fixes-bug="43917"> Bugfix for border-after painting and element list generation when a forced break is involved. diff --git a/test/layoutengine/standard-testcases/bookmarks_2.xml b/test/layoutengine/standard-testcases/bookmarks_2.xml new file mode 100644 index 000000000..b66b27bcf --- /dev/null +++ b/test/layoutengine/standard-testcases/bookmarks_2.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<testcase bug="37993"> + <info> + <p> + This test checks the handling of duplicate destination in the bookmarks tree. There was a + bug earlier (#37993) which made two bookmarks pointing to the same destination impossible. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in" + margin="20pt"> + <fo:region-body background-color="yellow"/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:bookmark-tree> + <fo:bookmark internal-destination="chapter1"> + <fo:bookmark-title>Chapter 1</fo:bookmark-title> + </fo:bookmark> + <fo:bookmark internal-destination="chapter1" starting-state="hide"> + <fo:bookmark-title>Again Chapter 1</fo:bookmark-title> + </fo:bookmark> + </fo:bookmark-tree> + <fo:page-sequence id="page-sequence" master-reference="normal"> + <fo:flow flow-name="xsl-region-body"> + <fo:block id="chapter1" font-weight="bold" font-size="larger">Chapter 1</fo:block> + <fo:block>Blah blah bla.</fo:block> + <fo:block id="chapter2" font-weight="bold" font-size="larger" break-before="page">Chapter 2</fo:block> + <fo:block>Blah blah bla.</fo:block> + <fo:block id="chapter2-sec1" font-weight="bold">Section 1</fo:block> + <fo:block>Blah blah bla.</fo:block> + <fo:block id="chapter2-sec2" font-weight="bold">Section 2</fo:block> + <fo:block>Blah blah bla.</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <eval expected="2" xpath="count(//pageViewport)"/> + + <eval expected="Chapter 1" xpath="//bookmarkTree/bookmark[1]/@title"/> + <eval expected="true" xpath="//bookmarkTree/bookmark[1]/@show-children"/> + <eval expected="Again Chapter 1" xpath="//bookmarkTree/bookmark[2]/@title"/> + <eval expected="false" xpath="//bookmarkTree/bookmark[2]/@show-children"/> + + <eval expected="(P1,chapter1)" xpath="//bookmarkTree/bookmark[1]/@internal-link"/> + <eval expected="(P1,chapter1)" xpath="//bookmarkTree/bookmark[2]/@internal-link"/> + + </checks> +</testcase> |