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 kl...@apache.org on 2001/11/11 15:13:51 UTC

cvs commit: xml-fop/src/org/apache/fop/layoutmgr BlockLayoutManager.java LineLayoutManager.java TextLayoutManager.java

klease      01/11/11 06:13:51

  Added:       src/org/apache/fop/layoutmgr BlockLayoutManager.java
                        LineLayoutManager.java TextLayoutManager.java
  Log:
  new layout managers
  
  Revision  Changes    Path
  1.1                  xml-fop/src/org/apache/fop/layoutmgr/BlockLayoutManager.java
  
  Index: BlockLayoutManager.java
  ===================================================================
  /*
   * $Id: BlockLayoutManager.java,v 1.1 2001/11/11 14:13:51 klease Exp $
   * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
   * For details on use and redistribution please refer to the
   * LICENSE file included with these sources.
   */
  
  package org.apache.fop.layoutmgr;
  
  import org.apache.fop.fo.FObj;
  import org.apache.fop.area.Area;
  import org.apache.fop.area.BlockParent;
  import org.apache.fop.area.Block;
  import org.apache.fop.area.LineArea;
  
  import java.util.ListIterator;
  
  /**
   * LayoutManager for a block FO.
   */
  public class BlockLayoutManager extends BlockStackingLayoutManager {
  
      private Block curBlockArea;
  
      public BlockLayoutManager(FObj fobj) {
  	super(fobj);
      }
  
      // DESIGN. Potential alternative to getParentArea() scheme
  //     /**
  //      * Called by child layout manager to get the available space for
  //      * content in the inline progression direction.
  //      * Note that a manager may need to ask its parent for this.
  //      * For a block area, available IPD is determined by indents.
  //      */
  //     public int getContentIPD() {
  // 	getArea(); // make if not existing
  // 	return blockArea.getIPD();
  //     }
  
      /**
       * Generate areas by tellings all layout managers for its FO's
       * children to generate areas.
       */
      public void generateAreas() {
  	ListIterator children = fobj.getChildren();
  	while (children.hasNext()) {
  	    LayoutManager lm = ((FObj)children.next()).getLayoutManager();
   	    if (lm != null) {
  		if (lm.generatesInlineAreas()) {
  		    // Back up one
  		    children.previous();
  		    lm = new LineLayoutManager(children);
  		}
  		lm.setParentLM(this);
  		lm.generateAreas();
  	    }
  	}
  	flush(); // Add last area to parent
      }
  
  
      /**
       * Return an Area which can contain the passed childArea. The childArea
       * may not yet have any content, but it has essential traits set.
       * In general, if the LayoutManager already has an Area it simply returns
       * it. Otherwise, it makes a new Area of the appropriate class.
       * It gets a parent area for its area by calling its parent LM.
       * Finally, based on the dimensions of the parent area, it initializes
       * its own area. This includes setting the content IPD and the maximum
       * BPD.
       */
      public Area getParentArea(Area childArea) {
  	if (curBlockArea == null) {
  	    curBlockArea = new Block();
  	    // Set up dimensions
  	    // Must get dimensions from parent area
  	    //MinOptMax referenceIPD = parentLM.getReferenceIPD();
  	    Area parentArea = parentLM.getParentArea(curBlockArea);
  	    // Get reference IPD from parentArea
  	    setCurrentArea(curBlockArea); // ??? for generic operations
  	}
  	return curBlockArea;
      }
  	
  
      public void addChild(Area childArea) {
  	if (curBlockArea != null) {
  	    if (childArea instanceof LineArea) {
  		// Something about widows and orphans
  		// Position the line area and calculate size...
  		curBlockArea.addLineArea((LineArea)childArea);
  	    }
  	    else {
  		super.addChild(childArea);
  	    }
  	}
      }
  
  
  
  //     /**
  //      * Called by child LayoutManager when it has filled one of its areas.
  //      * If no current container, make one.
  //      * See if the area will fit in the current container.
  //      * If so, add it.
  //      * @param childArea the area to add: will either be a LineArea or
  //      * a BlockArea.
  //      */
  //     public void  addChild(Area childArea) {
  // 	/* If the childArea fits entirely in the maximum available BPD
  // 	 * add it and return an OK status.
  // 	 * If it doesn't all fit, overrun or ask for split?
  // 	 * Might as well just add it since the page layout process
  // 	 * may need to make other adjustments, resulting in changing
  // 	 * split point.
  // 	 */
  // 	// Things like breaks on child area can cause premature
  // 	// termination of the current area.
  // 	/* We go past the theoretical maximum to be able to handle things
  // 	 * like widows. 
  // 	 */
  // 	// WARNING: this doesn't take into account space-specifier
  // 	// adujstment between childArea and last content of blockArea!
  // 	if (blockArea.getContentBPD().min + childArea.getAllocationBPD().min
  // 	    > blockArea.getAvailBPD().max) {
  // 	    if (++extraLines <= iWidows) {
  // 		blockArea.add(childArea);
  // 	    }
  // 	    else {
  // 		blockArea.setIsLast(false);
  // 		parentLM.addChildArea(blockArea);
  // 		// Make a new one for this area
  // 		blockArea = makeAreaForChild(childArea);
  // 		extraLines = 0; // Count potential widows
  // 		blockArea.add(childArea);
  // 	    }
  // 	}
  // 	else {
  // 	    blockArea.add(childArea);
  // 	}
  //     }
  
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/layoutmgr/LineLayoutManager.java
  
  Index: LineLayoutManager.java
  ===================================================================
  /*
   * $Id: LineLayoutManager.java,v 1.1 2001/11/11 14:13:51 klease Exp $
   * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
   * For details on use and redistribution please refer to the
   * LICENSE file included with these sources.
   */
  
  package org.apache.fop.layoutmgr;
  
  
  import org.apache.fop.fo.FObj;
  import org.apache.fop.area.Area;
  import org.apache.fop.area.LineArea;
  import org.apache.fop.area.MinOptMax;
  import org.apache.fop.area.inline.InlineArea;
  
  import java.util.ListIterator;
  
  /**
   * LayoutManager for lines. It builds one or more lines containing
   * inline areas generated by its sub layout managers.
   */
  public class LineLayoutManager extends AbstractLayoutManager {
      /** Reference to FO whose areas it's managing or to the traits
       * of the FO.
       */
      private ListIterator fobjIter;
      private LineArea lineArea = null;
      private boolean bFirstLine;
      private LayoutManager curLM;
      private MinOptMax remainingIPD;
  
      public LineLayoutManager(ListIterator fobjIter) {
  	super(null);
  	this.fobjIter = fobjIter;
      }
  
  
      /**
       * Call child layout managers to generate content as long as they
       * generate inline areas. If a block-level generating LM is found,
       * finish any line being filled and return to the parent LM.
       */
      public void generateAreas() {
  	this.bFirstLine = true;
  	while (fobjIter.hasNext()) {
  	    FObj fobj = (FObj)fobjIter.next();
  	    curLM = fobj.getLayoutManager();
   	    if (curLM != null) {
  		if (curLM.generatesInlineAreas()==false) {
  		    // It generates blocks, pass back to parent
  		    // Back up one
  		    fobjIter.previous();
  		    break;
  		}
  		else { // generates inline area
  		    curLM.setParentLM(this);
  		    curLM.generateAreas();
  		}
  	    }
  	}
  	flush(); // Add last area to parent
      }
  
  
      /**
       * Align and position curLine and add it to parentContainer.
       * Set curLine to null.
       */
      public void flush() {
  	if (lineArea != null) {
  	    // Adjust spacing as necessary
  	    // Calculate height, based on content (or does the Area do this?)
  	    parentLM.addChild(lineArea);
  	    lineArea = null;
  	}
      }
  
  
      /**
       * Return current lineArea or generate a new one if necessary.
       */
      public Area getParentArea(Area childArea) {
  	if (lineArea == null) {
  	    createLine();
  	}
  	return lineArea;
      }
  
      private void createLine() {
  	lineArea = new LineArea();
  	/* Set line IPD from parentArea
  	 * This accounts for indents. What about first line indent?
  	 * Should we set an "isFirst" flag on the lineArea to signal
  	 * that to the parent (Block) LM? That's where indent property
  	 * information will be managed.
  	 */
  	Area parent = parentLM.getParentArea(lineArea);
  	// lineArea.setContentIPD(parent.getContentIPD());
  	// remainingIPD = parent.getContentIPD();
  	// OR???
  	// remainingIPD = parentLM.getContentIPD();
  	remainingIPD = new MinOptMax(100000);  // TESTING!!!
  	this.bFirstLine = false;
      }
  
  
      /**
       * Called by child LayoutManager when it has filled one of its areas.
       * See if the area will fit in the current container.
       * If so, add it.
       * This should also handle floats if childArea is an anchor.
       * @param childArea the area to add: should be an InlineArea subclass!
       */
      public void addChild(Area childArea) {
  	if ((childArea instanceof InlineArea)==false) {
  	    // SIGNAL AN ERROR!!!
  	    return;
  	}
  	InlineArea inlineArea = (InlineArea)childArea;
  	if (lineArea == null) {
  	    createLine();
  	}
  	if (inlineArea.getAllocationIPD().min < remainingIPD.max) {
  	    lineArea.addInlineArea(inlineArea);
  	    remainingIPD.subtract(inlineArea.getAllocationIPD());
  	    // Calculate number of spaces
  	    // Forced line break after this area (ex. ends with LF in nowrap)
  	    /* NOTYET!
  	    if (inlineArea.breakAfter()) {
  		flush();
  	    }
  	    */
  	    /* Check if line could end after this area (potential line-break
  	     * character. If not, it must be joined with following inline
  	     * area to make a word. Otherwise, if the line could break here
  	     * and if it is "full", add it to the parent area.
  	     */
  	    if (remainingIPD.min<=0) {
  		flush();
  	    }
  	}
  
  	else {
  	    /* The inline area won't entirely fit in this line. Ask its
  	     * layout manager to split it (by hyphenation for example),
  	     * in order to fit part of it in the line.
  	     * Note: only the current child LM could have generated this
  	     * area, so we ask it to do the split.
  	     */
  	    SplitContext splitContext = new SplitContext(remainingIPD);
  	    if (curLM.splitArea(inlineArea, splitContext)) {
  		// inlineArea should now fit
  		lineArea.addInlineArea(inlineArea);
  		flush();
  	    }
  	    addChild(splitContext.nextArea);
  	}
      }
  
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/layoutmgr/TextLayoutManager.java
  
  Index: TextLayoutManager.java
  ===================================================================
  /*
   * $Id: TextLayoutManager.java,v 1.1 2001/11/11 14:13:51 klease Exp $
   * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
   * For details on use and redistribution please refer to the
   * LICENSE file included with these sources.
   */
  
  package org.apache.fop.layoutmgr;
  
  import org.apache.fop.fo.FObj;
  import org.apache.fop.area.Area;
  import org.apache.fop.area.inline.Word;
  
  import java.util.ListIterator;
  
  /**
   * LayoutManager for text (a sequence of characters) which generates one
   * more inline areas.
   */
  public class TextLayoutManager extends AbstractLayoutManager {
  
      private char[] chars;
      private Word curWordArea;
  
      public TextLayoutManager(FObj fobj, char[] chars) {
  	super(fobj);
  	this.chars = chars;
      }
  
  
      /**
       * Generate inline areas for words in text.
       */
      public void generateAreas() {
  	// Iterate over characters and make text areas.
  	// Add each one to parent. Handle word-space.
  	curWordArea = new Word();
  	curWordArea.setWord(new String(chars));
  	flush();
      }
  
  
      protected void flush() {
  	parentLM.addChild(curWordArea);
      }
  
  
      public boolean generatesInlineAreas() {
  	return true;
      }
  
      /**
       * This is a leaf-node, so this method is never called.
       */
      public void addChild(Area childArea) {}
  
  
      /**
       * This is a leaf-node, so this method is never called.
       */
      public Area getParentArea(Area childArea) {
  	return null;
      }
  	
  
  
      /** Try to split the word area by hyphenating the word. */
      public boolean splitArea(Area areaToSplit, SplitContext context) {
  	context.nextArea = areaToSplit;
  	return false;
      }
  
  }
  
  
  

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