aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/apache')
-rw-r--r--src/org/apache/fop/apps/CommandLineStarter.java1
-rw-r--r--src/org/apache/fop/area/Block.java13
-rw-r--r--src/org/apache/fop/area/LineArea.java4
-rw-r--r--src/org/apache/fop/area/inline/Stretch.java18
-rw-r--r--src/org/apache/fop/fo/FOText.java103
-rw-r--r--src/org/apache/fop/fo/FObj.java111
-rw-r--r--src/org/apache/fop/fo/FObjMixed.java46
-rw-r--r--src/org/apache/fop/fo/flow/BasicLink.java6
-rw-r--r--src/org/apache/fop/fo/flow/BidiOverride.java66
-rw-r--r--src/org/apache/fop/fo/flow/Block.java392
-rw-r--r--src/org/apache/fop/fo/flow/Character.java26
-rw-r--r--src/org/apache/fop/fo/flow/ExternalGraphic.java5
-rw-r--r--src/org/apache/fop/fo/flow/Flow.java62
-rw-r--r--src/org/apache/fop/fo/flow/Footnote.java12
-rw-r--r--src/org/apache/fop/fo/flow/Inline.java2
-rw-r--r--src/org/apache/fop/fo/flow/InlineContainer.java33
-rw-r--r--src/org/apache/fop/fo/flow/InstreamForeignObject.java9
-rw-r--r--src/org/apache/fop/fo/flow/Leader.java23
-rw-r--r--src/org/apache/fop/fo/flow/PageNumber.java24
-rw-r--r--src/org/apache/fop/fo/flow/PageNumberCitation.java79
-rw-r--r--src/org/apache/fop/layoutmgr/AbstractLayoutManager.java47
-rw-r--r--src/org/apache/fop/layoutmgr/BlockLayoutManager.java69
-rw-r--r--src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java45
-rw-r--r--src/org/apache/fop/layoutmgr/FlowLayoutManager.java4
-rw-r--r--src/org/apache/fop/layoutmgr/LayoutInfo.java5
-rw-r--r--src/org/apache/fop/layoutmgr/LayoutManager.java6
-rw-r--r--src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java29
-rw-r--r--src/org/apache/fop/layoutmgr/LineLayoutManager.java444
-rw-r--r--src/org/apache/fop/layoutmgr/PageLayoutManager.java20
-rw-r--r--src/org/apache/fop/layoutmgr/TextLayoutManager.java49
-rw-r--r--src/org/apache/fop/render/pdf/PDFRenderer.java10
-rw-r--r--src/org/apache/fop/svg/SVGElement.java4
32 files changed, 1155 insertions, 612 deletions
diff --git a/src/org/apache/fop/apps/CommandLineStarter.java b/src/org/apache/fop/apps/CommandLineStarter.java
index e3db06fe8..45c01940f 100644
--- a/src/org/apache/fop/apps/CommandLineStarter.java
+++ b/src/org/apache/fop/apps/CommandLineStarter.java
@@ -26,7 +26,6 @@ import org.apache.fop.configuration.Configuration;
*
* Modified to use new streaming API by Mark Lillywhite, mark-fop@inomial.com
*/
-
public class CommandLineStarter extends Starter {
CommandLineOptions commandLineOptions;
diff --git a/src/org/apache/fop/area/Block.java b/src/org/apache/fop/area/Block.java
index 9073c23a7..5dcbb7df4 100644
--- a/src/org/apache/fop/area/Block.java
+++ b/src/org/apache/fop/area/Block.java
@@ -10,6 +10,7 @@ package org.apache.fop.area;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Iterator;
import java.awt.geom.Rectangle2D;
// block areas hold either more block areas or line
@@ -54,6 +55,18 @@ public class Block extends BlockParent implements Serializable {
children.add(line);
}
+ public MinOptMax getContentBPD() {
+ MinOptMax bpd = new MinOptMax();
+ if(children != null) {
+ for(Iterator iter = children.iterator(); iter.hasNext(); ) {
+ Area area = (Area)iter.next();
+ MinOptMax mom = area.getContentBPD();
+ bpd.add(mom);
+ }
+ }
+ return bpd;
+ }
+
public int getPositioning() {
return positioning;
}
diff --git a/src/org/apache/fop/area/LineArea.java b/src/org/apache/fop/area/LineArea.java
index 5da4fee09..7496dd10a 100644
--- a/src/org/apache/fop/area/LineArea.java
+++ b/src/org/apache/fop/area/LineArea.java
@@ -39,6 +39,10 @@ public class LineArea extends Area {
return lineHeight;
}
+ public MinOptMax getContentBPD() {
+ return new MinOptMax(lineHeight);
+ }
+
public void addInlineArea(InlineArea area) {
inlineAreas.add(area);
}
diff --git a/src/org/apache/fop/area/inline/Stretch.java b/src/org/apache/fop/area/inline/Stretch.java
index fee1a3333..ed1ba2254 100644
--- a/src/org/apache/fop/area/inline/Stretch.java
+++ b/src/org/apache/fop/area/inline/Stretch.java
@@ -7,11 +7,21 @@
package org.apache.fop.area.inline;
+import org.apache.fop.area.MinOptMax;
+
public class Stretch extends InlineArea {
+ MinOptMax contentIPD;
- // min size
- // set size
- // get size
- // height 0
+ public void setAllocationIPD(MinOptMax mom) {
+ contentIPD = mom;
+ }
+ public MinOptMax getAllocationIPD() {
+ // Should also account for any borders and padding in the
+ // inline progression dimension
+ if (contentIPD != null) {
+ return contentIPD;
+ }
+ return super.getAllocationIPD();
+ }
}
diff --git a/src/org/apache/fop/fo/FOText.java b/src/org/apache/fop/fo/FOText.java
index ac18fb1c7..a54dce5be 100644
--- a/src/org/apache/fop/fo/FOText.java
+++ b/src/org/apache/fop/fo/FOText.java
@@ -19,6 +19,7 @@ import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.TextLayoutManager;
import java.util.NoSuchElementException;
+import java.util.List;
/**
* a text node in the formatting object tree
@@ -41,21 +42,21 @@ public class FOText extends FObj {
super(null);
this.start = 0;
this.ca = new char[e - s];
- System.arraycopy(chars, s, ca, 0, e-s);
+ System.arraycopy(chars, s, ca, 0, e - s);
this.length = e - s;
textInfo = ti;
}
public boolean willCreateArea() {
- if (textInfo.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE
- && length > 0) {
+ if (textInfo.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE &&
+ length > 0) {
return true;
}
for (int i = start; i < start + length; i++) {
char ch = ca[i];
- if (!((ch == ' ') || (ch == '\n') || (ch == '\r')
- || (ch == '\t'))) { // whitespace
+ if (!((ch == ' ') || (ch == '\n') || (ch == '\r') ||
+ (ch == '\t'))) { // whitespace
return true;
}
}
@@ -65,61 +66,59 @@ public class FOText extends FObj {
// Just to keep PageNumber and PageNumber citation happy for now.
// The real code is moved to TextLayoutManager!
- public static int addText(BlockArea ba, FontState fontState, float red,
- float green, float blue, int wrapOption,
- LinkSet ls, int whiteSpaceCollapse,
- char data[], int start, int end,
- TextState textState, int vAlign) {
- return 0;
+ public static int addText(BlockArea ba, FontState fontState,
+ float red, float green, float blue, int wrapOption,
+ LinkSet ls, int whiteSpaceCollapse, char data[],
+ int start, int end, TextState textState, int vAlign) {
+ return 0;
}
- public LayoutManager getLayoutManager() {
- // What if nothing left (length=0)?
- if (length < ca.length) {
- char[] tmp = ca;
- ca = new char[length];
- System.arraycopy(tmp, 0, ca, 0, length);
- }
- return new TextLayoutManager(this, ca, textInfo);
+ public void addLayoutManager(List list) {
+ // What if nothing left (length=0)?
+ if (length < ca.length) {
+ char[] tmp = ca;
+ ca = new char[length];
+ System.arraycopy(tmp, 0, ca, 0, length);
+ }
+ list.add(new TextLayoutManager(this, ca, textInfo));
}
public CharIterator charIterator() {
- return new TextCharIterator();
+ return new TextCharIterator();
}
private class TextCharIterator extends AbstractCharIterator {
- int curIndex = 0;
- public boolean hasNext() {
- return (curIndex < length);
- }
-
- public char nextChar() {
- if (curIndex < length) {
- // Just a char class? Don't actually care about the value!
- return ca[curIndex++];
- }
- else throw new NoSuchElementException();
- }
-
- public void remove() {
- if (curIndex>0 && curIndex < length) {
- // copy from curIndex to end to curIndex-1
- System.arraycopy(ca, curIndex, ca, curIndex-1,
- length-curIndex);
- length--;
- curIndex--;
- }
- else if (curIndex == length) {
- curIndex = --length;
- }
- }
-
-
- public void replaceChar(char c) {
- if (curIndex>0 && curIndex <= length) {
- ca[curIndex-1]=c;
- }
- }
+ int curIndex = 0;
+ public boolean hasNext() {
+ return (curIndex < length);
+ }
+
+ public char nextChar() {
+ if (curIndex < length) {
+ // Just a char class? Don't actually care about the value!
+ return ca[curIndex++];
+ } else
+ throw new NoSuchElementException();
+ }
+
+ public void remove() {
+ if (curIndex > 0 && curIndex < length) {
+ // copy from curIndex to end to curIndex-1
+ System.arraycopy(ca, curIndex, ca, curIndex - 1,
+ length - curIndex);
+ length--;
+ curIndex--;
+ } else if (curIndex == length) {
+ curIndex = --length;
+ }
+ }
+
+
+ public void replaceChar(char c) {
+ if (curIndex > 0 && curIndex <= length) {
+ ca[curIndex - 1] = c;
+ }
+ }
}
diff --git a/src/org/apache/fop/fo/FObj.java b/src/org/apache/fop/fo/FObj.java
index e6bb8205c..01ae205d4 100644
--- a/src/org/apache/fop/fo/FObj.java
+++ b/src/org/apache/fop/fo/FObj.java
@@ -26,6 +26,7 @@ import org.xml.sax.Attributes;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.ArrayList;
+import java.util.List;
import java.util.HashMap;
/**
@@ -53,7 +54,7 @@ public class FObj extends FONode {
*/
protected int marker = START;
- protected ArrayList children = new ArrayList(); // made public for searching for id's
+ protected ArrayList children = new ArrayList(); // made public for searching for id's
protected boolean isInTableCell = false;
@@ -75,7 +76,7 @@ public class FObj extends FONode {
super(parent);
markers = new HashMap();
if (parent instanceof FObj)
- this.areaClass = ((FObj)parent).areaClass;
+ this.areaClass = ((FObj) parent).areaClass;
}
public void setName(String str) {
@@ -85,14 +86,16 @@ public class FObj extends FONode {
protected static PropertyListBuilder plb = null;
protected PropertyListBuilder getListBuilder() {
- if(plb == null) {
+ if (plb == null) {
plb = new PropertyListBuilder();
plb.addList(FOPropertyMapping.getGenericMappings());
- for (Iterator iter = FOPropertyMapping.getElementMappings().iterator();
- iter.hasNext(); ) {
- String elem = (String)iter.next();
- plb.addElementList(elem, FOPropertyMapping.getElementMapping(elem));
+ for (Iterator iter =
+ FOPropertyMapping.getElementMappings().iterator();
+ iter.hasNext();) {
+ String elem = (String) iter.next();
+ plb.addElementList(elem,
+ FOPropertyMapping.getElementMapping(elem));
}
}
return plb;
@@ -106,22 +109,22 @@ public class FObj extends FONode {
public void handleAttrs(Attributes attlist) throws FOPException {
String uri = "http://www.w3.org/1999/XSL/Format";
FONode par = parent;
- while(par != null && !(par instanceof FObj)) {
+ while (par != null && !(par instanceof FObj)) {
par = par.parent;
}
PropertyList props = null;
- if(par != null) {
- props = ((FObj)par).properties;
+ if (par != null) {
+ props = ((FObj) par).properties;
}
- properties =
- getListBuilder().makeList(uri, name, attlist,
- props, (FObj)par);
+ properties = getListBuilder().makeList(uri, name, attlist, props,
+ (FObj) par);
properties.setFObj(this);
this.propMgr = makePropertyManager(properties);
setWritingMode();
}
- protected PropertyManager makePropertyManager(PropertyList propertyList) {
+ protected PropertyManager makePropertyManager(
+ PropertyList propertyList) {
return new PropertyManager(propertyList);
}
@@ -158,15 +161,16 @@ public class FObj extends FONode {
* @param idReferences the id to remove
*/
public void removeID(IDReferences idReferences) {
- if (((FObj)this).properties.get("id") == null
- || ((FObj)this).properties.get("id").getString() == null)
+ if (((FObj) this).properties.get("id") == null ||
+ ((FObj) this).properties.get("id").getString() == null)
return;
- idReferences.removeID(((FObj)this).properties.get("id").getString());
+ idReferences.removeID(
+ ((FObj) this).properties.get("id").getString());
int numChildren = this.children.size();
for (int i = 0; i < numChildren; i++) {
- FONode child = (FONode)children.get(i);
+ FONode child = (FONode) children.get(i);
if ((child instanceof FObj)) {
- ((FObj)child).removeID(idReferences);
+ ((FObj) child).removeID(idReferences);
}
}
}
@@ -189,18 +193,19 @@ public class FObj extends FONode {
protected void setWritingMode() {
FObj p;
FONode parent;
- for (p = this;
- !p.generatesReferenceAreas() && (parent = p.getParent()) != null && (parent instanceof FObj);
- p = (FObj)parent);
- this.properties.setWritingMode(p.getProperty("writing-mode").getEnum());
+ for (p = this; !p.generatesReferenceAreas() &&
+ (parent = p.getParent()) != null &&
+ (parent instanceof FObj); p = (FObj) parent)
+ ;
+ this.properties.setWritingMode(
+ p.getProperty("writing-mode").getEnum());
}
/**
* Return a LayoutManager responsible for laying out this FObj's content.
* Must override in subclasses if their content can be laid out.
*/
- public LayoutManager getLayoutManager() {
- return null;
+ public void addLayoutManager(List list) {
}
/**
@@ -208,7 +213,7 @@ public class FObj extends FONode {
* @return A ListIterator.
*/
public ListIterator getChildren() {
- return children.listIterator();
+ return children.listIterator();
}
/**
@@ -219,11 +224,11 @@ public class FObj extends FONode {
* this FObj.
*/
public ListIterator getChildren(FONode childNode) {
- int i = children.indexOf(childNode);
- if (i >= 0) {
- return children.listIterator(i);
- }
- else return null;
+ int i = children.indexOf(childNode);
+ if (i >= 0) {
+ return children.listIterator(i);
+ } else
+ return null;
}
public void setIsInTableCell() {
@@ -231,20 +236,20 @@ public class FObj extends FONode {
// made recursive by Eric Schaeffer
for (int i = 0; i < this.children.size(); i++) {
Object obj = this.children.get(i);
- if(obj instanceof FObj) {
- FObj child = (FObj)obj;
+ if (obj instanceof FObj) {
+ FObj child = (FObj) obj;
child.setIsInTableCell();
}
}
}
-
+
public void forceStartOffset(int offset) {
- this.forcedStartOffset = offset;
+ this.forcedStartOffset = offset;
// made recursive by Eric Schaeffer
for (int i = 0; i < this.children.size(); i++) {
Object obj = this.children.get(i);
- if(obj instanceof FObj) {
- FObj child = (FObj)obj;
+ if (obj instanceof FObj) {
+ FObj child = (FObj) obj;
child.forceStartOffset(offset);
}
}
@@ -255,8 +260,8 @@ public class FObj extends FONode {
// made recursive by Eric Schaeffer
for (int i = 0; i < this.children.size(); i++) {
Object obj = this.children.get(i);
- if(obj instanceof FObj) {
- FObj child = (FObj)obj;
+ if (obj instanceof FObj) {
+ FObj child = (FObj) obj;
child.forceWidth(width);
}
}
@@ -267,8 +272,8 @@ public class FObj extends FONode {
int numChildren = this.children.size();
for (int i = 0; i < numChildren; i++) {
Object obj = this.children.get(i);
- if(obj instanceof FObj) {
- FObj child = (FObj)obj;
+ if (obj instanceof FObj) {
+ FObj child = (FObj) obj;
child.resetMarker();
}
}
@@ -277,7 +282,7 @@ public class FObj extends FONode {
public void setWidows(int wid) {
widows = wid;
}
-
+
public void setOrphans(int orph) {
orphans = orph;
}
@@ -290,8 +295,8 @@ public class FObj extends FONode {
this.linkSet = linkSet;
for (int i = 0; i < this.children.size(); i++) {
Object obj = this.children.get(i);
- if(obj instanceof FObj) {
- FObj child = (FObj)obj;
+ if (obj instanceof FObj) {
+ FObj child = (FObj) obj;
child.setLinkSet(linkSet);
}
}
@@ -317,7 +322,8 @@ public class FObj extends FONode {
else if (children.isEmpty())
return snapshot;
else
- return ((FObj)children.get(this.marker)).getMarkerSnapshot(snapshot);
+ return ( (FObj) children.get(this.marker)).getMarkerSnapshot(
+ snapshot);
}
/**
@@ -327,7 +333,7 @@ public class FObj extends FONode {
* @param snapshot the ArrayList of saved markers (Integers)
*/
public void rollback(ArrayList snapshot) {
- this.marker = ((Integer)snapshot.get(0)).intValue();
+ this.marker = ((Integer) snapshot.get(0)).intValue();
snapshot.remove(0);
if (this.marker == START) {
@@ -345,12 +351,12 @@ public class FObj extends FONode {
for (int i = this.marker + 1; i < numChildren; i++) {
Object obj = this.children.get(i);
- if(obj instanceof FObj) {
- FObj child = (FObj)obj;
+ if (obj instanceof FObj) {
+ FObj child = (FObj) obj;
child.resetMarker();
}
}
- ((FObj)children.get(this.marker)).rollback(snapshot);
+ ((FObj) children.get(this.marker)).rollback(snapshot);
}
@@ -359,10 +365,9 @@ public class FObj extends FONode {
if (!markers.containsKey(mcname) && children.isEmpty()) {
markers.put(mcname, marker);
} else {
- log.error("fo:marker must be an initial child,"
- + "and 'marker-class-name' must be unique for same parent");
- throw new FOPException("fo:marker must be an initial child,"
- + "and 'marker-class-name' must be unique for same parent");
+ log.error("fo:marker must be an initial child," + "and 'marker-class-name' must be unique for same parent");
+ throw new FOPException(
+ "fo:marker must be an initial child," + "and 'marker-class-name' must be unique for same parent");
}
}
diff --git a/src/org/apache/fop/fo/FObjMixed.java b/src/org/apache/fop/fo/FObjMixed.java
index 75f736bd7..f2a180f65 100644
--- a/src/org/apache/fop/fo/FObjMixed.java
+++ b/src/org/apache/fop/fo/FObjMixed.java
@@ -14,6 +14,7 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.StreamRenderer;
import org.apache.fop.datatypes.ColorType;
+import java.util.List;
/**
* base class for representation of mixed content formatting objects
@@ -21,37 +22,48 @@ import org.apache.fop.datatypes.ColorType;
*/
public class FObjMixed extends FObj {
TextInfo textInfo = null;
- protected FontInfo fontInfo=null;
+ protected FontInfo fontInfo = null;
public FObjMixed(FONode parent) {
super(parent);
}
public void setStreamRenderer(StreamRenderer st) {
- fontInfo = st.getFontInfo();
+ fontInfo = st.getFontInfo();
}
- protected void addCharacters(char data[], int start, int length) {
- if(textInfo == null) {
- textInfo = new TextInfo();
+ public void addLayoutManager(List lms) {
+ // set start and end properties for this element, id, etc.
+ int numChildren = this.children.size();
+ for (int i = 0; i < numChildren; i++) {
+ Object o = children.get(i);
+ if (o instanceof FObj) {
+ FObj fo = (FObj) o;
+ fo.addLayoutManager(lms);
+ }
+ }
+ }
- try {
- textInfo.fs = propMgr.getFontState(fontInfo);
- } catch (FOPException fopex) {
- log.error("Error setting FontState for characters: " +
- fopex.getMessage());
- }
+ protected void addCharacters(char data[], int start, int length) {
+ if (textInfo == null) {
+ textInfo = new TextInfo();
+
+ try {
+ textInfo.fs = propMgr.getFontState(fontInfo);
+ } catch (FOPException fopex) {
+ log.error("Error setting FontState for characters: " +
+ fopex.getMessage());
+ }
ColorType c = getProperty("color").getColorType();
textInfo.color = c;
textInfo.verticalAlign =
- getProperty("vertical-align").getEnum();
+ getProperty("vertical-align").getEnum();
- textInfo.wrapOption =
- getProperty("wrap-option").getEnum();
+ textInfo.wrapOption = getProperty("wrap-option").getEnum();
textInfo.whiteSpaceCollapse =
- getProperty("white-space-collapse").getEnum();
+ getProperty("white-space-collapse").getEnum();
}
@@ -82,7 +94,7 @@ public class FObjMixed extends FObj {
int numChildren = this.children.size();
for (int i = this.marker; i < numChildren; i++) {
- FONode fo = (FONode)children.get(i);
+ FONode fo = (FONode) children.get(i);
Status status;
if ((status = fo.layout(area)).isIncomplete()) {
this.marker = i;
@@ -93,7 +105,7 @@ public class FObjMixed extends FObj {
}
public CharIterator charIterator() {
- return new RecursiveCharIterator(this);
+ return new RecursiveCharIterator(this);
}
}
diff --git a/src/org/apache/fop/fo/flow/BasicLink.java b/src/org/apache/fop/fo/flow/BasicLink.java
index 5b8344341..938c43dcc 100644
--- a/src/org/apache/fop/fo/flow/BasicLink.java
+++ b/src/org/apache/fop/fo/flow/BasicLink.java
@@ -17,6 +17,7 @@ import org.apache.fop.datatypes.ColorType;
// Java
import java.util.Enumeration;
import java.awt.Rectangle;
+import java.util.List;
public class BasicLink extends Inline {
@@ -24,6 +25,11 @@ public class BasicLink extends Inline {
super(parent);
}
+ // add start and end properties for the link
+ public void addLayoutManager(List lms) {
+ super.addLayoutManager(lms);
+ }
+
public Status layout(Area area) throws FOPException {
String destination;
int linkType;
diff --git a/src/org/apache/fop/fo/flow/BidiOverride.java b/src/org/apache/fop/fo/flow/BidiOverride.java
index 208f2ae0f..d7123ed39 100644
--- a/src/org/apache/fop/fo/flow/BidiOverride.java
+++ b/src/org/apache/fop/fo/flow/BidiOverride.java
@@ -9,21 +9,48 @@ package org.apache.fop.fo.flow;
// FOP
import org.apache.fop.fo.*;
-import org.apache.fop.layout.*;
+import org.apache.fop.layout.AuralProps;
+import org.apache.fop.layout.RelativePositionProps;
import org.apache.fop.fo.flow.*;
import org.apache.fop.fo.properties.*;
import org.apache.fop.layout.AreaTree;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.layoutmgr.LeafNodeLayoutManager;
+import org.apache.fop.layoutmgr.LayoutManager;
+import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.area.inline.Word;
+
+import java.util.List;
+import java.util.ArrayList;
+
/**
*/
-public class BidiOverride extends ToBeImplementedElement {
+public class BidiOverride extends FObjMixed {
public BidiOverride(FONode parent) {
super(parent);
}
- public Status layout(Area area) throws FOPException {
+ public void addLayoutManager(List list) {
+ if (false) {
+ super.addLayoutManager(list);
+ } else {
+ ArrayList childList = new ArrayList();
+ super.addLayoutManager(childList);
+ for (int count = childList.size() - 1; count >= 0; count--) {
+ LayoutManager lm = (LayoutManager) childList.get(count);
+ if (lm.generatesInlineAreas()) {
+ list.add( new BidiLayoutManager(this,
+ (LeafNodeLayoutManager) lm));
+ } else {
+ list.add(lm);
+ }
+ }
+ }
+ }
+
+ public void setup() {
// Common Aural Properties
AuralProps mAurProps = propMgr.getAuralProps();
@@ -46,6 +73,37 @@ public class BidiOverride extends ToBeImplementedElement {
// this.properties.get("unicode-bidi");
// this.properties.get("word-spacing");
- return super.layout(area);
+ }
+
+ /**
+ * If this bidi has a different writing mode direction
+ * ltr or rtl than its parent writing mode then this
+ * reverses the inline areas (at the character level).
+ */
+ class BidiLayoutManager extends LeafNodeLayoutManager {
+ List childs;
+
+ BidiLayoutManager(FObj obj, LeafNodeLayoutManager cLM) {
+ super(obj);
+ childs = new ArrayList();
+ for (int count = cLM.size() - 1; count >= 0; count--) {
+ InlineArea ia = cLM.get(count);
+ if (ia instanceof Word) {
+ // reverse word
+ Word word = (Word) ia;
+ StringBuffer sb = new StringBuffer(word.getWord());
+ word.setWord(sb.reverse().toString());
+ }
+ childs.add(ia);
+ }
+ }
+
+ public int size() {
+ return childs.size();
+ }
+
+ public InlineArea get(int index) {
+ return (InlineArea) childs.get(index);
+ }
}
}
diff --git a/src/org/apache/fop/fo/flow/Block.java b/src/org/apache/fop/fo/flow/Block.java
index d234cc159..1bf604eb8 100644
--- a/src/org/apache/fop/fo/flow/Block.java
+++ b/src/org/apache/fop/fo/flow/Block.java
@@ -20,6 +20,8 @@ import org.apache.fop.apps.StreamRenderer;
import org.xml.sax.Attributes;
+import java.util.List;
+
/*
Modified by Mark Lillywhite mark-fop@inomial.com. The changes
here are based on memory profiling and do not change functionality.
@@ -31,9 +33,9 @@ import org.xml.sax.Attributes;
the reference to BlockArea was made local, the required information
is now stored (instead of a reference to the complex BlockArea object)
and it appears that there are a lot of changes in this file, in fact
- there are only a few sematic changes; mostly I just got rid of
+ there are only a few sematic changes; mostly I just got rid of
"this." from blockArea since BlockArea is now local.
- */
+ */
public class Block extends FObjMixed {
@@ -76,10 +78,13 @@ public class Block extends FObjMixed {
public void handleAttrs(Attributes attlist) throws FOPException {
super.handleAttrs(attlist);
this.span = this.properties.get("span").getEnum();
- this.wsTreatment = this.properties.get("white-space-treatment").getEnum();
- this.bWScollapse = (this.properties.get("white-space-collapse").getEnum() ==
- Constants.TRUE);
- this.lfTreatment = this.properties.get("linefeed-treatment").getEnum();
+ this.wsTreatment =
+ this.properties.get("white-space-treatment").getEnum();
+ this.bWScollapse =
+ (this.properties.get("white-space-collapse").getEnum()
+ == Constants.TRUE);
+ this.lfTreatment =
+ this.properties.get("linefeed-treatment").getEnum();
}
public Status layout(Area area) throws FOPException {
@@ -114,7 +119,8 @@ public class Block extends FObjMixed {
MarginProps mProps = propMgr.getMarginProps();
// Common Relative Position Properties
- RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
+ RelativePositionProps mRelProps =
+ propMgr.getRelativePositionProps();
// this.properties.get("break-after");
// this.properties.get("break-before");
@@ -145,29 +151,30 @@ public class Block extends FObjMixed {
// this.properties.get("z-index");
this.align = this.properties.get("text-align").getEnum();
- this.alignLast = this.properties.get("text-align-last").getEnum();
+ this.alignLast =
+ this.properties.get("text-align-last").getEnum();
this.breakAfter = this.properties.get("break-after").getEnum();
- this.lineHeight =
- this.properties.get("line-height").getLength().mvalue();
- this.startIndent =
- this.properties.get("start-indent").getLength().mvalue();
- this.endIndent =
- this.properties.get("end-indent").getLength().mvalue();
- this.spaceBefore =
- this.properties.get("space-before.optimum").getLength().mvalue();
- this.spaceAfter =
- this.properties.get("space-after.optimum").getLength().mvalue();
- this.textIndent =
- this.properties.get("text-indent").getLength().mvalue();
+ this.lineHeight = this.properties.get(
+ "line-height").getLength().mvalue();
+ this.startIndent = this.properties.get(
+ "start-indent").getLength().mvalue();
+ this.endIndent = this.properties.get(
+ "end-indent").getLength().mvalue();
+ this.spaceBefore = this.properties.get(
+ "space-before.optimum").getLength().mvalue();
+ this.spaceAfter = this.properties.get(
+ "space-after.optimum").getLength().mvalue();
+ this.textIndent = this.properties.get(
+ "text-indent").getLength().mvalue();
this.keepWithNext =
- this.properties.get("keep-with-next").getEnum();
- this.backgroundColor =
- this.properties.get("background-color").getColorType();
+ this.properties.get("keep-with-next").getEnum();
+ this.backgroundColor = this.properties.get(
+ "background-color").getColorType();
this.blockWidows =
- this.properties.get("widows").getNumber().intValue();
+ this.properties.get("widows").getNumber().intValue();
this.blockOrphans =
- this.properties.get("orphans").getNumber().intValue();
+ this.properties.get("orphans").getNumber().intValue();
this.id = this.properties.get("id").getString();
@@ -189,9 +196,9 @@ public class Block extends FObjMixed {
int numChildren = this.children.size();
for (int i = 0; i < numChildren; i++) {
- FONode fo = (FONode)children.get(i);
+ FONode fo = (FONode) children.get(i);
if (fo instanceof FOText) {
- if (((FOText)fo).willCreateArea()) {
+ if (((FOText) fo).willCreateArea()) {
//fo.setWidows(blockWidows);
break;
} else {
@@ -206,9 +213,9 @@ public class Block extends FObjMixed {
}
for (int i = numChildren - 1; i >= 0; i--) {
- FONode fo = (FONode)children.get(i);
+ FONode fo = (FONode) children.get(i);
if (fo instanceof FOText) {
- if (((FOText)fo).willCreateArea()) {
+ if (((FOText) fo).willCreateArea()) {
//fo.setOrphans(blockOrphans);
break;
}
@@ -232,11 +239,10 @@ public class Block extends FObjMixed {
}
int spaceLeft = area.spaceLeft();
- blockArea =
- new BlockArea(propMgr.getFontState(area.getFontInfo()),
- area.getAllocationWidth(), area.spaceLeft(),
- startIndent, endIndent, textIndent, align,
- alignLast, lineHeight);
+ blockArea = new BlockArea( propMgr.getFontState(area.getFontInfo()),
+ area.getAllocationWidth(), area.spaceLeft(),
+ startIndent, endIndent, textIndent, align, alignLast,
+ lineHeight);
blockArea.setGeneratedBy(this);
this.areasGenerated++;
if (this.areasGenerated == 1)
@@ -246,9 +252,9 @@ public class Block extends FObjMixed {
// markers
//if (this.hasMarkers())
- //blockArea.addMarkers(this.getMarkers());
+ //blockArea.addMarkers(this.getMarkers());
- blockArea.setParent(area); // BasicLink needs it
+ blockArea.setParent(area); // BasicLink needs it
blockArea.setPage(area.getPage());
blockArea.setBackgroundColor(backgroundColor);
blockArea.setBorderAndPadding(propMgr.getBorderAndPadding());
@@ -262,7 +268,7 @@ public class Block extends FObjMixed {
int numChildren = this.children.size();
for (int i = this.marker; i < numChildren; i++) {
- FONode fo = (FONode)children.get(i);
+ FONode fo = (FONode) children.get(i);
Status status;
if ((status = fo.layout(blockArea)).isIncomplete()) {
this.marker = i;
@@ -280,14 +286,15 @@ public class Block extends FObjMixed {
if ((i != 0)) {
status = new Status(Status.AREA_FULL_SOME);
area.addChild(blockArea);
- area.setMaxHeight(area.getMaxHeight() - spaceLeft
- + blockArea.getMaxHeight());
+ area.setMaxHeight(area.getMaxHeight() -
+ spaceLeft + blockArea.getMaxHeight());
area.increaseHeight(blockArea.getHeight());
- area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
+ area.setAbsoluteHeight(
+ blockArea.getAbsoluteHeight());
anythingLaidOut = true;
return status;
- } else // i == 0 nothing was laid out..
+ } else // i == 0 nothing was laid out..
{
anythingLaidOut = false;
return status;
@@ -296,8 +303,8 @@ public class Block extends FObjMixed {
// blockArea.end();
area.addChild(blockArea);
- area.setMaxHeight(area.getMaxHeight() - spaceLeft
- + blockArea.getMaxHeight());
+ area.setMaxHeight(area.getMaxHeight() - spaceLeft +
+ blockArea.getMaxHeight());
area.increaseHeight(blockArea.getHeight());
area.setAbsoluteHeight(blockArea.getAbsoluteHeight());
anythingLaidOut = true;
@@ -308,8 +315,8 @@ public class Block extends FObjMixed {
blockArea.end();
- area.setMaxHeight(area.getMaxHeight() - spaceLeft
- + blockArea.getMaxHeight());
+ area.setMaxHeight(area.getMaxHeight() - spaceLeft +
+ blockArea.getMaxHeight());
area.addChild(blockArea);
@@ -327,8 +334,8 @@ public class Block extends FObjMixed {
}
// This is not needed any more and it consumes a LOT
// of memory. So we release it for the GC.
- areaHeight= blockArea.getHeight();
- contentWidth= blockArea.getContentWidth();
+ areaHeight = blockArea.getHeight();
+ contentWidth = blockArea.getContentWidth();
// no break if last in area tree, or trailing in context
// area
@@ -359,7 +366,7 @@ public class Block extends FObjMixed {
* Return the content width of the boxes generated by this FO.
*/
public int getContentWidth() {
- return contentWidth; // getAllocationWidth()??
+ return contentWidth; // getAllocationWidth()??
}
@@ -367,26 +374,25 @@ public class Block extends FObjMixed {
return this.span;
}
- public LayoutManager getLayoutManager() {
-BlockLayoutManager blm = new BlockLayoutManager(this);
-TextInfo ti = new TextInfo();
+ public void addLayoutManager(List list) {
+ BlockLayoutManager blm = new BlockLayoutManager(this);
+ TextInfo ti = new TextInfo();
- try {
- ti.fs = propMgr.getFontState(fontInfo);
- } catch (FOPException fopex) {
- log.error("Error setting FontState for characters: " +
- fopex.getMessage());
- }
- ti.lineHeight = this.lineHeight;
+ try {
+ ti.fs = propMgr.getFontState(fontInfo);
+ } catch (FOPException fopex) {
+ log.error("Error setting FontState for characters: " +
+ fopex.getMessage());
+ }
+ ti.lineHeight = this.lineHeight;
- ColorType c = getProperty("color").getColorType();
- ti.color = c;
+ ColorType c = getProperty("color").getColorType();
+ ti.color = c;
- ti.verticalAlign =
- getProperty("vertical-align").getEnum();
+ ti.verticalAlign = getProperty("vertical-align").getEnum();
-blm.setBlockTextInfo(ti);
- return blm;
+ blm.setBlockTextInfo(ti);
+ list.add(blm);
}
public boolean generatesInlineAreas() {
@@ -394,144 +400,142 @@ blm.setBlockTextInfo(ti);
}
public void addChild(FONode child) {
- // Handle whitespace based on values of properties
- // Handle a sequence of inline-producing children in
- // one pass
- if (((FObj)child).generatesInlineAreas()) {
- if (firstInlineChild == null) {
- firstInlineChild = child;
- }
- // lastInlineChild = children.size();
- }
- else {
- // Handle whitespace in preceeding inline areas if any
- handleWhiteSpace();
- }
- super.addChild(child);
+ // Handle whitespace based on values of properties
+ // Handle a sequence of inline-producing children in
+ // one pass
+ if (((FObj) child).generatesInlineAreas()) {
+ if (firstInlineChild == null) {
+ firstInlineChild = child;
+ }
+ // lastInlineChild = children.size();
+ } else {
+ // Handle whitespace in preceeding inline areas if any
+ handleWhiteSpace();
+ }
+ super.addChild(child);
}
public void end() {
- handleWhiteSpace();
+ handleWhiteSpace();
}
private void handleWhiteSpace() {
- log.debug("fo:block: handleWhiteSpace");
- if (firstInlineChild != null) {
- boolean bInWS=false;
- boolean bPrevWasLF=false;
- RecursiveCharIterator charIter =
- new RecursiveCharIterator(this, firstInlineChild);
- LFchecker lfCheck = new LFchecker(charIter);
-
- while (charIter.hasNext()) {
- switch (CharUtilities.classOf(charIter.nextChar())) {
- case CharUtilities.XMLWHITESPACE:
- /* Some kind of whitespace character, except linefeed. */
- boolean bIgnore=false;
-
- switch (wsTreatment) {
- case Constants.IGNORE:
- bIgnore=true;
- break;
- case Constants.IGNORE_IF_BEFORE_LINEFEED:
- bIgnore = lfCheck.nextIsLF();
- break;
- case Constants.IGNORE_IF_SURROUNDING_LINEFEED:
- bIgnore = (bPrevWasLF || lfCheck.nextIsLF());
- break;
- case Constants.IGNORE_IF_AFTER_LINEFEED:
- bIgnore = bPrevWasLF;
- break;
- }
- // Handle ignore
- if (bIgnore) {
- charIter.remove();
- }
- else if (bWScollapse) {
- if (bInWS || (lfTreatment == Constants.PRESERVE &&
- (bPrevWasLF || lfCheck.nextIsLF()))) {
- charIter.remove();
- }
- else {
- bInWS = true;
- }
- }
- break;
-
- case CharUtilities.LINEFEED:
- /* A linefeed */
- lfCheck.reset();
- bPrevWasLF=true; // for following whitespace
-
- switch (lfTreatment) {
- case Constants.IGNORE:
- charIter.remove();
- break;
- case Constants.TREAT_AS_SPACE:
- if (bInWS) {
- // only if bWScollapse=true
- charIter.remove();
- }
- else {
- if (bWScollapse) bInWS=true;
- charIter.replaceChar('\u0020');
- }
- break;
- case Constants.TREAT_AS_ZERO_WIDTH_SPACE:
- charIter.replaceChar('\u200b');
- // Fall through: this isn't XML whitespace
- case Constants.PRESERVE:
- bInWS=false;
- break;
- }
- break;
-
- case CharUtilities.EOT:
- // A "boundary" objects such as non-character inline
- // or nested block object was encountered.
- // If any whitespace run in progress, finish it.
- // FALL THROUGH
-
- case CharUtilities.UCWHITESPACE: // Non XML-whitespace
- case CharUtilities.NONWHITESPACE:
- /* Any other character */
- bInWS = bPrevWasLF=false;
- lfCheck.reset();
- break;
- }
- }
- firstInlineChild = null;
- }
+ log.debug("fo:block: handleWhiteSpace");
+ if (firstInlineChild != null) {
+ boolean bInWS = false;
+ boolean bPrevWasLF = false;
+ RecursiveCharIterator charIter =
+ new RecursiveCharIterator(this, firstInlineChild);
+ LFchecker lfCheck = new LFchecker(charIter);
+
+ while (charIter.hasNext()) {
+ switch (CharUtilities.classOf(charIter.nextChar())) {
+ case CharUtilities.XMLWHITESPACE:
+ /* Some kind of whitespace character, except linefeed. */
+ boolean bIgnore = false;
+
+ switch (wsTreatment) {
+ case Constants.IGNORE:
+ bIgnore = true;
+ break;
+ case Constants.IGNORE_IF_BEFORE_LINEFEED:
+ bIgnore = lfCheck.nextIsLF();
+ break;
+ case Constants.IGNORE_IF_SURROUNDING_LINEFEED:
+ bIgnore = (bPrevWasLF ||
+ lfCheck.nextIsLF());
+ break;
+ case Constants.IGNORE_IF_AFTER_LINEFEED:
+ bIgnore = bPrevWasLF;
+ break;
+ }
+ // Handle ignore
+ if (bIgnore) {
+ charIter.remove();
+ } else if (bWScollapse) {
+ if (bInWS || (lfTreatment ==
+ Constants.PRESERVE &&
+ (bPrevWasLF || lfCheck.nextIsLF()))) {
+ charIter.remove();
+ } else {
+ bInWS = true;
+ }
+ }
+ break;
+
+ case CharUtilities.LINEFEED:
+ /* A linefeed */
+ lfCheck.reset();
+ bPrevWasLF = true; // for following whitespace
+
+ switch (lfTreatment) {
+ case Constants.IGNORE:
+ charIter.remove();
+ break;
+ case Constants.TREAT_AS_SPACE:
+ if (bInWS) {
+ // only if bWScollapse=true
+ charIter.remove();
+ } else {
+ if (bWScollapse)
+ bInWS = true;
+ charIter.replaceChar('\u0020');
+ }
+ break;
+ case Constants.TREAT_AS_ZERO_WIDTH_SPACE:
+ charIter.replaceChar('\u200b');
+ // Fall through: this isn't XML whitespace
+ case Constants.PRESERVE:
+ bInWS = false;
+ break;
+ }
+ break;
+
+ case CharUtilities.EOT:
+ // A "boundary" objects such as non-character inline
+ // or nested block object was encountered.
+ // If any whitespace run in progress, finish it.
+ // FALL THROUGH
+
+ case CharUtilities.UCWHITESPACE: // Non XML-whitespace
+ case CharUtilities.NONWHITESPACE:
+ /* Any other character */
+ bInWS = bPrevWasLF = false;
+ lfCheck.reset();
+ break;
+ }
+ }
+ firstInlineChild = null;
+ }
}
private static class LFchecker {
- private boolean bNextIsLF=false;
- private RecursiveCharIterator charIter;
-
- LFchecker(RecursiveCharIterator charIter) {
- this.charIter = charIter;
- }
-
- boolean nextIsLF() {
- if (bNextIsLF==false) {
- CharIterator lfIter = charIter.mark();
- while (lfIter.hasNext()) {
- char c = lfIter.nextChar();
- if (c == '\n') {
- bNextIsLF=true;
- break;
- }
- else if (CharUtilities.classOf(c) !=
- CharUtilities.XMLWHITESPACE) {
- break;
- }
- }
- }
- return bNextIsLF;
- }
-
- void reset() {
- bNextIsLF=false;
- }
+ private boolean bNextIsLF = false;
+ private RecursiveCharIterator charIter;
+
+ LFchecker(RecursiveCharIterator charIter) {
+ this.charIter = charIter;
+ }
+
+ boolean nextIsLF() {
+ if (bNextIsLF == false) {
+ CharIterator lfIter = charIter.mark();
+ while (lfIter.hasNext()) {
+ char c = lfIter.nextChar();
+ if (c == '\n') {
+ bNextIsLF = true;
+ break;
+ } else if (CharUtilities.classOf(c) !=
+ CharUtilities.XMLWHITESPACE) {
+ break;
+ }
+ }
+ }
+ return bNextIsLF;
+ }
+
+ void reset() {
+ bNextIsLF = false;
+ }
}
}
diff --git a/src/org/apache/fop/fo/flow/Character.java b/src/org/apache/fop/fo/flow/Character.java
index 9f22c7c30..17243d949 100644
--- a/src/org/apache/fop/fo/flow/Character.java
+++ b/src/org/apache/fop/fo/flow/Character.java
@@ -24,6 +24,7 @@ import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafNodeLayoutManager;
+import java.util.List;
/**
* this class represents the flow object 'fo:character'. Its use is defined by
@@ -48,13 +49,23 @@ public class Character extends FObj {
super(parent);
}
- public LayoutManager getLayoutManager() {
- LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this);
- lm.setCurrentArea(getInlineArea());
- return lm;
+ public void addLayoutManager(List list) {
+ InlineArea inline = getInlineArea();
+ if (inline != null) {
+ LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this);
+ lm.setCurrentArea(inline);
+ list.add(lm);
+ }
}
protected InlineArea getInlineArea() {
+ String str = this.properties.get("character").getString();
+ if (str.length() == 1) {
+ org.apache.fop.area.inline.Character ch =
+ new org.apache.fop.area.inline.Character(
+ str.charAt(0));
+ return ch;
+ }
return null;
}
@@ -77,7 +88,8 @@ public class Character extends FObj {
MarginInlineProps mProps = propMgr.getMarginInlineProps();
// Common Relative Position Properties
- RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
+ RelativePositionProps mRelProps =
+ propMgr.getRelativePositionProps();
// this.properties.get("alignment-adjust");
// this.properties.get("treat-as-word-space");
@@ -105,8 +117,8 @@ public class Character extends FObj {
}
public CharIterator charIterator() {
- return new OneCharIterator(characterValue);
- // But what it the character is ignored due to white space handling?
+ return new OneCharIterator(characterValue);
+ // But what it the character is ignored due to white space handling?
}
diff --git a/src/org/apache/fop/fo/flow/ExternalGraphic.java b/src/org/apache/fop/fo/flow/ExternalGraphic.java
index 1183afdea..96689b8c4 100644
--- a/src/org/apache/fop/fo/flow/ExternalGraphic.java
+++ b/src/org/apache/fop/fo/flow/ExternalGraphic.java
@@ -22,6 +22,7 @@ import org.apache.fop.area.inline.Viewport;
// Java
import java.net.URL;
import java.net.MalformedURLException;
+import java.util.List;
public class ExternalGraphic extends FObj {
String url;
@@ -41,10 +42,10 @@ public class ExternalGraphic extends FObj {
super(parent);
}
- public LayoutManager getLayoutManager() {
+ public void addLayoutManager(List list) {
LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this);
lm.setCurrentArea(getInlineArea());
- return lm;
+ list.add(lm);
}
protected InlineArea getInlineArea() {
diff --git a/src/org/apache/fop/fo/flow/Flow.java b/src/org/apache/fop/fo/flow/Flow.java
index f0828f426..bdeb21db8 100644
--- a/src/org/apache/fop/fo/flow/Flow.java
+++ b/src/org/apache/fop/fo/flow/Flow.java
@@ -19,6 +19,7 @@ import org.apache.fop.layoutmgr.FlowLayoutManager;
// Java
import java.util.ArrayList;
+import java.util.List;
import org.xml.sax.Attributes;
@@ -59,36 +60,35 @@ public class Flow extends FObj {
public void handleAttrs(Attributes attlist) throws FOPException {
super.handleAttrs(attlist);
if (parent.getName().equals("fo:page-sequence")) {
- this.pageSequence = (PageSequence)parent;
+ this.pageSequence = (PageSequence) parent;
} else {
- throw new FOPException("flow must be child of "
- + "page-sequence, not "
- + parent.getName());
+ throw new FOPException("flow must be child of " +
+ "page-sequence, not " + parent.getName());
}
// according to communication from Paul Grosso (XSL-List,
// 001228, Number 406), confusion in spec section 6.4.5 about
// multiplicity of fo:flow in XSL 1.0 is cleared up - one (1)
// fo:flow per fo:page-sequence only.
-/* if (pageSequence.isFlowSet()) {
- if (this.name.equals("fo:flow")) {
- throw new FOPException("Only a single fo:flow permitted"
- + " per fo:page-sequence");
- } else {
- throw new FOPException(this.name
- + " not allowed after fo:flow");
- }
- }
-*/
+ /* if (pageSequence.isFlowSet()) {
+ if (this.name.equals("fo:flow")) {
+ throw new FOPException("Only a single fo:flow permitted"
+ + " per fo:page-sequence");
+ } else {
+ throw new FOPException(this.name
+ + " not allowed after fo:flow");
+ }
+ }
+ */
setFlowName(getProperty("flow-name").getString());
- // Now done in addChild of page-sequence
+ // Now done in addChild of page-sequence
//pageSequence.addFlow(this);
}
protected void setFlowName(String name) throws FOPException {
if (name == null || name.equals("")) {
- throw new FOPException("A 'flow-name' is required for "
- + getName());
+ throw new FOPException("A 'flow-name' is required for " +
+ getName());
} else {
_flowName = name;
}
@@ -109,7 +109,7 @@ public class Flow extends FObj {
}
// flow is *always* laid out into a BodyAreaContainer
- BodyAreaContainer bac = (BodyAreaContainer)area;
+ BodyAreaContainer bac = (BodyAreaContainer) area;
boolean prevChildMustKeepWithNext = false;
ArrayList pageMarker = this.getMarkerSnapshot(new ArrayList());
@@ -119,7 +119,7 @@ public class Flow extends FObj {
throw new FOPException("fo:flow must contain block-level children");
}
for (int i = this.marker; i < numChildren; i++) {
- FObj fo = (FObj)children.get(i);
+ FObj fo = (FObj) children.get(i);
if (bac.isBalancingRequired(fo)) {
// reset the the just-done span area in preparation
@@ -139,8 +139,8 @@ public class Flow extends FObj {
this.marker = i;
markerSnapshot = this.getMarkerSnapshot(new ArrayList());
}
- // Set current content width for percent-based lengths in children
- setContentWidth(currentArea.getContentWidth());
+ // Set current content width for percent-based lengths in children
+ setContentWidth(currentArea.getContentWidth());
_status = fo.layout(currentArea);
@@ -155,9 +155,10 @@ public class Flow extends FObj {
* }
*/
if (_status.isIncomplete()) {
- if ((prevChildMustKeepWithNext) && (_status.laidOutNone())) {
+ if ((prevChildMustKeepWithNext) &&
+ (_status.laidOutNone())) {
this.marker = i - 1;
- FObj prevChild = (FObj)children.get(this.marker);
+ FObj prevChild = (FObj) children.get(this.marker);
prevChild.removeAreas();
prevChild.resetMarker();
prevChild.removeID(area.getIDReferences());
@@ -169,8 +170,8 @@ public class Flow extends FObj {
if (bac.isLastColumn())
if (_status.getCode() == Status.FORCE_COLUMN_BREAK) {
this.marker = i;
- _status =
- new Status(Status.FORCE_PAGE_BREAK); // same thing
+ _status = new Status(Status.FORCE_PAGE_BREAK);
+ // same thing
return _status;
} else {
this.marker = i;
@@ -183,7 +184,8 @@ public class Flow extends FObj {
return _status;
}
// I don't much like exposing this. (AHS 001217)
- ((org.apache.fop.layout.ColumnArea)currentArea).incrementSpanIndex();
+ ((org.apache.fop.layout.ColumnArea) currentArea).
+ incrementSpanIndex();
i--;
}
}
@@ -197,14 +199,14 @@ public class Flow extends FObj {
}
protected void setContentWidth(int contentWidth) {
- this.contentWidth = contentWidth;
+ this.contentWidth = contentWidth;
}
/**
* Return the content width of this flow (really of the region
* in which it is flowing).
*/
public int getContentWidth() {
- return this.contentWidth;
+ return this.contentWidth;
}
public Status getStatus() {
@@ -215,8 +217,8 @@ public class Flow extends FObj {
return true;
}
- public LayoutManager getLayoutManager() {
- return new FlowLayoutManager(this);
+ public void addLayoutManager(List list) {
+ list.add(new FlowLayoutManager(this));
}
}
diff --git a/src/org/apache/fop/fo/flow/Footnote.java b/src/org/apache/fop/fo/flow/Footnote.java
index 0374e0400..103e6665c 100644
--- a/src/org/apache/fop/fo/flow/Footnote.java
+++ b/src/org/apache/fop/fo/flow/Footnote.java
@@ -12,6 +12,11 @@ import org.apache.fop.fo.*;
import org.apache.fop.layout.*;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.properties.*;
+import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.layoutmgr.LayoutManager;
+import org.apache.fop.layoutmgr.LeafNodeLayoutManager;
+
+import java.util.List;
// Java
import java.util.ArrayList;
@@ -22,6 +27,13 @@ public class Footnote extends FObj {
super(parent);
}
+ public void addLayoutManager(List lms) {
+ // add inlines layout manager
+ //inline.addLayoutManager(lms);
+ // set start and end footnote reference
+ }
+
+
public Status layout(Area area) throws FOPException {
FONode inline = null;
FONode fbody = null;
diff --git a/src/org/apache/fop/fo/flow/Inline.java b/src/org/apache/fop/fo/flow/Inline.java
index c6f78e8d0..c25104ac3 100644
--- a/src/org/apache/fop/fo/flow/Inline.java
+++ b/src/org/apache/fop/fo/flow/Inline.java
@@ -89,7 +89,7 @@ public class Inline extends FObjMixed {
public CharIterator charIterator() {
- return new InlineCharIterator(this, propMgr.getBorderAndPadding());
+ return new InlineCharIterator(this, propMgr.getBorderAndPadding());
}
}
diff --git a/src/org/apache/fop/fo/flow/InlineContainer.java b/src/org/apache/fop/fo/flow/InlineContainer.java
index 78bbbce04..d3a46f016 100644
--- a/src/org/apache/fop/fo/flow/InlineContainer.java
+++ b/src/org/apache/fop/fo/flow/InlineContainer.java
@@ -13,17 +13,28 @@ import org.apache.fop.fo.flow.*;
import org.apache.fop.fo.properties.*;
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.xml.sax.Attributes;
+import java.util.List;
+import java.util.ArrayList;
+
/**
*/
-public class InlineContainer extends ToBeImplementedElement {
+public class InlineContainer extends FObj {
public InlineContainer(FONode parent) {
super(parent);
}
+ public void addLayoutManager(List lms) {
+ ArrayList childList = new ArrayList();
+ super.addLayoutManager(childList);
+ lms.add(new ICLayoutManager(this, childList));
+ }
+
public void handleAttrs(Attributes attlist) throws FOPException {
super.handleAttrs(attlist);
// Common Border, Padding, and Background Properties
@@ -34,7 +45,8 @@ public class InlineContainer extends ToBeImplementedElement {
MarginInlineProps mProps = propMgr.getMarginInlineProps();
// Common Relative Position Properties
- RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
+ RelativePositionProps mRelProps =
+ propMgr.getRelativePositionProps();
// this.properties.get("alignment-adjust");
// this.properties.get("alignment-baseline");
@@ -57,4 +69,21 @@ public class InlineContainer extends ToBeImplementedElement {
// this.properties.get("writing-mode");
}
+ /**
+ * This creates a single inline container area after
+ * laying out the child block areas. All footnotes, floats
+ * and id areas are maintained for later retrieval.
+ */
+ class ICLayoutManager extends LeafNodeLayoutManager {
+ List childrenLM;
+
+ ICLayoutManager(FObj obj, List childLM) {
+ super(obj);
+ childrenLM = childLM;
+ }
+
+ public InlineArea get(int index) {
+ return null;
+ }
+ }
}
diff --git a/src/org/apache/fop/fo/flow/InstreamForeignObject.java b/src/org/apache/fop/fo/flow/InstreamForeignObject.java
index 9dc8682b6..df30fccaf 100644
--- a/src/org/apache/fop/fo/flow/InstreamForeignObject.java
+++ b/src/org/apache/fop/fo/flow/InstreamForeignObject.java
@@ -29,6 +29,7 @@ import org.apache.fop.layoutmgr.LayoutInfo;
import org.w3c.dom.Document;
import java.awt.geom.Point2D;
+import java.util.List;
public class InstreamForeignObject extends FObj {
@@ -60,10 +61,10 @@ public class InstreamForeignObject extends FObj {
super(parent);
}
- public LayoutManager getLayoutManager() {
+ public void addLayoutManager(List list) {
LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this);
lm.setCurrentArea(getInlineArea());
- return lm;
+ list.add(lm);
}
/**
@@ -144,6 +145,10 @@ public class InstreamForeignObject extends FObj {
return areaCurrent;
}
+ public boolean generatesInlineAreas() {
+ return true;
+ }
+
/**
* layout this formatting object.
*
diff --git a/src/org/apache/fop/fo/flow/Leader.java b/src/org/apache/fop/fo/flow/Leader.java
index 7089ce78a..92cbf999a 100644
--- a/src/org/apache/fop/fo/flow/Leader.java
+++ b/src/org/apache/fop/fo/flow/Leader.java
@@ -20,6 +20,9 @@ import org.apache.fop.layout.FontState;
import org.apache.fop.apps.FOPException;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafNodeLayoutManager;
+import org.apache.fop.area.MinOptMax;
+
+import java.util.List;
/**
* Implements fo:leader; main property of leader leader-pattern.
@@ -32,14 +35,22 @@ public class Leader extends FObjMixed {
super(parent);
}
- public LayoutManager getLayoutManager() {
- LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this);
- lm.setCurrentArea(getInlineArea());
- return lm;
+ public void addLayoutManager(List list) {
+ list.add(new LeafNodeLayoutManager(this) {
+ public InlineArea get(int index) {
+ if(index > 0)
+ return null;
+ int contentIPD = parentLM.getContentIPD();
+ return getInlineArea(contentIPD);
+ }
+ });
}
- protected InlineArea getInlineArea() {
- return null;
+ protected InlineArea getInlineArea(int maxIPD) {
+ org.apache.fop.area.inline.Leader leader = new org.apache.fop.area.inline.Leader();
+ leader.setWidth(maxIPD / 2);
+ leader.setAllocationIPD(new MinOptMax(0, maxIPD / 2, maxIPD));
+ return leader;
}
public Status layout(Area area) throws FOPException {
diff --git a/src/org/apache/fop/fo/flow/PageNumber.java b/src/org/apache/fop/fo/flow/PageNumber.java
index b1eb6a696..a1dfb10ce 100644
--- a/src/org/apache/fop/fo/flow/PageNumber.java
+++ b/src/org/apache/fop/fo/flow/PageNumber.java
@@ -15,8 +15,12 @@ import org.apache.fop.fo.properties.*;
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.inline.Word;
+
// Java
-import java.util.Enumeration;
+import java.util.List;
public class PageNumber extends FObj {
@@ -31,6 +35,24 @@ public class PageNumber extends FObj {
super(parent);
}
+ public void addLayoutManager(List lms) {
+ lms.add(new LeafNodeLayoutManager(this) {
+ public InlineArea get(int index) {
+ if(index > 0)
+ return null;
+ // get page string from parent, build area
+ Word inline = new Word();
+ //String parentLM.getCurrentPageNumber();
+ inline.setWord("01");
+ return inline;
+ }
+
+ public boolean resolved() {
+ return true;
+ }
+ });
+ }
+
public Status layout(Area area) throws FOPException {
if (!(area instanceof BlockArea)) {
log.warn("page-number outside block area");
diff --git a/src/org/apache/fop/fo/flow/PageNumberCitation.java b/src/org/apache/fop/fo/flow/PageNumberCitation.java
index af9d1eeaf..0c705a8af 100644
--- a/src/org/apache/fop/fo/flow/PageNumberCitation.java
+++ b/src/org/apache/fop/fo/flow/PageNumberCitation.java
@@ -14,7 +14,11 @@ import org.apache.fop.datatypes.*;
import org.apache.fop.fo.properties.*;
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 java.util.List;
+import java.util.ArrayList;
/**
* 6.6.11 fo:page-number-citation
@@ -88,6 +92,18 @@ public class PageNumberCitation extends FObj {
super(parent);
}
+ public void addLayoutManager(List lms) {
+ LeafNodeLayoutManager lnlm = new LeafNodeLayoutManager(this);
+ lnlm.setCurrentArea(getInlineArea());
+ lms.add(lnlm);
+ }
+
+ // is id can be resolved then simply return a word, otherwise
+ // return a resolveable area
+ private InlineArea getInlineArea() {
+ return null;
+ }
+
public Status layout(Area area) throws FOPException {
if (!(area instanceof BlockArea)) {
log.warn("page-number-citation outside block area");
@@ -98,37 +114,38 @@ public class PageNumberCitation extends FObj {
this.area = area;
if (this.marker == START) {
- // Common Accessibility Properties
+ // Common Accessibility Properties
AccessibilityProps mAccProps = propMgr.getAccessibilityProps();
- // Common Aural Properties
- AuralProps mAurProps = propMgr.getAuralProps();
+ // Common Aural Properties
+ AuralProps mAurProps = propMgr.getAuralProps();
- // Common Border, Padding, and Background Properties
- BorderAndPadding bap = propMgr.getBorderAndPadding();
- BackgroundProps bProps = propMgr.getBackgroundProps();
+ // Common Border, Padding, and Background Properties
+ BorderAndPadding bap = propMgr.getBorderAndPadding();
+ BackgroundProps bProps = propMgr.getBackgroundProps();
- // Common Font Properties
- //this.fontState = propMgr.getFontState(area.getFontInfo());
+ // Common Font Properties
+ //this.fontState = propMgr.getFontState(area.getFontInfo());
- // Common Margin Properties-Inline
- MarginInlineProps mProps = propMgr.getMarginInlineProps();
+ // Common Margin Properties-Inline
+ MarginInlineProps mProps = propMgr.getMarginInlineProps();
- // Common Relative Position Properties
- RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
+ // Common Relative Position Properties
+ RelativePositionProps mRelProps =
+ propMgr.getRelativePositionProps();
- // this.properties.get("alignment-adjust");
- // this.properties.get("alignment-baseline");
- // this.properties.get("baseline-shift");
- // this.properties.get("dominant-baseline");
- // this.properties.get("id");
- // this.properties.get("keep-with-next");
+ // this.properties.get("alignment-adjust");
+ // this.properties.get("alignment-baseline");
+ // this.properties.get("baseline-shift");
+ // this.properties.get("dominant-baseline");
+ // this.properties.get("id");
+ // this.properties.get("keep-with-next");
// this.properties.get("keep-with-previous");
// this.properties.get("letter-spacing");
// this.properties.get("line-height");
- // this.properties.get("line-height-shift-adjustment");
- // this.properties.get("ref-id");
- // this.properties.get("score-spaces");
+ // this.properties.get("line-height-shift-adjustment");
+ // this.properties.get("ref-id");
+ // this.properties.get("score-spaces");
// this.properties.get("text-decoration");
// this.properties.get("text-shadow");
// this.properties.get("text-transform");
@@ -141,7 +158,7 @@ public class PageNumberCitation extends FObj {
this.wrapOption = this.properties.get("wrap-option").getEnum();
this.whiteSpaceCollapse =
- this.properties.get("white-space-collapse").getEnum();
+ this.properties.get("white-space-collapse").getEnum();
this.refId = this.properties.get("ref-id").getString();
@@ -164,16 +181,14 @@ public class PageNumberCitation extends FObj {
pageNumber = idReferences.getPageNumber(refId);
- if (pageNumber != null) { // if we already know the page number
- this.marker =
- FOText.addText((BlockArea)area,
- propMgr.getFontState(area.getFontInfo()), red,
- green, blue, wrapOption, null,
- whiteSpaceCollapse, pageNumber.toCharArray(),
- 0, pageNumber.length(), ts,
- VerticalAlign.BASELINE);
- } else { // add pageNumberCitation to area to be resolved during rendering
- BlockArea blockArea = (BlockArea)area;
+ if (pageNumber != null) { // if we already know the page number
+ this.marker = FOText.addText((BlockArea) area,
+ propMgr.getFontState(area.getFontInfo()), red,
+ green, blue, wrapOption, null, whiteSpaceCollapse,
+ pageNumber.toCharArray(), 0, pageNumber.length(),
+ ts, VerticalAlign.BASELINE);
+ } else { // add pageNumberCitation to area to be resolved during rendering
+ BlockArea blockArea = (BlockArea) area;
LineArea la = blockArea.getCurrentLineArea();
if (la == null) {
return new Status(Status.AREA_FULL_NONE);
diff --git a/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java
index df6d58a45..50d4b643a 100644
--- a/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java
@@ -12,6 +12,7 @@ import org.apache.fop.fo.FONode;
import org.apache.fop.area.Area;
import java.util.ListIterator;
+import java.util.ArrayList;
/**
* The base class for all LayoutManagers.
@@ -20,6 +21,12 @@ public abstract class AbstractLayoutManager implements LayoutManager {
protected LayoutManager parentLM;
protected FObj fobj;
+ protected LayoutPos curPos = new LayoutPos();
+
+ static class LayoutPos {
+ int lmIndex = 0;
+ int subIndex = 0;
+ }
public AbstractLayoutManager(FObj fobj) {
this.fobj = fobj;
@@ -39,19 +46,27 @@ public abstract class AbstractLayoutManager implements LayoutManager {
* children of its FO, asks each for its LayoutManager and calls
* its generateAreas method.
*/
- public void generateAreas() {
- ListIterator children = fobj.getChildren();
- while (children.hasNext()) {
- FONode node = (FONode) children.next();
- if (node instanceof FObj) {
- LayoutManager lm = ((FObj) node).getLayoutManager();
- if (lm != null) {
- lm.setParentLM(this);
- lm.generateAreas();
+ public boolean generateAreas() {
+ ArrayList lms = new ArrayList();
+ if (fobj != null) {
+ ListIterator children = fobj.getChildren();
+ while (children.hasNext()) {
+ FONode node = (FONode) children.next();
+ if (node instanceof FObj) {
+ ((FObj) node).addLayoutManager(lms);
}
}
+ fobj = null;
+ }
+
+ for (int count = 0; count < lms.size(); count++) {
+ LayoutManager lm = (LayoutManager) lms.get(count);
+ lm.setParentLM(this);
+ if (lm.generateAreas()) {
+ break;
+ }
}
- flush(); // Add last area to parent
+ return flush(); // Add last area to parent
}
// /**
@@ -77,7 +92,7 @@ public abstract class AbstractLayoutManager implements LayoutManager {
/**
* Force current area to be added to parent area.
*/
- abstract protected void flush();
+ abstract protected boolean flush();
/**
@@ -93,18 +108,16 @@ public abstract class AbstractLayoutManager implements LayoutManager {
abstract public Area getParentArea(Area childArea);
-
- // public boolean generatesInlineAreas() {
- // return false;
- // }
-
+ public boolean generatesInlineAreas() {
+ return false;
+ }
/**
* Add a child area to the current area. If this causes the maximum
* dimension of the current area to be exceeded, the parent LM is called
* to add it.
*/
- abstract public void addChild(Area childArea);
+ abstract public boolean addChild(Area childArea);
/** Do nothing */
public boolean splitArea(Area areaToSplit, SplitContext context) {
diff --git a/src/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/org/apache/fop/layoutmgr/BlockLayoutManager.java
index 94993b722..b1c537e85 100644
--- a/src/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -13,8 +13,10 @@ import org.apache.fop.area.Area;
import org.apache.fop.area.BlockParent;
import org.apache.fop.area.Block;
import org.apache.fop.area.LineArea;
+import org.apache.fop.area.MinOptMax;
import java.util.ListIterator;
+import java.util.ArrayList;
/**
* LayoutManager for a block FO.
@@ -45,7 +47,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
*/
public int getContentIPD() {
// adjust for side floats and indents
- //getParentArea(null); // make if not existing
+ getParentArea(null); // make if not existing
return curBlockArea.getIPD();
}
@@ -53,23 +55,46 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
* Generate areas by tellings all layout managers for its FO's
* children to generate areas.
*/
- public void generateAreas() {
- ListIterator children = fobj.getChildren();
+ public boolean generateAreas() {
+ ArrayList lms = new ArrayList();
LayoutManager lm = null;
- while (children.hasNext()) {
- FObj childFO = (FObj) children.next();
- if (childFO.generatesInlineAreas()) {
- children.previous();
- lm = new LineLayoutManager(children, lineHeight, lead, follow);
- } else {
- lm = childFO.getLayoutManager();
+
+ if (fobj != null) {
+ ListIterator children = fobj.getChildren();
+ while (children.hasNext()) {
+ FObj childFO = (FObj) children.next();
+ childFO.addLayoutManager(lms);
+ }
+ fobj = null;
+ }
+
+ for (int count = 0; count < lms.size(); count++) {
+ lm = (LayoutManager) lms.get(count);
+ if (lm.generatesInlineAreas()) {
+ ArrayList inlines = new ArrayList();
+ inlines.add(lm);
+ //lms.remove(count);
+ while (count + 1 < lms.size()) {
+ lm = (LayoutManager) lms.get(count + 1);
+ if (lm.generatesInlineAreas()) {
+ inlines.add(lm);
+ lms.remove(count + 1);
+ } else {
+ break;
+ }
+ }
+ lm = new LineLayoutManager(inlines, lineHeight, lead,
+ follow);
+ lms.set(count, lm);
}
- if (lm != null) {
- lm.setParentLM(this);
- lm.generateAreas();
+ lm.setParentLM(this);
+ if (lm.generateAreas()) {
+ if (flush()) {
+ return true;
+ }
}
}
- flush(); // Add last area to parent
+ return flush(); // Add last area to parent
}
@@ -98,16 +123,28 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
}
- public void addChild(Area childArea) {
+ public boolean addChild(Area childArea) {
if (curBlockArea != null) {
if (childArea instanceof LineArea) {
// Something about widows and orphans
// Position the line area and calculate size...
curBlockArea.addLineArea((LineArea) childArea);
+
+ MinOptMax targetDim = parentArea.getAvailBPD();
+ MinOptMax currentDim = curBlockArea.getContentBPD();
+ //if(currentDim.min > targetDim.max) {
+ // return true;
+ //}
+
+ return false;
} else {
- super.addChild(childArea);
+ curBlockArea.addBlock((Block) childArea);
+ //return super.addChild(childArea);
+
+ return false;
}
}
+ return false;
}
diff --git a/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 423af36d3..52156eca4 100644
--- a/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -30,12 +30,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
super(fobj);
}
-
-
public boolean splitArea(Area area, SplitContext splitContext) {
// Divide area so that it will be within targetLength if possible
// If not, it can be shorter, but not longer.
- /* Iterate over contents of the area. */
+ /* Iterate over contents of the area. *
// Need to figure out if we can do this generically
// Logically a BlockStacking LM only handles Block-type areas
@@ -66,13 +64,13 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
/* Split 'area', placing all children after
* minBreakCost.getArea() into a new area,
* which we store in the splitContext.
- */
+ *
// splitContext.nextArea = area.splitAfter(minBreakCost.getArea());
} else {
/* This area will be shorter than the desired minimum.
* Split before the current childArea (which will be
* the first area in the newly created Area.
- */
+ *
//splitContext.nextArea = area.splitBefore(childArea);
}
} else
@@ -94,7 +92,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
}
// True if some part of area can be placed, false if none is placed
return (splitContext.nextArea != area);
-
+ */
+ return false;
}
private BreakCost evaluateBreakCost(Area parent, Area child) {
@@ -136,11 +135,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
* @param childArea the area to add: will be some block-stacked Area.
* @param parentArea the area in which to add the childArea
*/
- protected void addChildToArea(Area childArea, BlockParent parentArea) {
+ protected boolean addChildToArea(Area childArea, BlockParent parentArea) {
// This should be a block-level Area (Block in the generic sense)
if (!(childArea instanceof Block)) {
System.err.println("Child not a Block in BlockStackingLM!");
- return;
+ return false;
}
// See if the whole thing fits, including space before
@@ -151,23 +150,28 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
if (targetDim.max >= childArea.getAllocationBPD().min) {
//parentArea.addBlock(new InterBlockSpace(spaceBefore));
parentArea.addBlock((Block) childArea);
- return;
+ return false;
} else {
+ parentArea.addBlock((Block) childArea);
+ flush(); // hand off current area to parent
// Probably need something like max BPD so we don't get into
// infinite loops with large unbreakable chunks
- SplitContext splitContext = new SplitContext(targetDim);
+ //SplitContext splitContext = new SplitContext(targetDim);
- LayoutManager childLM =
+ /*LayoutManager childLM =
childArea.getGeneratingFObj(). getLayoutManager();
if (childLM.splitArea(childArea, splitContext)) {
//parentArea.addBlock(new InterBlockSpace(spaceBefore));
parentArea.addBlock((Block) childArea);
- }
- flush(); // hand off current area to parent
- getParentArea(splitContext.nextArea);
+ }*/
+ //flush(); // hand off current area to parent
+ //getParentArea(splitContext.nextArea);
+ //getParentArea(childArea);
// Check that reference IPD hasn't changed!!!
// If it has, we must "reflow" the content
- addChild(splitContext.nextArea);
+ //addChild(splitContext.nextArea);
+ //addChild(childArea);
+ return true;
}
}
@@ -180,17 +184,18 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
* If so, add it. Otherwise initiate breaking.
* @param childArea the area to add: will be some block-stacked Area.
*/
- public void addChild(Area childArea) {
- addChildToArea(childArea, getCurrentArea());
+ public boolean addChild(Area childArea) {
+ return addChildToArea(childArea, getCurrentArea());
}
/**
* Force current area to be added to parent area.
*/
- protected void flush() {
+ protected boolean flush() {
if (getCurrentArea() != null)
- parentLM.addChild(getCurrentArea());
+ return parentLM.addChild(getCurrentArea());
+ return false;
}
-
}
+
diff --git a/src/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/org/apache/fop/layoutmgr/FlowLayoutManager.java
index 9c9a05a56..9bdd93abe 100644
--- a/src/org/apache/fop/layoutmgr/FlowLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/FlowLayoutManager.java
@@ -38,8 +38,8 @@ public class FlowLayoutManager extends BlockStackingLayoutManager {
* area class. A Flow can fill at most one area container of any class
* at any one time. The actual work is done by BlockStackingLM.
*/
- public void addChild(Area childArea) {
- addChildToArea(childArea,
+ public boolean addChild(Area childArea) {
+ return addChildToArea(childArea,
this.currentAreas[childArea.getAreaClass()]);
}
diff --git a/src/org/apache/fop/layoutmgr/LayoutInfo.java b/src/org/apache/fop/layoutmgr/LayoutInfo.java
index 0c6e0f6aa..b9187aa3b 100644
--- a/src/org/apache/fop/layoutmgr/LayoutInfo.java
+++ b/src/org/apache/fop/layoutmgr/LayoutInfo.java
@@ -14,6 +14,11 @@ public class LayoutInfo {
public int alignment;
public int lead;
public boolean blOffset = false;
+ public boolean breakAfter = false;
+
+ public boolean keepNext = false;
+ public boolean keepPrev = false;
+ public boolean isText = false;
public LayoutInfo() {
}
diff --git a/src/org/apache/fop/layoutmgr/LayoutManager.java b/src/org/apache/fop/layoutmgr/LayoutManager.java
index 4d3878b99..15763ec0b 100644
--- a/src/org/apache/fop/layoutmgr/LayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/LayoutManager.java
@@ -14,10 +14,10 @@ import org.apache.fop.area.Area;
* The interface for all LayoutManagers.
*/
public interface LayoutManager {
- public void generateAreas();
- //public boolean generatesInlineAreas();
+ public boolean generateAreas();
+ public boolean generatesInlineAreas();
public Area getParentArea (Area childArea);
- public void addChild (Area childArea);
+ public boolean addChild (Area childArea);
public boolean splitArea(Area areaToSplit, SplitContext context);
public void setParentLM(LayoutManager lm);
public int getContentIPD();
diff --git a/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java b/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java
index 1bd8e9095..c97f85855 100644
--- a/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java
@@ -19,29 +19,46 @@ import org.apache.fop.area.inline.InlineArea;
*/
public class LeafNodeLayoutManager extends AbstractLayoutManager {
- private InlineArea curArea;
+ private InlineArea curArea = null;
public LeafNodeLayoutManager(FObj fobj) {
super(fobj);
}
+ public int size() {
+ return 1;
+ }
+
+ public InlineArea get(int index) {
+ if(index > 0)
+ return null;
+ return curArea;
+ }
+
+ public boolean generatesInlineAreas() {
+ return true;
+ }
+
+ public boolean resolved() {
+ return false;
+ }
public void setCurrentArea(InlineArea ia) {
curArea = ia;
}
- public void generateAreas() {
- flush();
+ public boolean generateAreas() {
+ return flush();
}
- protected void flush() {
- parentLM.addChild(curArea);
+ protected boolean flush() {
+ return false;
}
/**
* This is a leaf-node, so this method is never called.
*/
- public void addChild(Area childArea) {}
+ public boolean addChild(Area childArea) {return false;}
/**
diff --git a/src/org/apache/fop/layoutmgr/LineLayoutManager.java b/src/org/apache/fop/layoutmgr/LineLayoutManager.java
index b3b863a41..fdf6cc60b 100644
--- a/src/org/apache/fop/layoutmgr/LineLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/LineLayoutManager.java
@@ -16,150 +16,342 @@ import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.fo.properties.VerticalAlign;
import org.apache.fop.area.inline.Word;
+import org.apache.fop.area.inline.Space;
import org.apache.fop.area.inline.Character;
import java.util.ListIterator;
import java.util.List;
+import java.util.ArrayList;
import java.util.Iterator;
/**
* LayoutManager for lines. It builds one or more lines containing
* inline areas generated by its sub layout managers.
+ *
+ * The line layout manager does the following things:
+ * receives a list of inline creating layout managers
+ * adds the inline areas retrieved from the child layout managers
+ * finds the best line break position
+ * adds complete line to parent
+ * stores the starting position for each line in case of recreation
+ * if ipd not changed but line contains resolved values (eg. page number), redoes from that line
+ * when freeing memory, release all layout managers and inline areas before current position
+ * As each child layout manager is used it gets the start, end and normal references for id area, footnotes, floats, links, colour-back properties
+ * first line properties are set and used by the child when retrieving the inline area(s)
+ *
+ * Hyphenation is handled by asking the child to split the words then this
+ * adds the hyph char. If redone then exra char ignored.
+ *
+ * How do we handle Unicode BIDI?
*/
public class LineLayoutManager extends AbstractLayoutManager {
- /** Reference to FO whose areas it's managing or to the traits
- * of the FO.
- */
- private ListIterator fobjIter;
- private LineArea lineArea = null;
- private boolean bFirstLine;
- private LayoutManager curLM;
- private MinOptMax remainingIPD;
+ private LineInfo currentLine = null;
+ private boolean bFirstLine = true;
+ private MinOptMax totalIPD;
// the following values must be set by the block
// these are the dominant basline and lineheight values
private int lineHeight;
private int lead;
private int follow;
- public LineLayoutManager(ListIterator fobjIter, int lh, int l, int f) {
+ List lmList;
+ List lines = new ArrayList();
+
+ private LayoutPos bestPos = null;
+ private MinOptMax bestIPD = null;
+
+ static class LineInfo {
+ LayoutPos startPos;
+ LineArea area;
+ boolean hasResolved = false;
+ boolean noJustify = false;
+ // footnotes, floats?
+ }
+
+ public LineLayoutManager(List lms, int lh, int l, int f) {
super(null);
- this.fobjIter = fobjIter;
+ lmList = lms;
lineHeight = lh;
lead = l;
follow = f;
}
+ public int getContentIPD() {
+ return parentLM.getContentIPD();
+ }
+
/**
* Call child layout managers to generate content as long as they
* generate inline areas. If a block-level generating LM is found,
* finish any line being filled and return to the parent LM.
*/
- public void generateAreas() {
- this.bFirstLine = true;
- while (fobjIter.hasNext()) {
- FObj childFO = (FObj) fobjIter.next();
- if (childFO.generatesInlineAreas() == false) {
- // It generates blocks, pass back to parent
- // Back up one
- fobjIter.previous();
- break;
- } else { // generates inline area
- curLM = childFO.getLayoutManager();
- if (curLM != null) {
- curLM.setParentLM(this);
- curLM.generateAreas();
+ public boolean generateAreas() {
+ // if a side float is added and the line contains content
+ // where the ipd depends on the line width then restart
+ // the line with the adjusted length
+
+ while (curPos.lmIndex < lmList.size()) {
+ LeafNodeLayoutManager curLM =
+ (LeafNodeLayoutManager) lmList.get(curPos.lmIndex);
+ curLM.setParentLM(this);
+
+ LeafNodeLayoutManager nextLM = null;
+ if (curPos.lmIndex + 1 < lmList.size()) {
+ nextLM = (LeafNodeLayoutManager) lmList.get(
+ curPos.lmIndex + 1);
+ while (nextLM.size() == 0) {
+ lmList.remove(curPos.lmIndex + 1);
+ if (curPos.lmIndex + 1 == lmList.size()) {
+ nextLM = null;
+ break;
+ }
+ nextLM = (LeafNodeLayoutManager) lmList.get(
+ curPos.lmIndex + 1);
+
+ }
+ }
+ if (nextLM != null) {
+ nextLM.setParentLM(this);
+ }
+ if (curLM.resolved()) {
+ currentLine.hasResolved = true;
+ }
+ while (curPos.subIndex < curLM.size()) {
+ InlineArea ia = curLM.get(curPos.subIndex);
+ InlineArea next = null;
+ if (curPos.subIndex + 1 < curLM.size()) {
+ next = curLM.get(curPos.subIndex + 1);
+ } else if (curPos.lmIndex + 1 < lmList.size()) {
+ if (nextLM != null) {
+ next = nextLM.get(0);
+ }
}
+ if (currentLine != null && !currentLine.noJustify &&
+ (curPos.subIndex + 1 == curLM.size() &&
+ curPos.lmIndex + 1 == lmList.size())) {
+ currentLine.noJustify = true;
+ }
+ if (addChild(ia, next)) {
+ if (flush()) {
+ return true;
+ }
+ }
+ // flush final line in same context as other lines
+ // handle last line concepts
+ if (curPos.subIndex + 1 == curLM.size() &&
+ curPos.lmIndex + 1 == lmList.size()) {
+ if (flush()) {
+ return true;
+ }
+ if (curPos.subIndex + 1 == curLM.size() &&
+ curPos.lmIndex + 1 == lmList.size()) {
+ return false;
+ }
+
+ }
+ curPos.subIndex++;
}
+ curPos.lmIndex++;
+ curPos.subIndex = 0;
}
- flush(); // Add last area to parent
+ return false;
}
/**
* Align and position curLine and add it to parentContainer.
* Set curLine to null.
*/
- public void flush() {
- if (lineArea != null) {
+ public boolean flush() {
+ if (currentLine != null) {
// Adjust spacing as necessary
-
+ adjustSpacing();
verticalAlign();
- parentLM.addChild(lineArea);
- lineArea = null;
+ boolean res = parentLM.addChild(currentLine.area);
+
+ lines.add(currentLine);
+ currentLine = null;
+ bestPos = null;
+ bestIPD = null;
+
+ return res;
}
+ return false;
+ }
+
+ /**
+ * Do the ipd adjustment for stretch areas etc.
+ * Consecutive spaces need to be collapsed if possible.
+ * should this be on the line area so it can finish resolved areas?
+ */
+ private void adjustSpacing() {
+ List inlineAreas = currentLine.area.getInlineAreas();
+
+ // group text elements to split at hyphen if available
+ // remove collapsable spaces at start or end on line
+
+ // backtrack to best position
+ while (true) {
+ if (curPos.lmIndex == bestPos.lmIndex &&
+ curPos.subIndex == bestPos.subIndex) {
+ break;
+ }
+
+ InlineArea inline =
+ (InlineArea) inlineAreas.get(inlineAreas.size() - 1);
+ MinOptMax ipd = inline.getAllocationIPD();
+ totalIPD.subtract(ipd);
+
+ inlineAreas.remove(inlineAreas.size() - 1);
+ currentLine.noJustify = false;
+
+ curPos.subIndex--;
+ if (curPos.subIndex == -1) {
+ curPos.lmIndex--;
+ LeafNodeLayoutManager curLM =
+ (LeafNodeLayoutManager) lmList.get( curPos.lmIndex);
+ curPos.subIndex = curLM.size() - 1;
+ }
+ }
+
+
+ // for justify also stretch spaces to fill
+ // stretch to best match
+ float percentAdjust = 0;
+ boolean maxSide = false;
+ int realWidth = bestIPD.opt;
+ if (bestIPD.opt > parentLM.getContentIPD()) {
+ if (bestIPD.opt - parentLM.getContentIPD() <
+ (bestIPD.max - bestIPD.opt)) {
+ percentAdjust = (bestIPD.opt - parentLM.getContentIPD()) /
+ (float)(bestIPD.max - bestIPD.opt);
+ realWidth = parentLM.getContentIPD();
+ } else {
+ percentAdjust = 1;
+ realWidth = bestIPD.max;
+ }
+ maxSide = true;
+ } else {
+ if (parentLM.getContentIPD() - bestIPD.opt <
+ bestIPD.opt - bestIPD.min) {
+ percentAdjust = (parentLM.getContentIPD() - bestIPD.opt) /
+ (float)(bestIPD.opt - bestIPD.min);
+ realWidth = parentLM.getContentIPD();
+ } else {
+ percentAdjust = 1;
+ realWidth = bestIPD.min;
+ }
+ }
+ if (percentAdjust > 0) {
+ for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
+ InlineArea inline = (InlineArea) iter.next();
+ int width;
+ MinOptMax iipd = inline.getAllocationIPD();
+ if (!maxSide) {
+ width = iipd.opt +
+ (int)((iipd.max - iipd.opt) * percentAdjust);
+ } else {
+ width = iipd.opt -
+ (int)((iipd.opt - iipd.min) * percentAdjust);
+ }
+ inline.setWidth(width);
+ }
+ }
+
+ // don't justify lines ending with U+000A or last line
+ if (/*justify && */!currentLine.noJustify &&
+ realWidth != parentLM.getContentIPD()) {
+ ArrayList spaces = new ArrayList();
+ for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
+ InlineArea inline = (InlineArea) iter.next();
+ if (inline instanceof Space /* && !((Space)inline).fixed*/) {
+ spaces.add(inline);
+ }
+ }
+ for (Iterator iter = spaces.iterator(); iter.hasNext();) {
+ Space space = (Space) iter.next();
+ space.setWidth(space.getWidth() +
+ (parentLM.getContentIPD() - realWidth) /
+ spaces.size());
+ }
+ }
+
}
private void verticalAlign() {
int maxHeight = lineHeight;
- List inlineAreas = lineArea.getInlineAreas();
+ List inlineAreas = currentLine.area.getInlineAreas();
// get smallest possible offset to before edge
// this depends on the height of no and middle alignments
int before = lead;
int after = follow;
- for(Iterator iter = inlineAreas.iterator(); iter.hasNext(); ) {
- InlineArea inline = (InlineArea)iter.next();
+ int halfLeading = (lineHeight - lead - follow) / 2;
+ before += halfLeading;
+ for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
+ InlineArea inline = (InlineArea) iter.next();
LayoutInfo info = inline.info;
int al;
int ld = inline.getHeight();
- if(info != null) {
+ if (info != null) {
al = info.alignment;
ld = info.lead;
} else {
al = VerticalAlign.BASELINE;
}
- if(al == VerticalAlign.BASELINE) {
- if(ld > before) {
+ if (al == VerticalAlign.BASELINE) {
+ if (ld > before) {
before = ld;
}
- if(inline.getHeight() > before) {
+ if (inline.getHeight() > before) {
before = inline.getHeight();
}
- } else if(al == VerticalAlign.MIDDLE) {
- if(inline.getHeight() / 2 + lead / 2 > before) {
+ } else if (al == VerticalAlign.MIDDLE) {
+ if (inline.getHeight() / 2 + lead / 2 > before) {
before = inline.getHeight() / 2 + lead / 2;
}
- if(inline.getHeight() / 2 - lead / 2 > after) {
+ if (inline.getHeight() / 2 - lead / 2 > after) {
after = inline.getHeight() / 2 - lead / 2;
}
- } else if(al == VerticalAlign.TOP) {
- } else if(al == VerticalAlign.BOTTOM) {
+ } else if (al == VerticalAlign.TOP) {
+ } else if (al == VerticalAlign.BOTTOM) {
}
}
// then align all before, no and middle alignment
- for(Iterator iter = inlineAreas.iterator(); iter.hasNext(); ) {
- InlineArea inline = (InlineArea)iter.next();
+ for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
+ InlineArea inline = (InlineArea) iter.next();
LayoutInfo info = inline.info;
int al;
int ld = inline.getHeight();
boolean bloffset = false;
- if(info != null) {
+ if (info != null) {
al = info.alignment;
ld = info.lead;
bloffset = info.blOffset;
} else {
al = VerticalAlign.BASELINE;
}
- if(al == VerticalAlign.BASELINE) {
+ if (al == VerticalAlign.BASELINE) {
// the offset position for text is the baseline
- if(bloffset) {
+ if (bloffset) {
inline.setOffset(before);
} else {
inline.setOffset(before - ld);
}
- if(inline.getHeight() - ld > after) {
+ if (inline.getHeight() - ld > after) {
after = inline.getHeight() - ld;
}
- } else if(al == VerticalAlign.MIDDLE) {
- inline.setOffset(before - inline.getHeight() / 2 - lead / 2);
- } else if(al == VerticalAlign.TOP) {
+ } else if (al == VerticalAlign.MIDDLE) {
+ inline.setOffset(before - inline.getHeight() / 2 -
+ lead / 2);
+ } else if (al == VerticalAlign.TOP) {
inline.setOffset(0);
- if(inline.getHeight() - before > after) {
+ if (inline.getHeight() - before > after) {
after = inline.getHeight() - before;
}
- } else if(al == VerticalAlign.BOTTOM) {
- if(inline.getHeight() - before > after) {
+ } else if (al == VerticalAlign.BOTTOM) {
+ if (inline.getHeight() - before > after) {
after = inline.getHeight() - before;
}
}
@@ -167,26 +359,26 @@ public class LineLayoutManager extends AbstractLayoutManager {
// after alignment depends on maximum height of before
// and middle alignments
- for(Iterator iter = inlineAreas.iterator(); iter.hasNext(); ) {
- InlineArea inline = (InlineArea)iter.next();
+ for (Iterator iter = inlineAreas.iterator(); iter.hasNext();) {
+ InlineArea inline = (InlineArea) iter.next();
LayoutInfo info = inline.info;
- int al;
- if(info != null) {
+ int al;
+ if (info != null) {
al = info.alignment;
} else {
al = VerticalAlign.BASELINE;
}
- if(al == VerticalAlign.BASELINE) {
- } else if(al == VerticalAlign.MIDDLE) {
- } else if(al == VerticalAlign.TOP) {
- } else if(al == VerticalAlign.BOTTOM) {
+ if (al == VerticalAlign.BASELINE) {
+ } else if (al == VerticalAlign.MIDDLE) {
+ } else if (al == VerticalAlign.TOP) {
+ } else if (al == VerticalAlign.BOTTOM) {
inline.setOffset(before + after - inline.getHeight());
}
}
- if(before + after > maxHeight) {
- lineArea.setHeight(before + after);
+ if (before + after > maxHeight) {
+ currentLine.area.setHeight(before + after);
} else {
- lineArea.setHeight(maxHeight);
+ currentLine.area.setHeight(maxHeight);
}
}
@@ -194,25 +386,27 @@ public class LineLayoutManager extends AbstractLayoutManager {
* Return current lineArea or generate a new one if necessary.
*/
public Area getParentArea(Area childArea) {
- if (lineArea == null) {
+ if (currentLine.area == null) {
createLine();
}
- return lineArea;
+ return currentLine.area;
}
private void createLine() {
- lineArea = new LineArea();
+ currentLine = new LineInfo();
+ currentLine.startPos = curPos;
+ currentLine.area = new LineArea();
/* Set line IPD from parentArea
* This accounts for indents. What about first line indent?
* Should we set an "isFirst" flag on the lineArea to signal
* that to the parent (Block) LM? That's where indent property
* information will be managed.
*/
- Area parent = parentLM.getParentArea(lineArea);
- // lineArea.setContentIPD(parent.getContentIPD());
- // remainingIPD = parent.getContentIPD();
+ Area parent = parentLM.getParentArea(currentLine.area);
+ // currentLine.area.setContentIPD(parent.getContentIPD());
+ // totalIPD = new MinOptMax();
// OR???
- remainingIPD = new MinOptMax(parentLM.getContentIPD());
+ totalIPD = new MinOptMax();
this.bFirstLine = false;
}
@@ -223,55 +417,73 @@ public class LineLayoutManager extends AbstractLayoutManager {
* This should also handle floats if childArea is an anchor.
* @param childArea the area to add: should be an InlineArea subclass!
*/
- public void addChild(Area childArea) {
- if ((childArea instanceof InlineArea) == false) {
- // SIGNAL AN ERROR!!!
- return;
- }
- InlineArea inlineArea = (InlineArea) childArea;
- if (lineArea == null) {
+ public boolean addChild(InlineArea inlineArea, InlineArea nextArea) {
+ if (currentLine == null) {
createLine();
}
- if (inlineArea.getAllocationIPD().min < remainingIPD.max) {
- lineArea.addInlineArea(inlineArea);
- remainingIPD.subtract(inlineArea.getAllocationIPD());
- // Calculate number of spaces
- // Forced line break after this area (ex. ends with LF in nowrap)
- /* NOTYET!
- if (inlineArea.breakAfter()) {
- flush();
- }
- */
- /* Check if line could end after this area (potential line-break
- * character. If not, it must be joined with following inline
- * area to make a word. Otherwise, if the line could break here
- * and if it is "full", add it to the parent area.
- */
- if (remainingIPD.min <= 0) {
- flush();
- }
+
+ // add side floats first
+
+ int pIPD = parentLM.getContentIPD();
+
+ currentLine.area.addInlineArea(inlineArea);
+ totalIPD.add(inlineArea.getAllocationIPD());
+
+ LayoutInfo info = inlineArea.info;
+ if (info == null) {
+ info = new LayoutInfo();
}
- else {
- /* The inline area won't entirely fit in this line. Ask its
- * layout manager to split it (by hyphenation for example),
- * in order to fit part of it in the line.
- * Note: only the current child LM could have generated this
- * area, so we ask it to do the split.
- */
- SplitContext splitContext = new SplitContext(remainingIPD);
- if (curLM.splitArea(inlineArea, splitContext)) {
- // inlineArea should now fit
- lineArea.addInlineArea(inlineArea);
- flush();
- addChild(splitContext.nextArea);
- } else {
- lineArea.addInlineArea((InlineArea)splitContext.nextArea);
- remainingIPD.subtract(inlineArea.getAllocationIPD());
- if (remainingIPD.min <= 0) {
- flush();
- }
+ LayoutInfo ninfo;
+ if (nextArea != null && nextArea.info != null) {
+ ninfo = nextArea.info;
+ } else {
+ ninfo = new LayoutInfo();
+ }
+
+ // the best pos cannot be before the first area
+ if (bestPos == null || bestIPD == null) {
+ bestPos = new LayoutPos();
+ bestPos.lmIndex = curPos.lmIndex;
+ bestPos.subIndex = curPos.subIndex;
+ MinOptMax imop = inlineArea.getAllocationIPD();
+ bestIPD = new MinOptMax(imop.min, imop.opt, imop.max);
+ } else {
+
+ // bestPos changed only when it can break
+ // before/after a space or other atomic inlines
+ // check keep-with on this and next
+ // since chars are optimized as words we cannot assume a
+ // word is complete and therefore hyphenate or break after
+ // side floats effect the available ipd but do not add to line
+
+ if (!ninfo.keepPrev && !info.keepNext &&
+ !(info.isText && ninfo.isText)) {
+ if (Math.abs(bestIPD.opt - pIPD) >
+ Math.abs(totalIPD.opt - pIPD) &&
+ (totalIPD.min <= pIPD)) {
+ bestPos.lmIndex = curPos.lmIndex;
+ bestPos.subIndex = curPos.subIndex;
+ bestIPD = new MinOptMax(totalIPD.min, totalIPD.opt,
+ totalIPD.max);
+ }
}
}
+
+ // Forced line break after this area (ex. ends with LF in nowrap)
+ if (info.breakAfter) {
+ currentLine.noJustify = true;
+ return true;
+ }
+
+ if (totalIPD.min > pIPD) {
+ return true;
+ }
+
+ return false;
}
+ public boolean addChild(Area childArea) {
+ return false;
+ }
}
+
diff --git a/src/org/apache/fop/layoutmgr/PageLayoutManager.java b/src/org/apache/fop/layoutmgr/PageLayoutManager.java
index d88d5d410..5d8a05804 100644
--- a/src/org/apache/fop/layoutmgr/PageLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/PageLayoutManager.java
@@ -41,6 +41,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
* references?
*/
private AreaTree areaTree;
+ private PageSequence pageSequence;
/**
* This is the top level layout manager.
@@ -49,6 +50,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
public PageLayoutManager(AreaTree areaTree, PageSequence pageseq) {
super(pageseq);
this.areaTree = areaTree;
+ pageSequence = pageseq;
}
@@ -69,13 +71,14 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
/**
* For now, only handle normal flow areas.
*/
- public void addChild(Area childArea) {
+ public boolean addChild(Area childArea) {
if (childArea == null)
- return;
+ return false;
if (childArea.getAreaClass() == Area.CLASS_NORMAL) {
- placeFlowRefArea(childArea);
+ return placeFlowRefArea(childArea);
} else
; // TODO: all the others!
+ return false;
}
/**
@@ -85,7 +88,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
* current span, so we are just checking to see if the span is "full",
* possibly moving to the next column or to the next page.
*/
- protected void placeFlowRefArea(Area area) {
+ protected boolean placeFlowRefArea(Area area) {
// assert (curSpan != null);
// assert (area == curFlow);
// assert (curFlow == curSpan.getFlow(curSpan.getColumnCount()-1));
@@ -100,13 +103,16 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
// end the page.
// Alternatively the child LM indicates to parent that it's full?
+System.out.println("size: " + area.getAllocationBPD().max + ":" + curSpan.getMaxBPD().min);
if (area.getAllocationBPD().max >= curSpan.getMaxBPD().min) {
// Consider it filled
if (curSpan.getColumnCount() == curSpanColumns) {
finishPage();
+ return true;
} else
curFlow = null; // Create new flow on next getParentArea()
}
+ return false;
}
@@ -133,7 +139,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
private PageViewport makeNewPage(boolean bIsBlank, boolean bIsLast) {
finishPage();
try {
- curPage = ((PageSequence) fobj).createPage(bIsBlank, bIsLast);
+ curPage = pageSequence.createPage(bIsBlank, bIsLast);
} catch (FOPException fopex) { /* ???? */
fopex.printStackTrace();
}
@@ -308,6 +314,7 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
private Flow createFlow() {
curFlow = new Flow();
curFlow.setIPD(curSpan.getIPD()); // adjust for columns
+ //curFlow.setBPD(100000);
// Set IPD and max BPD on the curFlow from curBody
curSpan.addFlow(curFlow);
return curFlow;
@@ -336,8 +343,9 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
}
// See finishPage...
- protected void flush() {
+ protected boolean flush() {
finishPage();
+ return false;
}
}
diff --git a/src/org/apache/fop/layoutmgr/TextLayoutManager.java b/src/org/apache/fop/layoutmgr/TextLayoutManager.java
index ac8f83436..04add7dfb 100644
--- a/src/org/apache/fop/layoutmgr/TextLayoutManager.java
+++ b/src/org/apache/fop/layoutmgr/TextLayoutManager.java
@@ -11,6 +11,7 @@ import org.apache.fop.fo.FObj;
import org.apache.fop.fo.TextInfo;
import org.apache.fop.area.Area;
import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.Word;
import org.apache.fop.area.inline.Space;
import org.apache.fop.util.CharUtilities;
@@ -19,6 +20,7 @@ import org.apache.fop.fo.properties.VerticalAlign;
import org.apache.fop.fo.properties.*;
import java.util.ListIterator;
+import java.util.ArrayList;
/**
* LayoutManager for text (a sequence of characters) which generates one
@@ -29,6 +31,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private char[] chars;
private TextInfo textInfo;
+ ArrayList words = new ArrayList();
+
private static final char NEWLINE = '\n';
private static final char RETURN = '\r';
private static final char TAB = '\t';
@@ -49,29 +53,36 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
this.textInfo = textInfo;
}
+ public int size() {
+ parseChars();
+ return words.size();
+ }
+
+ public InlineArea get(int index) {
+ parseChars();
+ return (InlineArea)words.get(index);
+ }
+
/**
* Generate inline areas for words in text.
*/
- public void generateAreas() {
+ public boolean generateAreas() {
// Handle white-space characteristics. Maybe there is no area to
// generate....
// Iterate over characters and make text areas.
// Add each one to parent. Handle word-space.
- // Word curWordArea = new Word();
- // curWordArea.setWord(new String(chars));
- //System.out.println("word:" + new String(chars));
- //parentLM.addChild(curWordArea);
- parseChars();
-
- //setCurrentArea(curWordArea);
- //flush();
+ return false;
}
protected void parseChars() {
+ if(chars == null) {
+ return;
+ }
+ int whitespaceWidth;
// With CID fonts, space isn't neccesary currentFontState.width(32)
- int whitespaceWidth = CharUtilities.getCharWidth(' ', textInfo.fs);
+ whitespaceWidth = CharUtilities.getCharWidth(' ', textInfo.fs);
int wordStart = -1;
int wordLength = 0;
@@ -79,9 +90,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
int spaceWidth = 0;
int prev = NOTHING;
+ int i = 0;
/* iterate over each character */
- for (int i = 0; i < chars.length; i++) {
+ for (; i < chars.length; i++) {
int charWidth;
/* get the character */
char c = chars[i];
@@ -115,8 +127,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
if (spaceWidth > 0) {
Space is = new Space();
is.setWidth(spaceWidth);
- parentLM.addChild(is);
spaceWidth = 0;
+ words.add(is);
}
} else if (c == TAB) {
spaceWidth += 8 * whitespaceWidth;
@@ -127,8 +139,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
if (spaceWidth > 0) {
Space is = new Space();
is.setWidth(spaceWidth);
- parentLM.addChild(is);
+ is.info = new LayoutInfo();
+ is.info.breakAfter = true;
spaceWidth = 0;
+ words.add(is);
}
}
@@ -142,8 +156,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
if (spaceWidth > 0) {
Space is = new Space();
is.setWidth(spaceWidth);
- parentLM.addChild(is);
spaceWidth = 0;
+ words.add(is);
}
// add the current word
@@ -153,7 +167,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// spaces. Split the word and add Space
// as necessary. All spaces inside the word
// Have a fixed width.
- parentLM.addChild(createWord(new String(chars, wordStart + 1,
+ words.add(createWord(new String(chars, wordStart + 1,
wordLength), wordWidth));
// reset word width
@@ -190,7 +204,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// textdecoration not used because spaceWidth is 0
Space is = new Space();
is.setWidth(spaceWidth);
- parentLM.addChild(is);
+ words.add(is);
} else if (c == TAB) {
prev = WHITESPACE;
spaceWidth = 8 * whitespaceWidth;
@@ -215,8 +229,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
wordLength = chars.length - 1 - wordStart;
}
- parentLM.addChild(createWord(new String(chars, wordStart + 1, wordLength), wordWidth));
-
+ words.add(createWord(new String(chars, wordStart + 1, wordLength), wordWidth));
}
chars = null;
diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java
index 0db612f8d..cedd387c3 100644
--- a/src/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/org/apache/fop/render/pdf/PDFRenderer.java
@@ -569,5 +569,15 @@ public class PDFRenderer extends PrintRenderer {
}*/
super.renderViewport(viewport);
}
+
+ public void renderLeader(Leader area) {
+ currentStream.add("ET\n");
+ currentStream.add((((float)currentBlockIPPosition) / 1000f) + " "
+ + ((currentBPPosition + area.getOffset()) / 1000f) + " m\n");
+ currentStream.add(((currentBlockIPPosition + area.getWidth()) / 1000f) + " " + ((currentBPPosition + area.getOffset()) / 1000f) + " l\n");
+ currentStream.add("S\n");
+ currentStream.add("BT\n");
+ super.renderLeader(area);
+ }
}
diff --git a/src/org/apache/fop/svg/SVGElement.java b/src/org/apache/fop/svg/SVGElement.java
index 7f6373536..0bfa212e4 100644
--- a/src/org/apache/fop/svg/SVGElement.java
+++ b/src/org/apache/fop/svg/SVGElement.java
@@ -97,6 +97,10 @@ public class SVGElement extends SVGObj {
return new AffineTransform();
}
+ public AffineTransform getGlobalTransform() {
+ return new AffineTransform();
+ }
+
public float getViewportWidth() {
return (float)view.getX();
}