aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache
diff options
context:
space:
mode:
authorKaren Lease <klease@apache.org>2001-11-11 14:13:51 +0000
committerKaren Lease <klease@apache.org>2001-11-11 14:13:51 +0000
commit33c605ec16b366fb1a064a8258a450e5b4c249b3 (patch)
tree440fe9daf210b6ebd62907c957f9b73ffac0457b /src/org/apache
parent987d0265dfea3a2bba8a30ae0931925e4791e76c (diff)
downloadxmlgraphics-fop-33c605ec16b366fb1a064a8258a450e5b4c249b3.tar.gz
xmlgraphics-fop-33c605ec16b366fb1a064a8258a450e5b4c249b3.zip
new layout managers
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194557 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org/apache')
-rw-r--r--src/org/apache/fop/layoutmgr/BlockLayoutManager.java144
-rw-r--r--src/org/apache/fop/layoutmgr/LineLayoutManager.java161
-rw-r--r--src/org/apache/fop/layoutmgr/TextLayoutManager.java73
3 files changed, 378 insertions, 0 deletions
diff --git a/src/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/org/apache/fop/layoutmgr/BlockLayoutManager.java
new file mode 100644
index 000000000..7b4bfbc80
--- /dev/null
+++ b/src/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -0,0 +1,144 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.BlockParent;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.LineArea;
+
+import java.util.ListIterator;
+
+/**
+ * LayoutManager for a block FO.
+ */
+public class BlockLayoutManager extends BlockStackingLayoutManager {
+
+ private Block curBlockArea;
+
+ public BlockLayoutManager(FObj fobj) {
+ super(fobj);
+ }
+
+ // DESIGN. Potential alternative to getParentArea() scheme
+// /**
+// * Called by child layout manager to get the available space for
+// * content in the inline progression direction.
+// * Note that a manager may need to ask its parent for this.
+// * For a block area, available IPD is determined by indents.
+// */
+// public int getContentIPD() {
+// getArea(); // make if not existing
+// return blockArea.getIPD();
+// }
+
+ /**
+ * Generate areas by tellings all layout managers for its FO's
+ * children to generate areas.
+ */
+ public void generateAreas() {
+ ListIterator children = fobj.getChildren();
+ while (children.hasNext()) {
+ LayoutManager lm = ((FObj)children.next()).getLayoutManager();
+ if (lm != null) {
+ if (lm.generatesInlineAreas()) {
+ // Back up one
+ children.previous();
+ lm = new LineLayoutManager(children);
+ }
+ lm.setParentLM(this);
+ lm.generateAreas();
+ }
+ }
+ flush(); // Add last area to parent
+ }
+
+
+ /**
+ * 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.
+ */
+ public Area getParentArea(Area childArea) {
+ if (curBlockArea == null) {
+ curBlockArea = new Block();
+ // Set up dimensions
+ // Must get dimensions from parent area
+ //MinOptMax referenceIPD = parentLM.getReferenceIPD();
+ Area parentArea = parentLM.getParentArea(curBlockArea);
+ // Get reference IPD from parentArea
+ setCurrentArea(curBlockArea); // ??? for generic operations
+ }
+ return curBlockArea;
+ }
+
+
+ public void 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);
+ }
+ else {
+ super.addChild(childArea);
+ }
+ }
+ }
+
+
+
+// /**
+// * Called by child LayoutManager when it has filled one of its areas.
+// * If no current container, make one.
+// * See if the area will fit in the current container.
+// * If so, add it.
+// * @param childArea the area to add: will either be a LineArea or
+// * a BlockArea.
+// */
+// public void addChild(Area childArea) {
+// /* If the childArea fits entirely in the maximum available BPD
+// * add it and return an OK status.
+// * If it doesn't all fit, overrun or ask for split?
+// * Might as well just add it since the page layout process
+// * may need to make other adjustments, resulting in changing
+// * split point.
+// */
+// // Things like breaks on child area can cause premature
+// // termination of the current area.
+// /* We go past the theoretical maximum to be able to handle things
+// * like widows.
+// */
+// // WARNING: this doesn't take into account space-specifier
+// // adujstment between childArea and last content of blockArea!
+// if (blockArea.getContentBPD().min + childArea.getAllocationBPD().min
+// > blockArea.getAvailBPD().max) {
+// if (++extraLines <= iWidows) {
+// blockArea.add(childArea);
+// }
+// else {
+// blockArea.setIsLast(false);
+// parentLM.addChildArea(blockArea);
+// // Make a new one for this area
+// blockArea = makeAreaForChild(childArea);
+// extraLines = 0; // Count potential widows
+// blockArea.add(childArea);
+// }
+// }
+// else {
+// blockArea.add(childArea);
+// }
+// }
+
+}
diff --git a/src/org/apache/fop/layoutmgr/LineLayoutManager.java b/src/org/apache/fop/layoutmgr/LineLayoutManager.java
new file mode 100644
index 000000000..38451354b
--- /dev/null
+++ b/src/org/apache/fop/layoutmgr/LineLayoutManager.java
@@ -0,0 +1,161 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.LineArea;
+import org.apache.fop.area.MinOptMax;
+import org.apache.fop.area.inline.InlineArea;
+
+import java.util.ListIterator;
+
+/**
+ * LayoutManager for lines. It builds one or more lines containing
+ * inline areas generated by its sub layout managers.
+ */
+public class LineLayoutManager extends AbstractLayoutManager {
+ /** Reference to FO whose areas it's managing or to the traits
+ * of the FO.
+ */
+ private ListIterator fobjIter;
+ private LineArea lineArea = null;
+ private boolean bFirstLine;
+ private LayoutManager curLM;
+ private MinOptMax remainingIPD;
+
+ public LineLayoutManager(ListIterator fobjIter) {
+ super(null);
+ this.fobjIter = fobjIter;
+ }
+
+
+ /**
+ * Call child layout managers to generate content as long as they
+ * generate inline areas. If a block-level generating LM is found,
+ * finish any line being filled and return to the parent LM.
+ */
+ public void generateAreas() {
+ this.bFirstLine = true;
+ while (fobjIter.hasNext()) {
+ FObj fobj = (FObj)fobjIter.next();
+ curLM = fobj.getLayoutManager();
+ if (curLM != null) {
+ if (curLM.generatesInlineAreas()==false) {
+ // It generates blocks, pass back to parent
+ // Back up one
+ fobjIter.previous();
+ break;
+ }
+ else { // generates inline area
+ curLM.setParentLM(this);
+ curLM.generateAreas();
+ }
+ }
+ }
+ flush(); // Add last area to parent
+ }
+
+
+ /**
+ * Align and position curLine and add it to parentContainer.
+ * Set curLine to null.
+ */
+ public void flush() {
+ if (lineArea != null) {
+ // Adjust spacing as necessary
+ // Calculate height, based on content (or does the Area do this?)
+ parentLM.addChild(lineArea);
+ lineArea = null;
+ }
+ }
+
+
+ /**
+ * Return current lineArea or generate a new one if necessary.
+ */
+ public Area getParentArea(Area childArea) {
+ if (lineArea == null) {
+ createLine();
+ }
+ return lineArea;
+ }
+
+ private void createLine() {
+ lineArea = new LineArea();
+ /* Set line IPD from parentArea
+ * This accounts for indents. What about first line indent?
+ * Should we set an "isFirst" flag on the lineArea to signal
+ * that to the parent (Block) LM? That's where indent property
+ * information will be managed.
+ */
+ Area parent = parentLM.getParentArea(lineArea);
+ // lineArea.setContentIPD(parent.getContentIPD());
+ // remainingIPD = parent.getContentIPD();
+ // OR???
+ // remainingIPD = parentLM.getContentIPD();
+ remainingIPD = new MinOptMax(100000); // TESTING!!!
+ this.bFirstLine = false;
+ }
+
+
+ /**
+ * Called by child LayoutManager when it has filled one of its areas.
+ * See if the area will fit in the current container.
+ * If so, add it.
+ * This should also handle floats if childArea is an anchor.
+ * @param childArea the area to add: should be an InlineArea subclass!
+ */
+ public void addChild(Area childArea) {
+ if ((childArea instanceof InlineArea)==false) {
+ // SIGNAL AN ERROR!!!
+ return;
+ }
+ InlineArea inlineArea = (InlineArea)childArea;
+ if (lineArea == null) {
+ createLine();
+ }
+ if (inlineArea.getAllocationIPD().min < remainingIPD.max) {
+ lineArea.addInlineArea(inlineArea);
+ remainingIPD.subtract(inlineArea.getAllocationIPD());
+ // Calculate number of spaces
+ // Forced line break after this area (ex. ends with LF in nowrap)
+ /* NOTYET!
+ if (inlineArea.breakAfter()) {
+ flush();
+ }
+ */
+ /* Check if line could end after this area (potential line-break
+ * character. If not, it must be joined with following inline
+ * area to make a word. Otherwise, if the line could break here
+ * and if it is "full", add it to the parent area.
+ */
+ if (remainingIPD.min<=0) {
+ flush();
+ }
+ }
+
+ else {
+ /* The inline area won't entirely fit in this line. Ask its
+ * layout manager to split it (by hyphenation for example),
+ * in order to fit part of it in the line.
+ * Note: only the current child LM could have generated this
+ * area, so we ask it to do the split.
+ */
+ SplitContext splitContext = new SplitContext(remainingIPD);
+ if (curLM.splitArea(inlineArea, splitContext)) {
+ // inlineArea should now fit
+ lineArea.addInlineArea(inlineArea);
+ flush();
+ }
+ addChild(splitContext.nextArea);
+ }
+ }
+
+}
diff --git a/src/org/apache/fop/layoutmgr/TextLayoutManager.java b/src/org/apache/fop/layoutmgr/TextLayoutManager.java
new file mode 100644
index 000000000..aa88340ab
--- /dev/null
+++ b/src/org/apache/fop/layoutmgr/TextLayoutManager.java
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.inline.Word;
+
+import java.util.ListIterator;
+
+/**
+ * LayoutManager for text (a sequence of characters) which generates one
+ * more inline areas.
+ */
+public class TextLayoutManager extends AbstractLayoutManager {
+
+ private char[] chars;
+ private Word curWordArea;
+
+ public TextLayoutManager(FObj fobj, char[] chars) {
+ super(fobj);
+ this.chars = chars;
+ }
+
+
+ /**
+ * Generate inline areas for words in text.
+ */
+ public void generateAreas() {
+ // Iterate over characters and make text areas.
+ // Add each one to parent. Handle word-space.
+ curWordArea = new Word();
+ curWordArea.setWord(new String(chars));
+ flush();
+ }
+
+
+ protected void flush() {
+ parentLM.addChild(curWordArea);
+ }
+
+
+ public boolean generatesInlineAreas() {
+ return true;
+ }
+
+ /**
+ * This is a leaf-node, so this method is never called.
+ */
+ public void addChild(Area childArea) {}
+
+
+ /**
+ * This is a leaf-node, so this method is never called.
+ */
+ public Area getParentArea(Area childArea) {
+ return null;
+ }
+
+
+
+ /** Try to split the word area by hyphenating the word. */
+ public boolean splitArea(Area areaToSplit, SplitContext context) {
+ context.nextArea = areaToSplit;
+ return false;
+ }
+
+}