You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2008/03/06 14:34:59 UTC

svn commit: r634267 [9/39] - in /xmlgraphics/fop/branches/Temp_ProcessingFeedback: ./ examples/embedding/ examples/embedding/java/embedding/ examples/embedding/java/embedding/intermediate/ examples/embedding/xml/xml/ examples/fo/ examples/fo/advanced/ ...

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/TraitSetter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/TraitSetter.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/TraitSetter.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/TraitSetter.java Thu Mar  6 05:33:44 2008
@@ -281,6 +281,90 @@
     }
 
     /**
+     * Add background to an area. This method is mainly used by table-related layout
+     * managers to add background for column, body or row. Since the area corresponding to
+     * border-separation must be filled with the table's background, for every cell an
+     * additional area with the same dimensions is created to hold the background for the
+     * corresponding column/body/row. An additional shift must then be added to
+     * background-position-horizontal/vertical to ensure the background images are
+     * correctly placed. Indeed the placement of images must be made WRT the
+     * column/body/row and not the cell.
+     * 
+     * <p>Note: The area's IPD and BPD must be set before calling this method.</p>
+     * 
+     * <p>TODO the regular
+     * {@link #addBackground(Area, CommonBorderPaddingBackground, PercentBaseContext)}
+     * method should be used instead, and a means to retrieve the original area's
+     * dimensions must be found.</p>
+     * 
+     * <p>TODO the placement of images in the x- or y-direction will be incorrect if
+     * background-repeat is set for that direction.</p>
+     * 
+     * @param area the area to set the traits on
+     * @param backProps the background properties
+     * @param context Property evaluation context
+     * @param ipdShift horizontal shift to affect to the background, in addition to the
+     * value of the background-position-horizontal property
+     * @param bpdShift vertical shift to affect to the background, in addition to the
+     * value of the background-position-vertical property
+     * @param referenceIPD value to use as a reference for percentage calculation
+     * @param referenceBPD value to use as a reference for percentage calculation
+     */
+    public static void addBackground(Area area, 
+            CommonBorderPaddingBackground backProps,
+            PercentBaseContext context,
+            int ipdShift, int bpdShift, int referenceIPD, int referenceBPD) {
+        if (!backProps.hasBackground()) {
+            return;
+        }
+        Trait.Background back = new Trait.Background();
+        back.setColor(backProps.backgroundColor);
+
+        if (backProps.getImageInfo() != null) {
+            back.setURL(backProps.backgroundImage);
+            back.setImageInfo(backProps.getImageInfo());
+            back.setRepeat(backProps.backgroundRepeat);
+            if (backProps.backgroundPositionHorizontal != null) {
+                if (back.getRepeat() == Constants.EN_NOREPEAT 
+                        || back.getRepeat() == Constants.EN_REPEATY) {
+                    if (area.getIPD() > 0) {
+                        PercentBaseContext refContext = new SimplePercentBaseContext(context,
+                                LengthBase.IMAGE_BACKGROUND_POSITION_HORIZONTAL,
+                                (referenceIPD - back.getImageInfo().getSize().getWidthMpt()));
+
+                        back.setHoriz(ipdShift
+                                + backProps.backgroundPositionHorizontal.getValue(refContext));
+                    } else {
+                        // TODO Area IPD has to be set for this to work
+                        log.warn("Horizontal background image positioning ignored"
+                                + " because the IPD was not set on the area."
+                                + " (Yes, it's a bug in FOP)");
+                    }
+                }
+            }
+            if (backProps.backgroundPositionVertical != null) {
+                if (back.getRepeat() == Constants.EN_NOREPEAT 
+                        || back.getRepeat() == Constants.EN_REPEATX) {
+                    if (area.getBPD() > 0) {
+                        PercentBaseContext refContext = new SimplePercentBaseContext(context,
+                                LengthBase.IMAGE_BACKGROUND_POSITION_VERTICAL,
+                                (referenceBPD - back.getImageInfo().getSize().getHeightMpt()));
+                        back.setVertical(bpdShift
+                                + backProps.backgroundPositionVertical.getValue(refContext));
+                    } else {
+                        // TODO Area BPD has to be set for this to work
+                        log.warn("Vertical background image positioning ignored"
+                                + " because the BPD was not set on the area."
+                                + " (Yes, it's a bug in FOP)");
+                    }
+                }
+            }
+        }
+
+        area.addTrait(Trait.BACKGROUND, back);
+    }
+
+    /**
      * Add background to an area.
      * Layout managers that create areas with a background can use this to
      * add the background to the area.
@@ -312,7 +396,7 @@
                         back.setHoriz(backProps.backgroundPositionHorizontal.getValue(
                                 new SimplePercentBaseContext(context, 
                                     LengthBase.IMAGE_BACKGROUND_POSITION_HORIZONTAL,
-                                    (width - back.getImageInfo().getSize().getHeightMpt())
+                                    (width - back.getImageInfo().getSize().getWidthMpt())
                                 )
                             ));
                     } else {

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/BidiLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/FootnoteLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java Thu Mar  6 05:33:44 2008
@@ -163,10 +163,12 @@
 
         //Adjust viewport if not explicit
         if (ipd == -1) {
-            ipd = constrainExtent(cwidth, props.getInlineProgressionDimension());
+            ipd = constrainExtent(cwidth,
+                    props.getInlineProgressionDimension(), props.getContentWidth());
         }
         if (bpd == -1) {
-            bpd = constrainExtent(cheight, props.getBlockProgressionDimension());
+            bpd = constrainExtent(cheight,
+                    props.getBlockProgressionDimension(), props.getContentHeight());
         }
 
         this.clip = false;
@@ -189,19 +191,21 @@
         this.placement = new Rectangle(xoffset, yoffset, cwidth, cheight);
     }
     
-    private int constrainExtent(int extent, LengthRangeProperty range) {
+    private int constrainExtent(int extent, LengthRangeProperty range, Length contextExtent) {
+        boolean mayScaleUp = (contextExtent.getEnum() != EN_SCALE_DOWN_TO_FIT); 
+        boolean mayScaleDown = (contextExtent.getEnum() != EN_SCALE_UP_TO_FIT); 
         Length len;
         len = range.getMaximum(percentBaseContext).getLength();
         if (len.getEnum() != EN_AUTO) {
             int max = len.getValue(percentBaseContext);
-            if (max != -1) {
+            if (max != -1 && mayScaleDown) {
                 extent = Math.min(extent, max);
             }
         }
         len = range.getMinimum(percentBaseContext).getLength();
         if (len.getEnum() != EN_AUTO) {
             int min = len.getValue(percentBaseContext);
-            if (min != -1) {
+            if (min != -1 && mayScaleUp) {
                 extent = Math.max(extent, min);
             }
         }
@@ -210,8 +214,10 @@
     
     private Dimension constrain(Dimension size) {
         Dimension adjusted = new Dimension(size);
-        int effWidth = constrainExtent(size.width, props.getInlineProgressionDimension());
-        int effHeight = constrainExtent(size.height, props.getBlockProgressionDimension());
+        int effWidth = constrainExtent(size.width,
+                props.getInlineProgressionDimension(), props.getContentWidth());
+        int effHeight = constrainExtent(size.height,
+                props.getBlockProgressionDimension(), props.getContentHeight());
         int scaling = props.getScaling();
         if (scaling == EN_UNIFORM) {
             double rat1 = (double)effWidth / size.width;

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java Thu Mar  6 05:33:44 2008
@@ -548,6 +548,14 @@
      */
     protected void addKnuthElementsForBorderPaddingStart(List returnList) {
         //Border and Padding (start)
+        /**
+         * If the returnlist is a BlockKnuthSequence, the border and padding should be added
+         * to the first paragraph inside it, but it is too late to do that now.
+         * At least, avoid adding it to the bpd sequence.
+         */
+        if (returnList instanceof BlockKnuthSequence) {
+            return;
+        }
         CommonBorderPaddingBackground borderAndPadding = fobj.getCommonBorderPaddingBackground();
         if (borderAndPadding != null) {
             int ipStart = borderAndPadding.getBorderStartWidth(false)
@@ -564,6 +572,14 @@
      */
     protected void addKnuthElementsForBorderPaddingEnd(List returnList) {
         //Border and Padding (after)
+        /**
+         * If the returnlist is a BlockKnuthSequence, the border and padding should be added
+         * to the last paragraph inside it, but it is too late to do that now.
+         * At least, avoid adding it to the bpd sequence.
+         */
+        if (returnList instanceof BlockKnuthSequence) {
+            return;
+        }
         CommonBorderPaddingBackground borderAndPadding = fobj.getCommonBorderPaddingBackground();
         if (borderAndPadding != null) {
             int ipEnd = borderAndPadding.getBorderEndWidth(false)

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/InlineLevelLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/InstreamForeignObjectLM.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/LineLayoutPossibilities.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java Thu Mar  6 05:33:44 2008
@@ -1,81 +1,81 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.layoutmgr.inline;
-
-import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.fo.flow.Wrapper;
-import org.apache.fop.layoutmgr.LayoutContext;
-import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.TraitSetter;
-
-/**
- * This is the layout manager for the fo:wrapper formatting object.
- */
-public class WrapperLayoutManager extends LeafNodeLayoutManager {
-    
-    private Wrapper fobj;
-
-    /**
-     * Creates a new LM for fo:wrapper.
-     * @param node the fo:wrapper
-     */
-    public WrapperLayoutManager(Wrapper node) {
-        super(node);
-        fobj = node;
-    }
-
-    /** {@inheritDoc} */
-    public InlineArea get(LayoutContext context) {
-        // Create a zero-width, zero-height dummy area so this node can
-        // participate in the ID handling. Otherwise, addId() wouldn't
-        // be called. The area must also be added to the tree, because
-        // determination of the X,Y position is done in the renderer.
-        InlineArea area = new InlineArea();
-        if (fobj.hasId()) {
-            TraitSetter.setProducerID(area, fobj.getId());
-        }
-        return area;
-    }
-
-    /**
-     * Add the area for this layout manager.
-     * This adds the dummy area to the parent, *if* it has an id
-     * - otherwise it serves no purpose.
-     *
-     * @param posIter the position iterator
-     * @param context the layout context for adding the area
-     */
-    public void addAreas(PositionIterator posIter, LayoutContext context) {
-        if (fobj.hasId()) {
-            addId();
-            InlineArea area = getEffectiveArea();
-            parentLM.addChildArea(area);
-        }
-        while (posIter.hasNext()) {
-            posIter.next();
-        }
-    }
-
-    /** {@inheritDoc} */
-    protected void addId() {
-        getPSLM().addIDToPage(fobj.getId());
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr.inline;
+
+import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.fo.flow.Wrapper;
+import org.apache.fop.layoutmgr.LayoutContext;
+import org.apache.fop.layoutmgr.PositionIterator;
+import org.apache.fop.layoutmgr.TraitSetter;
+
+/**
+ * This is the layout manager for the fo:wrapper formatting object.
+ */
+public class WrapperLayoutManager extends LeafNodeLayoutManager {
+    
+    private Wrapper fobj;
+
+    /**
+     * Creates a new LM for fo:wrapper.
+     * @param node the fo:wrapper
+     */
+    public WrapperLayoutManager(Wrapper node) {
+        super(node);
+        fobj = node;
+    }
+
+    /** {@inheritDoc} */
+    public InlineArea get(LayoutContext context) {
+        // Create a zero-width, zero-height dummy area so this node can
+        // participate in the ID handling. Otherwise, addId() wouldn't
+        // be called. The area must also be added to the tree, because
+        // determination of the X,Y position is done in the renderer.
+        InlineArea area = new InlineArea();
+        if (fobj.hasId()) {
+            TraitSetter.setProducerID(area, fobj.getId());
+        }
+        return area;
+    }
+
+    /**
+     * Add the area for this layout manager.
+     * This adds the dummy area to the parent, *if* it has an id
+     * - otherwise it serves no purpose.
+     *
+     * @param posIter the position iterator
+     * @param context the layout context for adding the area
+     */
+    public void addAreas(PositionIterator posIter, LayoutContext context) {
+        if (fobj.hasId()) {
+            addId();
+            InlineArea area = getEffectiveArea();
+            parentLM.addChildArea(area);
+        }
+        while (posIter.hasNext()) {
+            posIter.next();
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected void addId() {
+        getPSLM().addIDToPage(fobj.getId());
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/inline/WrapperLayoutManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java Thu Mar  6 05:33:44 2008
@@ -22,9 +22,11 @@
 import java.util.List;
 import java.util.ListIterator;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.flow.table.ConditionalBorder;
 import org.apache.fop.fo.flow.table.EffRow;
-import org.apache.fop.fo.flow.table.GridUnit;
 import org.apache.fop.fo.flow.table.PrimaryGridUnit;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.layoutmgr.ElementListUtils;
@@ -36,6 +38,9 @@
  * A cell playing in the construction of steps for a row-group.
  */
 class ActiveCell {
+
+    private static Log log = LogFactory.getLog(ActiveCell.class);
+
     private PrimaryGridUnit pgu;
     /** Knuth elements for this active cell. */
     private List elementList;
@@ -45,29 +50,36 @@
     private int endRowIndex;
     /** Length of the Knuth elements not yet included in the steps. */
     private int remainingLength;
-    /** Heights of the rows (in the row-group) preceding the one where this cell starts. */
-    private int previousRowsLength;
     /** Total length of this cell's content plus the lengths of the previous rows. */
     private int totalLength;
     /** Length of the Knuth elements already included in the steps. */
     private int includedLength;
 
-    private int borderBeforeNormal;
-    private int borderBeforeLeading;
-    private int borderAfterNormal;
-    private int borderAfterTrailing;
     private int paddingBeforeNormal;
     private int paddingBeforeLeading;
     private int paddingAfterNormal;
     private int paddingAfterTrailing;
 
+    private int bpBeforeNormal;
+    private int bpBeforeLeading;
+    private int bpAfterNormal;
+    private int bpAfterTrailing;
+
+    /** True if the next CellPart that will be created will be the last one for this cell. */
+    private boolean lastCellPart;
+
     private boolean keepWithNextSignal;
 
     private int spanIndex = 0;
-    private CellPart lastCellPart;
 
     private Step previousStep;
     private Step nextStep;
+    /**
+     * The step following nextStep. Computing it early allows to calculate
+     * {@link Step#condBeforeContentLength}, thus to easily determine the remaining
+     * length. That also helps for {@link #increaseCurrentStep(int)}.
+     */
+    private Step afterNextStep;
 
     /**
      * Auxiliary class to store all the informations related to a breaking step.
@@ -84,16 +96,20 @@
         /** Length of the penalty ending this step, if any. */
         private int penaltyLength;
         /**
-         * Length of the optional content for the next step. That is, content that will
-         * not appear if the next step starts a new page.
+         * One of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
+         * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE},
+         * {@link Constants#EN_ODD_PAGE}. Set to auto if the break isn't at a penalty
+         * element.
+         */
+        private int breakClass;
+        /**
+         * Length of the optional content at the beginning of the step. That is, content
+         * that will not appear if this step starts a new page.
          */
-        private int nextCondBeforeContentLength;
+        private int condBeforeContentLength;
 
         Step(int contentLength) {
             this.contentLength = contentLength;
-            // TODO necessary if a cell part must be created while this cell hasn't
-            // contributed any content yet. To be removed along with the 900-penalty
-            // mechanism
             this.end = -1;
         }
 
@@ -107,7 +123,13 @@
             this.contentLength = other.contentLength;
             this.totalLength   = other.totalLength;
             this.penaltyLength = other.penaltyLength;
-            this.nextCondBeforeContentLength = other.nextCondBeforeContentLength;
+            this.condBeforeContentLength = other.condBeforeContentLength;
+            this.breakClass    = other.breakClass;
+        }
+
+        /** {@inheritDoc} */
+        public String toString() {
+            return "Step: start=" + start + " end=" + end + " length=" + totalLength;
         }
     }
 
@@ -116,16 +138,17 @@
         this.pgu = pgu;
         CommonBorderPaddingBackground bordersPaddings = pgu.getCell()
                 .getCommonBorderPaddingBackground();
-        borderBeforeNormal = pgu.getBeforeBorderWidth(0, ConditionalBorder.NORMAL);
-        borderBeforeLeading = pgu.getBeforeBorderWidth(0, ConditionalBorder.REST);
-        borderAfterNormal = pgu.getAfterBorderWidth(ConditionalBorder.NORMAL);
-        borderAfterTrailing = pgu.getAfterBorderWidth(0, ConditionalBorder.REST);
         TableCellLayoutManager cellLM = pgu.getCellLM();
         paddingBeforeNormal = bordersPaddings.getPaddingBefore(false, cellLM);
         paddingBeforeLeading = bordersPaddings.getPaddingBefore(true, cellLM);
         paddingAfterNormal = bordersPaddings.getPaddingAfter(false, cellLM);
         paddingAfterTrailing = bordersPaddings.getPaddingAfter(true, cellLM);
-
+        bpBeforeNormal = paddingBeforeNormal
+                + pgu.getBeforeBorderWidth(0, ConditionalBorder.NORMAL);
+        bpBeforeLeading = paddingBeforeLeading
+                + pgu.getBeforeBorderWidth(0, ConditionalBorder.REST);
+        bpAfterNormal = paddingAfterNormal + pgu.getAfterBorderWidth(ConditionalBorder.NORMAL);
+        bpAfterTrailing = paddingAfterTrailing + pgu.getAfterBorderWidth(0, ConditionalBorder.REST);
         boolean makeBoxForWholeRow = false;
         if (row.getExplicitHeight().min > 0) {
             boolean contentsSmaller = ElementListUtils.removeLegalBreaks(
@@ -134,31 +157,32 @@
                 makeBoxForWholeRow = true;
             }
         }
-        if (pgu.isLastGridUnitRowSpan() && pgu.getRow() != null) {
-            makeBoxForWholeRow |= pgu.getRow().mustKeepTogether();
-            makeBoxForWholeRow |= tableLM.getTable().mustKeepTogether();
-        }
         if (makeBoxForWholeRow) {
             elementList = new java.util.ArrayList(1);
             int height = row.getHeight().opt;
-            height -= 2 * tableLM.getHalfBorderSeparationBPD();
-            height -= borderBeforeNormal + borderAfterNormal;  // TODO conditionals
-            height -= paddingBeforeNormal + paddingAfterNormal;
+            height -= bpBeforeNormal + bpAfterNormal;
             elementList.add(new KnuthBoxCellWithBPD(height));
         } else {
             elementList = pgu.getElements();
         }
         knuthIter = elementList.listIterator();
         includedLength = -1;  // Avoid troubles with cells having content of zero length
-        this.previousRowsLength = previousRowsLength;
         totalLength = previousRowsLength + ElementListUtils.calcContentLength(elementList);
         endRowIndex = rowIndex + pgu.getCell().getNumberRowsSpanned() - 1;
         keepWithNextSignal = false;
         remainingLength = totalLength - previousRowsLength;
 
-        nextStep = new Step(previousRowsLength);
-        previousStep = new Step(nextStep);
-        goToNextLegalBreak();
+        afterNextStep = new Step(previousRowsLength);
+        previousStep = new Step(afterNextStep);
+        gotoNextLegalBreak();
+        nextStep = new Step(afterNextStep);
+        if (afterNextStep.end < elementList.size() - 1) {
+            gotoNextLegalBreak();
+        }
+    }
+
+    PrimaryGridUnit getPrimaryGridUnit() {
+        return pgu;
     }
 
     /**
@@ -175,56 +199,121 @@
      * Returns the length of this cell's content not yet included in the steps, plus the
      * cell's borders and paddings if applicable.
      * 
-     * @param activeRowIndex index of the row currently considered
-     * @return the remaining length, or zero if the cell doesn't end on the given row.
+     * @return the remaining length, zero if the cell is finished
      */
-    int getRemainingHeight(int activeRowIndex) {
-        if (!endsOnRow(activeRowIndex)) {
-            return 0;
-        } else if (includedLength == totalLength) {
+    int getRemainingLength() {
+        if (includedInLastStep() && (nextStep.end == elementList.size() - 1)) {
+            // The cell is finished
             return 0;
         } else {
-            return borderBeforeLeading + paddingBeforeLeading + remainingLength
-                    + paddingAfterNormal + borderAfterNormal;
+            return bpBeforeLeading + remainingLength + bpAfterNormal;
         }
     }
 
-    private void goToNextLegalBreak() {
-        nextStep.penaltyLength = 0;
+    private void gotoNextLegalBreak() {
+        afterNextStep.penaltyLength = 0;
+        afterNextStep.condBeforeContentLength = 0;
+        afterNextStep.breakClass = Constants.EN_AUTO;
         boolean breakFound = false;
         boolean prevIsBox = false;
+        boolean boxFound = false;
         while (!breakFound && knuthIter.hasNext()) {
             KnuthElement el = (KnuthElement) knuthIter.next();
             if (el.isPenalty()) {
                 prevIsBox = false;
                 if (el.getP() < KnuthElement.INFINITE) {
                     // First legal break point
-                    nextStep.penaltyLength = el.getW();
                     breakFound = true;
+                    afterNextStep.penaltyLength = el.getW();
+                    KnuthPenalty p = (KnuthPenalty) el;
+                    if (p.isForcedBreak()) {
+                        afterNextStep.breakClass = p.getBreakClass();
+                    }
                 }
             } else if (el.isGlue()) {
                 if (prevIsBox) {
                     // Second legal break point
                     breakFound = true;
                 } else {
-                    nextStep.contentLength += el.getW();
+                    afterNextStep.contentLength += el.getW();
+                    if (!boxFound) {
+                        afterNextStep.condBeforeContentLength += el.getW();
+                    }
                 }
                 prevIsBox = false;
             } else {
                 prevIsBox = true;
-                nextStep.contentLength += el.getW();
+                boxFound = true;
+                afterNextStep.contentLength += el.getW();
             }
         }
-        nextStep.end = knuthIter.nextIndex() - 1;
-        if (nextStep.end == elementList.size() - 1) {
-            // TODO wait that every cell on the row has finished before including border-after!!
-            nextStep.totalLength = borderBeforeNormal + paddingBeforeNormal
-                    + nextStep.contentLength + nextStep.penaltyLength
-                    + paddingAfterNormal + borderAfterNormal;
-        } else {
-            nextStep.totalLength = borderBeforeNormal + paddingBeforeNormal
-                    + nextStep.contentLength + nextStep.penaltyLength
-                    + paddingAfterTrailing + borderAfterTrailing; 
+        afterNextStep.end = knuthIter.nextIndex() - 1;
+        afterNextStep.totalLength = bpBeforeNormal
+                + afterNextStep.contentLength + afterNextStep.penaltyLength
+                + bpAfterTrailing; 
+    }
+
+    /**
+     * Returns the minimal step that is needed for this cell to contribute some content.
+     *  
+     * @return the step for this cell's first legal break
+     */
+    int getFirstStep() {
+        log.debug(this + ": min first step = " + nextStep.totalLength);
+        return nextStep.totalLength;
+    }
+
+    /**
+     * Returns the last step for this cell.
+     * 
+     * @return the step including all of the cell's content plus the normal borders and paddings
+     */
+    int getLastStep() {
+        assert nextStep.end == elementList.size() - 1;
+        assert nextStep.contentLength == totalLength && nextStep.penaltyLength == 0;
+        int lastStep = bpBeforeNormal + totalLength + bpAfterNormal;
+        log.debug(this + ": last step = " + lastStep);
+        return lastStep;
+    }
+
+    /**
+     * Increases the next step up to the given limit.
+     * 
+     * @param limit the length up to which the next step is allowed to increase
+     * @see #signalRowFirstStep(int)
+     * @see #signalRowLastStep(int)
+     */
+    private void increaseCurrentStep(int limit) {
+        if (nextStep.end < elementList.size() - 1) {
+            while (afterNextStep.totalLength <= limit && nextStep.breakClass == Constants.EN_AUTO) {
+                nextStep.set(afterNextStep);
+                if (afterNextStep.end >= elementList.size() - 1) {
+                    break;
+                }
+                gotoNextLegalBreak();
+            }
+        }
+    }
+
+    /**
+     * Gets the selected first step for the current row. If this cell's first step is
+     * smaller, then it may be able to add some more of its content, since there will be
+     * no break before the given step anyway.
+     * 
+     * @param firstStep the current row's first step
+     */
+    void signalRowFirstStep(int firstStep) {
+        increaseCurrentStep(firstStep);
+        if (log.isTraceEnabled()) {
+            log.trace(this + ": first step increased to " + nextStep.totalLength);
+        }
+    }
+
+    /** See {@link #signalRowFirstStep(int)}. */
+    void signalRowLastStep(int lastStep) {
+        increaseCurrentStep(lastStep);
+        if (log.isTraceEnabled()) {
+            log.trace(this + ": next step increased to " + nextStep.totalLength);
         }
     }
 
@@ -236,11 +325,16 @@
     int getNextStep() {
         if (includedInLastStep()) {
             previousStep.set(nextStep);
-            nextStep.start = nextStep.end + 1;
-            if (!knuthIter.hasNext()) {
+            if (nextStep.end >= elementList.size() - 1) {
+                nextStep.start = elementList.size();
                 return -1;
             } else {
-                goToNextLegalBreak();
+                nextStep.set(afterNextStep);
+                nextStep.start = previousStep.end + 1;
+                afterNextStep.start = nextStep.start;
+                if (afterNextStep.end < elementList.size() - 1) {
+                    gotoNextLegalBreak();
+                }
             }
         }
         return nextStep.totalLength;
@@ -255,82 +349,68 @@
      * its own step may be included or not.
      * 
      * @param minStep length of the chosen next step
-     * @return
+     * @return the break class of the step, if any. One of {@link Constants#EN_AUTO},
+     * {@link Constants#EN_COLUMN}, {@link Constants#EN_PAGE},
+     * {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE}. EN_AUTO if this
+     * cell's step is not included in the next step.
      */
-    boolean signalMinStep(int minStep) {
+    int signalNextStep(int minStep) {
         if (nextStep.totalLength <= minStep) {
             includedLength = nextStep.contentLength;
-            computeRemainingLength();
-            return false;
+            remainingLength = totalLength - includedLength - afterNextStep.condBeforeContentLength;
+            return nextStep.breakClass;
         } else {
-            return borderBeforeNormal + paddingBeforeNormal + previousRowsLength
-                    + paddingAfterTrailing + borderAfterTrailing > minStep;
-        }
-    }
-
-    void endRow(int rowIndex) {
-        if (endsOnRow(rowIndex)) {
-            int bpAfterNormal = paddingAfterNormal + borderAfterNormal;
-            int bpAfterLast = paddingAfterNormal
-                    + pgu.getAfterBorderWidth(ConditionalBorder.LEADING_TRAILING);
-            lastCellPart.setLast(bpAfterNormal, bpAfterLast);
-        } else {
-            spanIndex++;
-            borderBeforeLeading = pgu.getBeforeBorderWidth(spanIndex, ConditionalBorder.REST);
-            borderAfterTrailing = pgu.getAfterBorderWidth(spanIndex, ConditionalBorder.REST);
+            return Constants.EN_AUTO;
         }
     }
 
     /**
-     * Computes the length of the cell's content after the current legal break. Discards
-     * every glue or penalty following the break if needed. The cell's borders and
-     * paddings are not considered here.
-     */
-    private void computeRemainingLength() {
-        remainingLength = totalLength - nextStep.contentLength;
-        nextStep.nextCondBeforeContentLength = 0;
-        // Save the current location in the element list
-        int oldIndex = knuthIter.nextIndex();
-        KnuthElement el;
-        while (knuthIter.hasNext() && !(el = (KnuthElement) knuthIter.next()).isBox()) {
-            if (el.isGlue()) {
-                remainingLength -= el.getW();
-                nextStep.nextCondBeforeContentLength += el.getW();
-            }
-        }
-        // Reset the iterator to the current location
-        while (knuthIter.nextIndex() > oldIndex) {
-            knuthIter.previous();
-        }
-    }
-
-    /**
-     * Returns true if some content of this cell is part of the chosen next step.
-     * 
-     * @return true if this cell's next step is inferior or equal to the next minimal step
+     * Receives indication that the next row is about to start, and that (collapse)
+     * borders must be updated accordingly.
      */
-    boolean contributesContent() {
-        // return includedInLastStep() && the cell hasn't finished yet, otherwise there's
-        // nothing more to contribute
-        return includedInLastStep() && nextStep.end >= nextStep.start;
+    void nextRowStarts() {
+        spanIndex++;
+        // Subtract the old value of bpAfterTrailing...
+        nextStep.totalLength -= bpAfterTrailing;
+        afterNextStep.totalLength -= bpAfterTrailing;
+
+        bpAfterTrailing = paddingAfterTrailing
+                + pgu.getAfterBorderWidth(spanIndex, ConditionalBorder.REST);
+
+        // ... and add the new one
+        nextStep.totalLength += bpAfterTrailing;
+        afterNextStep.totalLength += bpAfterTrailing;
+        // TODO if the new after border is greater than the previous one the next step may
+        // increase further than the row's first step, which can lead to wrong output in
+        // some cases
     }
 
     /**
-     * Returns true if this cell has already started to contribute some content to the steps.
+     * Receives indication that the current row is ending, and that (collapse) borders
+     * must be updated accordingly.
      * 
-     * @return true if this cell's first step is inferior or equal to the current one 
+     * @param rowIndex the index of the ending row
      */
-    boolean hasStarted() {
-        return includedLength >= 0;
+    void endRow(int rowIndex) {
+        if (endsOnRow(rowIndex)) {
+            bpAfterTrailing = paddingAfterNormal
+                    + pgu.getAfterBorderWidth(ConditionalBorder.LEADING_TRAILING);
+            lastCellPart = true;
+        } else {
+            bpBeforeLeading = paddingBeforeLeading
+                    + pgu.getBeforeBorderWidth(spanIndex + 1, ConditionalBorder.REST);
+        }
     }
 
     /**
-     * Returns true if this cell has contributed all of its content to the steps.
+     * Returns true if this cell would be finished after the given step. That is, it would
+     * be included in the step and the end of its content would be reached.
      * 
-     * @return true if the end of this cell is reached
+     * @param step the next step
+     * @return true if this cell finishes at the given step
      */
-    boolean isFinished() {
-        return includedInLastStep() && (nextStep.end == elementList.size() - 1);
+    boolean finishes(int step) {
+        return nextStep.totalLength <= step && (nextStep.end == elementList.size() - 1);
     }
 
     /**
@@ -341,59 +421,53 @@
      */
     CellPart createCellPart() {
         if (nextStep.end + 1 == elementList.size()) {
-            if (pgu.getFlag(GridUnit.KEEP_WITH_NEXT_PENDING)) {
-                keepWithNextSignal = true;
-            }
-            if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) {
-                keepWithNextSignal = true;
-            }
+            keepWithNextSignal = pgu.mustKeepWithNext();
+            // TODO if keep-with-next is set on the row, must every cell of the row
+            // contribute some content from children blocks?
+            // see http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200802.mbox/
+            // %3c47BDA379.4050606@anyware-tech.com%3e
+            // Assuming no, but if yes the following code should enable this behaviour
+//            if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) {
+//                keepWithNextSignal = true;
+//            }
         }
-        int bpBeforeNormal;
         int bpBeforeFirst;
-        int bpAfterNormal;
-        int bpAfterLast;
         if (nextStep.start == 0) {
-            bpBeforeNormal = borderBeforeNormal + paddingBeforeNormal;
             bpBeforeFirst = pgu.getBeforeBorderWidth(0, ConditionalBorder.LEADING_TRAILING)
                     + paddingBeforeNormal;
         } else {
-            bpBeforeNormal = 0;
-            bpBeforeFirst = borderBeforeLeading + paddingBeforeLeading;
+            bpBeforeFirst = bpBeforeLeading;
         }
-        bpAfterNormal = 0;
-        bpAfterLast = paddingAfterTrailing + borderAfterTrailing;
-        int length = nextStep.contentLength - previousStep.contentLength
-                - previousStep.nextCondBeforeContentLength;
+        int length = nextStep.contentLength - nextStep.condBeforeContentLength
+                - previousStep.contentLength;
         if (!includedInLastStep() || nextStep.start == elementList.size()) {
-            lastCellPart = new CellPart(pgu, nextStep.start, previousStep.end,
+            return new CellPart(pgu, nextStep.start, previousStep.end, lastCellPart,
                     0, 0, previousStep.penaltyLength,
-                    bpBeforeNormal, bpBeforeFirst, bpAfterNormal, bpAfterLast);
+                    bpBeforeNormal, bpBeforeFirst, bpAfterNormal, bpAfterTrailing);
         } else if (nextStep.start == 0 && nextStep.end == 0
                 && elementList.size() == 1
                 && elementList.get(0) instanceof KnuthBoxCellWithBPD) {
             //Special case: Cell with fixed BPD
-            lastCellPart = new CellPart(pgu, 0, pgu.getElements().size() - 1,
-                    previousStep.nextCondBeforeContentLength, length, nextStep.penaltyLength,
-                    bpBeforeNormal, bpBeforeFirst, bpAfterNormal, bpAfterLast);
+            return new CellPart(pgu, 0, pgu.getElements().size() - 1, lastCellPart,
+                    nextStep.condBeforeContentLength, length, nextStep.penaltyLength,
+                    bpBeforeNormal, bpBeforeFirst, bpAfterNormal, bpAfterTrailing);
         } else {
-            lastCellPart = new CellPart(pgu, nextStep.start, nextStep.end,
-                    previousStep.nextCondBeforeContentLength, length, nextStep.penaltyLength,
-                    bpBeforeNormal, bpBeforeFirst, bpAfterNormal, bpAfterLast);
+            return new CellPart(pgu, nextStep.start, nextStep.end, lastCellPart,
+                    nextStep.condBeforeContentLength, length, nextStep.penaltyLength,
+                    bpBeforeNormal, bpBeforeFirst, bpAfterNormal, bpAfterTrailing);
         }
-        return lastCellPart;
     }
 
-    boolean isLastForcedBreak() {
-        return ((KnuthElement)elementList.get(nextStep.end)).isForcedBreak();
+    boolean keepWithNextSignal() {
+        return keepWithNextSignal;
     }
 
-    int getLastBreakClass() {
-        return ((KnuthPenalty)elementList.get(nextStep.end)).getBreakClass();
+    
+    /** {@inheritDoc} */
+    public String toString() {
+        return "Cell " + (pgu.getRowIndex() + 1) + "." + (pgu.getColIndex() + 1);
     }
 
-    boolean keepWithNextSignal() {
-        return keepWithNextSignal;
-    }
 
     /**
      * Marker class denoting table cells fitting in just one box (no legal break inside).

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/CellPart.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/CellPart.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/CellPart.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/CellPart.java Thu Mar  6 05:33:44 2008
@@ -19,7 +19,6 @@
 
 package org.apache.fop.layoutmgr.table;
 
-import org.apache.fop.fo.flow.table.GridUnit;
 import org.apache.fop.fo.flow.table.PrimaryGridUnit;
 
 /**
@@ -49,6 +48,7 @@
      * @param pgu Primary grid unit
      * @param start starting element
      * @param end ending element
+     * @param last true if this cell part is the last one for the cell
      * @param condBeforeContentLength length of the additional content that will have to
      * be displayed if this part will be the first one on the page
      * @param length length of the content represented by this cell part
@@ -58,16 +58,17 @@
      * @param bpBeforeFirst width of (possibly optional) border- and padding-before if
      * this part will be the first one on the page
      * @param bpAfterNormal width of border- and padding-after in the normal case
-     * @param bpAfterFirst width of (possibly optional) border- and padding-after if this
+     * @param bpAfterLast width of (possibly optional) border- and padding-after if this
      * part will be the last one on the page
      */
-    protected CellPart(PrimaryGridUnit pgu, int start, int end,
+    protected CellPart(PrimaryGridUnit pgu, int start, int end, boolean last,
             int condBeforeContentLength, int length, int condAfterContentLength,
             int bpBeforeNormal, int bpBeforeFirst,
             int bpAfterNormal, int bpAfterLast) {
         this.pgu = pgu;
         this.start = start;
         this.end = end;
+        this.isLast = last;
         this.condBeforeContentLength = condBeforeContentLength;
         this.length = length;
         this.condAfterContentLength = condAfterContentLength;
@@ -87,12 +88,6 @@
         return isLast;
     }
 
-    void setLast(int bpNormal, int bpLast) {
-        isLast = true;
-        bpAfterNormal = bpNormal;
-        bpAfterLast = bpLast;
-    }
-
     int getBorderPaddingBefore(boolean firstOnPage) {
         if (firstOnPage) {
             return bpBeforeFirst;
@@ -128,11 +123,6 @@
         sb.append(" [").append(isFirstPart() ? "F" : "-").append(isLastPart() ? "L" : "-");
         sb.append("] ").append(pgu);
         return sb.toString();
-    }
-
-    boolean mustKeepWithPrevious() {
-        return pgu.getFlag(GridUnit.KEEP_WITH_PREVIOUS_PENDING)
-                || (pgu.getRow() != null && pgu.getRow().mustKeepWithPrevious());
     }
 
 }

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/CellPart.java
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java Thu Mar  6 05:33:44 2008
@@ -32,18 +32,15 @@
 import org.apache.fop.fo.flow.table.TableRow;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.LengthRangeProperty;
-import org.apache.fop.layoutmgr.BreakElement;
 import org.apache.fop.layoutmgr.ElementListObserver;
-import org.apache.fop.layoutmgr.KnuthElement;
-import org.apache.fop.layoutmgr.KnuthPenalty;
 import org.apache.fop.layoutmgr.LayoutContext;
-import org.apache.fop.layoutmgr.ListElement;
 import org.apache.fop.layoutmgr.MinOptMaxUtil;
 import org.apache.fop.traits.MinOptMax;
+import org.apache.fop.util.BreakUtil;
 
 class RowGroupLayoutManager {
 
-    private static Log log = LogFactory.getLog(TableContentLayoutManager.class);
+    private static Log log = LogFactory.getLog(RowGroupLayoutManager.class);
 
     private EffRow[] rowGroup;
 
@@ -58,66 +55,30 @@
         this.tableStepper = tableStepper;
     }
 
-    /**
-     * 
-     * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
-     * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
-     * {@link Constants#EN_ODD_PAGE}
-     */
-    int getBreakBefore() {
-        TableRow rowFO = rowGroup[0].getTableRow();
-        if (rowFO == null) {
-            return Constants.EN_AUTO;
-        } else {
-            return rowFO.getBreakBefore(); 
-        }
-    }
-
-    /**
-     * 
-     * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
-     * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, or
-     * {@link Constants#EN_ODD_PAGE}
-     */
-    int getBreakAfter() {
-        TableRow rowFO = rowGroup[rowGroup.length - 1].getTableRow();
-        if (rowFO == null) {
-            return Constants.EN_AUTO;
-        } else {
-            return rowFO.getBreakAfter(); 
-        }
-    }
-
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment, int bodyType) {
         LinkedList returnList = new LinkedList();
-
-        //Reset keep-with-next when remaining inside the table.
-        //The context flag is only used to propagate keep-with-next to the outside.
-        //The clearing is ok here because createElementsForRowGroup already handles
-        //the keep when inside a table.
-        context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
-
-        //Element list creation
         createElementsForRowGroup(context, alignment, bodyType, returnList);
 
-        //Handle keeps
-        if (context.isKeepWithNextPending()) {
-            log.debug("child LM (row group) signals pending keep-with-next");
-        }
-        if (context.isKeepWithPreviousPending()) {
-            log.debug("child LM (row group) signals pending keep-with-previous");
-            if (returnList.size() > 0) {
-                //Modify last penalty
-                ListElement last = (ListElement)returnList.getLast();
-                if (last.isPenalty()) {
-                    BreakElement breakPoss = (BreakElement)last;
-                    //Only honor keep if there's no forced break
-                    if (!breakPoss.isForcedBreak()) {
-                        breakPoss.setPenaltyValue(KnuthPenalty.INFINITE);
-                    }
-                }
-            }
+        context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING,
+                rowGroup[0].mustKeepWithPrevious());
+        context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING,
+                rowGroup[rowGroup.length - 1].mustKeepWithNext());
+
+        int breakBefore = Constants.EN_AUTO;
+        TableRow firstRow = rowGroup[0].getTableRow();
+        if (firstRow != null) {
+            breakBefore = firstRow.getBreakBefore(); 
+        }
+        context.setBreakBefore(BreakUtil.compareBreakClasses(breakBefore,
+                rowGroup[0].getBreakBefore()));
+
+        int breakAfter = Constants.EN_AUTO;
+        TableRow lastRow = rowGroup[rowGroup.length - 1].getTableRow();
+        if (lastRow != null) {
+            breakAfter = lastRow.getBreakAfter(); 
         }
+        context.setBreakAfter(BreakUtil.compareBreakClasses(breakAfter,
+                rowGroup[rowGroup.length - 1].getBreakAfter()));
 
         return returnList;
     }
@@ -156,7 +117,8 @@
                     PrimaryGridUnit primary = gu.getPrimary();
                     
                     if (gu.isPrimary()) {
-                        primary.createCellLM(); // TODO a new LM must be created for every new static-content
+                        // TODO a new LM must be created for every new static-content
+                        primary.createCellLM();
                         primary.getCellLM().setParent(tableLM);
                      
                         //Determine the table-row if any
@@ -192,24 +154,7 @@
                         LinkedList elems = primary.getCellLM().getNextKnuthElements(
                                                 childLC, alignment);
                         ElementListObserver.observe(elems, "table-cell", primary.getCell().getId());
-
-                        if ((elems.size() > 0) 
-                                && ((KnuthElement)elems.getLast()).isForcedBreak()) {
-                            // a descendant of this block has break-after
-                            log.debug("Descendant of table-cell signals break: " 
-                                    + primary.getCellLM().isFinished());
-                        }
-                        
                         primary.setElements(elems);
-                        
-                        if (childLC.isKeepWithNextPending()) {
-                            log.debug("child LM signals pending keep-with-next");
-                            primary.setFlag(GridUnit.KEEP_WITH_NEXT_PENDING, true);
-                        }
-                        if (childLC.isKeepWithPreviousPending()) {
-                            log.debug("child LM signals pending keep-with-previous");
-                            primary.setFlag(GridUnit.KEEP_WITH_PREVIOUS_PENDING, true);
-                        }
                     }
 
                     //Calculate height of row, see CSS21, 17.5.3 Table height algorithms
@@ -278,11 +223,8 @@
                 log.debug("  height=" + rowHeights[i] + " explicit=" + explicitRowHeights[i]);
             }
         }
-        LinkedList returnedList = tableStepper.getCombinedKnuthElementsForRowGroup(context,
+        LinkedList elements = tableStepper.getCombinedKnuthElementsForRowGroup(context,
                 rowGroup, bodyType);
-        if (returnedList != null) {
-            returnList.addAll(returnedList);
-        }
-        
+        returnList.addAll(elements);
     }
 }

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowPainter.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/RowPainter.java Thu Mar  6 05:33:44 2008
@@ -26,22 +26,23 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fop.area.Block;
 import org.apache.fop.fo.flow.table.ConditionalBorder;
 import org.apache.fop.fo.flow.table.EffRow;
 import org.apache.fop.fo.flow.table.GridUnit;
 import org.apache.fop.fo.flow.table.PrimaryGridUnit;
-import org.apache.fop.fo.flow.table.TableRow;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.layoutmgr.ElementListUtils;
 import org.apache.fop.layoutmgr.KnuthElement;
 import org.apache.fop.layoutmgr.KnuthPossPosIter;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.SpaceResolver;
+import org.apache.fop.layoutmgr.TraitSetter;
 import org.apache.fop.traits.BorderProps;
 
 class RowPainter {
     private static Log log = LogFactory.getLog(RowPainter.class);
-    /** The fo:table-row containing the currently handled grid rows. */
-    private TableRow rowFO = null;
     private int colCount;
     private int currentRowOffset = 0;
     /** Currently handled row (= last encountered row). */
@@ -71,6 +72,13 @@
     private CellPart[] firstCellParts;
     private CellPart[] lastCellParts;
 
+    /** y-offset of the current table part. */
+    private int tablePartOffset = 0;
+    /** See {@link RowPainter#registerPartBackgroundArea(Block)}. */
+    private CommonBorderPaddingBackground tablePartBackground;
+    /** See {@link RowPainter#registerPartBackgroundArea(Block)}. */
+    private List tablePartBackgroundAreas;
+
     private TableContentLayoutManager tclm;
 
     RowPainter(TableContentLayoutManager tclm, LayoutContext layoutContext) {
@@ -85,6 +93,44 @@
         this.firstRowOnPageIndex = -1;
     }
 
+    void startTablePart(TableBody tablePart) {
+        CommonBorderPaddingBackground background = tablePart.getCommonBorderPaddingBackground();
+        if (background.hasBackground()) {
+            tablePartBackground = background;
+            if (tablePartBackgroundAreas == null) {
+                tablePartBackgroundAreas = new ArrayList();
+            }
+        }
+        tablePartOffset = currentRowOffset;
+    }
+
+    /**
+     * Signals that the end of the current table part is reached.
+     * 
+     * @param lastInBody true if the part is the last table-body element to be displayed
+     * on the current page. In which case all the cells must be flushed even if they
+     * aren't finished, plus the proper collapsed borders must be selected (trailing
+     * instead of normal, or rest if the cell is unfinished)
+     * @param lastOnPage true if the part is the last to be displayed on the current page.
+     * In which case collapsed after borders for the cells on the last row must be drawn
+     * in the outer mode
+     */
+    void endTablePart(boolean lastInBody, boolean lastOnPage) {
+        addAreasAndFlushRow(lastInBody, lastOnPage);
+    
+        if (tablePartBackground != null) {
+            TableLayoutManager tableLM = tclm.getTableLM();
+            for (Iterator iter = tablePartBackgroundAreas.iterator(); iter.hasNext();) {
+                Block backgroundArea = (Block) iter.next();
+                TraitSetter.addBackground(backgroundArea, tablePartBackground, tableLM,
+                        -backgroundArea.getXOffset(), tablePartOffset - backgroundArea.getYOffset(),
+                        tableLM.getContentAreaIPD(), currentRowOffset - tablePartOffset);
+            }
+            tablePartBackground = null;
+            tablePartBackgroundAreas.clear();
+        }
+    }
+
     int getAccumulatedBPD() {
         return currentRowOffset;
     }
@@ -96,14 +142,18 @@
      * @param tcpos a position representing the row fragment
      */
     void handleTableContentPosition(TableContentPosition tcpos) {
-        if (tcpos.row != currentRow && currentRow != null) {
-            addAreasAndFlushRow(false, false);
-        }
         if (log.isDebugEnabled()) {
             log.debug("===handleTableContentPosition(" + tcpos);
         }
-        rowFO = tcpos.row.getTableRow();
-        currentRow = tcpos.row;
+        if (currentRow == null) {
+            currentRow = tcpos.getNewPageRow();
+        } else {
+            EffRow row = tcpos.getRow();
+            if (row.getIndex() > currentRow.getIndex()) {
+                addAreasAndFlushRow(false, false);
+                currentRow = row;
+            }
+        }
         if (firstRowIndex < 0) {
             firstRowIndex = currentRow.getIndex();
             if (firstRowOnPageIndex < 0) {
@@ -143,7 +193,7 @@
      * displayed on the current page. In which case collapsed after borders must be drawn
      * in the outer mode
      */
-    void addAreasAndFlushRow(boolean lastInPart, boolean lastOnPage) {
+    private void addAreasAndFlushRow(boolean lastInPart, boolean lastOnPage) {
         if (log.isDebugEnabled()) {
             log.debug("Remembering yoffset for row " + currentRow.getIndex() + ": "
                     + currentRowOffset);
@@ -155,7 +205,17 @@
         for (int i = 0; i < colCount; i++) {
             GridUnit currentGU = currentRow.getGridUnit(i);            
             if (!currentGU.isEmpty() && currentGU.getColSpanIndex() == 0
-                    && (lastInPart || currentGU.isLastGridUnitRowSpan())) {
+                    && (lastInPart || currentGU.isLastGridUnitRowSpan())
+                    && firstCellParts[i] != null) {
+                // TODO
+                // The last test above is a workaround for the stepping algorithm's
+                // fundamental flaw making it unable to produce the right element list for
+                // multiple breaks inside a same row group.
+                // (see http://wiki.apache.org/xmlgraphics-fop/TableLayout/KnownProblems)
+                // In some extremely rare cases (forced breaks, very small page height), a
+                // TableContentPosition produced during row delaying may end up alone on a
+                // page. It will not contain the CellPart instances for the cells starting
+                // the next row, so firstCellParts[i] will still be null for those ones.
                 int cellHeight = cellHeights[i];
                 cellHeight += lastCellParts[i].getConditionalAfterContentLength();
                 cellHeight += lastCellParts[i].getBorderPaddingAfter(lastInPart);
@@ -167,12 +227,11 @@
         }
 
         // Then add areas for cells finishing on the current row
-        tclm.addRowBackgroundArea(rowFO, actualRowHeight, layoutContext.getRefIPD(),
-                currentRowOffset);
         for (int i = 0; i < colCount; i++) {
             GridUnit currentGU = currentRow.getGridUnit(i);            
             if (!currentGU.isEmpty() && currentGU.getColSpanIndex() == 0
-                    && (lastInPart || currentGU.isLastGridUnitRowSpan())) {
+                    && (lastInPart || currentGU.isLastGridUnitRowSpan())
+                    && firstCellParts[i] != null) {
                 assert firstCellParts[i].pgu == currentGU.getPrimary();
                 int borderBeforeWhich;
                 if (firstCellParts[i].start == 0) {
@@ -234,20 +293,26 @@
     // be used as padding.
     // This should be handled automatically by a proper use of Knuth elements
     private int computeContentLength(PrimaryGridUnit pgu, int startIndex, int endIndex) {
-        int actualStart = startIndex;
-        // Skip from the content length calculation glues and penalties occurring at the
-        // beginning of the page
-        while (actualStart <= endIndex
-                && !((KnuthElement) pgu.getElements().get(actualStart)).isBox()) {
-            actualStart++;
-        }
-        int len = ElementListUtils.calcContentLength(
-                pgu.getElements(), actualStart, endIndex);
-        KnuthElement el = (KnuthElement)pgu.getElements().get(endIndex);
-        if (el.isPenalty()) {
-            len += el.getW();
+        if (startIndex > endIndex) {
+             // May happen if the cell contributes no content on the current page (empty
+             // cell, in most cases)
+            return 0;
+        } else {
+            int actualStart = startIndex;
+            // Skip from the content length calculation glues and penalties occurring at the
+            // beginning of the page
+            while (actualStart <= endIndex
+                    && !((KnuthElement) pgu.getElements().get(actualStart)).isBox()) {
+                actualStart++;
+            }
+            int len = ElementListUtils.calcContentLength(
+                    pgu.getElements(), actualStart, endIndex);
+            KnuthElement el = (KnuthElement)pgu.getElements().get(endIndex);
+            if (el.isPenalty()) {
+                len += el.getW();
+            }
+            return len;
         }
-        return len;
     }
 
     private void addAreasForCell(PrimaryGridUnit pgu, int startPos, int endPos,
@@ -256,8 +321,20 @@
          * Determine the index of the first row of this cell that will be displayed on the
          * current page.
          */
-        int startRowIndex = Math.max(pgu.getRowIndex(), firstRowIndex);
         int currentRowIndex = currentRow.getIndex();
+        int startRowIndex;
+        int firstRowHeight;
+        if (pgu.getRowIndex() >= firstRowIndex) {
+            startRowIndex = pgu.getRowIndex();
+            if (startRowIndex < currentRowIndex) {
+                firstRowHeight = getRowOffset(startRowIndex + 1) - getRowOffset(startRowIndex);
+            } else {
+                firstRowHeight = rowHeight;
+            }
+        } else {
+            startRowIndex = firstRowIndex;
+            firstRowHeight = 0;
+        }
 
         /*
          * In collapsing-border model, if the cell spans over several columns/rows then
@@ -297,7 +374,25 @@
         cellLM.addAreas(new KnuthPossPosIter(pgu.getElements(), startPos, endPos + 1),
                 layoutContext, spannedGridRowHeights, startRowIndex - pgu.getRowIndex(),
                 currentRowIndex - pgu.getRowIndex(), borderBeforeWhich, borderAfterWhich,
-                startRowIndex == firstRowOnPageIndex, lastOnPage);
+                startRowIndex == firstRowOnPageIndex, lastOnPage, this, firstRowHeight);
+    }
+
+
+    /**
+     * Registers the given area, that will be used to render the part of
+     * table-header/footer/body background covered by a table-cell. If percentages are
+     * used to place the background image, the final bpd of the (fraction of) table part
+     * that will be rendered on the current page must be known. The traits can't then be
+     * set when the areas for the cell are created since at that moment this bpd is yet
+     * unknown. So they will instead be set in
+     * {@link #addAreasAndFlushRow(boolean, boolean)}.
+     * 
+     * @param backgroundArea the block of the cell's dimensions that will hold the part
+     * background
+     */
+    void registerPartBackgroundArea(Block backgroundArea) {
+        tclm.getTableLM().addBackgroundArea(backgroundArea);
+        tablePartBackgroundAreas.add(backgroundArea);
     }
 
     /**
@@ -335,11 +430,13 @@
     }
 
     // TODO get rid of that
+    /** Signals that the first table-body instance has started. */
     void startBody() {
         Arrays.fill(firstCellOnPage, true);
     }
 
     // TODO get rid of that
+    /** Signals that the last table-body instance has ended. */
     void endBody() {
         Arrays.fill(firstCellOnPage, false);
     }

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java?rev=634267&r1=634266&r2=634267&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java Thu Mar  6 05:33:44 2008
@@ -27,12 +27,14 @@
 import org.apache.fop.area.Block;
 import org.apache.fop.area.Trait;
 import org.apache.fop.datatypes.PercentBaseContext;
-import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.flow.table.ConditionalBorder;
 import org.apache.fop.fo.flow.table.GridUnit;
 import org.apache.fop.fo.flow.table.PrimaryGridUnit;
 import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
 import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
 import org.apache.fop.layoutmgr.AreaAdditionUtil;
@@ -71,7 +73,7 @@
     private int xoffset;
     private int yoffset;
     private int cellIPD;
-    private int rowHeight;
+    private int totalHeight;
     private int usedBPD;
     private int borderAndPaddingBPD;
     private boolean emptyCell = true;
@@ -116,11 +118,7 @@
      * @return the table owning this cell
      */
     public Table getTable() {
-        FONode node = fobj.getParent();
-        while (!(node instanceof Table)) {
-            node = node.getParent();
-        }
-        return (Table)node;
+        return getTableCell().getTable();
     }
 
 
@@ -173,7 +171,7 @@
                 log.debug("child LM signals pending keep with next");
             }
             if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) {
-                context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+                primaryGridUnit.setKeepWithPrevious();
                 childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
             }
 
@@ -210,7 +208,7 @@
                     // with a SpaceResolver.SpaceHandlingBreakPosition element, having no
                     // LM associated to it. Thus it will stop early instead of adding
                     // areas for following Positions. The above test aims at preventing
-                    // such a situation from occuring. add a null penalty to allow a break
+                    // such a situation from occurring. add a null penalty to allow a break
                     // between blocks
                     contentList.add(new BreakElement(
                             new Position(this), 0, context));
@@ -233,6 +231,9 @@
             }
             prevLM = curLM;
         }
+        if (context.isKeepWithNextPending()) {
+            primaryGridUnit.setKeepWithNext();
+        }
 
         returnedList = new LinkedList();
         if (contentList.size() > 0) {
@@ -246,6 +247,16 @@
         }
         //Space resolution
         SpaceResolver.resolveElementList(returnList);
+        if (((KnuthElement) returnList.getFirst()).isForcedBreak()) {
+            primaryGridUnit.setBreakBefore(((KnuthPenalty) returnList.getFirst()).getBreakClass());
+            returnList.removeFirst();
+            assert !returnList.isEmpty();
+        }
+        if (((KnuthElement) returnList.getLast()).isForcedBreak()) {
+            KnuthPenalty p = (KnuthPenalty) returnList.getLast();
+            primaryGridUnit.setBreakAfter(p.getBreakClass());
+            p.setP(0);
+        }
 
         getPSLM().notifyEndOfLayout(((TableCell)getFObj()).getId());
 
@@ -290,7 +301,7 @@
      * @param h the height of cell
      */
     public void setTotalHeight(int h) {
-        rowHeight = h;
+        totalHeight = h;
     }
 
     /**
@@ -317,6 +328,10 @@
      * which case collapsed before borders must be drawn in the outer mode
      * @param lastOnPage true if the cell will be the very last one on the page, in which
      * case collapsed after borders must be drawn in the outer mode
+     * @param painter painter
+     * @param firstRowHeight height of the first row spanned by this cell (may be zero if
+     * this row is placed on a previous page). Used to calculate the placement of the
+     * row's background image if any
      */
     public void addAreas(PositionIterator parentIter,
                          LayoutContext layoutContext,
@@ -326,13 +341,24 @@
                          int borderBeforeWhich,
                          int borderAfterWhich,
                          boolean firstOnPage,
-                         boolean lastOnPage) {
+                         boolean lastOnPage,
+                         RowPainter painter,
+                         int firstRowHeight) {
         getParentArea(null);
 
         getPSLM().addIDToPage(getTableCell().getId());
 
         int borderBeforeWidth = primaryGridUnit.getBeforeBorderWidth(startRow, borderBeforeWhich);
         int borderAfterWidth = primaryGridUnit.getAfterBorderWidth(endRow, borderAfterWhich);
+
+        CommonBorderPaddingBackground padding = primaryGridUnit.getCell()
+                .getCommonBorderPaddingBackground();
+        int cellBPD = totalHeight - borderBeforeWidth - borderAfterWidth;
+        cellBPD -= padding.getPaddingBefore(borderBeforeWhich == ConditionalBorder.REST, this);
+        cellBPD -= padding.getPaddingAfter(borderAfterWhich == ConditionalBorder.REST, this);
+
+        addBackgroundAreas(painter, firstRowHeight, borderBeforeWidth, cellBPD);
+
         if (isSeparateBorderModel()) {
             if (!emptyCell || getTableCell().showEmptyCells()) {
                 if (borderBeforeWidth > 0) {
@@ -424,18 +450,12 @@
             }
         }
 
-        CommonBorderPaddingBackground padding = primaryGridUnit.getCell()
-                .getCommonBorderPaddingBackground();
         TraitSetter.addPadding(curBlockArea,
                 padding,
                 borderBeforeWhich == ConditionalBorder.REST,
                 borderAfterWhich == ConditionalBorder.REST,
                 false, false, this);
 
-        int cellBPD = rowHeight - borderBeforeWidth - borderAfterWidth;
-        cellBPD -= padding.getPaddingBefore(borderBeforeWhich == ConditionalBorder.REST, this);
-        cellBPD -= padding.getPaddingAfter(borderAfterWhich == ConditionalBorder.REST, this);
-
         //Handle display-align
         if (usedBPD < cellBPD) {
             if (getTableCell().getDisplayAlign() == EN_CENTER) {
@@ -455,16 +475,9 @@
         curBlockArea.setBPD(cellBPD);
 
         // Add background after we know the BPD
-        if (isSeparateBorderModel()) {
-            if (!emptyCell || getTableCell().showEmptyCells()) {
-                TraitSetter.addBackground(curBlockArea,
-                        getTableCell().getCommonBorderPaddingBackground(),
-                        this);
-            }
-        } else {
+        if (!isSeparateBorderModel() || !emptyCell || getTableCell().showEmptyCells()) {
             TraitSetter.addBackground(curBlockArea,
-                    getTableCell().getCommonBorderPaddingBackground(),
-                    this);
+                    getTableCell().getCommonBorderPaddingBackground(), this);
         }
 
         flush();
@@ -472,6 +485,32 @@
         curBlockArea = null;
     }
 
+    /** Adds background areas for the column, body and row, if any. */
+    private void addBackgroundAreas(RowPainter painter, int firstRowHeight, int borderBeforeWidth,
+            int cellBPD) {
+        TableColumn column = getTable().getColumn(primaryGridUnit.getColIndex());
+        if (column.getCommonBorderPaddingBackground().hasBackground()) {
+            Block colBackgroundArea = getBackgroundArea(cellBPD, borderBeforeWidth);
+            ((TableLayoutManager) parentLM).registerColumnBackgroundArea(column, colBackgroundArea,
+                    -startIndent);
+        }
+
+        TableBody body = primaryGridUnit.getTableBody();
+        if (body.getCommonBorderPaddingBackground().hasBackground()) {
+            painter.registerPartBackgroundArea(getBackgroundArea(cellBPD, borderBeforeWidth));
+        }
+
+        TableRow row = primaryGridUnit.getRow();
+        if (row != null && row.getCommonBorderPaddingBackground().hasBackground()) {
+            Block rowBackgroundArea = getBackgroundArea(cellBPD, borderBeforeWidth);
+            ((TableLayoutManager) parentLM).addBackgroundArea(rowBackgroundArea);
+            TraitSetter.addBackground(rowBackgroundArea, row.getCommonBorderPaddingBackground(),
+                    (TableLayoutManager) parentLM,
+                    -xoffset - startIndent, -borderBeforeWidth,
+                    parentLM.getContentAreaIPD(), firstRowHeight);
+        }
+    }
+
     private void addBorder(Block[][] blocks, int i, int j, Integer side, BorderInfo border,
             boolean outer) {
         if (blocks[i][j] == null) {
@@ -498,6 +537,17 @@
 
     private static void adjustBPD(Block block, int amount) {
         block.setBPD(block.getBPD() + amount);
+    }
+
+    private Block getBackgroundArea(int bpd, int borderBeforeWidth) {
+        Block block = new Block();
+        TraitSetter.setProducerID(block, getTable().getId());
+        block.setPositioning(Block.ABSOLUTE);
+        block.setIPD(cellIPD);
+        block.setBPD(bpd);
+        block.setXOffset(xoffset + startIndent);
+        block.setYOffset(yoffset + borderBeforeWidth);
+        return block;
     }
 
     /**

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu Mar  6 05:33:44 2008
@@ -1 +1 @@
-Author Date Id Revision
+Id



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org