improved some resolving of references git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195155 13f79535-47bb-0310-9956-ffa450edef68pull/30/head
@@ -1,6 +1,6 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
@@ -34,45 +34,74 @@ import java.util.Iterator; | |||
public class AreaTree { | |||
// allows for different models to deal with adding/rendering | |||
// in different situations | |||
AreaTreeModel model; | |||
private AreaTreeModel model; | |||
// hashmap of arraylists containing pages with id area | |||
HashMap idLocations = new HashMap(); | |||
private HashMap idLocations = new HashMap(); | |||
// list of id's yet to be resolved and arraylists of pages | |||
HashMap resolve = new HashMap(); | |||
ArrayList treeExtensions = new ArrayList(); | |||
private HashMap resolve = new HashMap(); | |||
private ArrayList treeExtensions = new ArrayList(); | |||
/** | |||
* Create a render pages area tree model. | |||
* @param rend the renderer that will be used | |||
* @return RenderPagesModel the new area tree model | |||
*/ | |||
public RenderPagesModel createRenderPagesModel(Renderer rend) { | |||
return new RenderPagesModel(rend); | |||
} | |||
/** | |||
* Create a new store pages model. | |||
* @return StorePagesModel the new model | |||
*/ | |||
public static StorePagesModel createStorePagesModel() { | |||
return new StorePagesModel(); | |||
} | |||
/** | |||
* Set the tree model to use for this area tree. | |||
* The different models can have different behaviour | |||
* when pages area added and other changes. | |||
* @param m the area tree model | |||
*/ | |||
public void setTreeModel(AreaTreeModel m) { | |||
model = m; | |||
} | |||
/** | |||
* Start a new page sequence. | |||
* This signals that a new page sequence has started in the document. | |||
* @param title the title of the new page sequence or null if no title | |||
*/ | |||
public void startPageSequence(Title title) { | |||
model.startPageSequence(title); | |||
} | |||
/** | |||
* Add a new page to the area tree. | |||
* @param page the page to add | |||
*/ | |||
public void addPage(PageViewport page) { | |||
model.addPage(page); | |||
} | |||
/** | |||
* Add an id reference pointing to a page viewport. | |||
* @param id the id of the reference | |||
* @param pv the page viewport that contains the id reference | |||
*/ | |||
public void addIDRef(String id, PageViewport pv) { | |||
ArrayList list = (ArrayList)idLocations.get(id); | |||
if(list == null) { | |||
List list = (List)idLocations.get(id); | |||
if (list == null) { | |||
list = new ArrayList(); | |||
idLocations.put(id, list); | |||
} | |||
list.add(pv); | |||
ArrayList todo = (ArrayList)resolve.get(id); | |||
if(todo != null) { | |||
for(int count = 0; count < todo.size(); count++) { | |||
List todo = (List)resolve.get(id); | |||
if (todo != null) { | |||
for (int count = 0; count < todo.size(); count++) { | |||
Resolveable res = (Resolveable)todo.get(count); | |||
res.resolve(id, list); | |||
} | |||
@@ -80,47 +109,80 @@ public class AreaTree { | |||
} | |||
} | |||
/** | |||
* Get the list of id references for an id. | |||
* @param id the id to lookup | |||
* @return the list of id references. | |||
*/ | |||
public List getIDReferences(String id) { | |||
return (List)idLocations.get(id); | |||
} | |||
/** | |||
* Add an unresolved object with a given id. | |||
* @param id the id reference that needs resolving | |||
* @param res the Resolveable object to resolve | |||
*/ | |||
public void addUnresolvedID(String id, Resolveable res) { | |||
ArrayList todo = (ArrayList)resolve.get(id); | |||
if(todo == null) { | |||
if (todo == null) { | |||
todo = new ArrayList(); | |||
resolve.put(id, todo); | |||
} | |||
todo.add(res); | |||
} | |||
/** | |||
* Add a tree extension. | |||
* This checks if the extension is resolveable and attempts | |||
* to resolve or add the resolveable ids for later resolution. | |||
* @param ext the tree extension to add. | |||
*/ | |||
public void addTreeExtension(TreeExt ext) { | |||
treeExtensions.add(ext); | |||
if(ext.isResolveable()) { | |||
if (ext.isResolveable()) { | |||
Resolveable res = (Resolveable)ext; | |||
String[] ids = res.getIDs(); | |||
for(int count = 0; count < ids.length; count++) { | |||
if(idLocations.containsKey(ids[count])) { | |||
for (int count = 0; count < ids.length; count++) { | |||
if (idLocations.containsKey(ids[count])) { | |||
res.resolve(ids[count], (ArrayList)idLocations.get(ids[count])); | |||
} else { | |||
ArrayList todo = (ArrayList)resolve.get(ids[count]); | |||
if(todo == null) { | |||
if (todo == null) { | |||
todo = new ArrayList(); | |||
resolve.put(ids[count], todo); | |||
} | |||
todo.add(ext); | |||
} | |||
} | |||
} else { | |||
handleTreeExtension(ext, TreeExt.IMMEDIATELY); | |||
} | |||
} | |||
/** | |||
* Handle a tree extension. | |||
* This sends the extension to the model for handling. | |||
* @param ext the tree extension to handle | |||
* @param when when the extension should be handled by the model | |||
*/ | |||
public void handleTreeExtension(TreeExt ext, int when) { | |||
// queue tree extension according to the when | |||
model.addExtension(ext, when); | |||
} | |||
/** | |||
* Signal end of document. | |||
* This indicates that the document is complete and any unresolved | |||
* reference can be dealt with. | |||
*/ | |||
public void endDocument() { | |||
for(Iterator iter = resolve.keySet().iterator(); iter.hasNext(); ) { | |||
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++) { | |||
for (int count = 0; count < list.size(); count++) { | |||
Resolveable res = (Resolveable)list.get(count); | |||
if(!res.isResolved()) { | |||
if (!res.isResolved()) { | |||
res.resolve(id, null); | |||
} | |||
} | |||
@@ -128,24 +190,59 @@ public class AreaTree { | |||
model.endDocument(); | |||
} | |||
// this is the model for the area tree object | |||
public static abstract class AreaTreeModel { | |||
/** | |||
* This is the model for the area tree object. | |||
* The model implementation can handle the page sequence, | |||
* page and extensions. | |||
*/ | |||
public abstract static class AreaTreeModel { | |||
/** | |||
* Start a page sequence on this model. | |||
* @param title the title of the new page sequence | |||
*/ | |||
public abstract void startPageSequence(Title title); | |||
/** | |||
* Add a page to this moel. | |||
* @param page the page to add to the model. | |||
*/ | |||
public abstract void addPage(PageViewport page); | |||
/** | |||
* Add an extension to this model. | |||
* @param ext the extension to add | |||
* @param when when the extension should be handled | |||
*/ | |||
public abstract void addExtension(TreeExt ext, int when); | |||
/** | |||
* Signal the end of the document for any processing. | |||
*/ | |||
public abstract void endDocument(); | |||
} | |||
// this class stores all the pages in the document | |||
// for interactive agents | |||
/** | |||
* This class stores all the pages in the document | |||
* for interactive agents. | |||
* The pages are stored and can be retrieved in any order. | |||
*/ | |||
public static class StorePagesModel extends AreaTreeModel { | |||
ArrayList pageSequence = null; | |||
ArrayList titles = new ArrayList(); | |||
ArrayList currSequence; | |||
ArrayList extensions = new ArrayList(); | |||
public StorePagesModel() {} | |||
private ArrayList pageSequence = null; | |||
private ArrayList titles = new ArrayList(); | |||
private ArrayList currSequence; | |||
private ArrayList extensions = new ArrayList(); | |||
/** | |||
* Create a new store pages model | |||
*/ | |||
public StorePagesModel() { | |||
} | |||
/** | |||
* Start a new page sequence. | |||
* This creates a new list for the pages in the new page sequence. | |||
* @param title the title of the page sequence. | |||
*/ | |||
public void startPageSequence(Title title) { | |||
titles.add(title); | |||
if (pageSequence == null) { | |||
@@ -155,28 +252,59 @@ public class AreaTree { | |||
pageSequence.add(currSequence); | |||
} | |||
/** | |||
* Add a page. | |||
* @param page the page to add to the current page sequence | |||
*/ | |||
public void addPage(PageViewport page) { | |||
currSequence.add(page); | |||
} | |||
/** | |||
* Get the page sequence count. | |||
* @return the number of page sequences in the document. | |||
*/ | |||
public int getPageSequenceCount() { | |||
return pageSequence.size(); | |||
} | |||
/** | |||
* Get the title for a page sequence. | |||
* @param count the page sequence count | |||
* @return the title of the page sequence | |||
*/ | |||
public Title getTitle(int count) { | |||
return (Title) titles.get(count); | |||
} | |||
/** | |||
* Get the page count. | |||
* @param seq the page sequence to count. | |||
* @return returns the number of pages in a page sequence | |||
*/ | |||
public int getPageCount(int seq) { | |||
ArrayList sequence = (ArrayList) pageSequence.get(seq); | |||
return sequence.size(); | |||
} | |||
/** | |||
* Get the page for a position in the document. | |||
* @param seq the page sequence number | |||
* @param count the page count in the sequence | |||
* @return the PageViewport for the particular page | |||
*/ | |||
public PageViewport getPage(int seq, int count) { | |||
ArrayList sequence = (ArrayList) pageSequence.get(seq); | |||
return (PageViewport) sequence.get(count); | |||
} | |||
/** | |||
* Add an extension to the store page model. | |||
* The extension is stored so that it can be retrieved in the | |||
* appropriate position. | |||
* @param ext the extension to add | |||
* @param when when the extension should be handled | |||
*/ | |||
public void addExtension(TreeExt ext, int when) { | |||
int seq, page; | |||
switch(when) { | |||
@@ -192,42 +320,78 @@ public class AreaTree { | |||
extensions.add(ext); | |||
} | |||
/** | |||
* Get the list of extensions that apply at a particular | |||
* position in the document. | |||
* @param seq the page sequence number | |||
* @param count the page count in the sequence | |||
* @return the list of extensions | |||
*/ | |||
public List getExtensions(int seq, int count) { | |||
return null; | |||
} | |||
/** | |||
* Get the end of document extensions for this stroe pages model. | |||
* @return the list of end extensions | |||
*/ | |||
public List getEndExtensions() { | |||
return extensions; | |||
} | |||
/** | |||
* End document, do nothing. | |||
*/ | |||
public void endDocument() { | |||
} | |||
} | |||
// this uses the store pages model to store the pages | |||
// each page is either rendered if ready or prepared | |||
// for later rendering | |||
/** | |||
* This uses the store pages model to store the pages | |||
* each page is either rendered if ready or prepared | |||
* for later rendering. | |||
* Once a page is rendered it is cleared to release the | |||
* contents but the PageViewport is retained. | |||
*/ | |||
public static class RenderPagesModel extends StorePagesModel { | |||
Renderer renderer; | |||
ArrayList prepared = new ArrayList(); | |||
ArrayList pendingExt = new ArrayList(); | |||
ArrayList endDocExt = new ArrayList(); | |||
private Renderer renderer; | |||
private ArrayList prepared = new ArrayList(); | |||
private ArrayList pendingExt = new ArrayList(); | |||
private ArrayList endDocExt = new ArrayList(); | |||
/** | |||
* Create a new render pages model with the given renderer. | |||
* @param rend the renderer to render pages to | |||
*/ | |||
public RenderPagesModel(Renderer rend) { | |||
renderer = rend; | |||
} | |||
/** | |||
* Start a new page sequence. | |||
* This tells the renderer that a new page sequence has | |||
* started with the given title. | |||
* @param title the title of the new page sequence | |||
*/ | |||
public void startPageSequence(Title title) { | |||
super.startPageSequence(title); | |||
renderer.startPageSequence(title); | |||
} | |||
/** | |||
* Add a page to the render page model. | |||
* If the page is finished it can be rendered immediately. | |||
* If the page needs resolving then if the renderer supports | |||
* out of order rendering it can prepare the page. Otherwise | |||
* the page is added to a queue. | |||
* @param page the page to add to the model | |||
*/ | |||
public void addPage(PageViewport page) { | |||
super.addPage(page); | |||
// if page finished | |||
try { | |||
renderer.renderPage(page); | |||
} catch(Exception e) { | |||
} catch (Exception e) { | |||
// use error handler to handle this FOP or IO Exception | |||
} | |||
page.clear(); | |||
@@ -240,6 +404,15 @@ public class AreaTree { | |||
prepared.add(page); | |||
} | |||
/** | |||
* Add an extension to this model. | |||
* If handle immediately then send directly to the renderer. | |||
* The after page ones are handled after the next page is added. | |||
* End of document extensions are added to a list to be | |||
* handled at the end. | |||
* @param ext the extension | |||
* @param when when to render the extension | |||
*/ | |||
public void addExtension(TreeExt ext, int when) { | |||
switch(when) { | |||
case TreeExt.IMMEDIATELY: | |||
@@ -255,12 +428,15 @@ public class AreaTree { | |||
} | |||
private void renderExtensions(ArrayList list) { | |||
for(int count = 0; count < list.size(); count++) { | |||
for (int count = 0; count < list.size(); count++) { | |||
TreeExt ext = (TreeExt)list.get(count); | |||
renderer.renderExtension(ext); | |||
} | |||
} | |||
/** | |||
* End the document. Render any end document extensions. | |||
*/ | |||
public void endDocument() { | |||
renderExtensions(endDocExt); | |||
} |
@@ -7,9 +7,15 @@ | |||
package org.apache.fop.area; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.io.Serializable; | |||
public interface Resolveable { | |||
/** | |||
* Resolveable Interface. | |||
* Classes that implement this can be resolved when | |||
* an id is added to the area tree. | |||
*/ | |||
public interface Resolveable extends Serializable { | |||
public boolean isResolved(); | |||
@@ -22,5 +28,5 @@ public interface Resolveable { | |||
* @param pages the list of pages with the id area | |||
* may be null if not found | |||
*/ | |||
public void resolve(String id, ArrayList pages); | |||
public void resolve(String id, List pages); | |||
} |
@@ -57,7 +57,7 @@ public class Trait implements Serializable { | |||
s_hmTraitInfo.put(ID_LINK, | |||
new TraitInfo("id-link", String.class)); | |||
s_hmTraitInfo.put(INTERNAL_LINK, | |||
new TraitInfo("internal-link", String.class)); | |||
new TraitInfo("internal-link", PageViewport.class)); | |||
s_hmTraitInfo.put(EXTERNAL_LINK, | |||
new TraitInfo("external-link", String.class)); | |||
s_hmTraitInfo.put(FONT_NAME, |
@@ -20,8 +20,7 @@ import java.util.ArrayList; | |||
* this inline parent. | |||
*/ | |||
public class FilledArea extends InlineParent { | |||
MinOptMax alloc; | |||
int unitWidth; | |||
private int unitWidth; | |||
public FilledArea() { | |||
} | |||
@@ -30,14 +29,6 @@ public class FilledArea extends InlineParent { | |||
unitWidth = w; | |||
} | |||
public void setAllocationIPD(MinOptMax all) { | |||
alloc = all; | |||
} | |||
public MinOptMax getAllocationIPD() { | |||
return alloc; | |||
} | |||
public List getChildAreas() { | |||
int units = (int)(getWidth() / unitWidth); | |||
ArrayList newList = new ArrayList(); |
@@ -1,6 +1,6 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
@@ -14,7 +14,6 @@ import org.apache.fop.render.Renderer; | |||
import org.apache.fop.traits.BorderProps; | |||
import org.apache.fop.fo.properties.VerticalAlign; | |||
import java.util.List; | |||
import java.util.ArrayList; | |||
/** | |||
@@ -29,8 +28,8 @@ public class InlineArea extends Area { | |||
int height; | |||
protected int contentIPD = 0; | |||
// position within the line area, either top or baseline | |||
int verticalPosition = VerticalAlign.BASELINE; | |||
// offset position from top of parent area | |||
int verticalPosition = 0; | |||
// store properties in array list, need better solution | |||
ArrayList props = null; | |||
@@ -53,6 +52,10 @@ public class InlineArea extends Area { | |||
this.contentIPD = ipd; | |||
} | |||
public int getIPD() { | |||
return this.contentIPD; | |||
} | |||
public void increaseIPD(int ipd) { | |||
this.contentIPD += ipd; | |||
} |
@@ -14,18 +14,24 @@ import org.apache.fop.render.Renderer; | |||
import java.util.List; | |||
import java.util.ArrayList; | |||
// this is an inline area that can have other inlines as children | |||
/** | |||
* Inline parent area. | |||
* This is an inline area that can have other inlines as children. | |||
*/ | |||
public class InlineParent extends InlineArea { | |||
protected ArrayList inlines = new ArrayList(); | |||
public InlineParent() { | |||
} | |||
/** | |||
* Render this area. | |||
* @param renderer the renderer to render this area in | |||
*/ | |||
public void render(Renderer renderer) { | |||
renderer.renderInlineParent(this); | |||
} | |||
/** | |||
* Override generic Area method. | |||
*/ |
@@ -9,12 +9,13 @@ package org.apache.fop.area.inline; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.Resolveable; | |||
import org.apache.fop.area.Trait; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
public class UnresolvedPageNumber extends Word implements Resolveable { | |||
boolean resolved = false; | |||
String pageRefId; | |||
private boolean resolved = false; | |||
private String pageRefId; | |||
public UnresolvedPageNumber(String id) { | |||
pageRefId = id; | |||
@@ -25,11 +26,19 @@ public class UnresolvedPageNumber extends Word implements Resolveable { | |||
return new String[] {pageRefId}; | |||
} | |||
public void resolve(String id, ArrayList pages) { | |||
public void resolve(String id, List pages) { | |||
resolved = true; | |||
PageViewport page = (PageViewport)pages.get(0); | |||
String str = page.getPageNumber(); | |||
word = str; | |||
if(pages != null) { | |||
PageViewport page = (PageViewport)pages.get(0); | |||
String str = page.getPageNumber(); | |||
word = str; | |||
// update ipd | |||
String name = (String) getTrait(Trait.FONT_NAME); | |||
int size = ((Integer) getTrait(Trait.FONT_SIZE)).intValue(); | |||
//FontMetric metrics = fontInfo.getMetricsFor(name); | |||
//FontState fs = new FontState(name, metrics, size); | |||
} | |||
} | |||
public boolean isResolved() { |
@@ -91,7 +91,7 @@ public class BookmarkData implements Resolveable, TreeExt { | |||
return (String[])idRefs.keySet().toArray(new String[] {}); | |||
} | |||
public void resolve(String id, ArrayList pages) { | |||
public void resolve(String id, List pages) { | |||
if(!id.equals(idRef)) { | |||
BookmarkData bd = (BookmarkData)idRefs.get(id); | |||
idRefs.remove(id); |
@@ -13,13 +13,24 @@ import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.fo.properties.*; | |||
import org.apache.fop.layout.*; | |||
import org.apache.fop.datatypes.ColorType; | |||
import org.apache.fop.area.inline.InlineParent; | |||
import org.apache.fop.area.Trait; | |||
import org.apache.fop.area.Resolveable; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.layoutmgr.InlineStackingLayoutManager; | |||
import org.apache.fop.layoutmgr.LMiter; | |||
import org.apache.fop.layoutmgr.LayoutManager; | |||
// Java | |||
import java.util.Enumeration; | |||
import java.awt.Rectangle; | |||
import java.util.List; | |||
import java.util.ArrayList; | |||
public class BasicLink extends Inline { | |||
String link = null; | |||
boolean external = false; | |||
public BasicLink(FONode parent) { | |||
super(parent); | |||
@@ -27,7 +38,32 @@ public class BasicLink extends Inline { | |||
// add start and end properties for the link | |||
public void addLayoutManager(List lms) { | |||
super.addLayoutManager(lms); | |||
setup(); | |||
lms.add(new InlineStackingLayoutManager(this, | |||
new LMiter(children.listIterator())) { | |||
protected InlineParent createArea() { | |||
InlineParent area = super.createArea(); | |||
setupLinkArea(parentLM, area); | |||
return area; | |||
} | |||
}); | |||
} | |||
protected void setupLinkArea(LayoutManager parentLM, InlineParent area) { | |||
if(link == null) { | |||
return; | |||
} | |||
if(external) { | |||
area.addTrait(Trait.EXTERNAL_LINK, link); | |||
} else { | |||
PageViewport page = parentLM.resolveRefID(link); | |||
if(page != null) { | |||
area.addTrait(Trait.INTERNAL_LINK, page); | |||
} else { | |||
LinkResolver res = new LinkResolver(link, area); | |||
parentLM.addUnresolvedArea(link, res); | |||
} | |||
} | |||
} | |||
public void setup() { | |||
@@ -55,20 +91,61 @@ public class BasicLink extends Inline { | |||
// this.properties.get("baseline-shift"); | |||
// this.properties.get("destination-place-offset"); | |||
// this.properties.get("dominant-baseline"); | |||
// this.properties.get("external-destination"); | |||
String ext = properties.get("external-destination").getString(); | |||
setupID(); | |||
// this.properties.get("indicate-destination"); | |||
// this.properties.get("internal-destination"); | |||
// this.properties.get("indicate-destination"); | |||
String internal = properties.get("internal-destination").getString(); | |||
if(ext.length() > 0) { | |||
link = ext; | |||
external = true; | |||
} else if(internal.length() > 0) { | |||
link = internal; | |||
} else { | |||
getLogger().error("basic-link requires an internal or external destination"); | |||
} | |||
// this.properties.get("keep-together"); | |||
// this.properties.get("keep-with-next"); | |||
// this.properties.get("keep-with-previous"); | |||
// this.properties.get("line-height"); | |||
// this.properties.get("line-height-shift-adjustment"); | |||
// this.properties.get("show-destination"); | |||
// this.properties.get("target-processing-context"); | |||
// this.properties.get("target-presentation-context"); | |||
// this.properties.get("target-stylesheet"); | |||
// this.properties.get("show-destination"); | |||
// this.properties.get("target-processing-context"); | |||
// this.properties.get("target-presentation-context"); | |||
// this.properties.get("target-stylesheet"); | |||
} | |||
protected static class LinkResolver implements Resolveable { | |||
private boolean resolved = false; | |||
private String idRef; | |||
// NOTE: there will be a problem with serialization | |||
private Area area; | |||
public LinkResolver(String id, Area a) { | |||
idRef = id; | |||
area = a; | |||
} | |||
public boolean isResolved() { | |||
return resolved; | |||
} | |||
public String[] getIDs() { | |||
return new String[] {idRef}; | |||
} | |||
/** | |||
* Resolve by removing the id link and replacing with | |||
* an internal link. | |||
*/ | |||
public void resolve(String id, List pages) { | |||
if(idRef.equals(id) && pages != null) { | |||
PageViewport page = (PageViewport)pages.get(0); | |||
area.addTrait(Trait.INTERNAL_LINK, page); | |||
} | |||
} | |||
} | |||
} | |||
@@ -55,25 +55,21 @@ public class Leader extends FObjMixed { | |||
public void addLayoutManager(List list) { | |||
LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this) { | |||
public InlineArea get(LayoutContext context) { | |||
int refIPD = context.getRefIPD(); | |||
return getInlineArea(refIPD); | |||
return getInlineArea(); | |||
} | |||
protected MinOptMax getAllocationIPD(int refIPD) { | |||
return getAllocIPD(refIPD); | |||
} | |||
}; | |||
lm.setAlignment(properties.get("leader-alignment").getEnum()); | |||
list.add(lm); | |||
} | |||
protected InlineArea getInlineArea(int refIPD) { | |||
protected InlineArea getInlineArea() { | |||
if(leaderArea == null) { | |||
createLeaderArea(); | |||
} | |||
MinOptMax alloc = getAllocationIPD(refIPD); | |||
if(leaderArea instanceof Stretch) { | |||
((Stretch)leaderArea).setAllocationIPD(alloc); | |||
} else if(leaderArea instanceof FilledArea) { | |||
((FilledArea)leaderArea).setAllocationIPD(alloc); | |||
} | |||
leaderArea.setWidth(alloc.opt); | |||
return leaderArea; | |||
} | |||
@@ -88,9 +84,7 @@ public class Leader extends FObjMixed { | |||
leaderArea = leader; | |||
} else if (leaderPattern == LeaderPattern.SPACE) { | |||
Space space = new Space(); | |||
leaderArea = space; | |||
leaderArea = new Space(); | |||
} else if(leaderPattern == LeaderPattern.DOTS) { | |||
Word w = new Word(); | |||
char dot = '.'; // userAgent.getLeaderDotChar(); | |||
@@ -226,7 +220,7 @@ public class Leader extends FObjMixed { | |||
} | |||
protected MinOptMax getAllocationIPD(int ipd) { | |||
protected MinOptMax getAllocIPD(int ipd) { | |||
// length of the leader | |||
int opt = getLength("leader-length.optimum", ipd); | |||
int min = getLength("leader-length.minimum", ipd); |
@@ -16,6 +16,7 @@ import org.apache.fop.layout.*; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.layoutmgr.LeafNodeLayoutManager; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.util.CharUtilities; | |||
import org.apache.fop.apps.StructureHandler; | |||
import org.apache.fop.layoutmgr.LayoutContext; | |||
@@ -67,52 +68,54 @@ public class PageNumberCitation extends FObj { | |||
} | |||
public void addAreas(PositionIterator posIter, | |||
LayoutContext context) { | |||
LayoutContext context) { | |||
super.addAreas(posIter, context); | |||
if(unresolved) { | |||
parentLM.addUnresolvedArea(refId, (Resolveable)inline); | |||
if (unresolved) { | |||
parentLM.addUnresolvedArea(refId, | |||
(Resolveable) inline); | |||
} | |||
} | |||
} | |||
); | |||
} | |||
// is id can be resolved then simply return a word, otherwise | |||
// if id can be resolved then simply return a word, otherwise | |||
// return a resolveable area | |||
private InlineArea getInlineArea(LayoutManager parentLM) { | |||
if (refId.equals("")) { | |||
getLogger().error("page-number-citation must contain \"ref-id\""); | |||
return null; | |||
} | |||
String str = parentLM.resolveRefID(refId); | |||
if(str != null) { | |||
// get page string from parent, build area | |||
Word word = new Word(); | |||
inline = word; | |||
int width = getStringWidth(str); | |||
word.setWord(str); | |||
inline.setIPD(width); | |||
inline.setHeight(fontState.getAscender() - | |||
fontState.getDescender()); | |||
inline.setOffset(fontState.getAscender()); | |||
inline.addTrait(Trait.FONT_NAME, fontState.getFontName()); | |||
inline.addTrait(Trait.FONT_SIZE, | |||
new Integer(fontState.getFontSize())); | |||
PageViewport page = parentLM.resolveRefID(refId); | |||
if (page != null) { | |||
String str = page.getPageNumber(); | |||
// get page string from parent, build area | |||
Word word = new Word(); | |||
inline = word; | |||
int width = getStringWidth(str); | |||
word.setWord(str); | |||
inline.setIPD(width); | |||
inline.setHeight(fontState.getAscender() - | |||
fontState.getDescender()); | |||
inline.setOffset(fontState.getAscender()); | |||
inline.addTrait(Trait.FONT_NAME, fontState.getFontName()); | |||
inline.addTrait(Trait.FONT_SIZE, | |||
new Integer(fontState.getFontSize())); | |||
unresolved = false; | |||
} else { | |||
unresolved = true; | |||
inline = new UnresolvedPageNumber(refId); | |||
str = "MMM"; // reserve three spaces for page number | |||
int width = getStringWidth(str); | |||
inline.setIPD(width); | |||
inline.setHeight(fontState.getAscender() - | |||
fontState.getDescender()); | |||
inline.setOffset(fontState.getAscender()); | |||
inline.addTrait(Trait.FONT_NAME, fontState.getFontName()); | |||
inline.addTrait(Trait.FONT_SIZE, | |||
new Integer(fontState.getFontSize())); | |||
unresolved = true; | |||
inline = new UnresolvedPageNumber(refId); | |||
String str = "MMM"; // reserve three spaces for page number | |||
int width = getStringWidth(str); | |||
inline.setIPD(width); | |||
inline.setHeight(fontState.getAscender() - | |||
fontState.getDescender()); | |||
inline.setOffset(fontState.getAscender()); | |||
inline.addTrait(Trait.FONT_NAME, fontState.getFontName()); | |||
inline.addTrait(Trait.FONT_SIZE, | |||
new Integer(fontState.getFontSize())); | |||
} | |||
return inline; | |||
} |
@@ -11,6 +11,7 @@ import org.apache.fop.fo.FObj; | |||
import org.apache.fop.fo.FONode; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.area.Resolveable; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.fo.PropertyManager; | |||
import java.util.ListIterator; | |||
@@ -260,7 +261,7 @@ public abstract class AbstractLayoutManager implements LayoutManager { | |||
return parentLM.getCurrentPageNumber(); | |||
} | |||
public String resolveRefID(String ref) { | |||
public PageViewport resolveRefID(String ref) { | |||
return parentLM.resolveRefID(ref); | |||
} | |||
@@ -11,6 +11,7 @@ package org.apache.fop.layoutmgr; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.area.MinOptMax; | |||
import org.apache.fop.area.Resolveable; | |||
import org.apache.fop.area.PageViewport; | |||
import java.util.ArrayList; | |||
@@ -22,6 +23,7 @@ import java.util.ArrayList; | |||
public class ContentLayoutManager implements LayoutManager { | |||
Area holder; | |||
int stackSize; | |||
LayoutManager parentLM; | |||
public ContentLayoutManager(Area area) { | |||
holder = area; | |||
@@ -76,6 +78,7 @@ public class ContentLayoutManager implements LayoutManager { | |||
} | |||
public void setParentLM(LayoutManager lm) { | |||
parentLM = lm; | |||
} | |||
public boolean canBreakBefore(LayoutContext lc) { | |||
@@ -107,17 +110,19 @@ public class ContentLayoutManager implements LayoutManager { | |||
} | |||
public String getCurrentPageNumber() { | |||
return ""; | |||
return parentLM.getCurrentPageNumber(); | |||
} | |||
public String resolveRefID(String ref) { | |||
return null; | |||
public PageViewport resolveRefID(String ref) { | |||
return parentLM.resolveRefID(ref);; | |||
} | |||
public void addIDToPage(String id) { | |||
parentLM.addIDToPage(id); | |||
} | |||
public void addUnresolvedArea(String id, Resolveable res) { | |||
parentLM.addUnresolvedArea(id, res); | |||
} | |||
} | |||
@@ -42,6 +42,12 @@ public class FlowLayoutManager extends BlockStackingLayoutManager { | |||
MinOptMax stackSize = new MinOptMax(); | |||
while ((curLM = getChildLM()) != null) { | |||
if(curLM.generatesInlineAreas()) { | |||
// problem | |||
curLM.setFinished(true); | |||
continue; | |||
} | |||
// Make break positions and return page break | |||
// Set up a LayoutContext | |||
MinOptMax bpd = context.getStackLimit(); |
@@ -378,6 +378,10 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager { | |||
} | |||
*****/ | |||
protected InlineParent createArea() { | |||
return new InlineParent(); | |||
} | |||
/** | |||
* Generate and add areas to parent area. | |||
* Set size of each area. | |||
@@ -388,7 +392,10 @@ public class InlineStackingLayoutManager extends AbstractLayoutManager { | |||
*/ | |||
public void addAreas(PositionIterator parentIter, | |||
LayoutContext context) { | |||
setCurrentArea(new InlineParent()); | |||
InlineParent parent = createArea(); | |||
parent.setHeight(context.getLineHeight()); | |||
parent.setOffset(0); | |||
setCurrentArea(parent); | |||
setChildContext(new LayoutContext(context)); // Store current value | |||
@@ -10,6 +10,7 @@ package org.apache.fop.layoutmgr; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.area.Resolveable; | |||
import org.apache.fop.area.PageViewport; | |||
/** | |||
* The interface for all LayoutManagers. | |||
@@ -65,7 +66,7 @@ public interface LayoutManager { | |||
public String getCurrentPageNumber(); | |||
public String resolveRefID(String ref); | |||
public PageViewport resolveRefID(String ref); | |||
public void addIDToPage(String id); | |||
@@ -23,6 +23,7 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { | |||
private InlineArea curArea = null; | |||
private int alignment; | |||
private int lead; | |||
private MinOptMax ipd; | |||
public LeafNodeLayoutManager(FObj fobj) { | |||
super(fobj); | |||
@@ -76,7 +77,8 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { | |||
BreakPoss.CAN_BREAK_AFTER | | |||
BreakPoss.CAN_BREAK_BEFORE | BreakPoss.ISFIRST | | |||
BreakPoss.ISLAST); | |||
bp.setStackingSize(curArea.getAllocationIPD()); | |||
ipd = getAllocationIPD(context.getRefIPD()); | |||
bp.setStackingSize(ipd); | |||
bp.setNonStackingSize(curArea.getAllocationBPD()); | |||
bp.setTrailingSpace(new SpaceSpecifier(false)); | |||
@@ -101,6 +103,10 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { | |||
return bp; | |||
} | |||
protected MinOptMax getAllocationIPD(int refIPD) { | |||
return new MinOptMax(curArea.getIPD()); | |||
} | |||
public void resetPosition(Position resetPos) { | |||
// only reset if setting null, start again | |||
if(resetPos == null) { | |||
@@ -113,6 +119,15 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { | |||
addID(); | |||
offsetArea(context); | |||
widthAdjustArea(context); | |||
while (posIter.hasNext()) { | |||
posIter.next(); | |||
} | |||
} | |||
protected void offsetArea(LayoutContext context) { | |||
int bpd = curArea.getHeight(); | |||
switch(alignment) { | |||
case VerticalAlign.MIDDLE: | |||
@@ -129,9 +144,10 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { | |||
curArea.setOffset(context.getBaseline() - bpd); | |||
break; | |||
} | |||
} | |||
protected void widthAdjustArea(LayoutContext context) { | |||
double dAdjust = context.getIPDAdjust(); | |||
MinOptMax ipd = curArea.getAllocationIPD(); | |||
int width = ipd.opt; | |||
if(dAdjust < 0) { | |||
width = (int)(width + dAdjust * (ipd.opt - ipd.min)); | |||
@@ -139,10 +155,6 @@ public class LeafNodeLayoutManager extends AbstractLayoutManager { | |||
width = (int)(width + dAdjust * (ipd.max - ipd.opt)); | |||
} | |||
curArea.setWidth(width); | |||
while (posIter.hasNext()) { | |||
posIter.next(); | |||
} | |||
} | |||
public boolean canBreakBefore(LayoutContext context) { |
@@ -138,7 +138,11 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable | |||
return "" + pageCount; | |||
} | |||
public String resolveRefID(String ref) { | |||
public PageViewport resolveRefID(String ref) { | |||
List list = areaTree.getIDReferences(ref); | |||
if(list != null && list.size() > 0) { | |||
return (PageViewport)list.get(0); | |||
} | |||
return null; | |||
} | |||
@@ -155,6 +159,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable | |||
public void addUnresolvedArea(String id, Resolveable res) { | |||
// add unresolved to tree | |||
// should really add to the page viewport so it can serialize | |||
areaTree.addUnresolvedID(id, res); | |||
} | |||
@@ -21,7 +21,7 @@ import java.io.OutputStream; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.Rectangle2D; | |||
/** | |||
* class representing a PDF document. | |||
@@ -1174,7 +1174,7 @@ public class PDFDocument { | |||
* @param linkType the link type | |||
* @return the PDFLink object created | |||
*/ | |||
public PDFLink makeLink(Rectangle rect, String destination, | |||
public PDFLink makeLink(Rectangle2D rect, String destination, | |||
int linkType) { | |||
PDFLink linkObject; | |||
@@ -1216,7 +1216,7 @@ public class PDFDocument { | |||
this.trailerObjects.add(object); | |||
} | |||
public PDFLink makeLink(Rectangle rect, String page, String dest) { | |||
public PDFLink makeLink(Rectangle2D rect, String page, String dest) { | |||
PDFLink link = new PDFLink(++this.objectcount, rect); | |||
this.objects.add(link); | |||
@@ -8,7 +8,7 @@ | |||
package org.apache.fop.pdf; | |||
// Java | |||
import java.awt.Rectangle; | |||
import java.awt.geom.Rectangle2D; | |||
/** | |||
* class representing an /Annot object of /Subtype /Link | |||
@@ -30,14 +30,14 @@ public class PDFLink extends PDFObject { | |||
* @param number the object's number | |||
* @param producer the application producing the PDF | |||
*/ | |||
public PDFLink(int number, Rectangle r) { | |||
public PDFLink(int number, Rectangle2D r) { | |||
/* generic creation of PDF object */ | |||
super(number); | |||
this.ulx = r.x; | |||
this.uly = r.y; | |||
this.brx = r.x + r.width; | |||
this.bry = r.y - r.height; | |||
this.ulx = (float)r.getX(); | |||
this.uly = (float)r.getY(); | |||
this.brx = (float)(r.getX() + r.getWidth()); | |||
this.bry = (float)(r.getY() - r.getHeight()); | |||
this.color = "0 0 0"; // just for now | |||
} |
@@ -1,6 +1,6 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
@@ -35,6 +35,7 @@ import org.w3c.dom.Document; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.AffineTransform; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
@@ -178,7 +179,7 @@ public class PDFRenderer extends PrintRenderer { | |||
public void renderExtension(TreeExt ext) { | |||
// render bookmark extension | |||
if(ext instanceof BookmarkData) { | |||
if (ext instanceof BookmarkData) { | |||
renderRootExtensions((BookmarkData)ext); | |||
} | |||
} | |||
@@ -209,7 +210,7 @@ public class PDFRenderer extends PrintRenderer { | |||
} | |||
public void startPageSequence(Title seqTitle) { | |||
if(seqTitle != null) { | |||
if (seqTitle != null) { | |||
String str = convertTitleToString(seqTitle); | |||
PDFInfo info = this.pdfDoc.getInfo(); | |||
info.setTitle(str); | |||
@@ -326,7 +327,7 @@ public class PDFRenderer extends PrintRenderer { | |||
currentStream.add("ET\n"); | |||
if(bv.getClip()) { | |||
if (bv.getClip()) { | |||
Rectangle2D rect = bv.getBounds(); | |||
currentStream.add("q\n"); | |||
@@ -354,7 +355,7 @@ public class PDFRenderer extends PrintRenderer { | |||
Rectangle2D rect = bv.getBounds(); | |||
if(ctm != null) { | |||
if (ctm != null) { | |||
currentIPPosition = 0; | |||
currentBPPosition = 0; | |||
@@ -362,16 +363,16 @@ public class PDFRenderer extends PrintRenderer { | |||
double[] vals = ctm.toArray(); | |||
boolean aclock = vals[2] == 1.0; | |||
if(vals[2] == 1.0) { | |||
if (vals[2] == 1.0) { | |||
ctm = ctm.translate(-saveBP - rect.getHeight(), -saveIP); | |||
} else if(vals[0] == -1.0) { | |||
} else if (vals[0] == -1.0) { | |||
ctm = ctm.translate(-saveIP - rect.getWidth(), -saveBP - rect.getHeight()); | |||
} else { | |||
ctm = ctm.translate(saveBP, saveIP - rect.getWidth()); | |||
} | |||
} | |||
if(bv.getClip()) { | |||
if (bv.getClip()) { | |||
currentStream.add("q\n"); | |||
float x = (float)rect.getX() / 1000f; | |||
float y = (float)rect.getY() / 1000f; | |||
@@ -380,24 +381,24 @@ public class PDFRenderer extends PrintRenderer { | |||
clip(x, y, width, height); | |||
} | |||
if(ctm != null) { | |||
if (ctm != null) { | |||
startVParea(ctm); | |||
} | |||
renderBlocks(children); | |||
if(ctm != null) { | |||
if (ctm != null) { | |||
endVParea(); | |||
} | |||
if (bv.getClip()) { | |||
currentStream.add("Q\n"); | |||
} | |||
if(ctm != null) { | |||
if (ctm != null) { | |||
currentStream.add("BT\n"); | |||
} | |||
// clip if necessary | |||
if(rect != null) { | |||
if (rect != null) { | |||
currentIPPosition = saveIP; | |||
currentBPPosition = saveBP; | |||
currentBPPosition += (int)(rect.getHeight()); | |||
@@ -405,6 +406,15 @@ public class PDFRenderer extends PrintRenderer { | |||
} | |||
} | |||
/** | |||
* Clip an area. | |||
* write a clipping operation given coordinates in the current | |||
* transform. | |||
* @param x the x coordinate | |||
* @param y the y coordinate | |||
* @param width the width of the area | |||
* @param height the height of the area | |||
*/ | |||
protected void clip(float x, float y, float width, float height) { | |||
currentStream.add(x + " " + y + " m\n"); | |||
currentStream.add((x + width) + " " + y + " l\n"); | |||
@@ -420,6 +430,45 @@ public class PDFRenderer extends PrintRenderer { | |||
closeText(); | |||
} | |||
/** | |||
* Render inline parent area. | |||
* For pdf this handles the inline parent area traits such as | |||
* links, border, background. | |||
* @param ip the inline parent area | |||
*/ | |||
public void renderInlineParent(InlineParent ip) { | |||
Object tr = ip.getTrait(Trait.INTERNAL_LINK); | |||
boolean internal = false; | |||
String dest = null; | |||
if (tr == null) { | |||
dest = (String)ip.getTrait(Trait.EXTERNAL_LINK); | |||
} else { | |||
PageViewport pv = (PageViewport)tr; | |||
dest = (String)pageReferences.get(pv); | |||
internal = true; | |||
} | |||
if (dest != null) { | |||
float start = currentBlockIPPosition; | |||
float top = (ip.getOffset() + currentBPPosition) / 1000f; | |||
float height = ip.getHeight() / 1000f; | |||
super.renderInlineParent(ip); | |||
float width = (currentBlockIPPosition - start) / 1000f; | |||
start = start / 1000f; | |||
// add link to pdf document | |||
Rectangle2D rect = new Rectangle2D.Float(start, top, width, height); | |||
// transform rect to absolute coords | |||
AffineTransform transform = currentState.getTransform(); | |||
rect = transform.createTransformedShape(rect).getBounds(); | |||
rect = new Rectangle2D.Double(rect.getX(), rect.getY() + rect.getHeight(), rect.getWidth(), rect.getHeight()); | |||
int type = internal ? PDFLink.INTERNAL : PDFLink.EXTERNAL; | |||
PDFLink pdflink = pdfDoc.makeLink(rect, dest, type); | |||
currentPage.addAnnotation(pdflink); | |||
} else { | |||
super.renderInlineParent(ip); | |||
} | |||
} | |||
public void renderCharacter(Character ch) { | |||
super.renderCharacter(ch); | |||
@@ -453,8 +502,8 @@ public class PDFRenderer extends PrintRenderer { | |||
if (!textOpen || bl != prevWordY) { | |||
closeText(); | |||
pdf.append("1 0 0 -1 " + (rx / 1000f) + " " + | |||
(bl / 1000f) + " Tm [" + startText); | |||
pdf.append("1 0 0 -1 " + (rx / 1000f) + " " | |||
+ (bl / 1000f) + " Tm [" + startText); | |||
prevWordY = bl; | |||
textOpen = true; | |||
} else { | |||
@@ -467,8 +516,8 @@ public class PDFRenderer extends PrintRenderer { | |||
if (emDiff < -33000) { | |||
closeText(); | |||
pdf.append("1 0 0 1 " + (rx / 1000f) + " " + | |||
(bl / 1000f) + " Tm [" + startText); | |||
pdf.append("1 0 0 1 " + (rx / 1000f) + " " | |||
+ (bl / 1000f) + " Tm [" + startText); | |||
textOpen = true; | |||
} else { | |||
pdf.append(Float.toString(emDiff)); | |||
@@ -553,10 +602,11 @@ public class PDFRenderer extends PrintRenderer { | |||
(int) uniBytes[i]; | |||
String hexString = Integer.toHexString(b); | |||
if (hexString.length() == 1) | |||
if (hexString.length() == 1) { | |||
buf = buf.append("0" + hexString); | |||
else | |||
} else { | |||
buf = buf.append(hexString); | |||
} | |||
} | |||
return buf.toString(); | |||
} | |||
@@ -608,8 +658,8 @@ public class PDFRenderer extends PrintRenderer { | |||
} | |||
private void updateFont(String name, int size, StringBuffer pdf) { | |||
if ((!name.equals(this.currentFontName)) || | |||
(size != this.currentFontSize)) { | |||
if ((!name.equals(this.currentFontName)) | |||
|| (size != this.currentFontSize)) { | |||
closeText(); | |||
this.currentFontName = name; | |||
@@ -693,16 +743,16 @@ public class PDFRenderer extends PrintRenderer { | |||
try { | |||
this.pdfDoc.output(ostream); | |||
} catch (IOException ioe) { | |||
// ioexception will be caught later | |||
} | |||
} | |||
protected void placeImage(int x, int y, int w, int h, int xobj) { | |||
currentStream.add("q\n" + ((float) w) + " 0 0 " + | |||
((float) - h) + " " + | |||
(((float) currentBlockIPPosition) / 1000f + x) + " " + | |||
(((float)(currentBPPosition + 1000 * h)) / 1000f + | |||
y) + " cm\n" + "/Im" + xobj + " Do\nQ\n"); | |||
currentStream.add("q\n" + ((float) w) + " 0 0 " | |||
+ ((float) - h) + " " | |||
+ (((float) currentBlockIPPosition) / 1000f + x) + " " | |||
+ (((float)(currentBPPosition + 1000 * h)) / 1000f | |||
+ y) + " cm\n" + "/Im" + xobj + " Do\nQ\n"); | |||
} | |||
@@ -738,6 +788,11 @@ public class PDFRenderer extends PrintRenderer { | |||
} | |||
/** | |||
* Render an inline viewport. | |||
* This renders an inline viewport by clipping if necessary. | |||
* @param viewport the viewport to handle | |||
*/ | |||
public void renderViewport(Viewport viewport) { | |||
closeText(); | |||
currentStream.add("ET\n"); | |||
@@ -758,6 +813,11 @@ public class PDFRenderer extends PrintRenderer { | |||
currentStream.add("BT\n"); | |||
} | |||
/** | |||
* Render leader area. | |||
* This renders a leader area which is an area with a rule. | |||
* @param area the leader area to render | |||
*/ | |||
public void renderLeader(Leader area) { | |||
closeText(); | |||
currentStream.add("ET\n"); | |||
@@ -783,14 +843,14 @@ public class PDFRenderer extends PrintRenderer { | |||
float startx = ((float) currentBlockIPPosition) / 1000f; | |||
float starty = ((currentBPPosition + area.getOffset()) / 1000f); | |||
float endx = (currentBlockIPPosition + area.getWidth()) / 1000f; | |||
if(!alt) { | |||
if (!alt) { | |||
currentStream.add(area.getRuleThickness() / 1000f + " w\n"); | |||
currentStream.add(startx + " " + starty + " m\n"); | |||
currentStream.add(endx + " " + starty + " l\n"); | |||
currentStream.add("S\n"); | |||
} else { | |||
if(style == RuleStyle.DOUBLE) { | |||
if (style == RuleStyle.DOUBLE) { | |||
float third = area.getRuleThickness() / 3000f; | |||
currentStream.add(third + " w\n"); | |||
currentStream.add(startx + " " + starty + " m\n"); | |||
@@ -810,7 +870,7 @@ public class PDFRenderer extends PrintRenderer { | |||
currentStream.add(startx + " " + (starty + 2 * half) + " l\n"); | |||
currentStream.add("h\n"); | |||
currentStream.add("f\n"); | |||
if(style == RuleStyle.GROOVE) { | |||
if (style == RuleStyle.GROOVE) { | |||
currentStream.add("0 g\n"); | |||
currentStream.add(startx + " " + starty + " m\n"); | |||
currentStream.add(endx + " " + starty + " l\n"); |