Browse Source

starting implementation of tables

fixed some more styling errors


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195177 13f79535-47bb-0310-9956-ffa450edef68
pull/30/head
Keiron Liddle 22 years ago
parent
commit
72d09f7de3
39 changed files with 2176 additions and 704 deletions
  1. 4
    4
      src/org/apache/fop/apps/StructureHandler.java
  2. 75
    15
      src/org/apache/fop/area/Area.java
  3. 8
    2
      src/org/apache/fop/area/Block.java
  4. 33
    5
      src/org/apache/fop/area/BlockParent.java
  5. 116
    118
      src/org/apache/fop/area/Trait.java
  6. 2
    14
      src/org/apache/fop/fo/FOElementMapping.java
  7. 1
    0
      src/org/apache/fop/fo/FObj.java
  8. 1
    10
      src/org/apache/fop/fo/FObjMixed.java
  9. 17
    2
      src/org/apache/fop/fo/flow/Footnote.java
  10. 9
    3
      src/org/apache/fop/fo/flow/Leader.java
  11. 0
    126
      src/org/apache/fop/fo/flow/RowSpanMgr.java
  12. 101
    66
      src/org/apache/fop/fo/flow/Table.java
  13. 36
    26
      src/org/apache/fop/fo/flow/TableBody.java
  14. 11
    0
      src/org/apache/fop/fo/flow/TableCell.java
  15. 11
    1
      src/org/apache/fop/fo/flow/TableColumn.java
  16. 9
    202
      src/org/apache/fop/fo/flow/TableRow.java
  17. 47
    14
      src/org/apache/fop/layoutmgr/AbstractLayoutManager.java
  18. 14
    10
      src/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
  19. 0
    9
      src/org/apache/fop/layoutmgr/BlockLayoutManager.java
  20. 3
    4
      src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
  21. 1
    1
      src/org/apache/fop/layoutmgr/BreakPossPosIter.java
  22. 10
    0
      src/org/apache/fop/layoutmgr/ContentLayoutManager.java
  23. 11
    0
      src/org/apache/fop/layoutmgr/FlowLayoutManager.java
  24. 49
    0
      src/org/apache/fop/layoutmgr/LayoutManager.java
  25. 13
    0
      src/org/apache/fop/layoutmgr/PageLayoutManager.java
  26. 1
    1
      src/org/apache/fop/layoutmgr/PositionIterator.java
  27. 15
    7
      src/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
  28. 213
    0
      src/org/apache/fop/layoutmgr/table/Body.java
  29. 190
    0
      src/org/apache/fop/layoutmgr/table/Caption.java
  30. 215
    0
      src/org/apache/fop/layoutmgr/table/Cell.java
  31. 92
    0
      src/org/apache/fop/layoutmgr/table/Column.java
  32. 277
    0
      src/org/apache/fop/layoutmgr/table/Row.java
  33. 192
    0
      src/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
  34. 291
    0
      src/org/apache/fop/layoutmgr/table/TableLayoutManager.java
  35. 48
    1
      src/org/apache/fop/render/AbstractRenderer.java
  36. 17
    20
      src/org/apache/fop/render/pdf/PDFRenderer.java
  37. 1
    1
      src/org/apache/fop/traits/BlockProps.java
  38. 15
    15
      src/org/apache/fop/traits/BorderProps.java
  39. 27
    27
      src/org/apache/fop/traits/LayoutProps.java

+ 4
- 4
src/org/apache/fop/apps/StructureHandler.java View File

@@ -86,19 +86,19 @@ public class StructureHandler extends AbstractLogEnabled {

}

