From c81cdfd5b27ecd0cb1485349a36e2e6d14ed7f90 Mon Sep 17 00:00:00 2001 From: Keiron Liddle Date: Fri, 23 Aug 2002 13:45:25 +0000 Subject: [PATCH] implemented leader pattern: space, dots and use content implemented title for pdf renderer todo: sort out how leader creates areas and offset of areas git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195114 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/area/inline/InlineParent.java | 2 +- src/org/apache/fop/area/inline/Space.java | 2 - src/org/apache/fop/fo/Title.java | 18 ++- src/org/apache/fop/fo/flow/Leader.java | 135 ++++++++++++++++-- .../fop/fo/pagination/PageSequence.java | 2 - .../fop/layoutmgr/ContentLayoutManager.java | 85 +++++++++++ .../fop/layoutmgr/LeafNodeLayoutManager.java | 1 + src/org/apache/fop/pdf/PDFDocument.java | 4 + .../apache/fop/render/AbstractRenderer.java | 16 ++- .../apache/fop/render/pdf/PDFRenderer.java | 8 ++ 10 files changed, 254 insertions(+), 19 deletions(-) create mode 100644 src/org/apache/fop/layoutmgr/ContentLayoutManager.java diff --git a/src/org/apache/fop/area/inline/InlineParent.java b/src/org/apache/fop/area/inline/InlineParent.java index 8ea743d9c..cc733b9ad 100644 --- a/src/org/apache/fop/area/inline/InlineParent.java +++ b/src/org/apache/fop/area/inline/InlineParent.java @@ -16,7 +16,7 @@ import java.util.ArrayList; // this is an inline area that can have other inlines as children public class InlineParent extends InlineArea { - ArrayList inlines = new ArrayList(); + protected ArrayList inlines = new ArrayList(); public InlineParent() { } diff --git a/src/org/apache/fop/area/inline/Space.java b/src/org/apache/fop/area/inline/Space.java index 1ba825524..7b98b3c17 100644 --- a/src/org/apache/fop/area/inline/Space.java +++ b/src/org/apache/fop/area/inline/Space.java @@ -10,8 +10,6 @@ package org.apache.fop.area.inline; import org.apache.fop.render.Renderer; public class Space extends Stretch { - public boolean collapse = true; - public boolean fixed = false; public void render(Renderer renderer) { renderer.renderInlineSpace(this); diff --git a/src/org/apache/fop/fo/Title.java b/src/org/apache/fop/fo/Title.java index 9122296db..7799f70ee 100644 --- a/src/org/apache/fop/fo/Title.java +++ b/src/org/apache/fop/fo/Title.java @@ -15,9 +15,13 @@ import org.apache.fop.fo.flow.*; import org.apache.fop.fo.properties.*; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.LMiter; +import org.apache.fop.layoutmgr.InlineStackingBPLayoutManager; +import org.apache.fop.layoutmgr.ContentLayoutManager; + /** */ -public class Title extends ToBeImplementedElement { +public class Title extends FObjMixed { public Title(FONode parent) { super(parent); @@ -28,6 +32,18 @@ public class Title extends ToBeImplementedElement { new org.apache.fop.area.Title(); // use special layout manager to add the inline areas // to the Title. + InlineStackingBPLayoutManager lm; + lm = new InlineStackingBPLayoutManager(this, + new LMiter(children.listIterator())); + lm.init(); + + // get breaks then add areas to title + + ContentLayoutManager clm = new ContentLayoutManager(title); + lm.setParentLM(clm); + + clm.fillArea(lm); + return title; } diff --git a/src/org/apache/fop/fo/flow/Leader.java b/src/org/apache/fop/fo/flow/Leader.java index bf0906f14..15d383b31 100644 --- a/src/org/apache/fop/fo/flow/Leader.java +++ b/src/org/apache/fop/fo/flow/Leader.java @@ -16,11 +16,22 @@ import org.apache.fop.layout.*; import org.apache.fop.layout.FontState; import org.apache.fop.apps.FOPException; import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.InlineStackingBPLayoutManager; import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.layoutmgr.ContentLayoutManager; import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.LMiter; import org.apache.fop.area.MinOptMax; +import org.apache.fop.area.inline.Space; +import org.apache.fop.area.inline.Word; +import org.apache.fop.area.inline.Stretch; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.util.CharUtilities; +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.area.Trait; import java.util.List; +import java.util.ArrayList; /** * Implements fo:leader; main property of leader leader-pattern. @@ -31,6 +42,10 @@ public class Leader extends FObjMixed { int ruleStyle; int ruleThickness; int leaderPattern; + int patternWidth; + protected FontInfo fontInfo = null; + protected FontState fontState; + protected InlineArea leaderArea = null; public Leader(FONode parent) { super(parent); @@ -48,20 +63,122 @@ public class Leader extends FObjMixed { } protected InlineArea getInlineArea(int refIPD) { - setup(); - - org.apache.fop.area.inline.Leader leader = new org.apache.fop.area.inline.Leader(); - + if(leaderArea == null) { + createLeaderArea(); + } MinOptMax alloc = getAllocationIPD(refIPD); - leader.setAllocationIPD(alloc); - leader.setWidth(alloc.opt); + if(leaderArea instanceof Stretch) { + ((Stretch)leaderArea).setAllocationIPD(alloc); + } else if(leaderArea instanceof FilledArea) { + ((FilledArea)leaderArea).setAllocationIPD(alloc); + } + leaderArea.setWidth(alloc.opt); + return leaderArea; + } + + protected void createLeaderArea() { + setup(); if(leaderPattern == LeaderPattern.RULE) { + org.apache.fop.area.inline.Leader leader = new org.apache.fop.area.inline.Leader(); + leader.setRuleStyle(ruleStyle); leader.setRuleThickness(ruleThickness); + + leaderArea = leader; + } else if (leaderPattern == LeaderPattern.SPACE) { + Space space = new Space(); + + leaderArea = space; + } else if(leaderPattern == LeaderPattern.DOTS) { + Word w = new Word(); + char dot = '.'; // userAgent.getLeaderDotChar(); + + w.setWord("" + dot); + w.addTrait(Trait.FONT_NAME, fontState.getFontName()); + w.addTrait(Trait.FONT_SIZE, + new Integer(fontState.getFontSize())); + // set offset of dot within inline parent + w.setOffset(fontState.getAscender()); + int width = CharUtilities.getCharWidth(dot, fontState); + Space spacer = null; + if(patternWidth > width) { + spacer = new Space(); + spacer.setWidth(patternWidth - width); + width = patternWidth; + } + FilledArea fa = new FilledArea(); + fa.setUnitWidth(width); + fa.addChild(w); + if(spacer != null) { + fa.addChild(spacer); + } + + leaderArea = fa; + } else if(leaderPattern == LeaderPattern.USECONTENT) { + InlineStackingBPLayoutManager lm; + lm = new InlineStackingBPLayoutManager(this, + new LMiter(children.listIterator())); + lm.init(); + + // get breaks then add areas to FilledArea + FilledArea fa = new FilledArea(); + + ContentLayoutManager clm = new ContentLayoutManager(fa); + lm.setParentLM(clm); + + clm.fillArea(lm); + int width = clm.getStackingSize(); + Space spacer = null; + if(patternWidth > width) { + spacer = new Space(); + spacer.setWidth(patternWidth - width); + width = patternWidth; + } + fa.setUnitWidth(width); + if(spacer != null) { + fa.addChild(spacer); + } + leaderArea = fa; } + } + + protected static class FilledArea extends InlineParent { + MinOptMax alloc; + int unitWidth; + + public FilledArea() { + } + + public void setUnitWidth(int w) { + unitWidth = w; + } + + public void setAllocationIPD(MinOptMax all) { + alloc = all; + } + + public MinOptMax getAllocationIPD() { + return alloc; + } + + public void addChild(InlineArea childArea) { + inlines.add(childArea); + } + + public List getChildAreas() { + int units = (int)(getWidth() / unitWidth); + ArrayList newList = new ArrayList(); + for(int count = 0; count < units; count++) { + newList.addAll(inlines); + } + return newList; + } + } - return leader; + public void setStructHandler(StructureHandler st) { + super.setStructHandler(st); + fontInfo = st.getFontInfo(); } public void setup() { @@ -77,7 +194,7 @@ public class Leader extends FObjMixed { BackgroundProps bProps = propMgr.getBackgroundProps(); // Common Font Properties - //this.fontState = propMgr.getFontState(area.getFontInfo()); + this.fontState = propMgr.getFontState(fontInfo); // Common Margin Properties-Inline MarginInlineProps mProps = propMgr.getMarginInlineProps(); @@ -136,7 +253,7 @@ public class Leader extends FObjMixed { } // if leaderPatternWidth = 0 = default = use-font-metric - int leaderPatternWidth = + patternWidth = this.properties.get("leader-pattern-width").getLength().mvalue(); } diff --git a/src/org/apache/fop/fo/pagination/PageSequence.java b/src/org/apache/fop/fo/pagination/PageSequence.java index 8664d663c..b37b7f24a 100644 --- a/src/org/apache/fop/fo/pagination/PageSequence.java +++ b/src/org/apache/fop/fo/pagination/PageSequence.java @@ -232,8 +232,6 @@ public class PageSequence extends FObj { getLogger().warn("fo:title should be first in page-sequence"); } else { this.titleFO = (Title)child; - structHandler.startPageSequence(this, titleFO, layoutMasterSet); - sequenceStarted = true; } } else if (childName.equals("fo:flow")) { if (this.mainFlow != null) { diff --git a/src/org/apache/fop/layoutmgr/ContentLayoutManager.java b/src/org/apache/fop/layoutmgr/ContentLayoutManager.java new file mode 100644 index 000000000..8f3c64261 --- /dev/null +++ b/src/org/apache/fop/layoutmgr/ContentLayoutManager.java @@ -0,0 +1,85 @@ +/* + * $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.layoutmgr; + + +import org.apache.fop.area.Area; +import org.apache.fop.area.MinOptMax; + +import java.util.ArrayList; + +/** + * Content Layout Manager. + * For use with objects that contain inline areas such as + * leader use-content and title. + */ +public class ContentLayoutManager implements LayoutManager { + Area holder; + int stackSize; + + public ContentLayoutManager(Area area) { + holder = area; + } + + public void fillArea(BPLayoutManager curLM) { + + ArrayList childBreaks = new ArrayList(); + MinOptMax stack = new MinOptMax(); + int ipd = 1000000; + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(LayoutContext.NEW_AREA); + childLC.setLeadingSpace(new SpaceSpecifier(false)); + childLC.setTrailingSpace(new SpaceSpecifier(false)); + // set stackLimit for lines + childLC.setStackLimit(new MinOptMax(ipd)); + childLC.setRefIPD(ipd); + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC, null)) != null) { + stack.add(bp.getStackingSize()); + childBreaks.add(bp); + } + } + + LayoutContext lc = new LayoutContext(0); + lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); + lc.setLeadingSpace(new SpaceSpecifier(false)); + lc.setTrailingSpace(new SpaceSpecifier(false)); + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, 0, childBreaks.size()); + curLM.addAreas(breakPosIter, lc); + stackSize = stack.opt; + } + + public int getStackingSize() { + return stackSize; + } + + public boolean generatesInlineAreas() { + return true; + } + + public Area getParentArea (Area childArea) { + return holder; + } + + public boolean addChild (Area childArea) { + holder.addChild(childArea); + return true; + } + + public void setParentLM(LayoutManager lm) { + } + + public int getContentIPD() { + return 10000000; + } + +} + diff --git a/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java b/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java index d2c6d42e2..d8a00f0f7 100644 --- a/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java +++ b/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java @@ -79,6 +79,7 @@ public class LeafNodeLayoutManager extends AbstractBPLayoutManager { BreakPoss.ISLAST); bp.setStackingSize(curArea.getAllocationIPD()); bp.setNonStackingSize(curArea.getAllocationBPD()); + bp.setTrailingSpace(new SpaceSpecifier(false)); int bpd = curArea.getHeight(); switch(alignment) { diff --git a/src/org/apache/fop/pdf/PDFDocument.java b/src/org/apache/fop/pdf/PDFDocument.java index 1fcfdf696..a551dc929 100644 --- a/src/org/apache/fop/pdf/PDFDocument.java +++ b/src/org/apache/fop/pdf/PDFDocument.java @@ -238,6 +238,10 @@ public class PDFDocument { return pdfInfo; } + public PDFInfo getInfo() { + return info; + } + /** * Make a Type 0 sampled function * diff --git a/src/org/apache/fop/render/AbstractRenderer.java b/src/org/apache/fop/render/AbstractRenderer.java index 2075a4fd1..a21eb1374 100644 --- a/src/org/apache/fop/render/AbstractRenderer.java +++ b/src/org/apache/fop/render/AbstractRenderer.java @@ -82,18 +82,25 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren public String convertTitleToString(Title title) { String str = ""; List children = title.getInlineAreas(); + str = convertToString(children); + return str.trim(); + } + private String convertToString(List children) { + String str = ""; for (int count = 0; count < children.size(); count++) { InlineArea inline = (InlineArea) children.get(count); if (inline instanceof Character) { str += ((Character) inline).getChar(); } else if (inline instanceof Word) { str += ((Word) inline).getWord(); + } else if (inline instanceof InlineParent) { + str += convertToString(((InlineParent)inline).getChildAreas()); } else { str += " "; } } - return str.trim(); + return str; } public void startPageSequence(Title seqTitle) { @@ -304,11 +311,12 @@ public abstract class AbstractRenderer extends AbstractLogEnabled implements Ren } public void renderInlineParent(InlineParent ip) { - // currentBlockIPPosition += ip.getWidth(); - Iterator iter = ip.getChildAreas().iterator(); - while (iter.hasNext()) { + int saveIP = currentBlockIPPosition; + Iterator iter = ip.getChildAreas().iterator(); + while (iter.hasNext()) { ((InlineArea)iter.next()).render(this); } + currentBlockIPPosition = saveIP + ip.getWidth(); } protected void renderBlocks(List blocks) { diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index c7059f21c..84ac9cb96 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -176,6 +176,14 @@ public class PDFRenderer extends PrintRenderer { return true; } + public void startPageSequence(Title seqTitle) { + if(seqTitle != null) { + String str = convertTitleToString(seqTitle); + PDFInfo info = this.pdfDoc.getInfo(); + info.setTitle(str); + } + } + /** * The pdf page is prepared by making the page. * The page is made in the pdf document without any contents -- 2.39.5