]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla #37993:
authorJeremias Maerki <jeremias@apache.org>
Fri, 30 Nov 2007 09:04:54 +0000 (09:04 +0000)
committerJeremias Maerki <jeremias@apache.org>
Fri, 30 Nov 2007 09:04:54 +0000 (09:04 +0000)
Bugfix: allow multiple bookmarks to point at the same destination.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@599746 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/area/BookmarkData.java
status.xml
test/layoutengine/standard-testcases/bookmarks_2.xml [new file with mode: 0644]

index 30bd704b1f41871d8cf27a9364ef8f5ec22bbefd..07290824e0d249886c85b3611a0d653a0a5cc444 100644 (file)
  
 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 {
index 6e165d9981f52b14e8a738d308371a9ad39d1189..172869f606f597c7d6753ac683a0a06a97fc9b10 100644 (file)
@@ -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 (file)
index 0000000..b66b27b
--- /dev/null
@@ -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>