public void startHeader(TableHeader th) {
public void startHeader(TableBody th) {

}

public void endHeader(TableHeader th) {
public void endHeader(TableBody th) {

}

public void startFooter(TableFooter tf) {
public void startFooter(TableBody tf) {

}

public void endFooter(TableFooter tf) {
public void endFooter(TableBody tf) {

}


+ 75
- 15
src/org/apache/fop/area/Area.java View File

@@ -1,6 +1,6 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/
@@ -24,38 +24,96 @@ import java.util.HashMap;
*/
public class Area implements Serializable {
// stacking directions
/**
* Stacking left to right
*/
public static final int LR = 0;

/**
* Stacking right to left
*/
public static final int RL = 1;

/**
* Stacking top to bottom
*/
public static final int TB = 2;

/**
* Stacking bottom to top
*/
public static final int BT = 3;

// orientations for reference areas
/**
* Normal orientation
*/
public static final int ORIENT_0 = 0;

/**
* Rotated 90 degrees clockwise
*/
public static final int ORIENT_90 = 1;
/**
* Rotate 180 degrees
*/
public static final int ORIENT_180 = 2;
/**
* Rotated 270 degrees clockwise
*/
public static final int ORIENT_270 = 3;

// area class values
/**
* Normal class
*/
public static final int CLASS_NORMAL = 0;

/**
* Fixed position class
*/
public static final int CLASS_FIXED = 1;

/**
* Absolute position class
*/
public static final int CLASS_ABSOLUTE = 2;

/**
* Before float class
*/
public static final int CLASS_BEFORE_FLOAT = 3;

/**
* Footnote class
*/
public static final int CLASS_FOOTNOTE = 4;

/**
* Side float class
*/
public static final int CLASS_SIDE_FLOAT = 5;

// IMPORTANT: make sure this is the maximum + 1
public static final int CLASS_MAX = CLASS_SIDE_FLOAT+1;
/**
* Maximum class count
*/
public static final int CLASS_MAX = CLASS_SIDE_FLOAT + 1;

private int areaClass = CLASS_NORMAL;
private int ipd;

protected Area parent =null; // Doesn't need to be saved in serialization
protected Area parent = null; // Doesn't need to be saved in serialization

public int getAreaClass() {
return areaClass;
return areaClass;
}

public void setAreaClass(int areaClass) {
this.areaClass = areaClass;
this.areaClass = areaClass;
}

public void setIPD(int i) {
@@ -73,7 +131,7 @@ public class Area implements Serializable {
* and its current content.
*/
public MinOptMax getAvailBPD() {
return MinOptMax.subtract(getMaxBPD(), getContentBPD());
return MinOptMax.subtract(getMaxBPD(), getContentBPD());
}

/**
@@ -85,10 +143,11 @@ public class Area implements Serializable {
* for the sizes of the conditional areas.
*/
public MinOptMax getMaxBPD() {
if (parent != null) {
return parent.getMaxBPD();
}
else return new MinOptMax();
if (parent != null) {
return parent.getMaxBPD();
} else {
return new MinOptMax();
}
}

/**
@@ -98,7 +157,7 @@ public class Area implements Serializable {
* the area.
*/
public MinOptMax getContentBPD() {
return new MinOptMax();
return new MinOptMax();
}

/**
@@ -112,11 +171,11 @@ public class Area implements Serializable {
* to the allocation BPD, depending on conditionality.
*/
public MinOptMax getAllocationBPD() {
return getContentBPD();
return getContentBPD();
}

public void setParent(Area parent) {
this.parent = parent;
this.parent = parent;
}

// Do nothing! Let subclasses do something if they can have child areas.
@@ -141,10 +200,11 @@ public class Area implements Serializable {
}

public HashMap getTraits() {
return this.props;
return this.props;
}

public Object getTrait(Object oTraitCode) {
return (props != null? props.get(oTraitCode) : null);
return (props != null ? props.get(oTraitCode) : null);
}
}


+ 8
- 2
src/org/apache/fop/area/Block.java View File

@@ -24,10 +24,14 @@ public class Block extends BlockParent implements Serializable {
public static final int STACK = 0;
// placed relative to the parent area
public static final int RELATIVE = 1;
// placed relative to the page or viewport

/**
* Relative to the block parent but not effecting the stacking
* Used for block-container, tables and lists.
*/
public static final int ABSOLUTE = 2;

int stacking = TB;
private int stacking = TB;

// list of marker fo objects that are associated with this area
// if a retrieve marker resolves this area it will format the
@@ -45,6 +49,7 @@ public class Block extends BlockParent implements Serializable {
if (children == null) {
children = new ArrayList();
}
height += block.getHeight();
children.add(block);
}

@@ -52,6 +57,7 @@ public class Block extends BlockParent implements Serializable {
if (children == null) {
children = new ArrayList();
}
height += line.getHeight();
children.add(line);
}


+ 33
- 5
src/org/apache/fop/area/BlockParent.java View File

@@ -20,7 +20,10 @@ public class BlockParent extends Area implements Serializable {
// this position is used for absolute position
// or as an indent
// this has the size in the block progression dimension
Rectangle2D bounds = null;
protected int xOffset = 0;
protected int yOffset = 0;
protected int width = 0;
protected int height = 0;

ArrayList children = null;

@@ -38,11 +41,36 @@ public class BlockParent extends Area implements Serializable {
return children;
}

public void setBounds(Rectangle2D b) {
bounds = b;
public void setXOffset(int off) {
xOffset = off;
}

public Rectangle2D getBounds() {
return bounds;
public void setYOffset(int off) {
yOffset = off;
}

public void setWidth(int w) {
width = w;
}

public void setHeight(int h) {
height = h;
}

public int getXOffset() {
return xOffset;
}

public int getYOffset() {
return yOffset;
}

public int getWidth() {
return width;
}

public int getHeight() {
return height;
}

}

+ 116
- 118
src/org/apache/fop/area/Trait.java View File

@@ -19,155 +19,153 @@ import java.util.Iterator;
// properties should be serialized by the holder
public class Trait implements Serializable {
public static final Integer ID_LINK = new Integer(0);
public static final Integer INTERNAL_LINK = new Integer(1); //resolved
public static final Integer EXTERNAL_LINK = new Integer(2);
public static final Integer FONT_NAME = new Integer(3);
public static final Integer FONT_SIZE = new Integer(4);
public static final Integer COLOR = new Integer(7);
public static final Integer ID_AREA = new Integer(8);
public static final Integer BACKGROUND = new Integer(9);
public static final Integer UNDERLINE = new Integer(10);
public static final Integer OVERLINE = new Integer(11);
public static final Integer LINETHROUGH = new Integer(12);
public static final Integer OFFSET = new Integer(13);
public static final Integer SHADOW = new Integer(14);
public static final Integer BORDER_START = new Integer(15);
public static final Integer BORDER_END = new Integer(16);
public static final Integer BORDER_BEFORE = new Integer(17);
public static final Integer BORDER_AFTER = new Integer(18);
public static final Integer PADDING_START = new Integer(19);
public static final Integer PADDING_END = new Integer(20);
public static final Integer PADDING_BEFORE = new Integer(21);
public static final Integer PADDING_AFTER = new Integer(22);
public static final Integer INTERNAL_LINK = new Integer(1); //resolved
public static final Integer EXTERNAL_LINK = new Integer(2);
public static final Integer FONT_NAME = new Integer(3);
public static final Integer FONT_SIZE = new Integer(4);
public static final Integer COLOR = new Integer(7);
public static final Integer ID_AREA = new Integer(8);
public static final Integer BACKGROUND = new Integer(9);
public static final Integer UNDERLINE = new Integer(10);
public static final Integer OVERLINE = new Integer(11);
public static final Integer LINETHROUGH = new Integer(12);
public static final Integer OFFSET = new Integer(13);
public static final Integer SHADOW = new Integer(14);
public static final Integer BORDER_START = new Integer(15);
public static final Integer BORDER_END = new Integer(16);
public static final Integer BORDER_BEFORE = new Integer(17);
public static final Integer BORDER_AFTER = new Integer(18);
public static final Integer PADDING_START = new Integer(19);
public static final Integer PADDING_END = new Integer(20);
public static final Integer PADDING_BEFORE = new Integer(21);
public static final Integer PADDING_AFTER = new Integer(22);

static HashMap s_hmTraitInfo;

private static class TraitInfo {
String sName;
Class sClass; // Class of trait data
TraitInfo(String sName, Class sClass) {
this.sName = sName;
this.sClass = sClass;
}
String sName;
Class sClass; // Class of trait data
TraitInfo(String sName, Class sClass) {
this.sName = sName;
this.sClass = sClass;
}
}

static {
// Create a hashmap mapping trait code to name for external representation
s_hmTraitInfo = new HashMap();
s_hmTraitInfo.put(ID_LINK,
new TraitInfo("id-link", String.class));
s_hmTraitInfo.put(INTERNAL_LINK,
new TraitInfo("internal-link", PageViewport.class));
s_hmTraitInfo.put(EXTERNAL_LINK,
new TraitInfo("external-link", String.class));
s_hmTraitInfo.put(FONT_NAME,
new TraitInfo("font-family", String.class));
s_hmTraitInfo.put(FONT_SIZE,
new TraitInfo("font-size", Integer.class));
s_hmTraitInfo.put(COLOR,
new TraitInfo("color", String.class));
s_hmTraitInfo.put(ID_AREA,
new TraitInfo("id-area", String.class));
s_hmTraitInfo.put(BACKGROUND,
new TraitInfo("background", String.class));
s_hmTraitInfo.put(UNDERLINE,
new TraitInfo("underline", Integer.class));
s_hmTraitInfo.put(OVERLINE,
new TraitInfo("overline", Integer.class));
s_hmTraitInfo.put(LINETHROUGH,
new TraitInfo("linethrough", Integer.class));
s_hmTraitInfo.put(OFFSET,
new TraitInfo("offset", Integer.class));
s_hmTraitInfo.put(SHADOW,
new TraitInfo("shadow", Integer.class));
s_hmTraitInfo.put(BORDER_START,
new TraitInfo("border-start", BorderProps.class));
s_hmTraitInfo.put(BORDER_END,
new TraitInfo("border-end", BorderProps.class));
s_hmTraitInfo.put(BORDER_BEFORE,
new TraitInfo("border-before", BorderProps.class));
s_hmTraitInfo.put(BORDER_AFTER,
new TraitInfo("border-after", BorderProps.class));
s_hmTraitInfo.put(PADDING_START,
new TraitInfo("padding-start", Integer.class));
s_hmTraitInfo.put(PADDING_END,
new TraitInfo("padding-end", Integer.class));
s_hmTraitInfo.put(PADDING_BEFORE,
new TraitInfo("padding-before", Integer.class));
s_hmTraitInfo.put(PADDING_AFTER,
new TraitInfo("padding-after", Integer.class));
// Create a hashmap mapping trait code to name for external representation
s_hmTraitInfo = new HashMap();
s_hmTraitInfo.put(ID_LINK, new TraitInfo("id-link", String.class));
s_hmTraitInfo.put(INTERNAL_LINK,
new TraitInfo("internal-link", PageViewport.class));
s_hmTraitInfo.put(EXTERNAL_LINK,
new TraitInfo("external-link", String.class));
s_hmTraitInfo.put(FONT_NAME,
new TraitInfo("font-family", String.class));
s_hmTraitInfo.put(FONT_SIZE,
new TraitInfo("font-size", Integer.class));
s_hmTraitInfo.put(COLOR, new TraitInfo("color", String.class));
s_hmTraitInfo.put(ID_AREA, new TraitInfo("id-area", String.class));
s_hmTraitInfo.put(BACKGROUND,
new TraitInfo("background", Background.class));
s_hmTraitInfo.put(UNDERLINE,
new TraitInfo("underline", Integer.class));
s_hmTraitInfo.put(OVERLINE,
new TraitInfo("overline", Integer.class));
s_hmTraitInfo.put(LINETHROUGH,
new TraitInfo("linethrough", Integer.class));
s_hmTraitInfo.put(OFFSET, new TraitInfo("offset", Integer.class));
s_hmTraitInfo.put(SHADOW, new TraitInfo("shadow", Integer.class));
s_hmTraitInfo.put(BORDER_START,
new TraitInfo("border-start", BorderProps.class));
s_hmTraitInfo.put(BORDER_END,
new TraitInfo("border-end", BorderProps.class));
s_hmTraitInfo.put(BORDER_BEFORE,
new TraitInfo("border-before", BorderProps.class));
s_hmTraitInfo.put(BORDER_AFTER,
new TraitInfo("border-after", BorderProps.class));
s_hmTraitInfo.put(PADDING_START,
new TraitInfo("padding-start", Integer.class));
s_hmTraitInfo.put(PADDING_END,
new TraitInfo("padding-end", Integer.class));
s_hmTraitInfo.put(PADDING_BEFORE,
new TraitInfo("padding-before", Integer.class));
s_hmTraitInfo.put(PADDING_AFTER,
new TraitInfo("padding-after", Integer.class));
}

public static String getTraitName(Object traitCode) {
Object obj = s_hmTraitInfo.get(traitCode);
if (obj != null) {
return ((TraitInfo)obj).sName;
}
else {
return "unknown-trait-" + traitCode.toString();
}
Object obj = s_hmTraitInfo.get(traitCode);
if (obj != null) {
return ((TraitInfo) obj).sName;
} else {
return "unknown-trait-" + traitCode.toString();
}
}

public static Object getTraitCode(String sTraitName) {
Iterator iter = s_hmTraitInfo.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry)iter.next();
TraitInfo ti = (TraitInfo)entry.getValue();
if (ti != null && ti.sName.equals(sTraitName)) {
return entry.getKey();
}
}
return null;
Iterator iter = s_hmTraitInfo.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
TraitInfo ti = (TraitInfo) entry.getValue();
if (ti != null && ti.sName.equals(sTraitName)) {
return entry.getKey();
}
}
return null;
}

private static Class getTraitClass(Object oTraitCode) {
TraitInfo ti = (TraitInfo)s_hmTraitInfo.get(oTraitCode);
return (ti != null? ti.sClass : null);
TraitInfo ti = (TraitInfo) s_hmTraitInfo.get(oTraitCode);
return (ti != null ? ti.sClass : null);
}

public Object propType;
public Object data;

public Trait() {
this.propType = null;
this.data = null;
this.propType = null;
this.data = null;
}

public Trait(Object propType, Object data) {
this.propType = propType;
this.data = data;
this.propType = propType;
this.data = data;
}

public String toString() {
return data.toString();
return data.toString();
}

public static Object makeTraitValue(Object oCode, String sTraitValue) {
// Get the code from the name
// See what type of object it is
// Convert string value to an object of that type
Class tclass = getTraitClass(oCode);
if (tclass == null) return null;
if (tclass.equals(String.class)) {
return sTraitValue;
}
if (tclass.equals(Integer.class)) {
return new Integer(sTraitValue);
}
// See if the class has a constructor from string or can read from a string
try {
Object o = tclass.newInstance();
//return o.fromString(sTraitValue);
} catch (IllegalAccessException e1) {
System.err.println("Can't create instance of " + tclass.getName());
return null;
} catch (InstantiationException e2) {
System.err.println("Can't create instance of " + tclass.getName());
return null;
}

return null;
// Get the code from the name
// See what type of object it is
// Convert string value to an object of that type
Class tclass = getTraitClass(oCode);
if (tclass == null)
return null;
if (tclass.equals(String.class)) {
return sTraitValue;
}
if (tclass.equals(Integer.class)) {
return new Integer(sTraitValue);
}
// See if the class has a constructor from string or can read from a string
try {
Object o = tclass.newInstance();
//return o.fromString(sTraitValue);
} catch (IllegalAccessException e1) {
System.err.println("Can't create instance of " +
tclass.getName());
return null;
}
catch (InstantiationException e2) {
System.err.println("Can't create instance of " +
tclass.getName());
return null;
}


return null;
}

public static class Background {

+ 2
- 14
src/org/apache/fop/fo/FOElementMapping.java View File

@@ -72,8 +72,8 @@ public class FOElementMapping implements ElementMapping {
foObjs.put("table", new Ta());
foObjs.put("table-column", new TC());
foObjs.put("table-caption", new TCaption());
foObjs.put("table-header", new TH());
foObjs.put("table-footer", new TF());
foObjs.put("table-header", new TB());
foObjs.put("table-footer", new TB());
foObjs.put("table-body", new TB());
foObjs.put("table-row", new TR());
foObjs.put("table-cell", new TCell());
@@ -323,18 +323,6 @@ public class FOElementMapping implements ElementMapping {
}
}

static class TH extends ElementMapping.Maker {
public FONode make(FONode parent) {
return new TableHeader(parent);
}
}

static class TF extends ElementMapping.Maker {
public FONode make(FONode parent) {
return new TableFooter(parent);
}
}

static class TB extends ElementMapping.Maker {
public FONode make(FONode parent) {
return new TableBody(parent);

+ 1
- 0
src/org/apache/fop/fo/FObj.java View File

@@ -206,6 +206,7 @@ public class FObj extends FONode {
/**
* Return a LayoutManager responsible for laying out this FObj's content.
* Must override in subclasses if their content can be laid out.
* @param list the list to add the layout manager(s) to
*/
public void addLayoutManager(List list) {
}

+ 1
- 10
src/org/apache/fop/fo/FObjMixed.java View File

@@ -35,17 +35,8 @@ public class FObjMixed extends FObj {
}

public void addLayoutManager(List lms) {
lms.add(new InlineStackingLayoutManager(this,
lms.add(new InlineStackingLayoutManager(this,
new LMiter(children.listIterator())));
// 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);
// }
// }
}

protected void addCharacters(char data[], int start, int length) {

+ 17
- 2
src/org/apache/fop/fo/flow/Footnote.java View File

@@ -22,6 +22,8 @@ import java.util.List;
import java.util.ArrayList;

public class Footnote extends FObj {
Inline inlineFO = null;
FootnoteBody body;

public Footnote(FONode parent) {
super(parent);
@@ -29,9 +31,22 @@ public class Footnote extends FObj {

public void addLayoutManager(List lms) {
// add inlines layout manager
//inline.addLayoutManager(lms);
// set start and end footnote reference
if(inlineFO == null) {
getLogger().error("inline required in footnote");
return;
}
inlineFO.addLayoutManager(lms);
}

public void addChild(FONode child) {
String name = child.getName();
if ("fo:inline".equals(name)) {
inlineFO = (Inline)child;
} else if ("fo:footnote-body".equals(name)) {
body = (FootnoteBody)child;
} else {
getLogger().error("invalid child of footnote: " + name);
}
}
}


+ 9
- 3
src/org/apache/fop/fo/flow/Leader.java View File

@@ -36,8 +36,7 @@ import java.util.ArrayList;

/**
* Implements fo:leader; main property of leader leader-pattern.
* The following patterns are treated: rule, space, dots.
* The pattern use-content is ignored, i.e. it still must be implemented.
* The following patterns are treated: rule, space, dots and use-content.
*/
public class Leader extends FObjMixed {
int ruleStyle;
@@ -61,6 +60,12 @@ public class Leader extends FObjMixed {
protected MinOptMax getAllocationIPD(int refIPD) {
return getAllocIPD(refIPD);
}

/*protected void offsetArea(LayoutContext context) {
if(leaderPattern == LeaderPattern.DOTS) {
curArea.setOffset(context.getBaseline());
}
}*/
};
lm.setAlignment(properties.get("leader-alignment").getEnum());
list.add(lm);
@@ -87,7 +92,7 @@ public class Leader extends FObjMixed {
leaderArea = new Space();
} else if(leaderPattern == LeaderPattern.DOTS) {
Word w = new Word();
char dot = '.'; // userAgent.getLeaderDotChar();
char dot = '.'; // userAgent.getLeaderDotCharacter();

w.setWord("" + dot);
w.addTrait(Trait.FONT_NAME, fontState.getFontName());
@@ -108,6 +113,7 @@ public class Leader extends FObjMixed {
if(spacer != null) {
fa.addChild(spacer);
}
fa.setHeight(fontState.getAscender());

leaderArea = fa;
} else if(leaderPattern == LeaderPattern.USECONTENT) {

+ 0
- 126
src/org/apache/fop/fo/flow/RowSpanMgr.java View File

@@ -1,126 +0,0 @@
/*
* -- $Id$ --
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.fo.flow;

import java.util.Enumeration;

public class RowSpanMgr {
class SpanInfo {
int cellHeight;
int totalRowHeight;
int rowsRemaining;
// int numCols; // both V and H span
TableCell cell;

SpanInfo(TableCell cell, int cellHeight, int rowsSpanned) {
this.cell = cell;
this.cellHeight = cellHeight;
this.totalRowHeight = 0;
this.rowsRemaining = rowsSpanned;
}

/**
* Return the height remaining in the span.
*/
int heightRemaining() {
int hl = cellHeight - totalRowHeight;
return (hl > 0) ? hl : 0;
}

boolean isInLastRow() {
return (rowsRemaining == 1);
}

boolean finishRow(int rowHeight) {
totalRowHeight += rowHeight;
if (--rowsRemaining == 0) {
if (cell != null) {
}
return true;
} else
return false;
}

}

private SpanInfo spanInfo[];

public RowSpanMgr(int numCols) {
this.spanInfo = new SpanInfo[numCols];
}

public void addRowSpan(TableCell cell, int firstCol, int numCols,
int cellHeight, int rowsSpanned) {
spanInfo[firstCol - 1] = new SpanInfo(cell, cellHeight, rowsSpanned);
for (int i = 0; i < numCols - 1; i++) {
spanInfo[firstCol + i] = new SpanInfo(null, cellHeight,
rowsSpanned); // copy!
}
}

public boolean isSpanned(int colNum) {
return (spanInfo[colNum - 1] != null);
}


public TableCell getSpanningCell(int colNum) {
if (spanInfo[colNum - 1] != null) {
return spanInfo[colNum - 1].cell;
} else
return null;
}


/**
* Return true if any column has an unfinished vertical span.
*/
public boolean hasUnfinishedSpans() {
for (int i = 0; i < spanInfo.length; i++) {
if (spanInfo[i] != null)
return true;
}
return false;
}

/**
* Done with a row.
* Any spans with only one row left are done
* This means that we can now set the total height for this cell box
* Loop over all cells with spans and find number of rows remaining
* if rows remaining = 1, set the height on the cell area and
* then remove the cell from the list of spanned cells. For other
* spans, add the rowHeight to the spanHeight.
*/
public void finishRow(int rowHeight) {
for (int i = 0; i < spanInfo.length; i++) {
if (spanInfo[i] != null && spanInfo[i].finishRow(rowHeight))
spanInfo[i] = null;
}
}

/**
* If the cell in this column is in the last row of its vertical
* span, return the height left. If it's not in the last row, or if
* the content height <= the content height of the previous rows
* of the span, return 0.
*/
public int getRemainingHeight(int colNum) {
if (spanInfo[colNum - 1] != null) {
return spanInfo[colNum - 1].heightRemaining();
} else
return 0;
}

public boolean isInLastRow(int colNum) {
if (spanInfo[colNum - 1] != null) {
return spanInfo[colNum - 1].isInLastRow();
} else
return false;
}

}

+ 101
- 66
src/org/apache/fop/fo/flow/Table.java View File

@@ -14,13 +14,22 @@ import org.apache.fop.layout.*;
import org.apache.fop.datatypes.*;
import org.apache.fop.apps.FOPException;

import org.apache.fop.layoutmgr.table.TableLayoutManager;

// Java
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

public class Table extends FObj {

private static final int MINCOLWIDTH = 10000; // 10pt

protected ArrayList columns = null;
TableBody tableHeader = null;
TableBody tableFooter = null;
boolean omitHeaderAtBreak = false;
boolean omitFooterAtBreak = false;

int breakBefore;
int breakAfter;
int spaceBefore;
@@ -28,14 +37,8 @@ public class Table extends FObj {
ColorType backgroundColor;
LengthRange ipd;
int height;
TableHeader tableHeader = null;
TableFooter tableFooter = null;
boolean omitHeaderAtBreak = false;
boolean omitFooterAtBreak = false;

ArrayList columns = new ArrayList();
int bodyCount = 0;
private boolean bAutoLayout=false;
private boolean bAutoLayout = false;
private int contentWidth = 0; // Sum of column widths
/** Optimum inline-progression-dimension */
private int optIPD;
@@ -48,65 +51,97 @@ public class Table extends FObj {
super(parent);
}

protected void addChild(FONode child) {
if(child.getName().equals("fo:table-column")) {
if(columns == null) {
columns = new ArrayList();
}
columns.add(((TableColumn)child).getLayoutManager());
} else if(child.getName().equals("fo:table-footer")) {
tableFooter = (TableBody)child;
} else if(child.getName().equals("fo:table-header")) {
tableHeader = (TableBody)child;
} else {
// add bodies
children.add(child);
}
}

/**
* Return a LayoutManager responsible for laying out this FObj's content.
* Must override in subclasses if their content can be laid out.
*/
public void addLayoutManager(List list) {
TableLayoutManager tlm = new TableLayoutManager(this);
tlm.setColumns(columns);
if(tableHeader != null) {
tlm.setTableHeader(tableHeader.getLayoutManager());
}
if(tableFooter != null) {
tlm.setTableFooter(tableFooter.getLayoutManager());
}
list.add(tlm);
}

public void setup() {
// Common Accessibility Properties
AccessibilityProps mAccProps = propMgr.getAccessibilityProps();

// Common Aural Properties
AuralProps mAurProps = propMgr.getAuralProps();

// Common Border, Padding, and Background Properties
BorderAndPadding bap = propMgr.getBorderAndPadding();
BackgroundProps bProps = propMgr.getBackgroundProps();

// Common Margin Properties-Block
MarginProps mProps = propMgr.getMarginProps();

// Common Relative Position Properties
RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
// this.properties.get("block-progression-dimension");
// this.properties.get("border-after-precendence");
// this.properties.get("border-before-precedence");
// this.properties.get("border-collapse");
// this.properties.get("border-end-precendence");
// this.properties.get("border-separation");
// this.properties.get("border-start-precendence");
// this.properties.get("break-after");
// this.properties.get("break-before");
setupID();
// this.properties.get("inline-progression-dimension");
// this.properties.get("height");
// this.properties.get("keep-together");
// this.properties.get("keep-with-next");
// this.properties.get("keep-with-previous");
// this.properties.get("table-layout");
// this.properties.get("table-omit-footer-at-break");
// this.properties.get("table-omit-header-at-break");
// this.properties.get("width");
// this.properties.get("writing-mode");
this.breakBefore = this.properties.get("break-before").getEnum();
this.breakAfter = this.properties.get("break-after").getEnum();
this.spaceBefore =
this.properties.get("space-before.optimum").getLength().mvalue();
this.spaceAfter =
this.properties.get("space-after.optimum").getLength().mvalue();
this.backgroundColor =
this.properties.get("background-color").getColorType();
this.ipd =
this.properties.get("inline-progression-dimension").
getLengthRange();
this.height = this.properties.get("height").getLength().mvalue();
this.bAutoLayout = (this.properties.get("table-layout").getEnum() ==
TableLayout.AUTO);
this.omitHeaderAtBreak =
this.properties.get("table-omit-header-at-break").getEnum()
== TableOmitHeaderAtBreak.TRUE;
this.omitFooterAtBreak =
this.properties.get("table-omit-footer-at-break").getEnum()
== TableOmitFooterAtBreak.TRUE;
// Common Accessibility Properties
AccessibilityProps mAccProps = propMgr.getAccessibilityProps();
// Common Aural Properties
AuralProps mAurProps = propMgr.getAuralProps();
// Common Border, Padding, and Background Properties
BorderAndPadding bap = propMgr.getBorderAndPadding();
BackgroundProps bProps = propMgr.getBackgroundProps();
// Common Margin Properties-Block
MarginProps mProps = propMgr.getMarginProps();
// Common Relative Position Properties
RelativePositionProps mRelProps =
propMgr.getRelativePositionProps();
// this.properties.get("block-progression-dimension");
// this.properties.get("border-after-precendence");
// this.properties.get("border-before-precedence");
// this.properties.get("border-collapse");
// this.properties.get("border-end-precendence");
// this.properties.get("border-separation");
// this.properties.get("border-start-precendence");
// this.properties.get("break-after");
// this.properties.get("break-before");
setupID();
// this.properties.get("inline-progression-dimension");
// this.properties.get("height");
// this.properties.get("keep-together");
// this.properties.get("keep-with-next");
// this.properties.get("keep-with-previous");
// this.properties.get("table-layout");
// this.properties.get("table-omit-footer-at-break");
// this.properties.get("table-omit-header-at-break");
// this.properties.get("width");
// this.properties.get("writing-mode");
this.breakBefore = this.properties.get("break-before").getEnum();
this.breakAfter = this.properties.get("break-after").getEnum();
this.spaceBefore = this.properties.get(
"space-before.optimum").getLength().mvalue();
this.spaceAfter = this.properties.get(
"space-after.optimum").getLength().mvalue();
this.backgroundColor =
this.properties.get("background-color").getColorType();
this.ipd = this.properties.get(
"inline-progression-dimension"). getLengthRange();
this.height = this.properties.get("height").getLength().mvalue();
this.bAutoLayout = (this.properties.get("table-layout").getEnum() ==
TableLayout.AUTO);
this.omitHeaderAtBreak = this.properties.get(
"table-omit-header-at-break").getEnum() ==
TableOmitHeaderAtBreak.TRUE;
this.omitFooterAtBreak = this.properties.get(
"table-omit-footer-at-break").getEnum() ==
TableOmitFooterAtBreak.TRUE;

}


+ 36
- 26
src/org/apache/fop/fo/flow/TableBody.java View File

@@ -14,8 +14,11 @@ import org.apache.fop.datatypes.*;
import org.apache.fop.layout.*;
import org.apache.fop.apps.FOPException;

import org.apache.fop.layoutmgr.table.Body;

// Java
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

public class TableBody extends FObj {
@@ -24,39 +27,46 @@ public class TableBody extends FObj {
int spaceAfter;
ColorType backgroundColor;

ArrayList columns;
RowSpanMgr rowSpanMgr; // manage information about spanning rows

public TableBody(FONode parent) {
super(parent);
}

public void setColumns(ArrayList columns) {
this.columns = columns;
/**
* Return a LayoutManager responsible for laying out this FObj's content.
* Must override in subclasses if their content can be laid out.
*/
public void addLayoutManager(List list) {
list.add(getLayoutManager());
}

public Body getLayoutManager() {
Body blm = new Body(this);
return blm;
}

public void setup() throws FOPException {
// Common Accessibility Properties
AccessibilityProps mAccProps = propMgr.getAccessibilityProps();

// Common Aural Properties
AuralProps mAurProps = propMgr.getAuralProps();

// Common Border, Padding, and Background Properties
BorderAndPadding bap = propMgr.getBorderAndPadding();
BackgroundProps bProps = propMgr.getBackgroundProps();

// Common Relative Position Properties
RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
setupID();

this.spaceBefore =
this.properties.get("space-before.optimum").getLength().mvalue();
this.spaceAfter =
this.properties.get("space-after.optimum").getLength().mvalue();
this.backgroundColor =
this.properties.get("background-color").getColorType();
// Common Accessibility Properties
AccessibilityProps mAccProps = propMgr.getAccessibilityProps();

// Common Aural Properties
AuralProps mAurProps = propMgr.getAuralProps();

// Common Border, Padding, and Background Properties
BorderAndPadding bap = propMgr.getBorderAndPadding();
BackgroundProps bProps = propMgr.getBackgroundProps();

// Common Relative Position Properties
RelativePositionProps mRelProps =
propMgr.getRelativePositionProps();

setupID();

this.spaceBefore = this.properties.get(
"space-before.optimum").getLength().mvalue();
this.spaceAfter = this.properties.get(
"space-after.optimum").getLength().mvalue();
this.backgroundColor =
this.properties.get("background-color").getColorType();

}


+ 11
- 0
src/org/apache/fop/fo/flow/TableCell.java View File

@@ -14,8 +14,12 @@ import org.apache.fop.layout.*;
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.*;

import org.apache.fop.layoutmgr.table.Cell;

import org.xml.sax.Attributes;

import java.util.List;

public class TableCell extends FObj {

// int spaceBefore;
@@ -92,6 +96,13 @@ public class TableCell extends FObj {
doSetup(); // init some basic property values
}

/**
*/
public void addLayoutManager(List list) {
Cell clm = new Cell(this);
list.add(clm);
}

// Set position relative to table (set by body?)
public void setStartOffset(int offset) {
startOffset = offset;

+ 11
- 1
src/org/apache/fop/fo/flow/TableColumn.java View File

@@ -14,6 +14,10 @@ import org.apache.fop.layout.*;
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.*;

import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.table.Column;


public class TableColumn extends FObj {

ColorType backgroundColor;
@@ -30,6 +34,11 @@ public class TableColumn extends FObj {
super(parent);
}

public LayoutManager getLayoutManager() {
doSetup();
return new Column(this);
}

public Length getColumnWidthAsLength() {
return columnWidthPropVal;
}
@@ -54,7 +63,7 @@ public class TableColumn extends FObj {
return numColumnsRepeated;
}

public void doSetup() throws FOPException {
public void doSetup() {

// Common Border, Padding, and Background Properties
// only background apply, border apply if border-collapse
@@ -88,3 +97,4 @@ public class TableColumn extends FObj {
}

}


+ 9
- 202
src/org/apache/fop/fo/flow/TableRow.java View File

@@ -14,8 +14,11 @@ import org.apache.fop.datatypes.*;
import org.apache.fop.layout.*;
import org.apache.fop.apps.FOPException;

import org.apache.fop.layoutmgr.table.Row;

// Java
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

public class TableRow extends FObj {
@@ -29,140 +32,17 @@ public class TableRow extends FObj {
KeepValue keepWithPrevious;
KeepValue keepTogether;

int widthOfCellsSoFar = 0;
int largestCellHeight = 0;
int minHeight = 0; // force row height
ArrayList columns;

boolean areaAdded = false;

private RowSpanMgr rowSpanMgr = null;
private CellArray cellArray = null;

private static class CellArray {
public static final byte EMPTY = 0;
public static final byte CELLSTART = 1;
public static final byte CELLSPAN = 2;

private TableCell[] cells;
private byte[] states;

public CellArray(RowSpanMgr rsi, int numColumns) {
// Initialize the cell array by marking any cell positions
// occupied by spans from previous rows
cells = new TableCell[numColumns];
states = new byte[numColumns];
for (int i = 0; i < numColumns; i++) {
if (rsi.isSpanned(i + 1)) {
cells[i] = rsi.getSpanningCell(i + 1);
states[i] = CELLSPAN;
} else
states[i] = EMPTY;
}
}

/**
* Return column which doesn't already contain a span or a cell
* If past the end or no free cells after colNum, return -1
* Otherwise return value >= input value.
*/
int getNextFreeCell(int colNum) {
for (int i = colNum - 1; i < states.length; i++) {
if (states[i] == EMPTY)
return i + 1;
}
return -1;
}


/**
* Return type of cell in colNum (1 based)
*/
int getCellType(int colNum) {
if (colNum > 0 && colNum <= cells.length) {
return states[colNum - 1];
} else
return -1; // probably should throw exception
}

/**
* Return cell in colNum (1 based)
*/
TableCell getCell(int colNum) {
if (colNum > 0 && colNum <= cells.length) {
return cells[colNum - 1];
} else
return null; // probably should throw exception
}

/**
* Store cell starting at cellColNum (1 based) and spanning numCols
* If any of the columns is already occupied, return false, else true
*/
boolean storeCell(TableCell cell, int colNum, int numCols) {
boolean rslt = true;
int index = colNum - 1;
for (int count = 0; index < cells.length && count < numCols;
count++, index++) {
if (cells[index] == null) {
cells[index] = cell;
states[index] = (count == 0) ? CELLSTART : CELLSPAN;
} else {
rslt = false;
// print a message but continue!!!
}
}
return rslt;
}

// private class EnumCells implements Enumeration {
// private int iNextIndex=0;
// private Object nextCell = null;
// EnumCells() {
// findNextCell();
// }

// private void findNextCell() {
// for (; iNextIndex < cells.length; iNextIndex++) {
// if (states[iNextIndex] == CELLSTART) {
// nextCell = cells[iNextIndex];
// return;
// }
// }
// nextCell = null;
// }

// public boolean hasMoreElements() {
// return (nextCell != null);
// }

// public Object nextElement() {
// if (nextCell != null) {
// Object cell = nextCell;
// findNextCell();
// return cell;
// }
// else throw new java.util.NoSuchElementException("No more cells");
// }
// }

// /**
// * Return an enumeration over all cells in this row
// * Return each element in cells whose state is CELLSTART or EMPTY?
// * Skip spanning elements.
// */
// Enumeration getCells() {
// return new EnumCells();
// }
}


public TableRow(FONode parent) {
super(parent);
}

public void setColumns(ArrayList columns) {
this.columns = columns;
/**
*/
public void addLayoutManager(List list) {
Row rlm = new Row(this);
list.add(rlm);
}

public KeepValue getKeepWithPrevious() {
@@ -225,78 +105,5 @@ public class TableRow extends FObj {
// break;
}
}

/**
* Called by parent FO to initialize information about
* cells started in previous rows which span into this row.
* The layout operation modifies rowSpanMgr
*/
public void setRowSpanMgr(RowSpanMgr rowSpanMgr) {
this.rowSpanMgr = rowSpanMgr;
}

/**
* Before starting layout for the first time, initialize information
* about spanning rows, empty cells and spanning columns.
*/
private void initCellArray() {
cellArray = new CellArray(rowSpanMgr, columns.size());
int colNum = 1;
Iterator eCells = children.iterator();
while (eCells.hasNext()) {
colNum = cellArray.getNextFreeCell(colNum);
// If off the end, the rest of the cells had better be
// explicitly positioned!!! (returns -1)

TableCell cell = (TableCell)eCells.next();
int numCols = cell.getNumColumnsSpanned();
int numRows = cell.getNumRowsSpanned();
int cellColNum = cell.getColumnNumber();

if (cellColNum == 0) {
// Not explicitly specified, so put in next available colummn
// cell.setColumnNumber(colNum);
// If cellColNum "off the end", this cell is in limbo!
if (colNum < 1) {
// ERROR!!!
continue;
} else
cellColNum = colNum;
} else if (cellColNum > columns.size()) {
// Explicit specification out of range!
// Skip it and print an ERROR MESSAGE
continue;
}
// see if it fits and doesn't overwrite anything
if (cellColNum + numCols - 1 > columns.size()) {
// MESSAGE: TOO MANY COLUMNS SPANNED!
numCols = columns.size() - cellColNum + 1;
}
// Check for overwriting other cells (returns false)
if (cellArray.storeCell(cell, cellColNum, numCols) == false) {
// Print out some kind of warning message.
}
if (cellColNum > colNum) {
// Cells are initialized as empty already
colNum = cellColNum;
} else if (cellColNum < colNum) {
// MESSAGE ? cells out of order?
colNum = cellColNum; // CR "to the letter"!
}
int cellWidth = getCellWidth(cellColNum, numCols);
cell.setWidth(cellWidth);
colNum += numCols; // next cell in this column
}
}

// ATTENTION if startCol + numCols > number of columns in table!
private int getCellWidth(int startCol, int numCols) {
int width = 0;
for (int count = 0; count < numCols; count++) {
width += ((TableColumn)columns.get(startCol + count
- 1)).getColumnWidth();
}
return width;
}

}


+ 47
- 14
src/org/apache/fop/layoutmgr/AbstractLayoutManager.java View File

@@ -8,14 +8,12 @@
package org.apache.fop.layoutmgr;

import org.apache.fop.fo.FObj;
import org.apache.fop.fo.FONode;
import org.apache.fop.area.Area;
import org.apache.fop.area.Resolveable;
import org.apache.fop.area.PageViewport;
import org.apache.fop.fo.PropertyManager;

import java.util.ListIterator;
import java.util.ArrayList;

/**
* The base class for all LayoutManagers.
@@ -106,18 +104,10 @@ public abstract class AbstractLayoutManager implements LayoutManager {
return m_curChildLM;
}
while (m_childLMiter.hasNext()) {
Object obj = m_childLMiter.next();
if (obj instanceof LayoutManager) {
m_curChildLM = (LayoutManager) obj;
m_curChildLM.setParentLM(this);
m_curChildLM.init();
return m_curChildLM;
} else {
m_childLMiter.remove();
//log.warn(
// "child LM not a LayoutManager: " +
// obj.getClass().getName());
}
m_curChildLM = (LayoutManager) m_childLMiter.next();
m_curChildLM.setParentLM(this);
m_curChildLM.init();
return m_curChildLM;
}
return null;
}
@@ -257,26 +247,69 @@ public abstract class AbstractLayoutManager implements LayoutManager {
return false;
}

/**
* Delegate getting the current page number to the parent layout manager.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public String getCurrentPageNumber() {
return parentLM.getCurrentPageNumber();
}

/**
* Delegate resolving the id reference to the parent layout manager.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public PageViewport resolveRefID(String ref) {
return parentLM.resolveRefID(ref);
}

/**
* Add the id to the page.
* If the id string is not null then add the id to the current page.
*/
protected void addID() {
if(foID != null) {
addIDToPage(foID);
}
}

/**
* Delegate adding id reference to the parent layout manager.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public void addIDToPage(String id) {
parentLM.addIDToPage(id);
}

/**
* Delegate adding unresolved area to the parent layout manager.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public void addUnresolvedArea(String id, Resolveable res) {
parentLM.addUnresolvedArea(id, res);
}

/**
* Delegate adding marker to the parent layout manager.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public void addMarker(String name, LayoutManager lm, boolean start) {
parentLM.addMarker(name, lm, start);
}

/**
* Delegate retrieve marker to the parent layout manager.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public LayoutManager retrieveMarker(String name, int pos, int boundary) {
return parentLM.retrieveMarker(name, pos, boundary);
}

}


+ 14
- 10
src/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java View File

@@ -231,27 +231,26 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
if (curBlockArea == null) {
viewportBlockArea = new BlockViewport();
if(abProps.absolutePosition == AbsolutePosition.ABSOLUTE) {
Rectangle2D rect = new Rectangle2D.Double(abProps.left,
abProps.top, abProps.right - abProps.left,
abProps.bottom - abProps.top);
viewportBlockArea.setBounds(rect);
viewportBlockArea.setXOffset(abProps.left);
viewportBlockArea.setYOffset(abProps.top);
viewportBlockArea.setWidth(abProps.right - abProps.left);
viewportBlockArea.setHeight(abProps.bottom - abProps.top);

viewportBlockArea.setCTM(absoluteCTM);
viewportBlockArea.setClip(clip);
} else {
double[] vals = absoluteCTM.toArray();
boolean rotated = vals[0] == 0.0;
if(rotated) {
Rectangle2D rect = new Rectangle2D.Double(0, 0,
relDims.bpd, getRotatedIPD());
viewportBlockArea.setBounds(rect);
viewportBlockArea.setWidth(relDims.bpd);
viewportBlockArea.setHeight(getRotatedIPD());
viewportBlockArea.setCTM(absoluteCTM);
viewportBlockArea.setClip(clip);
} else if(vals[0] == -1.0) {
// need to set bpd to actual size for rotation
// and stacking
Rectangle2D rect = new Rectangle2D.Double(0, 0,
relDims.ipd, relDims.bpd);
viewportBlockArea.setBounds(rect);
viewportBlockArea.setWidth(relDims.ipd);
viewportBlockArea.setWidth(relDims.bpd);
viewportBlockArea.setCTM(absoluteCTM);
viewportBlockArea.setClip(clip);
}
@@ -289,5 +288,10 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
reset(null);
}
}

public void addMarker(String name, LayoutManager lm, boolean start) {
parentLM.addMarker(name, lm, start);
}

}


+ 0
- 9
src/org/apache/fop/layoutmgr/BlockLayoutManager.java View File

@@ -211,20 +211,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
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 {
curBlockArea.addBlock((Block) childArea);
//return super.addChild(childArea);

return false;
}

+ 3
- 4
src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java View File

@@ -1,6 +1,6 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/
@@ -48,8 +48,6 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
this.parentArea = parentArea;
}



protected MinOptMax resolveSpaceSpecifier(Area nextArea) {
SpaceSpecifier spaceSpec = new SpaceSpecifier(false);
// Area prevArea = getCurrentArea().getLast();
@@ -126,8 +124,9 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager {
* Force current area to be added to parent area.
*/
protected boolean flush() {
if (getCurrentArea() != null)
if (getCurrentArea() != null) {
return parentLM.addChild(getCurrentArea());
}
return false;
}


+ 1
- 1
src/org/apache/fop/layoutmgr/BreakPossPosIter.java View File

@@ -13,7 +13,7 @@ import java.util.List;
public class BreakPossPosIter extends PositionIterator {
private int m_iterCount ;

BreakPossPosIter(List bpList, int startPos, int endPos) {
public BreakPossPosIter(List bpList, int startPos, int endPos) {
super(bpList.listIterator(startPos));
m_iterCount = endPos - startPos;
}

+ 10
- 0
src/org/apache/fop/layoutmgr/ContentLayoutManager.java View File

@@ -178,5 +178,15 @@ public class ContentLayoutManager implements LayoutManager {
public void addUnresolvedArea(String id, Resolveable res) {
parentLM.addUnresolvedArea(id, res);
}

/** @see org.apache.fop.layoutmgr.LayoutManager */
public void addMarker(String name, LayoutManager lm, boolean start) {
parentLM.addMarker(name, lm, start);
}

/** @see org.apache.fop.layoutmgr.LayoutManager */
public LayoutManager retrieveMarker(String name, int pos, int boundary) {
return parentLM.retrieveMarker(name, pos, boundary);
}
}


+ 11
- 0
src/org/apache/fop/layoutmgr/FlowLayoutManager.java View File

@@ -138,5 +138,16 @@ public class FlowLayoutManager extends BlockStackingLayoutManager {
reset(null);
}
}

/**
* Retrieve marker is not allowed in the flow so this reports an
* error and returns null.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public LayoutManager retrieveMarker(String name, int pos, int boundary) {
// error cannot retrieve markers in flow
return null;
}
}


+ 49
- 0
src/org/apache/fop/layoutmgr/LayoutManager.java View File

@@ -64,11 +64,60 @@ public interface LayoutManager {
public void getWordChars(StringBuffer sbChars, Position bp1,
Position bp2);

/**
* Get the string of the current page number.
*
* @return the string for the current page number
*/
public String getCurrentPageNumber();

/**
* Resolve the id reference.
* This is called by an area looking for an id reference.
* If the id reference is not found then it should add a resolveable object.
*
* @param ref the id reference
* @return the page containing the id reference or null if not found
*/
public PageViewport resolveRefID(String ref);

/**
* Add an id to the page.
* @todo add the location of the area on the page
*
* @param id the id reference to add.
*/
public void addIDToPage(String id);

/**
* Add an unresolved area.
* The is used to add a resolveable object to the page for a given id.
*
* @param id the id reference this object needs for resolving
* @param res the resolveable object
*/
public void addUnresolvedArea(String id, Resolveable res);

/**
* Add the marker.
* A number of formatting objects may contain markers. This
* method is used to add those markers to the page.
*
* @param name the marker class name
* @param lm the layout manager of the marker child
* @param start true if the formatting object is starting false is finishing
*/
public void addMarker(String name, LayoutManager lm, boolean start);

/**
* Retrieve a marker.
* This method is used when retrieve a marker.
*
* @param name the class name of the marker
* @param pos the retrieve position
* @param boundary the boundary for retrieving the marker
* @return the layout manaager of the retrieved marker if any
*/
public LayoutManager retrieveMarker(String name, int pos, int boundary);

}

+ 13
- 0
src/org/apache/fop/layoutmgr/PageLayoutManager.java View File

@@ -164,6 +164,19 @@ public class PageLayoutManager extends AbstractLayoutManager implements Runnable
areaTree.addUnresolvedID(id, curPage);
}

public void addMarker(String name, LayoutManager lm, boolean start) {
if(start) {
// add marker to page on area tree
} else {
// add end marker to page on area tree
}
}

public LayoutManager retrieveMarker(String name, int pos, int boundary) {
// get marker from the current markers on area tree
return null;
}

/**
* For now, only handle normal flow areas.
*/

+ 1
- 1
src/org/apache/fop/layoutmgr/PositionIterator.java View File

@@ -23,7 +23,7 @@ public abstract class PositionIterator implements Iterator {
//checkNext();
}

LayoutManager getNextChildLM() {
public LayoutManager getNextChildLM() {
// Move to next "segment" of iterator, ie: new childLM
if (m_childLM == null && m_nextObj != null) {
m_childLM = getLM(m_nextObj);

+ 15
- 7
src/org/apache/fop/layoutmgr/StaticContentLayoutManager.java View File

@@ -1,19 +1,18 @@
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr;

import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.properties.Constants;
import org.apache.fop.area.*;
import org.apache.fop.area.RegionReference;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;

import java.util.ArrayList;
import java.util.List;

/**
* LayoutManager for an fo:flow object.
@@ -24,7 +23,7 @@ import java.util.List;
public class StaticContentLayoutManager extends BlockStackingLayoutManager {

private RegionReference region;
ArrayList blockBreaks = new ArrayList();
private ArrayList blockBreaks = new ArrayList();
public StaticContentLayoutManager(FObj fobj) {
super(fobj);
@@ -46,7 +45,7 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager {
if (!curLM.isFinished()) {
if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
blockBreaks.add(bp);
if(bp.isForcedBreak()) {
if (bp.isForcedBreak()) {
System.out.println("Forced breaks are not allowed in static content");
return null;
}
@@ -98,5 +97,14 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager {
return region;
}

/**
* Markers are not allowed in static areas so this reports an
* error and does nothing.
*
* @see org.apache.fop.layoutmgr.LayoutManager
*/
public void addMarker(String name, LayoutManager lm, boolean start) {
// error markers not allowed in static
}
}


+ 213
- 0
src/org/apache/fop/layoutmgr/table/Body.java View File

@@ -0,0 +1,213 @@
/*
* $Id$
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr.table;

import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.fo.FObj;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;

import java.util.ArrayList;
import java.util.List;

/**
* LayoutManager for a table-header, table-footer and table body FO.
* These fo objects have either rows or cells underneath.
* Cells are organised into rows.
*/
public class Body extends BlockStackingLayoutManager {

private boolean rows = true;
private List columns;

private int yoffset;
private int bodyHeight;

private Block curBlockArea;

private ArrayList childBreaks = new ArrayList();

/**
* Create a new body layout manager.
*
* @param fobj the formatting object that created this manager
*/
public Body(FObj fobj) {
super(fobj);
}

/**
* Set the columns from the table.
*
* @param cols the list of columns used for this body
*/
public void setColumns(List cols) {
columns = cols;
}

/**
* Breaks for this layout manager are of the form of before
* or after a row and inside a row.
*
* @param context the layout context for finding the breaks
* @return the next break possibility
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
Row curLM; // currently active LM

MinOptMax stackSize = new MinOptMax();
BreakPoss lastPos = null;

while ((curLM = (Row)getChildLM()) != null) {
// Make break positions
// Set up a LayoutContext
int ipd = context.getRefIPD();
BreakPoss bp;

LayoutContext childLC = new LayoutContext(0);
childLC.setStackLimit(
MinOptMax.subtract(context.getStackLimit(),
stackSize));
childLC.setRefIPD(ipd);

curLM.setColumns(columns);

while (!curLM.isFinished()) {
if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
stackSize.add(bp.getStackingSize());
if (stackSize.min > context.getStackLimit().max) {
// reset to last break
if (lastPos != null) {
reset(lastPos.getPosition());
} else {
curLM.resetPosition(null);
}
break;
}
lastPos = bp;
childBreaks.add(bp);

childLC.setStackLimit(MinOptMax.subtract(
context.getStackLimit(), stackSize));
}
}
BreakPoss breakPoss = new BreakPoss(
new LeafPosition(this, childBreaks.size() - 1));
breakPoss.setStackingSize(stackSize);
return breakPoss;
}

setFinished(true);
return null;
}

/**
* Set the y offset of this body within the table.
* This is used to set the row offsets.
*
* @param off the y offset position
*/
public void setYOffset(int off) {
yoffset = off;
}

/**
* Add the areas for the break points.
* This sets the offset of each row as it is added.
*
* @param parentIter the position iterator
* @param layoutContext the layout context for adding areas
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
addID();

Row childLM;
int iStartPos = 0;
LayoutContext lc = new LayoutContext(0);
int rowoffset = 0;
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
PositionIterator breakPosIter =
new BreakPossPosIter(childBreaks, iStartPos,
lfp.getLeafPos() + 1);
iStartPos = lfp.getLeafPos() + 1;
while ((childLM = (Row)breakPosIter.getNextChildLM()) != null) {
childLM.setYOffset(yoffset + rowoffset);
childLM.addAreas(breakPosIter, lc);
rowoffset += childLM.getRowHeight();
}
}
bodyHeight = rowoffset;

flush();

childBreaks.clear();
curBlockArea = null;
}

/**
* Get the body height of the body after adjusting.
* Should only be called after adding the body areas.
*
* @return the body height of this body
*/
public int getBodyHeight() {
return bodyHeight;
}

/**
* Return an Area which can contain the passed childArea. The childArea
* may not yet have any content, but it has essential traits set.
* In general, if the LayoutManager already has an Area it simply returns
* it. Otherwise, it makes a new Area of the appropriate class.
* It gets a parent area for its area by calling its parent LM.
* Finally, based on the dimensions of the parent area, it initializes
* its own area. This includes setting the content IPD and the maximum
* BPD.
*
* @param childArea the child area
* @return the parent are of the child
*/
public Area getParentArea(Area childArea) {
return parentLM.getParentArea(childArea);
}

/**
* Add the child area.
* The table-header, table-footer and table-body areas return
* the areas return by the children.
*
* @param childArea the child area to add
* @return unused
*/
public boolean addChild(Area childArea) {
return parentLM.addChild(childArea);
}

/**
* Reset the position of the layout manager.
*
* @param resetPos the position to reset to
*/
public void resetPosition(Position resetPos) {
if (resetPos == null) {
reset(null);
}
}
}


+ 190
- 0
src/org/apache/fop/layoutmgr/table/Caption.java View File

@@ -0,0 +1,190 @@
/*
* $Id$
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr.table;

import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.fo.FObj;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;

import java.util.ArrayList;

/**
* LayoutManager for a table-caption FO.
* The table caption contains blocks that are placed beside the
* table.
*/
public class Caption extends BlockStackingLayoutManager {

private Block curBlockArea;

private ArrayList childBreaks = new ArrayList();

/**
* Create a new Caption layout manager.
*
* @param fobj the formatting object that created this manager
*/
public Caption(FObj fobj) {
super(fobj);
}

/**
* Get the next break position for the caption.
*
* @param context the layout context for finding breaks
* @return the next break possibility
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
LayoutManager curLM; // currently active LM

MinOptMax stackSize = new MinOptMax();
// if starting add space before
// stackSize.add(spaceBefore);
BreakPoss lastPos = null;

// if there is a caption then get the side and work out when
// to handle it

while ((curLM = getChildLM()) != null) {
// Make break positions and return blocks!
// Set up a LayoutContext
int ipd = context.getRefIPD();
BreakPoss bp;

LayoutContext childLC = new LayoutContext(0);
// if line layout manager then set stack limit to ipd
// line LM actually generates a LineArea which is a block
childLC.setStackLimit(
MinOptMax.subtract(context.getStackLimit(),
stackSize));
childLC.setRefIPD(ipd);

while (!curLM.isFinished()) {
if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
stackSize.add(bp.getStackingSize());
if (stackSize.min > context.getStackLimit().max) {
// reset to last break
if (lastPos != null) {
reset(lastPos.getPosition());
} else {
curLM.resetPosition(null);
}
break;
}
lastPos = bp;
childBreaks.add(bp);

childLC.setStackLimit(MinOptMax.subtract(
context.getStackLimit(), stackSize));
}
}
BreakPoss breakPoss = new BreakPoss(
new LeafPosition(this, childBreaks.size() - 1));
breakPoss.setStackingSize(stackSize);
return breakPoss;
}
setFinished(true);
return null;
}

/**
* Add the areas to the parent.
*
* @param parentIter the position iterator of the breaks
* @param layoutContext the layout context for adding areas
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
addID();

LayoutManager childLM;
int iStartPos = 0;
LayoutContext lc = new LayoutContext(0);
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
PositionIterator breakPosIter =
new BreakPossPosIter(childBreaks, iStartPos,
lfp.getLeafPos() + 1);
iStartPos = lfp.getLeafPos() + 1;
while ((childLM = breakPosIter.getNextChildLM()) != null) {
childLM.addAreas(breakPosIter, lc);
}
}

flush();

childBreaks.clear();
curBlockArea = null;
}

/**
* Return an Area which can contain the passed childArea. The childArea
* may not yet have any content, but it has essential traits set.
* In general, if the LayoutManager already has an Area it simply returns
* it. Otherwise, it makes a new Area of the appropriate class.
* It gets a parent area for its area by calling its parent LM.
* Finally, based on the dimensions of the parent area, it initializes
* its own area. This includes setting the content IPD and the maximum
* BPD.
*
* @param childArea the child area
* @return the parent area from this caption
*/
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLM.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
setCurrentArea(curBlockArea); // ??? for generic operations
}
return curBlockArea;
}

/**
* Add the child to the caption area.
*
* @param childArea the child area to add
* @return unused
*/
public boolean addChild(Area childArea) {
if (curBlockArea != null) {
curBlockArea.addBlock((Block) childArea);
//return super.addChild(childArea);

return false;
}
return false;
}

/**
* Reset the layout position.
*
* @param resetPos the position to reset to
*/
public void resetPosition(Position resetPos) {
if (resetPos == null) {
reset(null);
}
}
}


+ 215
- 0
src/org/apache/fop/layoutmgr/table/Cell.java View File

@@ -0,0 +1,215 @@
/*
* $Id$
* Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr.table;

import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.fo.FObj;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;

import java.util.ArrayList;

/**
* LayoutManager for a table-cell FO.
* A cell contains blocks. These blocks fill the cell.
*/
public class Cell extends BlockStackingLayoutManager {

private Block curBlockArea;

private ArrayList childBreaks = new ArrayList();

private int xoffset;
private int yoffset;
private int cellIPD;

/**
* Create a new Cell layout manager.
* @param fobj the formatting object for the cell
*/
public Cell(FObj fobj) {
super(fobj);
}

/**
* Get the next break possibility for this cell.
* A cell contains blocks so there are breaks around the blocks
* and inside the blocks.
*
* @param context the layout context
* @return the next break possibility
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
LayoutManager curLM; // currently active LM

MinOptMax stackSize = new MinOptMax();
// if starting add space before
// stackSize.add(spaceBefore);
BreakPoss lastPos = null;

cellIPD = context.getRefIPD();

while ((curLM = getChildLM()) != null) {
// Set up a LayoutContext
int ipd = context.getRefIPD();
BreakPoss bp;

LayoutContext childLC = new LayoutContext(0);
childLC.setStackLimit(MinOptMax.subtract(context.getStackLimit(),
stackSize));
childLC.setRefIPD(ipd);

while (!curLM.isFinished()) {
if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
stackSize.add(bp.getStackingSize());
if (stackSize.min > context.getStackLimit().max) {
// reset to last break
if (lastPos != null) {
reset(lastPos.getPosition());
} else {
curLM.resetPosition(null);
}
break;
}
lastPos = bp;
childBreaks.add(bp);

childLC.setStackLimit(MinOptMax.subtract(
context.getStackLimit(), stackSize));
}
}
BreakPoss breakPoss = new BreakPoss(
new LeafPosition(this, childBreaks.size() - 1));
breakPoss.setStackingSize(stackSize);
return breakPoss;
}
setFinished(true);
return null;
}

/**
* Set the y offset of this cell.
* This offset is used to set the absolute position of the cell.
*
* @param off the y direction offset
*/
public void setYOffset(int off) {
yoffset = off;
}

/**
* Set the x offset of this cell.
* This offset is used to set the absolute position of the cell.
*
* @param off the x offset
*/
public void setXOffset(int off) {
xoffset = off;
}

/**
* Add the areas for the break points.
* The cell contains block stacking layout managers
* that add block areas.
*
* @param parentIter the iterator of the break positions
* @param layoutContext the layout context for adding the areas
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
addID();

LayoutManager childLM;
int iStartPos = 0;
LayoutContext lc = new LayoutContext(0);
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
PositionIterator breakPosIter =
new BreakPossPosIter(childBreaks, iStartPos,
lfp.getLeafPos() + 1);
iStartPos = lfp.getLeafPos() + 1;
while ((childLM = breakPosIter.getNextChildLM()) != null) {
childLM.addAreas(breakPosIter, lc);
}
}

flush();

childBreaks.clear();
curBlockArea = null;
}

/**
* Return an Area which can contain the passed childArea. The childArea
* may not yet have any content, but it has essential traits set.
* In general, if the LayoutManager already has an Area it simply returns
* it. Otherwise, it makes a new Area of the appropriate class.
* It gets a parent area for its area by calling its parent LM.
* Finally, based on the dimensions of the parent area, it initializes
* its own area. This includes setting the content IPD and the maximum
* BPD.
*
* @param childArea the child area to get the parent for
* @return the parent area
*/
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
curBlockArea.setPositioning(Block.ABSOLUTE);
// set position
curBlockArea.setXOffset(xoffset);
curBlockArea.setYOffset(yoffset);
curBlockArea.setWidth(cellIPD);
//curBlockArea.setHeight();

// Set up dimensions
Area parentArea = parentLM.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
setCurrentArea(curBlockArea); // ??? for generic operations
}
return curBlockArea;
}

/**
* Add the child to the cell block area.
*
* @param childArea the child to add to the cell
* @return unused
*/
public boolean addChild(Area childArea) {
if (curBlockArea != null) {
curBlockArea.addBlock((Block) childArea);
return false;
}
return false;
}

/**
* Reset the position of the layout.
*
* @param resetPos the position to reset to
*/
public void resetPosition(Position resetPos) {
if (resetPos == null) {
reset(null);
}
}
}


+ 92
- 0
src/org/apache/fop/layoutmgr/table/Column.java View File

@@ -0,0 +1,92 @@
/*
* $Id$
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr.table;

import org.apache.fop.layoutmgr.AbstractLayoutManager;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.fo.flow.TableColumn;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;

/**
* LayoutManager for a table-column FO.
* The table creates an area for the table-column background, this class
* is used to do the area creation. This is used during the layout to handle
* column properties.
*/
public class Column extends AbstractLayoutManager {
private int columnWidth;

/**
* Create a new column layout manager.
*
* @param fobj the table-column formatting object
*/
public Column(TableColumn fobj) {
super(fobj);
columnWidth = fobj.getColumnWidth();
}

/**
* Get the next break possibility.
* Columns do not create or return any areas.
*
* @param context the layout context
* @return the break possibility, always null
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
return null;
}

/**
* Add the areas.
* Although this adds no areas it is used to add the id
* reference of the table-column.
*
* @param parentIter the position iterator
* @param layoutContext the context
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
addID();
}

/**
* Get the parent area.
* This does nothing.
*
* @param childArea the child area
* @return always null
*/
public Area getParentArea(Area childArea) {
return null;
}

/**
* Get the width of this column.
*
* @return the width of the column
*/
public int getWidth() {
return columnWidth;
}

/**
* Create a column area.
* This area has the background and width set.
* The Body manager will then set the offset of the column.
*
* @return the new column area
*/
public Area createColumnArea() {
return new Block();
}
}


+ 277
- 0
src/org/apache/fop/layoutmgr/table/Row.java View File

@@ -0,0 +1,277 @@
/*
* $Id$
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr.table;

import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.fo.FObj;
import org.apache.fop.area.Area;
import org.apache.fop.area.MinOptMax;

import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;

/**
* LayoutManager for a table-row FO.
* The row contains cells that are organised according to the columns.
* A break in a table row will contain breaks for each table cell.
* If there are row spanning cells then these cells belong to this row
* but effect the occupied columns of future rows.
*/
public class Row extends BlockStackingLayoutManager {

private List cellList = null;
private List columns = null;
private int rowHeight;
private int yoffset;

private class RowPosition extends LeafPosition {
protected List cellBreaks;
protected RowPosition(LayoutManager lm, int pos, List l) {
super(lm, pos);
cellBreaks = l;
}
}

/**
* Create a new row layout manager.
*
* @param fobj the table-row formatting object
*/
public Row(FObj fobj) {
super(fobj);
}

/**
* Set the columns from the table.
*
* @param cols the list of columns for this table
*/
public void setColumns(List cols) {
columns = cols;
}

private void setupCells() {
cellList = new ArrayList();
// add cells to list
while (m_childLMiter.hasNext()) {
m_curChildLM = (LayoutManager) m_childLMiter.next();
m_curChildLM.setParentLM(this);
m_curChildLM.init();
cellList.add(m_curChildLM);
}
}

/**
* Get the layout manager for a cell.
*
* @param pos the position of the cell
* @return the cell layout manager
*/
protected Cell getCellLM(int pos) {
if (cellList == null) {
setupCells();
}
if (pos < cellList.size()) {
return (Cell)cellList.get(pos);
}
return null;
}

/**
* Get the next break possibility.
* A row needs to get the possible breaks for each cell
* in the row and find a suitable break across all cells.
*
* @param context the layout context for getting breaks
* @return the next break possibility
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
LayoutManager curLM; // currently active LM

BreakPoss lastPos = null;
ArrayList breakList = new ArrayList();

int min = 0;
int opt = 0;
int max = 0;

int cellcount = 0;
while ((curLM = getCellLM(cellcount++)) != null) {

ArrayList childBreaks = new ArrayList();
MinOptMax stackSize = new MinOptMax();

// Set up a LayoutContext
// the ipd is from the current column
int ipd = context.getRefIPD();
BreakPoss bp;

LayoutContext childLC = new LayoutContext(0);
childLC.setStackLimit(
MinOptMax.subtract(context.getStackLimit(),
stackSize));

Column col = (Column)columns.get(cellcount - 1);
childLC.setRefIPD(col.getWidth());

while (!curLM.isFinished()) {
if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
stackSize.add(bp.getStackingSize());
if (stackSize.min > context.getStackLimit().max) {
// reset to last break
if (lastPos != null) {
reset(lastPos.getPosition());
} else {
curLM.resetPosition(null);
}
break;
}
lastPos = bp;
childBreaks.add(bp);

childLC.setStackLimit(MinOptMax.subtract(
context.getStackLimit(), stackSize));
}
}
// the min is the maximum min of all cells
if (stackSize.min > min) {
min = stackSize.min;
}
// the optimum is the average of all optimums
opt += stackSize.opt;
// the maximum is the largest maximum
if (stackSize.max > max) {
max = stackSize.max;
}

breakList.add(childBreaks);
}
opt = opt / cellcount;
if (opt < min) {
opt = min;
}
rowHeight = opt;

MinOptMax rowSize = new MinOptMax(min, opt, max);

setFinished(true);
RowPosition rp = new RowPosition(this, breakList.size() - 1, breakList);
BreakPoss breakPoss = new BreakPoss(rp);
breakPoss.setStackingSize(rowSize);
return breakPoss;
}

/**
* Set the y position offset of this row.
* This is used to set the position of the areas returned by this row.
*
* @param off the y offset
*/
public void setYOffset(int off) {
yoffset = off;
}

/**
* Add the areas for the break points.
* This sets the offset of each cell as it is added.
*
* @param parentIter the position iterator
* @param layoutContext the layout context for adding areas
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
addID();

Cell childLM;
int iStartPos = 0;
LayoutContext lc = new LayoutContext(0);
while (parentIter.hasNext()) {
RowPosition lfp = (RowPosition) parentIter.next();
// Add the block areas to Area

int cellcount = 0;
int xoffset = 0;
for (Iterator iter = lfp.cellBreaks.iterator(); iter.hasNext();) {
List cellsbr = (List)iter.next();
PositionIterator breakPosIter;
breakPosIter = new BreakPossPosIter(cellsbr, 0, cellsbr.size());
iStartPos = lfp.getLeafPos() + 1;
Column col = (Column)columns.get(cellcount++);
while ((childLM = (Cell)breakPosIter.getNextChildLM()) != null) {
childLM.setXOffset(xoffset);
childLM.setYOffset(yoffset);
childLM.addAreas(breakPosIter, lc);
}
xoffset += col.getWidth();
}
}

flush();

}

/**
* Get the row height of the row after adjusting.
* Should only be called after adding the row areas.
*
* @return the row height of this row after adjustment
*/
public int getRowHeight() {
return rowHeight;
}

/**
* Return an Area which can contain the passed childArea. The childArea
* may not yet have any content, but it has essential traits set.
* In general, if the LayoutManager already has an Area it simply returns
* it. Otherwise, it makes a new Area of the appropriate class.
* It gets a parent area for its area by calling its parent LM.
* Finally, based on the dimensions of the parent area, it initializes
* its own area. This includes setting the content IPD and the maximum
* BPD.
*
* @param childArea the child area
* @return the parent are for the child
*/
public Area getParentArea(Area childArea) {
return parentLM.getParentArea(childArea);
}

/**
* Add the child.
* Rows return the areas returned by the child elements.
* This simply adds the area to the parent layout manager.
*
* @param childArea the child area
* @return unused
*/
public boolean addChild(Area childArea) {
return parentLM.addChild(childArea);
}

/**
* Reset the position of this layout manager.
*
* @param resetPos the position to reset to
*/
public void resetPosition(Position resetPos) {
if (resetPos == null) {
reset(null);
}
}
}


+ 192
- 0
src/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java View File

@@ -0,0 +1,192 @@
/*
* $Id$
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr.table;

import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.fo.FObj;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;

import java.util.ArrayList;

/**
* LayoutManager for a table-and-caption FO.
* A table and caption consists of a table and a caption.
* The caption contains blocks that are positioned next to the
* table on the caption side.
* The caption blocks have an implicit keep with the table.
*/
public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager {

private Block curBlockArea;

private ArrayList childBreaks = new ArrayList();

/**
* Create a new table and caption layout manager.
*
* @param fobj the table-and-caption formatting object
*/
public TableAndCaptionLayoutManager(FObj fobj) {
super(fobj);
}

/**
* Get the next break possibility.
*
* @param context the layout context for getting breaks
* @return the next break possibility
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
LayoutManager curLM; // currently active LM

MinOptMax stackSize = new MinOptMax();
// if starting add space before
// stackSize.add(spaceBefore);
BreakPoss lastPos = null;

// if there is a caption then get the side and work out when
// to handle it

while ((curLM = getChildLM()) != null) {
// Make break positions and return blocks!
// Set up a LayoutContext
int ipd = context.getRefIPD();
BreakPoss bp;

LayoutContext childLC = new LayoutContext(0);
// if line layout manager then set stack limit to ipd
// line LM actually generates a LineArea which is a block
childLC.setStackLimit(
MinOptMax.subtract(context.getStackLimit(),
stackSize));
childLC.setRefIPD(ipd);

while (!curLM.isFinished()) {
if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
stackSize.add(bp.getStackingSize());
if (stackSize.min > context.getStackLimit().max) {
// reset to last break
if (lastPos != null) {
reset(lastPos.getPosition());
} else {
curLM.resetPosition(null);
}
break;
}
lastPos = bp;
childBreaks.add(bp);

childLC.setStackLimit(MinOptMax.subtract(
context.getStackLimit(), stackSize));
}
}
BreakPoss breakPoss = new BreakPoss(
new LeafPosition(this, childBreaks.size() - 1));
breakPoss.setStackingSize(stackSize);
return breakPoss;
}
setFinished(true);
return null;
}

/**
* Add the areas.
*
* @param parentIter the position iterator
* @param layoutContext the layout context for adding areas
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
addID();

LayoutManager childLM;
int iStartPos = 0;
LayoutContext lc = new LayoutContext(0);
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
PositionIterator breakPosIter =
new BreakPossPosIter(childBreaks, iStartPos,
lfp.getLeafPos() + 1);
iStartPos = lfp.getLeafPos() + 1;
while ((childLM = breakPosIter.getNextChildLM()) != null) {
childLM.addAreas(breakPosIter, lc);
}
}

flush();

childBreaks.clear();
curBlockArea = null;
}

/**
* Return an Area which can contain the passed childArea. The childArea
* may not yet have any content, but it has essential traits set.
* In general, if the LayoutManager already has an Area it simply returns
* it. Otherwise, it makes a new Area of the appropriate class.
* It gets a parent area for its area by calling its parent LM.
* Finally, based on the dimensions of the parent area, it initializes
* its own area. This includes setting the content IPD and the maximum
* BPD.
*
* @param childArea the child area to locate the parent
* @return the area for this table and caption
*/
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLM.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
setCurrentArea(curBlockArea); // ??? for generic operations
}
return curBlockArea;
}

/**
* Add the child to the current area.
*
* @param childArea the area to add
* @return unused
*/
public boolean addChild(Area childArea) {
if (curBlockArea != null) {
curBlockArea.addBlock((Block) childArea);
//return super.addChild(childArea);

return false;
}
return false;
}

/**
* Reset the position of this layout manager.
*
* @param resetPos the position to reset to
*/
public void resetPosition(Position resetPos) {
if (resetPos == null) {
reset(null);
}
}
}


+ 291
- 0
src/org/apache/fop/layoutmgr/table/TableLayoutManager.java View File

@@ -0,0 +1,291 @@
/*
* $Id$
* Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/

package org.apache.fop.layoutmgr.table;

import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.BreakPoss;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.BreakPossPosIter;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.fo.FObj;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.MinOptMax;

import java.util.ArrayList;
import java.util.List;

/**
* LayoutManager for a table FO.
* A table consists of columns, table header, table footer and multiple
* table bodies.
* The header, footer and body add the areas created from the table cells.
* The table then creates areas for the columns, bodies and rows
* the render background.
*/
public class TableLayoutManager extends BlockStackingLayoutManager {
private List columns = null;
private Body tableHeader = null;
private Body tableFooter = null;

private Block curBlockArea;

private ArrayList bodyBreaks = new ArrayList();
private BreakPoss headerBreak;
private BreakPoss footerBreak;

private class SectionPosition extends LeafPosition {
protected List list;
protected SectionPosition(LayoutManager lm, int pos, List l) {
super(lm, pos);
list = l;
}
}

/**
* Create a new table layout manager.
*
* @param fobj the table formatting object
*/
public TableLayoutManager(FObj fobj) {
super(fobj);
}

/**
* Set the columns for this table.
*
* @param cols the list of column layout managers
*/
public void setColumns(List cols) {
columns = cols;
}

/**
* Set the table header.
*
* @param th the table header layout manager
*/
public void setTableHeader(Body th) {
tableHeader = th;
}

/**
* Set the table footer.
*
* @param tf the table footer layout manager
*/
public void setTableFooter(Body tf) {
tableFooter = tf;
}

/**
* Get the next break possibility.
* The break possibility depends on the height of the header and footer
* and possible breaks inside the table body.
*
* @param context the layout context for finding breaks
* @return the next break possibility
*/
public BreakPoss getNextBreakPoss(LayoutContext context) {
Body curLM; // currently active LM

MinOptMax stackSize = new MinOptMax();
// if starting add space before
// stackSize.add(spaceBefore);
BreakPoss lastPos = null;

MinOptMax headerSize = null;
if (tableHeader != null) {
headerBreak = getHeight(tableHeader, context);
headerSize = headerBreak.getStackingSize();
}

MinOptMax footerSize = null;
if (tableFooter != null) {
footerBreak = getHeight(tableFooter, context);
footerSize = footerBreak.getStackingSize();
}

while ((curLM = (Body)getChildLM()) != null) {
// Make break positions
// Set up a LayoutContext
int ipd = context.getRefIPD();
BreakPoss bp;

LayoutContext childLC = new LayoutContext(0);
childLC.setStackLimit(
MinOptMax.subtract(context.getStackLimit(),
stackSize));
childLC.setRefIPD(ipd);

curLM.setColumns(columns);

while (!curLM.isFinished()) {
if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
stackSize.add(bp.getStackingSize());
if (stackSize.min > context.getStackLimit().max) {
// reset to last break
if (lastPos != null) {
reset(lastPos.getPosition());
} else {
curLM.resetPosition(null);
}
break;
}
lastPos = bp;
bodyBreaks.add(bp);

childLC.setStackLimit(MinOptMax.subtract(
context.getStackLimit(), stackSize));
}
}
BreakPoss breakPoss = new BreakPoss(
new LeafPosition(this, bodyBreaks.size() - 1));
breakPoss.setStackingSize(stackSize);
return breakPoss;
}
setFinished(true);
return null;
}

/**
* Get the break possibility and height of the table header or footer.
*
* @param lm the header or footer layout manager
* @param context the parent layout context
* @return the break possibility containing the stacking size
*/
protected BreakPoss getHeight(Body lm, LayoutContext context) {
int ipd = context.getRefIPD();
BreakPoss bp;

MinOptMax stackSize = new MinOptMax();

LayoutContext childLC = new LayoutContext(0);
childLC.setStackLimit(context.getStackLimit());
childLC.setRefIPD(ipd);

lm.setColumns(columns);

ArrayList breaks = new ArrayList();
while (!lm.isFinished()) {
if ((bp = lm.getNextBreakPoss(childLC)) != null) {
stackSize.add(bp.getStackingSize());
breaks.add(bp);
childLC.setStackLimit(MinOptMax.subtract(
context.getStackLimit(), stackSize));
}
}
BreakPoss breakPoss = new BreakPoss(
new SectionPosition(this, breaks.size() - 1, breaks));
breakPoss.setStackingSize(stackSize);
return breakPoss;

}

/**
* The table area is a reference area that contains areas for
* columns, bodies, rows and the contents are in cells.
*
* @param parentIter the position iterator
* @param layoutContext the layout context for adding areas
*/
public void addAreas(PositionIterator parentIter,
LayoutContext layoutContext) {
getParentArea(null);
addID();

// add column, body then row areas

// add table header areas

int tableHeight = 0;

Body childLM;
int iStartPos = 0;
LayoutContext lc = new LayoutContext(0);
while (parentIter.hasNext()) {
LeafPosition lfp = (LeafPosition) parentIter.next();
// Add the block areas to Area
PositionIterator breakPosIter =
new BreakPossPosIter(bodyBreaks, iStartPos,
lfp.getLeafPos() + 1);
iStartPos = lfp.getLeafPos() + 1;
while ((childLM = (Body)breakPosIter.getNextChildLM()) != null) {
childLM.addAreas(breakPosIter, lc);
tableHeight += childLM.getBodyHeight();
}
}

// add footer areas

curBlockArea.setHeight(tableHeight);

flush();

bodyBreaks.clear();
curBlockArea = null;
}

/**
* Return an Area which can contain the passed childArea. The childArea
* may not yet have any content, but it has essential traits set.
* In general, if the LayoutManager already has an Area it simply returns
* it. Otherwise, it makes a new Area of the appropriate class.
* It gets a parent area for its area by calling its parent LM.
* Finally, based on the dimensions of the parent area, it initializes
* its own area. This includes setting the content IPD and the maximum
* BPD.
*
* @param childArea the child area
* @return the parent area of the child
*/
public Area getParentArea(Area childArea) {
if (curBlockArea == null) {
curBlockArea = new Block();
// Set up dimensions
// Must get dimensions from parent area
Area parentArea = parentLM.getParentArea(curBlockArea);
int referenceIPD = parentArea.getIPD();
curBlockArea.setIPD(referenceIPD);
// Get reference IPD from parentArea
setCurrentArea(curBlockArea); // ??? for generic operations
}
return curBlockArea;
}

/**
* Add the child area to this layout manager.
*
* @param childArea the child area to add
* @return unused
*/
public boolean addChild(Area childArea) {
if (curBlockArea != null) {
curBlockArea.addBlock((Block) childArea);

return false;
}
return false;
}

/**
* Reset the position of this layout manager.
*
* @param resetPos the position to reset to
*/
public void resetPosition(Position resetPos) {
if (resetPos == null) {
reset(null);
}
}
}


+ 48
- 1
src/org/apache/fop/render/AbstractRenderer.java View File

@@ -80,6 +80,19 @@ public abstract class AbstractRenderer extends AbstractLogEnabled
*/
protected int currentBlockIPPosition = 0;

/**
* the block progression position of the containing block used for
* absolutely positioned blocks
*/
protected int containingBPPosition = 0;

/**
* the inline progression position of the containing block used for
* absolutely positioned blocks
*/
protected int containingIPPosition = 0;


/** @see org.apache.fop.render.Renderer */
public void setUserAgent(FOUserAgent agent) {
userAgent = agent;
@@ -344,10 +357,33 @@ public abstract class AbstractRenderer extends AbstractLogEnabled
List children = block.getChildAreas();
if (children == null) {
// simply move position
currentBPPosition += block.getHeight();
} else if (block instanceof BlockViewport) {
renderBlockViewport((BlockViewport) block, children);
} else {
renderBlocks(children);
// save position and offset
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;

if (block.getPositioning() == Block.ABSOLUTE) {
currentIPPosition += block.getXOffset();
currentBPPosition += block.getYOffset();

renderBlocks(children);

// absolute blocks do not effect the layout
currentBPPosition = saveBP;
} else {
// relative blocks are offset
currentIPPosition += block.getXOffset();
currentBPPosition += block.getYOffset();

renderBlocks(children);

// stacked and relative blocks effect stacking
currentBPPosition = saveBP + block.getHeight();
}
currentIPPosition = saveIP;
}
}

@@ -493,10 +529,21 @@ public abstract class AbstractRenderer extends AbstractLogEnabled
* @param blocks The block areas
*/
protected void renderBlocks(List blocks) {
// the position of the containing block is used for
// absolutely positioned areas
int contBP = currentBPPosition;
int contIP = currentIPPosition;
containingBPPosition = contBP;
containingIPPosition = contIP;

for (int count = 0; count < blocks.size(); count++) {
Object obj = blocks.get(count);
if (obj instanceof Block) {
containingBPPosition = contBP;
containingIPPosition = contIP;
renderBlock((Block) obj);
containingBPPosition = contBP;
containingIPPosition = contIP;
} else {
// a line area is rendered from the top left position
// of the line, each inline object is offset from there

+ 17
- 20
src/org/apache/fop/render/pdf/PDFRenderer.java View File

@@ -360,16 +360,17 @@ public class PDFRenderer extends PrintRenderer {
currentStream.add("ET\n");

if (bv.getClip()) {
Rectangle2D rect = bv.getBounds();

currentStream.add("q\n");
float x = (float)rect.getX() / 1000f;
float y = (float)rect.getY() / 1000f;
float width = (float)rect.getWidth() / 1000f;
float height = (float)rect.getHeight() / 1000f;
float x = (float)(bv.getXOffset() + containingIPPosition) / 1000f;
float y = (float)(bv.getYOffset() + containingBPPosition) / 1000f;
float width = (float)bv.getWidth() / 1000f;
float height = (float)bv.getHeight() / 1000f;
clip(x, y, width, height);
}

CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
ctm = tempctm.multiply(ctm);

startVParea(ctm);
renderBlocks(children);
endVParea();
@@ -385,8 +386,6 @@ public class PDFRenderer extends PrintRenderer {
currentBPPosition = saveBP;
} else {

Rectangle2D rect = bv.getBounds();

if (ctm != null) {
currentIPPosition = 0;
currentBPPosition = 0;
@@ -396,20 +395,20 @@ public class PDFRenderer extends PrintRenderer {
double[] vals = ctm.toArray();
boolean aclock = vals[2] == 1.0;
if (vals[2] == 1.0) {
ctm = ctm.translate(-saveBP - rect.getHeight(), -saveIP);
ctm = ctm.translate(-saveBP - bv.getHeight(), -saveIP);
} else if (vals[0] == -1.0) {
ctm = ctm.translate(-saveIP - rect.getWidth(), -saveBP - rect.getHeight());
ctm = ctm.translate(-saveIP - bv.getWidth(), -saveBP - bv.getHeight());
} else {
ctm = ctm.translate(saveBP, saveIP - rect.getWidth());
ctm = ctm.translate(saveBP, saveIP - bv.getWidth());
}
}

if (bv.getClip()) {
currentStream.add("q\n");
float x = (float)rect.getX() / 1000f;
float y = (float)rect.getY() / 1000f;
float width = (float)rect.getWidth() / 1000f;
float height = (float)rect.getHeight() / 1000f;
float x = (float)bv.getXOffset() / 1000f;
float y = (float)bv.getYOffset() / 1000f;
float width = (float)bv.getWidth() / 1000f;
float height = (float)bv.getHeight() / 1000f;
clip(x, y, width, height);
}

@@ -430,11 +429,9 @@ public class PDFRenderer extends PrintRenderer {

// clip if necessary

if (rect != null) {
currentIPPosition = saveIP;
currentBPPosition = saveBP;
currentBPPosition += (int)(rect.getHeight());
}
currentIPPosition = saveIP;
currentBPPosition = saveBP;
currentBPPosition += (int)(bv.getHeight());
}
}


+ 1
- 1
src/org/apache/fop/traits/BlockProps.java View File

@@ -15,7 +15,7 @@ import org.apache.fop.datatypes.Length;
*/
public class BlockProps {
public int firstIndent; // text-indent
public int lastIndent; // last-line-indent
public int lastIndent; // last-line-indent
public int textAlign;
public int textAlignLast;
public int lineStackType; // line-stacking-strategy (enum)

+ 15
- 15
src/org/apache/fop/traits/BorderProps.java View File

@@ -10,25 +10,25 @@ package org.apache.fop.traits;
import org.apache.fop.datatypes.ColorType;

public class BorderProps {
public int style; // Enum for border style
public ColorType color; // Border color
public int width; // Border width
public int style; // Enum for border style
public ColorType color; // Border color
public int width; // Border width

public BorderProps(int style, int width, ColorType color) {
this.style = style;
this.width = width;
this.color = color;
this.style = style;
this.width = width;
this.color = color;
}

public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append('(');
sbuf.append(style); // Should get a String value for this enum constant
sbuf.append(',');
sbuf.append(color);
sbuf.append(',');
sbuf.append(width);
sbuf.append(')');
return sbuf.toString();
StringBuffer sbuf = new StringBuffer();
sbuf.append('(');
sbuf.append(style); // Should get a String value for this enum constant
sbuf.append(',');
sbuf.append(color);
sbuf.append(',');
sbuf.append(width);
sbuf.append(')');
return sbuf.toString();
}
}

+ 27
- 27
src/org/apache/fop/traits/LayoutProps.java View File

@@ -16,43 +16,43 @@ import org.apache.fop.fo.properties.Constants;
* Public "structure" allows direct member access.
*/
public class LayoutProps {
public int breakBefore; // enum constant BreakBefore.xxx
public int breakAfter; // enum constant BreakAfter.xxx
public int breakBefore; // enum constant BreakBefore.xxx
public int breakAfter; // enum constant BreakAfter.xxx
public boolean bIsSpan;
public SpaceVal spaceBefore;
public SpaceVal spaceAfter;

private static final int[] s_breakPriorities = new int[] {
Constants.AUTO, Constants.COLUMN, Constants.PAGE };
private static final int[] s_breakPriorities =
new int[]{ Constants.AUTO, Constants.COLUMN, Constants.PAGE };


public LayoutProps() {
breakBefore = breakAfter = Constants.AUTO;
bIsSpan = false;
breakBefore = breakAfter = Constants.AUTO;
bIsSpan = false;
}

// public static int higherBreak(int brkParent, int brkChild) {
// if (brkParent == brkChild) return brkChild;
// for (int i=0; i < s_breakPriorities.length; i++) {
// int bp = s_breakPriorities[i];
// if (bp == brkParent) return brkChild;
// else if (bp == brkChild) return brkParent;
// }
// return brkChild;
// }
// public static int higherBreak(int brkParent, int brkChild) {
// if (brkParent == brkChild) return brkChild;
// for (int i=0; i < s_breakPriorities.length; i++) {
// int bp = s_breakPriorities[i];
// if (bp == brkParent) return brkChild;
// else if (bp == brkChild) return brkParent;
// }
// return brkChild;
// }

public void combineWithParent(LayoutProps parentLP) {
if (parentLP.breakBefore != breakBefore) {
for (int i=0; i < s_breakPriorities.length; i++) {
int bp = s_breakPriorities[i];
if (bp == breakBefore) {
breakBefore = parentLP.breakBefore;
break;
}
else if (bp == parentLP.breakBefore) break;
}
}
// Parent span always overrides child span
bIsSpan = parentLP.bIsSpan;
if (parentLP.breakBefore != breakBefore) {
for (int i = 0; i < s_breakPriorities.length; i++) {
int bp = s_breakPriorities[i];
if (bp == breakBefore) {
breakBefore = parentLP.breakBefore;
break;
} else if (bp == parentLP.breakBefore)
break;
}
}
// Parent span always overrides child span
bIsSpan = parentLP.bIsSpan;
}
}

Loading…
Cancel
Save