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/23 17:01:14 UTC

cvs commit: xml-fop/src/java/org/apache/fop/area Page.java

jeremias    2005/06/23 08:01:14

  Modified:    src/java/org/apache/fop/layoutmgr
                        PageSequenceLayoutManager.java
                        BlockContainerLayoutManager.java
                        LineLayoutManager.java AbstractBreaker.java
                        BreakingAlgorithm.java PageBreakingAlgorithm.java
                        StaticContentLayoutManager.java
               src/java/org/apache/fop/area Page.java
  Log:
  First parts on a page which don't fit are moved to the next page. A counter avoids endless loops.
  Fixes normal-breaking5.xml.
  
  Revision  Changes    Path
  1.71      +6 -1      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.70
  retrieving revision 1.71
  diff -u -r1.70 -r1.71
  --- PageSequenceLayoutManager.java	22 Jun 2005 14:59:54 -0000	1.70
  +++ PageSequenceLayoutManager.java	23 Jun 2005 15:01:14 -0000	1.71
  @@ -286,6 +286,11 @@
               firstPart = false;
           }
           
  +        /** @see org.apache.fop.layoutmgr.AbstractBreaker#handleEmptyContent() */
  +        protected void handleEmptyContent() {
  +            curPV.getPage().fakeNonEmpty();
  +        }
  +        
           protected void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp) {
               // add footnote areas
               if (pbp.footnoteFirstListIndex < pbp.footnoteLastListIndex
  
  
  
  1.44      +6 -0      xml-fop/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
  
  Index: BlockContainerLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -r1.43 -r1.44
  --- BlockContainerLayoutManager.java	7 Jun 2005 20:43:43 -0000	1.43
  +++ BlockContainerLayoutManager.java	23 Jun 2005 15:01:14 -0000	1.44
  @@ -447,6 +447,12 @@
               this.ipd = ipd;
           }
   
  +        /** @see org.apache.fop.layoutmgr.AbstractBreaker#isPartOverflowRecoveryActivated() */
  +        protected boolean isPartOverflowRecoveryActivated() {
  +            //For block-containers, this must be disabled because of wanted overflow.
  +            return false;
  +        }
  +
           public int getDifferenceOfFirstPart() {
               PageBreakPosition pbp = (PageBreakPosition)this.deferredAlg.getPageBreaks().getFirst();
               return pbp.difference;
  
  
  
  1.51      +1 -1      xml-fop/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java
  
  Index: LineLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java,v
  retrieving revision 1.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- LineLayoutManager.java	15 Jun 2005 09:08:34 -0000	1.50
  +++ LineLayoutManager.java	23 Jun 2005 15:01:14 -0000	1.51
  @@ -273,7 +273,7 @@
                                         int indent, int fillerWidth,
                                         int lh, int ld, int fl, int ms, boolean first,
                                         LineLayoutManager llm) {
  -            super(textAlign, textAlignLast, first);
  +            super(textAlign, textAlignLast, first, false);
               pageAlignment = pageAlign;
               textIndent = indent;
               fillerMinWidth = fillerWidth;
  
  
  
  1.11      +22 -2     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.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- AbstractBreaker.java	22 Jun 2005 14:59:54 -0000	1.10
  +++ AbstractBreaker.java	23 Jun 2005 15:01:14 -0000	1.11
  @@ -106,6 +106,15 @@
       protected abstract LayoutManager getCurrentChildLM();
       
       /**
  +     * Controls the behaviour of the algorithm in cases where the first element of a part
  +     * overflows a line/page. 
  +     * @return true if the algorithm should try to send the element to the next line/page.
  +     */
  +    protected boolean isPartOverflowRecoveryActivated() {
  +        return true;
  +    }
  +
  +    /**
        * Returns the PageViewportProvider if any. PageBreaker overrides this method because each
        * page may have a different available BPD which needs to be accessible to the breaking
        * algorithm.
  @@ -131,6 +140,13 @@
           //nop
       }
       
  +    /**
  +     * This method is called when no content is available for a part. Used to force empty pages.
  +     */
  +    protected void handleEmptyContent() {
  +        //nop    
  +    }
  +    
       protected abstract void finishPart(PageBreakingAlgorithm alg, PageBreakPosition pbp);
   
       protected LayoutContext createLayoutContext() {
  @@ -182,7 +198,8 @@
                       + "), flow BPD =" + flowBPD);
               PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(),
                       getPageViewportProvider(),
  -                    alignment, alignmentLast, footnoteSeparatorLength);
  +                    alignment, alignmentLast, footnoteSeparatorLength,
  +                    isPartOverflowRecoveryActivated());
               int iOptPageCount;
   
               BlockSequence effectiveList;
  @@ -328,6 +345,9 @@
   
                   addAreas(new KnuthPossPosIter(effectiveList,
                           startElementIndex, endElementIndex + 1), childLC);
  +            } else {
  +                //no content for this part
  +                handleEmptyContent();
               }
   
               finishPart(alg, pbp);
  
  
  
  1.10      +64 -19    xml-fop/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
  
  Index: BreakingAlgorithm.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- BreakingAlgorithm.java	22 Jun 2005 14:55:33 -0000	1.9
  +++ BreakingAlgorithm.java	23 Jun 2005 15:01:14 -0000	1.10
  @@ -21,6 +21,7 @@
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  +import org.apache.fop.layoutmgr.PageBreakingAlgorithm.KnuthPageNode;
   import org.apache.fop.traits.MinOptMax;
   
   /**
  @@ -45,6 +46,8 @@
       
       protected static final int INFINITE_RATIO = 1000;
   
  +    private static final int MAX_RECOVERY_ATTEMPTS = 50;
  +
       // parameters of Knuth's algorithm:
       // penalty value for flagged penalties
       private int flaggedPenalty = 50;
  @@ -117,57 +120,66 @@
       protected BestRecords best;
       private KnuthNode[] positions;
   
  +    /** @see isPartOverflowRecoveryActivated() */
  +    private boolean partOverflowRecoveryActivated = true;
  +
       public BreakingAlgorithm(int align, int alignLast,
  -                             boolean first) {
  +                             boolean first, boolean partOverflowRecovery) {
           alignment = align;
           alignmentLast = alignLast;
           bFirst = first;
  +        this.partOverflowRecoveryActivated = partOverflowRecovery;
           this.best = new BestRecords();
       }
   
   
       // this class represent a feasible breaking point
       protected class KnuthNode {
  -        // index of the breakpoint represented by this node
  +        /** index of the breakpoint represented by this node */
           public int position;
   
  -        // number of the line ending at this breakpoint
  +        /** number of the line ending at this breakpoint */
           public int line;
   
  -        // fitness class of the line ending at his breakpoint
  +        /** fitness class of the line ending at his breakpoint */
           public int fitness;
   
  -        // accumulated width of the KnuthElements
  +        /** accumulated width of the KnuthElements */
           public int totalWidth;
   
  -        // accumulated stretchability of the KnuthElements
  +        /** accumulated stretchability of the KnuthElements */
           public int totalStretch;
   
  -        // accumulated shrinkability of the KnuthElements
  +        /** accumulated shrinkability of the KnuthElements */
           public int totalShrink;
   
  -        // adjustment ratio if the line ends at this breakpoint
  +        /** adjustment ratio if the line ends at this breakpoint */
           public double adjustRatio;
   
  -        // available stretch of the line ending at this breakpoint
  +        /** available stretch of the line ending at this breakpoint */
           public int availableShrink;
   
  -        // available shrink of the line ending at this breakpoint
  +        /** available shrink of the line ending at this breakpoint */
           public int availableStretch;
   
  -        // difference between target and actual line width
  +        /** difference between target and actual line width */
           public int difference;
   
  -        // minimum total demerits up to this breakpoint
  +        /** minimum total demerits up to this breakpoint */
           public double totalDemerits;
   
  -        // best node for the preceding breakpoint
  +        /** best node for the preceding breakpoint */
           public KnuthNode previous;
   
  -        // next possible node in the same line 
  +        /** next possible node in the same line */ 
           public KnuthNode next;
   
  -
  +        /**
  +         * Holds the number of subsequent recovery attempty that are made to get content fit
  +         * into a line.
  +         */
  +        public int fitRecoveryCounter = 0;
  +        
           public KnuthNode(int position, int line, int fitness,
                            int totalWidth, int totalStretch, int totalShrink,
                            double adjustRatio, int availableShrink, int availableStretch, int difference,
  @@ -219,7 +231,7 @@
                                 int availableShrink, int availableStretch,
                                 int difference, int fitness) {
               if (demerits > bestDemerits[fitness]) {
  -                log.error("New demerits value greter than the old one");
  +                log.error("New demerits value greater than the old one");
               }
               bestDemerits[fitness] = demerits;
               bestNode[fitness] = node;
  @@ -282,7 +294,22 @@
           }
       }
   
  -
  +    /**
  +     * @return the number of times the algorithm should try to move overflowing content to the
  +     * next line/page.
  +     */
  +    protected int getMaxRecoveryAttempts() {
  +        return MAX_RECOVERY_ATTEMPTS;
  +    }
  +    
  +    /**
  +     * Controls the behaviour of the algorithm in cases where the first element of a part
  +     * overflows a line/page. 
  +     * @return true if the algorithm should try to send the element to the next line/page.
  +     */
  +    protected boolean isPartOverflowRecoveryActivated() {
  +        return this.partOverflowRecoveryActivated;
  +    }
   
       public abstract void updateData1(int total, double demerits) ;
   
  @@ -367,7 +394,25 @@
                       return 0;
                   }
                   if (lastTooShort == null || lastForced.position == lastTooShort.position) {
  -                    lastForced = lastTooLong;
  +                    if (isPartOverflowRecoveryActivated()) {
  +                        // content would overflow, insert empty line/page and try again
  +                        KnuthNode node = createNode(
  +                                lastTooLong.previous.position, lastTooLong.previous.line + 1, 1,
  +                                0, 0, 0,
  +                                0, 0, 0,
  +                                0, 0, lastTooLong.previous);
  +                        lastForced = node;
  +                        node.fitRecoveryCounter = lastTooLong.previous.fitRecoveryCounter + 1;
  +                        log.debug("first part doesn't fit into line, recovering: " 
  +                                + node.fitRecoveryCounter);
  +                        if (node.fitRecoveryCounter > getMaxRecoveryAttempts()) {
  +                            throw new RuntimeException("Some content could not fit "
  +                                    + "into a line/page after " + getMaxRecoveryAttempts() 
  +                                    + " attempts. Giving up to avoid an endless loop.");
  +                        }
  +                    } else {
  +                        lastForced = lastTooLong;
  +                    }
                   } else {
                       lastForced = lastTooShort;
                   }
  
  
  
  1.10      +4 -3      xml-fop/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
  
  Index: PageBreakingAlgorithm.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- PageBreakingAlgorithm.java	22 Jun 2005 14:57:13 -0000	1.9
  +++ PageBreakingAlgorithm.java	23 Jun 2005 15:01:14 -0000	1.10
  @@ -67,8 +67,9 @@
       public PageBreakingAlgorithm(LayoutManager topLevelLM,
                                    PageSequenceLayoutManager.PageViewportProvider pvProvider,
                                    int alignment, int alignmentLast,
  -                                 MinOptMax fnSeparatorLength) {
  -        super(alignment, alignmentLast, true);
  +                                 MinOptMax fnSeparatorLength,
  +                                 boolean partOverflowRecovery) {
  +        super(alignment, alignmentLast, true, partOverflowRecovery);
           this.topLevelLM = topLevelLM;
           this.pvProvider = pvProvider;
           best = new BestPageRecords();
  
  
  
  1.17      +6 -0      xml-fop/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
  
  Index: StaticContentLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- StaticContentLayoutManager.java	10 Jun 2005 03:56:49 -0000	1.16
  +++ StaticContentLayoutManager.java	23 Jun 2005 15:01:14 -0000	1.17
  @@ -236,6 +236,12 @@
               this.displayAlign = displayAlign;
           }
   
  +        /** @see org.apache.fop.layoutmgr.AbstractBreaker#isPartOverflowRecoveryActivated() */
  +        protected boolean isPartOverflowRecoveryActivated() {
  +            //For side regions, this must be disabled because of wanted overflow.
  +            return false;
  +        }
  +
           public boolean isOverflow() {
               return this.overflow;
           }
  
  
  
  1.11      +14 -3     xml-fop/src/java/org/apache/fop/area/Page.java
  
  Index: Page.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/area/Page.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- Page.java	14 May 2005 05:22:16 -0000	1.10
  +++ Page.java	23 Jun 2005 15:01:14 -0000	1.11
  @@ -55,6 +55,9 @@
       // temporary map of unresolved objects used when serializing the page
       private HashMap unresolved = null;
   
  +    /** Set to true to make this page behave as if it were not empty. */
  +    private boolean fakeNonEmpty = false;
  +    
       /**
        *  Empty constructor, for cloning 
        */
  @@ -110,6 +113,13 @@
       }
   
       /**
  +     * Call this method to force this page to pretend not to be empty.
  +     */
  +    public void fakeNonEmpty() {
  +        this.fakeNonEmpty = true;
  +    }
  +    
  +    /**
        * Creates a RegionViewport Area object for this pagination Region.
        * @param reldims relative dimensions
        * @param pageCTM page coordinate transformation matrix
  @@ -197,10 +207,11 @@
        * @return whether any FOs have been added to the body region
        */
       public boolean isEmpty() {
  -        if (regionBody == null) {
  +        if (fakeNonEmpty) {
  +            return false;
  +        } else if (regionBody == null) {
               return true;
  -        }
  -        else {
  +        } else {
               BodyRegion body = (BodyRegion)regionBody.getRegionReference();
               return body.isEmpty();
           }
  
  
  

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