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-ffa450edef68tags/fop-0_95beta
@@ -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 { |
@@ -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. |
@@ -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> |