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 2005/06/22 16:59:54 UTC

cvs commit: xml-fop/src/java/org/apache/fop/layoutmgr PageSequenceLayoutManager.java BlockStackingLayoutManager.java AbstractBreaker.java

jeremias    2005/06/22 07:59:54

  Modified:    src/java/org/apache/fop/layoutmgr/table
                        TableLayoutManager.java TableStepper.java
                        EffRow.java TableContentLayoutManager.java
               src/java/org/apache/fop/layoutmgr
                        PageSequenceLayoutManager.java
                        BlockStackingLayoutManager.java
                        AbstractBreaker.java
  Log:
  breaks supported on tables, table-row and table-cell content now. Cheap approach for now. TableContentLM is not yet restartable, but the Breaker handles that pretty well.
  Improved page break handling to support the different break classes even if no new block sequence is started.
  
  Revision  Changes    Path
  1.27      +16 -6     xml-fop/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
  
  Index: TableLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- TableLayoutManager.java	7 Jun 2005 20:43:43 -0000	1.26
  +++ TableLayoutManager.java	22 Jun 2005 14:59:54 -0000	1.27
  @@ -116,12 +116,20 @@
           return iIndents;
       }
       
  -    /**
  -     * @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(org.apache.fop.layoutmgr.LayoutContext, int)
  -     */
  +    /** @see org.apache.fop.layoutmgr.LayoutManager */
       public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
           
  -        //Body curLM; // currently active LM
  +        LinkedList returnList = new LinkedList();
  +        
  +        if (!bBreakBeforeServed) {
  +            try {
  +                if (addKnuthElementsForBreakBefore(returnList)) {
  +                    return returnList;
  +                }
  +            } finally {
  +                bBreakBeforeServed = true;
  +            }
  +        }
   
           referenceIPD = context.getRefIPD();
           if (fobj.getInlineProgressionDimension().getOptimum().getEnum() != EN_AUTO) {
  @@ -169,7 +177,6 @@
   
           LinkedList returnedList = null;
           LinkedList contentList = new LinkedList();
  -        LinkedList returnList = new LinkedList();
           //Position returnPosition = new NonLeafPosition(this, null);
           //Body prevLM = null;
   
  @@ -179,7 +186,9 @@
                                    stackSize));
           childLC.setRefIPD(context.getRefIPD());
   
  -        contentLM = new TableContentLayoutManager(this);
  +        if (contentLM == null) {
  +            contentLM = new TableContentLayoutManager(this);
  +        }
           returnedList = contentLM.getNextKnuthElements(childLC, alignment);
           if (childLC.isKeepWithNextPending()) {
               log.debug("TableContentLM signals pending keep-with-next");
  @@ -261,6 +270,7 @@
               }
           }
           wrapPositionElements(contentList, returnList);
  +        addKnuthElementsForBreakAfter(returnList);
           setFinished(true);
           return returnList;
       }
  
  
  
  1.10      +48 -2     xml-fop/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
  
  Index: TableStepper.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/TableStepper.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- TableStepper.java	31 May 2005 12:46:14 -0000	1.9
  +++ TableStepper.java	22 Jun 2005 14:59:54 -0000	1.10
  @@ -24,6 +24,8 @@
   
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  +import org.apache.fop.fo.Constants;
  +import org.apache.fop.fo.flow.TableRow;
   import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
   import org.apache.fop.layoutmgr.ElementListUtils;
   import org.apache.fop.layoutmgr.KnuthBox;
  @@ -57,6 +59,7 @@
       private int[] borderAfter;
       private boolean rowBacktrackForLastStep;
       private boolean[] keepWithNextSignals;
  +    private boolean[] forcedBreaks;
       
       /**
        * Main constructor
  @@ -77,9 +80,23 @@
           borderBefore = new int[columnCount];
           borderAfter = new int[columnCount];
           keepWithNextSignals = new boolean[columnCount];
  +        forcedBreaks = new boolean[columnCount];
           Arrays.fill(end, -1);
       }
       
  +    private void clearBreakCondition() {
  +        Arrays.fill(forcedBreaks, false);
  +    }
  +    
  +    private boolean isBreakCondition() {
  +        for (int i = 0; i < forcedBreaks.length; i++) {
  +            if (forcedBreaks[i]) {
  +                return true;
  +            }
  +        }
  +        return false;
  +    }
  +    
       private EffRow getActiveRow() {
           return rowGroup[activeRow];
       }
  @@ -147,6 +164,7 @@
               widths[column] = 0;
               startRow[column] = activeRow;
               keepWithNextSignals[column] = false;
  +            forcedBreaks[column] = false;
           } else if (gu.isPrimary()) {
               PrimaryGridUnit pgu = (PrimaryGridUnit)gu;
               boolean makeBoxForWholeRow = false;
  @@ -184,6 +202,7 @@
               widths[column] = 0;
               startRow[column] = activeRow;
               keepWithNextSignals[column] = false;
  +            forcedBreaks[column] = false;
           }
       }
       
  @@ -303,6 +322,10 @@
               if (signalKeepWithNext || getTableLM().mustKeepTogether()) {
                   p = KnuthPenalty.INFINITE;
               }
  +            if (isBreakCondition()) {
  +                p = -KnuthPenalty.INFINITE; //Overrides any keeps (see 4.8 in XSL 1.0)
  +                clearBreakCondition();
  +            }
               returnList.add(new KnuthPenalty(effPenaltyLen, p, false, penaltyPos, false));
   
               log.debug("step=" + step + " (+" + increase + ")"
  @@ -321,11 +344,20 @@
               //we have to signal the still pending last keep-with-next using the LayoutContext.
               context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
           }
  +        if (isBreakCondition()) {
  +            ((KnuthPenalty)returnList.getLast()).setP(-KnuthPenalty.INFINITE);
  +        }
           lastTCPos.setFlag(TableContentPosition.LAST_IN_ROWGROUP, true);
           return returnList;
       }
       
       private int getNextStep(int lastStep) {
  +        //Check for forced break conditions
  +        /*
  +        if (isBreakCondition()) {
  +            return -1;
  +        }*/
  +        
           int[] backupWidths = new int[start.length];
           System.arraycopy(widths, 0, backupWidths, 0, backupWidths.length);
   
  @@ -349,6 +381,11 @@
   
           if (rowPendingIndicator == 0) {
               if (activeRow < rowGroup.length - 1) {
  +                TableRow rowFO = getActiveRow().getTableRow();
  +                if (rowFO != null && rowFO.getBreakAfter() != Constants.EN_AUTO) {
  +                    log.warn("break-after ignored on table-row because of row spanning "
  +                            + "in progress (See XSL 1.0, 7.19.1)");
  +                }
                   activeRow++;
                   log.debug("===> new row: " + activeRow);
                   initializeElementLists();
  @@ -357,6 +394,11 @@
                           backupWidths[i] = 0;
                       }
                   }
  +                rowFO = getActiveRow().getTableRow();
  +                if (rowFO != null && rowFO.getBreakBefore() != Constants.EN_AUTO) {
  +                    log.warn("break-before ignored on table-row because of row spanning "
  +                            + "in progress (See XSL 1.0, 7.19.2)");
  +                }
               }
           }
   
  @@ -370,7 +412,11 @@
                   end[i]++;
                   KnuthElement el = (KnuthElement)elementLists[i].get(end[i]);
                   if (el.isPenalty()) {
  -                    if (el.getP() < KnuthElement.INFINITE) {
  +                    if (el.getP() <= -KnuthElement.INFINITE) {
  +                        log.warn("FORCED break encountered!");
  +                        forcedBreaks[i] = true;
  +                        break;
  +                    } else if (el.getP() < KnuthElement.INFINITE) {
                           //First legal break point
                           break;
                       }
  
  
  
  1.5       +7 -1      xml-fop/src/java/org/apache/fop/layoutmgr/table/EffRow.java
  
  Index: EffRow.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/EffRow.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- EffRow.java	30 May 2005 09:11:10 -0000	1.4
  +++ EffRow.java	22 Jun 2005 14:59:54 -0000	1.5
  @@ -21,6 +21,7 @@
   import java.util.Iterator;
   import java.util.List;
   
  +import org.apache.fop.fo.flow.TableRow;
   import org.apache.fop.traits.MinOptMax;
   
   /**
  @@ -63,6 +64,11 @@
           return this.bodyType;
       }
       
  +    /** @return the table-row FO for this EffRow, or null if there is no table-row. */
  +    public TableRow getTableRow() {
  +        return getGridUnit(0).getRow();
  +    }
  +    
       /** @return the calculated height for this EffRow. */
       public MinOptMax getHeight() {
           return this.height;
  
  
  
  1.12      +73 -6     xml-fop/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
  
  Index: TableContentLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- TableContentLayoutManager.java	30 May 2005 09:11:10 -0000	1.11
  +++ TableContentLayoutManager.java	22 Jun 2005 14:59:54 -0000	1.12
  @@ -28,6 +28,7 @@
   import org.apache.commons.logging.LogFactory;
   import org.apache.fop.area.Block;
   import org.apache.fop.area.Trait;
  +import org.apache.fop.fo.Constants;
   import org.apache.fop.fo.flow.Table;
   import org.apache.fop.fo.flow.TableBody;
   import org.apache.fop.fo.flow.TableRow;
  @@ -63,6 +64,7 @@
       private LinkedList footerList;
       private int headerNetHeight = 0;
       private int footerNetHeight = 0;
  +    private boolean firstBreakBeforeServed = false;
   
       private int startXOffset;
       private int usedBPD;
  @@ -130,7 +132,7 @@
           KnuthBox headerAsFirst = null;
           KnuthBox headerAsSecondToLast = null;
           KnuthBox footerAsLast = null;
  -        if (headerIter != null) {
  +        if (headerIter != null && headerList == null) {
               this.headerList = getKnuthElementsForRowIterator(
                       headerIter, context, alignment, TableRowIterator.HEADER);
               ElementListUtils.removeLegalBreaks(this.headerList);
  @@ -148,7 +150,7 @@
                   headerAsSecondToLast = box;
               }
           }
  -        if (footerIter != null) {
  +        if (footerIter != null && footerList == null) {
               this.footerList = getKnuthElementsForRowIterator(
                       footerIter, context, alignment, TableRowIterator.FOOTER);
               ElementListUtils.removeLegalBreaks(this.footerList);
  @@ -190,11 +192,39 @@
           LinkedList returnList = new LinkedList();
           EffRow[] rowGroup = null;
           while ((rowGroup = iter.getNextRowGroup()) != null) {
  +            //Check for break-before on the table-row at the start of the row group
  +            TableRow rowFO = rowGroup[0].getTableRow(); 
  +            if (rowFO != null && rowFO.getBreakBefore() != Constants.EN_AUTO) {
  +                log.info("break-before found");
  +                if (returnList.size() > 0) {
  +                    KnuthElement last = (KnuthElement)returnList.getLast();
  +                    if (last.isPenalty()) {
  +                        KnuthPenalty pen = (KnuthPenalty)last;
  +                        pen.setP(-KnuthPenalty.INFINITE);
  +                        pen.setBreakClass(rowFO.getBreakBefore());
  +                    }
  +                } else {
  +                    if (!firstBreakBeforeServed) {
  +                        returnList.add(new KnuthPenalty(0, -KnuthPenalty.INFINITE, 
  +                                false, rowFO.getBreakBefore(), new Position(getTableLM()), true));
  +                        iter.backToPreviousRow();
  +                        firstBreakBeforeServed = true;
  +                        break;
  +                    }
  +                }
  +            }
  +            firstBreakBeforeServed = true;
  +            
  +            //Border resolution
               if (!isSeparateBorderModel()) {
                   resolveNormalBeforeAfterBordersForRowGroup(rowGroup, iter);
               }
  +            
  +            //Element list creation
               createElementsForRowGroup(context, alignment, bodyType, 
                           returnList, rowGroup);
  +            
  +            //Handle keeps
               if (context.isKeepWithNextPending()) {
                   log.debug("child LM (row group) signals pending keep-with-next");
               }
  @@ -205,7 +235,24 @@
                       KnuthElement last = (KnuthElement)returnList.getLast();
                       if (last.isPenalty()) {
                           KnuthPenalty pen = (KnuthPenalty)last;
  -                        pen.setP(KnuthPenalty.INFINITE);
  +                        //Only honor keep if there's no forced break
  +                        if (!pen.isForcedBreak()) {
  +                            pen.setP(KnuthPenalty.INFINITE);
  +                        }
  +                    }
  +                }
  +            }
  +            
  +            //Check for break-after on the table-row at the end of the row group
  +            rowFO = rowGroup[rowGroup.length - 1].getTableRow(); 
  +            if (rowFO != null && rowFO.getBreakAfter() != Constants.EN_AUTO) {
  +                log.info("break-after found");
  +                if (returnList.size() > 0) {
  +                    KnuthElement last = (KnuthElement)returnList.getLast();
  +                    if (last.isPenalty()) {
  +                        KnuthPenalty pen = (KnuthPenalty)last;
  +                        pen.setP(-KnuthPenalty.INFINITE);
  +                        pen.setBreakClass(rowFO.getBreakAfter());
                       }
                   }
               }
  @@ -215,7 +262,11 @@
               //Remove last penalty
               KnuthElement last = (KnuthElement)returnList.getLast();
               if (last.isPenalty()) {
  -                returnList.removeLast();
  +                KnuthPenalty pen = (KnuthPenalty)last;
  +                if (!pen.isForcedBreak()) {
  +                    //Only remove if we don't signal a forced break
  +                    returnList.removeLast();
  +                }
               }
           }
           return returnList;
  @@ -395,8 +446,24 @@
                           //Get the element list for the cell contents
                           LinkedList elems = primary.getCellLM().getNextKnuthElements(
                                                   childLC, alignment);
  -                        primary.setElements(elems);
  +                        //Temporary? Multiple calls in case of break conditions.
  +                        //TODO Revisit when table layout is restartable
  +                        while (!primary.getCellLM().isFinished()) {
  +                            LinkedList additionalElems = primary.getCellLM().getNextKnuthElements(
  +                                    childLC, alignment);
  +                            elems.addAll(additionalElems);
  +                        }
                           ElementListObserver.observe(elems, "table-cell", primary.getCell().getId());
  +
  +                        if (((KnuthElement)elems.getLast()).isPenalty()
  +                                && ((KnuthPenalty)elems.getLast()).getP() 
  +                                        == -KnuthElement.INFINITE) {
  +                            // a descendant of this block has break-after
  +                            log.warn("Descendant of table-cell signals break: " 
  +                                    + primary.getCellLM().isFinished());
  +                        }
  +                        
  +                        primary.setElements(elems);
                           
                           if (childLC.isKeepWithNextPending()) {
                               log.debug("child LM signals pending keep-with-next");
  
  
  
  1.70      +3 -3      xml-fop/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
  
  Index: PageSequenceLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  --- PageSequenceLayoutManager.java	16 Jun 2005 07:29:06 -0000	1.69
  +++ PageSequenceLayoutManager.java	22 Jun 2005 14:59:54 -0000	1.70
  @@ -261,7 +261,7 @@
               addAreas(alg, partCount, originalList, effectiveList);
           }
           
  -        protected void startPart(BlockSequence list, boolean bIsFirstPage) {
  +        protected void startPart(BlockSequence list, int breakClass) {
               if (curPV == null) {
                   throw new IllegalStateException("curPV must not be null");
               } else {
  @@ -276,7 +276,7 @@
                           // the current BlockSequence, it could have a break
                           // condition that must be satisfied;
                           // otherwise, we may simply need a new page
  -                        handleBreakTrait(bIsFirstPage ? list.getStartOn() : Constants.EN_PAGE);
  +                        handleBreakTrait(breakClass);
                       }
                   }
                   pvProvider.setStartPageOfNextElementList(currentPageNum);
  
  
  
  1.20      +4 -0      xml-fop/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
  
  Index: BlockStackingLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- BlockStackingLayoutManager.java	30 May 2005 09:11:09 -0000	1.19
  +++ BlockStackingLayoutManager.java	22 Jun 2005 14:59:54 -0000	1.20
  @@ -822,6 +822,8 @@
               breakBefore = ((org.apache.fop.fo.flow.Block) fobj).getBreakBefore();
           } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
               breakBefore = ((org.apache.fop.fo.flow.BlockContainer) fobj).getBreakBefore();
  +        } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
  +            breakBefore = ((org.apache.fop.fo.flow.Table) fobj).getBreakBefore();
           }
           if (breakBefore == EN_PAGE
                   || breakBefore == EN_COLUMN 
  @@ -849,6 +851,8 @@
               breakAfter = ((org.apache.fop.fo.flow.Block) fobj).getBreakAfter();
           } else if (fobj instanceof org.apache.fop.fo.flow.BlockContainer) {
               breakAfter = ((org.apache.fop.fo.flow.BlockContainer) fobj).getBreakAfter();
  +        } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
  +            breakAfter = ((org.apache.fop.fo.flow.Table) fobj).getBreakAfter();
           }
           if (breakAfter == EN_PAGE
                   || breakAfter == EN_COLUMN
  
  
  
  1.10      +32 -14    xml-fop/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
  
  Index: AbstractBreaker.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- AbstractBreaker.java	15 Jun 2005 09:08:34 -0000	1.9
  +++ AbstractBreaker.java	22 Jun 2005 14:59:54 -0000	1.10
  @@ -127,7 +127,7 @@
           return (blockLists.size() == 0);
       }
       
  -    protected void startPart(BlockSequence list, boolean bIsFirstPage) {
  +    protected void startPart(BlockSequence list, int breakClass) {
           //nop
       }
       
  @@ -183,7 +183,7 @@
               PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(),
                       getPageViewportProvider(),
                       alignment, alignmentLast, footnoteSeparatorLength);
  -            int iOptPageNumber;
  +            int iOptPageCount;
   
               BlockSequence effectiveList;
               if (alignment == Constants.EN_JUSTIFY) {
  @@ -194,16 +194,16 @@
                   effectiveList = blockList;
               }
   
  -            //iOptPageNumber = alg.firstFit(effectiveList, flowBPD, 1, true);
  +            //iOptPageCount = alg.firstFit(effectiveList, flowBPD, 1, true);
               alg.setConstantLineWidth(flowBPD);
  -            iOptPageNumber = alg.findBreakingPoints(effectiveList, /*flowBPD,*/
  -                    1, true, true);
  -            log.debug("PLM> iOptPageNumber= " + iOptPageNumber
  +            iOptPageCount = alg.findBreakingPoints(effectiveList, /*flowBPD,*/
  +                        1, true, true);
  +            log.debug("PLM> iOptPageCount= " + iOptPageCount
                       + " pageBreaks.size()= " + alg.getPageBreaks().size());
   
               
               //*** Phase 3: Add areas ***
  -            doPhase3(alg, iOptPageNumber, blockList, effectiveList);
  +            doPhase3(alg, iOptPageCount, blockList, effectiveList);
           }
       }
   
  @@ -233,20 +233,38 @@
           int endElementIndex = 0;
           for (int p = 0; p < partCount; p++) {
               PageBreakPosition pbp = (PageBreakPosition) alg.getPageBreaks().get(p);
  -            endElementIndex = pbp.getLeafPos();
  -            log.debug("PLM> part: " + (p + 1)
  -                    + ", break at position " + endElementIndex);
   
  -            startPart(effectiveList, (p == 0));
  -            
  -            int displayAlign = getCurrentDisplayAlign();
  +            //Check the last break position for forced breaks
  +            int lastBreakClass;
  +            if (p == 0) {
  +                lastBreakClass = effectiveList.getStartOn();
  +            } else {
  +                KnuthElement lastBreakElement = effectiveList.getElement(endElementIndex);
  +                if (lastBreakElement.isPenalty()) {
  +                    KnuthPenalty pen = (KnuthPenalty)lastBreakElement;
  +                    lastBreakClass = pen.getBreakClass();
  +                } else {
  +                    lastBreakClass = Constants.EN_AUTO;
  +                }
  +            }
               
  +            //the end of the new part
  +            endElementIndex = pbp.getLeafPos();
  +
               // ignore the first elements added by the
               // PageSequenceLayoutManager
               startElementIndex += (startElementIndex == 0) 
                       ? effectiveList.ignoreAtStart
                       : 0;
   
  +            log.debug("PLM> part: " + (p + 1)
  +                    + ", start at pos " + startElementIndex
  +                    + ", break at pos " + endElementIndex);
  +
  +            startPart(effectiveList, lastBreakClass);
  +            
  +            int displayAlign = getCurrentDisplayAlign();
  +            
               // ignore the last elements added by the
               // PageSequenceLayoutManager
               endElementIndex -= (endElementIndex == (originalList.size() - 1)) 
  
  
  

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