git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195152 13f79535-47bb-0310-9956-ffa450edef68pull/30/head
@@ -1,8 +1,16 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.apps; | |||
import java.io.OutputStream; | |||
import java.io.IOException; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import org.xml.sax.SAXException; | |||
@@ -10,6 +18,7 @@ import org.apache.fop.layout.FontInfo; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.AreaTree; | |||
import org.apache.fop.area.Title; | |||
import org.apache.fop.area.TreeExt; | |||
import org.apache.fop.render.Renderer; | |||
import org.apache.fop.fo.pagination.PageSequence; | |||
import org.apache.fop.fo.pagination.LayoutMasterSet; | |||
@@ -116,8 +125,8 @@ public class LayoutHandler extends StructureHandler { | |||
even if they are not resolved. | |||
*/ | |||
try { | |||
//processQueue(true); | |||
processAreaTree(); | |||
areaTree.endDocument(); | |||
renderer.stopRenderer(); | |||
} catch (FOPException e) { | |||
throw new SAXException(e); | |||
@@ -198,7 +207,11 @@ public class LayoutHandler extends StructureHandler { | |||
} | |||
count++; | |||
} | |||
List list = atModel.getEndExtensions(); | |||
for(count = 0; count < list.size(); count++) { | |||
TreeExt ext = (TreeExt)list.get(count); | |||
renderer.renderExtension(ext); | |||
} | |||
} | |||
public FontInfo getFontInfo() { |
@@ -10,7 +10,9 @@ package org.apache.fop.area; | |||
import org.apache.fop.render.Renderer; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
/** | |||
* Area tree for formatting objects. | |||
@@ -74,6 +76,7 @@ public class AreaTree { | |||
Resolveable res = (Resolveable)todo.get(count); | |||
res.resolve(id, list); | |||
} | |||
resolve.remove(id); | |||
} | |||
} | |||
@@ -106,10 +109,31 @@ public class AreaTree { | |||
} | |||
} | |||
public void handleTreeExtension(TreeExt ext, int when) { | |||
// queue tree extension according to the when | |||
model.addExtension(ext, when); | |||
} | |||
public void endDocument() { | |||
for(Iterator iter = resolve.keySet().iterator(); iter.hasNext(); ) { | |||
String id = (String)iter.next(); | |||
ArrayList list = (ArrayList)resolve.get(id); | |||
for(int count = 0; count < list.size(); count++) { | |||
Resolveable res = (Resolveable)list.get(count); | |||
if(!res.isResolved()) { | |||
res.resolve(id, null); | |||
} | |||
} | |||
} | |||
model.endDocument(); | |||
} | |||
// this is the model for the area tree object | |||
public static abstract class AreaTreeModel { | |||
public abstract void startPageSequence(Title title); | |||
public abstract void addPage(PageViewport page); | |||
public abstract void addExtension(TreeExt ext, int when); | |||
public abstract void endDocument(); | |||
} | |||
// this class stores all the pages in the document | |||
@@ -118,6 +142,7 @@ public class AreaTree { | |||
ArrayList pageSequence = null; | |||
ArrayList titles = new ArrayList(); | |||
ArrayList currSequence; | |||
ArrayList extensions = new ArrayList(); | |||
public StorePagesModel() {} | |||
@@ -151,6 +176,32 @@ public class AreaTree { | |||
ArrayList sequence = (ArrayList) pageSequence.get(seq); | |||
return (PageViewport) sequence.get(count); | |||
} | |||
public void addExtension(TreeExt ext, int when) { | |||
int seq, page; | |||
switch(when) { | |||
case TreeExt.IMMEDIATELY: | |||
seq = pageSequence == null ? 0 : pageSequence.size(); | |||
page = currSequence == null ? 0 : currSequence.size(); | |||
break; | |||
case TreeExt.AFTER_PAGE: | |||
break; | |||
case TreeExt.END_OF_DOC: | |||
break; | |||
} | |||
extensions.add(ext); | |||
} | |||
public List getExtensions(int seq, int count) { | |||
return null; | |||
} | |||
public List getEndExtensions() { | |||
return extensions; | |||
} | |||
public void endDocument() { | |||
} | |||
} | |||
// this uses the store pages model to store the pages | |||
@@ -159,6 +210,8 @@ public class AreaTree { | |||
public static class RenderPagesModel extends StorePagesModel { | |||
Renderer renderer; | |||
ArrayList prepared = new ArrayList(); | |||
ArrayList pendingExt = new ArrayList(); | |||
ArrayList endDocExt = new ArrayList(); | |||
public RenderPagesModel(Renderer rend) { | |||
renderer = rend; | |||
@@ -178,10 +231,39 @@ public class AreaTree { | |||
// use error handler to handle this FOP or IO Exception | |||
} | |||
page.clear(); | |||
renderExtensions(pendingExt); | |||
pendingExt.clear(); | |||
// else prepare | |||
//renderer.preparePage(page); | |||
prepared.add(page); | |||
} | |||
public void addExtension(TreeExt ext, int when) { | |||
switch(when) { | |||
case TreeExt.IMMEDIATELY: | |||
renderer.renderExtension(ext); | |||
break; | |||
case TreeExt.AFTER_PAGE: | |||
pendingExt.add(ext); | |||
break; | |||
case TreeExt.END_OF_DOC: | |||
endDocExt.add(ext); | |||
break; | |||
} | |||
} | |||
private void renderExtensions(ArrayList list) { | |||
for(int count = 0; count < list.size(); count++) { | |||
TreeExt ext = (TreeExt)list.get(count); | |||
renderer.renderExtension(ext); | |||
} | |||
} | |||
public void endDocument() { | |||
renderExtensions(endDocExt); | |||
} | |||
} | |||
} |
@@ -10,6 +10,10 @@ package org.apache.fop.area; | |||
/** | |||
*/ | |||
public interface TreeExt { | |||
public final static int IMMEDIATELY = 0; | |||
public final static int AFTER_PAGE = 1; | |||
public final static int END_OF_DOC = 2; | |||
public boolean isResolveable(); | |||
public String getMimeType(); | |||
public String getName(); |
@@ -10,6 +10,7 @@ package org.apache.fop.extensions; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.Resolveable; | |||
import org.apache.fop.area.TreeExt; | |||
import org.apache.fop.area.AreaTree; | |||
import java.util.*; | |||
@@ -17,6 +18,9 @@ public class BookmarkData implements Resolveable, TreeExt { | |||
private ArrayList subData = new ArrayList(); | |||
private HashMap idRefs = new HashMap(); | |||
// area tree for the top level object to notify when resolved | |||
private AreaTree areaTree = null; | |||
String idRef; | |||
PageViewport pageRef = null; | |||
String label = null; | |||
@@ -30,6 +34,10 @@ public class BookmarkData implements Resolveable, TreeExt { | |||
idRefs.put(idRef, this); | |||
} | |||
public void setAreaTree(AreaTree at) { | |||
areaTree = at; | |||
} | |||
public String getID() { | |||
return idRef; | |||
} | |||
@@ -37,12 +45,32 @@ public class BookmarkData implements Resolveable, TreeExt { | |||
public void addSubData(BookmarkData sub) { | |||
subData.add(sub); | |||
idRefs.put(sub.getID(), sub); | |||
String[] ids = sub.getIDs(); | |||
for(int count = 0; count < ids.length; count++) { | |||
idRefs.put(ids[count], sub); | |||
} | |||
} | |||
public void setLabel(String l) { | |||
label = l; | |||
} | |||
public String getLabel() { | |||
return label; | |||
} | |||
public int getCount() { | |||
return subData.size(); | |||
} | |||
public BookmarkData getSubData(int count) { | |||
return (BookmarkData)subData.get(count); | |||
} | |||
public PageViewport getPage() { | |||
return pageRef; | |||
} | |||
public boolean isResolveable() { | |||
return true; | |||
} | |||
@@ -66,12 +94,14 @@ public class BookmarkData implements Resolveable, TreeExt { | |||
public void resolve(String id, ArrayList pages) { | |||
if(!id.equals(idRef)) { | |||
BookmarkData bd = (BookmarkData)idRefs.get(id); | |||
bd.resolve(id, pages); | |||
if(bd.isResolved()) { | |||
idRefs.remove(id); | |||
if(idRefs.size() == 0) { | |||
idRefs = null; | |||
idRefs.remove(id); | |||
if(bd != null) { | |||
bd.resolve(id, pages); | |||
if(bd.isResolved()) { | |||
checkFinish(); | |||
} | |||
} else if (idRef == null) { | |||
checkFinish(); | |||
} | |||
} else { | |||
if(pages != null) { | |||
@@ -81,8 +111,15 @@ public class BookmarkData implements Resolveable, TreeExt { | |||
// get rect area of id on page | |||
idRefs.remove(idRef); | |||
if(idRefs.size() == 0) { | |||
idRefs = null; | |||
checkFinish(); | |||
} | |||
} | |||
private void checkFinish() { | |||
if(idRefs.size() == 0) { | |||
idRefs = null; | |||
if(areaTree != null) { | |||
areaTree.handleTreeExtension(this, TreeExt.AFTER_PAGE); | |||
} | |||
} | |||
} |
@@ -44,6 +44,7 @@ public class Bookmarks extends ExtensionObj { | |||
if(structHandler instanceof LayoutHandler) { | |||
AreaTree at = ((LayoutHandler)structHandler).getAreaTree(); | |||
at.addTreeExtension(data); | |||
data.setAreaTree(at); | |||
} | |||
} | |||
} |
@@ -1206,24 +1206,9 @@ public class PDFDocument { | |||
private String getGoToReference(String destination) { | |||
String goToReference = null; | |||
/*if (idReferences.doesIDExist(destination)) { | |||
if (idReferences.doesGoToReferenceExist(destination)) { | |||
goToReference = | |||
idReferences.getInternalLinkGoToReference(destination); | |||
} else { // assign Internal Link GoTo object | |||
goToReference = | |||
idReferences.createInternalLinkGoTo(destination, | |||
++this.objectcount); | |||
addTrailerObject(idReferences.getPDFGoTo(destination)); | |||
} | |||
} else { // id was not found, so create it | |||
idReferences.createUnvalidatedID(destination); | |||
idReferences.addToIdValidationList(destination); | |||
goToReference = idReferences.createInternalLinkGoTo(destination, | |||
++this.objectcount); | |||
addTrailerObject(idReferences.getPDFGoTo(destination)); | |||
}*/ | |||
PDFGoTo gt = new PDFGoTo(++this.objectcount, destination); | |||
goToReference = gt.referencePDF(); | |||
addTrailerObject(gt); | |||
return goToReference; | |||
} | |||
@@ -1323,14 +1308,12 @@ public class PDFDocument { | |||
String goToRef = getGoToReference(destination); | |||
PDFOutline obj = new PDFOutline(++this.objectcount, label, goToRef); | |||
//log.debug("created new outline object"); | |||
if (parent != null) { | |||
parent.addOutline(obj); | |||
} | |||
this.objects.add(obj); | |||
return obj; | |||
} | |||
/** |
@@ -62,6 +62,12 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren | |||
return false; | |||
} | |||
/** | |||
* Render tree extension. | |||
*/ | |||
public void renderExtension(TreeExt ext) { | |||
} | |||
/** | |||
* Prepare a page for rendering. | |||
* This is called if the renderer supports out of order rendering. |
@@ -58,6 +58,8 @@ public interface Renderer { | |||
public boolean supportsOutOfOrder(); | |||
public void renderExtension(TreeExt ext); | |||
public void preparePage(PageViewport page); | |||
public void startPageSequence(Title seqTitle); |
@@ -176,6 +176,38 @@ public class PDFRenderer extends PrintRenderer { | |||
return true; | |||
} | |||
public void renderExtension(TreeExt ext) { | |||
// render bookmark extension | |||
if(ext instanceof BookmarkData) { | |||
renderRootExtensions((BookmarkData)ext); | |||
} | |||
} | |||
protected void renderRootExtensions(BookmarkData bookmarks) { | |||
for (int i = 0; i < bookmarks.getCount(); i++) { | |||
BookmarkData ext = bookmarks.getSubData(i); | |||
renderOutline(ext, null); | |||
} | |||
} | |||
private void renderOutline(BookmarkData outline, PDFOutline parentOutline) { | |||
PDFOutline outlineRoot = pdfDoc.getOutlineRoot(); | |||
PDFOutline pdfOutline = null; | |||
String intDest = (String)pageReferences.get(outline.getPage()); | |||
if (parentOutline == null) { | |||
pdfOutline = pdfDoc.makeOutline(outlineRoot, | |||
outline.getLabel(), intDest); | |||
} else { | |||
PDFOutline pdfParentOutline = parentOutline; | |||
pdfOutline = pdfDoc.makeOutline(pdfParentOutline, | |||
outline.getLabel(), intDest); | |||
} | |||
for (int i = 0; i < outline.getCount(); i++) { | |||
renderOutline(outline.getSubData(i), pdfOutline); | |||
} | |||
} | |||
public void startPageSequence(Title seqTitle) { | |||
if(seqTitle != null) { | |||
String str = convertTitleToString(seqTitle); |