gmazza      2004/08/14 11:36:22

  Modified:    src/java/org/apache/fop/fo FObjMixed.java
               src/java/org/apache/fop/fo/flow Inline.java
                        InstreamForeignObject.java
               src/java/org/apache/fop/layoutmgr AddLMVisitor.java
  Added:       src/java/org/apache/fop/layoutmgr
                        InstreamForeignObjectLM.java
  Log:
  1.)  fo:Instream-Foreign-Object initialization logic moved from AddLMVisitor
  to flow.InstreamForiegnObject.java, and the layout logic itself moved to
  a new layoutmgr.InstreamForeignObjectLM.java.  (Broke with usual nomenclature of 
adding
  ~LayoutManager to end, given that newer 1.1 and post-1.1 FO names are
  getting even larger.)
  
  2.) validateChildNode() added for fo:inline.
  
  Revision  Changes    Path
  1.33      +1 -0      xml-fop/src/java/org/apache/fop/fo/FObjMixed.java
  
  Index: FObjMixed.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/fo/FObjMixed.java,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- FObjMixed.java    11 Aug 2004 04:15:25 -0000      1.32
  +++ FObjMixed.java    14 Aug 2004 18:36:21 -0000      1.33
  @@ -26,6 +26,7 @@
   /**
    * Base class for representation of mixed content formatting objects
    * and their processing
  + * @todo define what a "mixed content formatting object" is
    */
   public class FObjMixed extends FObj {
       /** TextInfo for this object */
  
  
  
  1.25      +53 -33    xml-fop/src/java/org/apache/fop/fo/flow/Inline.java
  
  Index: Inline.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/fo/flow/Inline.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Inline.java       11 Aug 2004 04:15:25 -0000      1.24
  +++ Inline.java       14 Aug 2004 18:36:21 -0000      1.25
  @@ -20,34 +20,23 @@
   
   // XML
   import org.xml.sax.Attributes;
  +import org.xml.sax.Locator;
   import org.xml.sax.SAXParseException;
   
   // FOP
  -import org.apache.fop.apps.FOPException;
   import org.apache.fop.fo.CharIterator;
   import org.apache.fop.fo.FONode;
   import org.apache.fop.fo.FObjMixed;
   import org.apache.fop.fo.InlineCharIterator;
  -import org.apache.fop.layoutmgr.AddLMVisitor;
  -import org.apache.fop.fo.properties.CommonAccessibility;
  -import org.apache.fop.fo.properties.CommonAural;
  -import org.apache.fop.fo.properties.CommonBackground;
  -import org.apache.fop.fo.properties.CommonBorderAndPadding;
  -import org.apache.fop.fo.properties.CommonMarginInline;
  -import org.apache.fop.fo.properties.CommonRelativePosition;
   
   /**
  - * Class modelling the fo:inline object. See Sec. 6.6.7 of the XSL-FO Standard.
  + * Class modelling the fo:inline formatting object.
    */
   public class Inline extends FObjMixed {
   
  -    // Textdecoration
  -    /** is this text underlined? */
  -    protected boolean underlined = false;
  -    /** is this text overlined? */
  -    protected boolean overlined = false;
  -    /** is this text lined through? */
  -    protected boolean lineThrough = false;
  +    // used for FO validation
  +    private boolean blockOrInlineItemFound = false;
  +    private boolean canHaveBlockLevelChildren = true;
   
       /**
        * @param parent FONode that is the parent of this object
  @@ -62,28 +51,56 @@
       protected void addProperties(Attributes attlist) throws SAXParseException {
           super.addProperties(attlist);
   
  -        if (parent.getName().equals("fo:flow")) {
  -            throw new SAXParseException("inline formatting objects cannot"
  -                                   + " be directly under flow", locator);
  -        }
  -
  -        int textDecoration = this.propertyList.get(PR_TEXT_DECORATION).getEnum();
  -
  -        if (textDecoration == TextDecoration.UNDERLINE) {
  -            this.underlined = true;
  -        }
  +       /* Check to see if this node can have block-level children.
  +        * See validateChildNode() below.
  +        */
  +       int lvlLeader = findAncestor("fo:leader");
  +       int lvlFootnote = findAncestor("fo:footnote");
  +       int lvlInCntr = findAncestor("fo:inline-container");
  +
  +       if (lvlLeader > 0) {
  +           if (lvlInCntr < 0 ||
  +               (lvlInCntr > 0 && lvlInCntr > lvlLeader)) {
  +               canHaveBlockLevelChildren = false;
  +           }
  +       } else if (lvlFootnote > 0) {
  +           if (lvlInCntr < 0 || lvlInCntr > lvlFootnote) {
  +               canHaveBlockLevelChildren = false;
  +           }
  +       }
   
  -        if (textDecoration == TextDecoration.OVERLINE) {
  -            this.overlined = true;
  -        }
  +        getFOInputHandler().startInline(this);
  +    }
   
  -        if (textDecoration == TextDecoration.LINE_THROUGH) {
  -            this.lineThrough = true;
  +    /**
  +     * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
  +     * XSL Content Model: marker* (#PCDATA|%inline;|%block;)*
  +     * Additionally: " An fo:inline that is a descendant of an fo:leader
  +     *  or fo:footnote may not have block-level children, unless it has a
  +     *  nearer ancestor that is an fo:inline-container." (paraphrased)
  +     */
  +    protected void validateChildNode(Locator loc, String nsURI, String localName) 
  +        throws SAXParseException {
  +        if (nsURI == FO_URI && localName.equals("marker")) {
  +            if (blockOrInlineItemFound) {
  +               nodesOutOfOrderError(loc, "fo:marker", 
  +                    "(#PCDATA|%inline;|%block;)");
  +            }
  +        } else if (!isBlockOrInlineItem(nsURI, localName)) {
  +            invalidChildError(loc, nsURI, localName);
  +        } else if (!canHaveBlockLevelChildren && isBlockItem(nsURI, localName)) {
  +            String ruleViolated = 
  +                " An fo:inline that is a descendant of an fo:leader" +
  +                " or fo:footnote may not have block-level children," +
  +                " unless it has a nearer ancestor that is an" +
  +                " fo:inline-container.";
  +            invalidChildError(loc, nsURI, localName, ruleViolated);
  +        } else {
  +            blockOrInlineItemFound = true;
           }
  -        
  -        getFOInputHandler().startInline(this);
       }
   
  +
       /**
        * @see org.apache.fop.fo.FONode#end
        */
  @@ -98,6 +115,9 @@
           return new InlineCharIterator(this, propMgr.getBorderAndPadding());
       }
   
  +    /**
  +     * @see org.apache.fop.fo.FObj#getName()
  +     */
       public String getName() {
           return "fo:inline";
       }
  
  
  
  1.20      +12 -8     
xml-fop/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
  
  Index: InstreamForeignObject.java
  ===================================================================
  RCS file: 
/home/cvs/xml-fop/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- InstreamForeignObject.java        8 Aug 2004 18:39:23 -0000       1.19
  +++ InstreamForeignObject.java        14 Aug 2004 18:36:21 -0000      1.20
  @@ -18,6 +18,9 @@
   
   package org.apache.fop.fo.flow;
   
  +// Java
  +import java.util.List;
  +
   // XML
   import org.xml.sax.Attributes;
   import org.xml.sax.Locator;
  @@ -25,8 +28,7 @@
   
   // FOP
   import org.apache.fop.fo.FONode;
  -import org.apache.fop.fo.LMVisited;
  -import org.apache.fop.layoutmgr.AddLMVisitor;
  +import org.apache.fop.layoutmgr.InstreamForeignObjectLM;
   import org.apache.fop.fo.FObj;
   
   /**
  @@ -34,7 +36,7 @@
    * This is an atomic inline object that contains
    * xml data.
    */
  -public class InstreamForeignObject extends FObj implements LMVisited {
  +public class InstreamForeignObject extends FObj {
   
       boolean hasNonXSLNamespaceElement = false;
   
  @@ -121,14 +123,16 @@
       }
   
       /**
  -     * This is a hook for the AddLMVisitor class to be able to access
  -     * this object.
  -     * @param aLMV the AddLMVisitor object that can access this object.
  +     * @see org.apache.fop.fo.FObj#addLayoutManager(List)
        */
  -    public void acceptVisitor(AddLMVisitor aLMV) {
  -        aLMV.serveInstreamForeignObject(this);
  +    public void addLayoutManager(List list) {
  +        InstreamForeignObjectLM lm = new InstreamForeignObjectLM(this);
  +        list.add(lm);
       }
   
  +    /**
  +     * @see org.apache.fop.fo.FObj#getName()
  +     */
       public String getName() {
           return "fo:instream-foreign-object";
       }
  
  
  
  1.56      +1 -170    xml-fop/src/java/org/apache/fop/layoutmgr/AddLMVisitor.java
  
  Index: AddLMVisitor.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/AddLMVisitor.java,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- AddLMVisitor.java 13 Aug 2004 12:29:51 -0000      1.55
  +++ AddLMVisitor.java 14 Aug 2004 18:36:21 -0000      1.56
  @@ -16,29 +16,20 @@
   
   /* $Id$ */
   
  -
   package org.apache.fop.layoutmgr;
   
  -import java.awt.geom.Point2D;
  -import java.awt.geom.Rectangle2D;
   import java.util.List;
   import java.util.ListIterator;
   
   import org.apache.fop.area.Trait;
   import org.apache.fop.area.inline.FilledArea;
  -import org.apache.fop.area.inline.ForeignObject;
   import org.apache.fop.area.inline.InlineArea;
   import org.apache.fop.area.inline.Space;
  -import org.apache.fop.area.inline.Viewport;
   import org.apache.fop.area.inline.TextArea;
   import org.apache.fop.datatypes.Length;
   import org.apache.fop.fo.Constants;
  -import org.apache.fop.fo.FONode;
   import org.apache.fop.fo.FObj;
  -import org.apache.fop.fo.XMLObj;
  -import org.apache.fop.fo.flow.Block;
   import org.apache.fop.fo.flow.Inline;
  -import org.apache.fop.fo.flow.InstreamForeignObject;
   import org.apache.fop.fo.flow.Leader;
   import org.apache.fop.fo.flow.Wrapper;
   import org.apache.fop.traits.MinOptMax;
  @@ -208,165 +199,5 @@
                leaderArea = fa;
            }
            return leaderArea;
  -     }
  -
  -     public void serveInstreamForeignObject(InstreamForeignObject node) {
  -         Viewport areaCurrent = getInstreamForeignObjectInlineArea(node);
  -         if (areaCurrent != null) {
  -             LeafNodeLayoutManager lm = new LeafNodeLayoutManager(node);
  -             lm.setCurrentArea(areaCurrent);
  -             
lm.setAlignment(node.getProperty(Constants.PR_VERTICAL_ALIGN).getEnum());
  -             lm.setLead(areaCurrent.getHeight());
  -             currentLMList.add(lm);
  -         }
  -     }
  -     /**
  -      * Get the inline area created by this element.
  -      *
  -      * @return the viewport inline area
  -      */
  -     public Viewport getInstreamForeignObjectInlineArea(InstreamForeignObject node) 
{
  -         if (node.getChildNodes() == null) {
  -             return null;
  -         }
  -
  -         if (node.childNodes.size() != 1) {
  -             // error
  -             return null;
  -         }
  -         FONode fo = (FONode) node.childNodes.get(0);
  -         if (!(fo instanceof XMLObj)) {
  -             // error
  -             return null;
  -         }
  -         XMLObj child = (XMLObj)fo;
  -
  -         // viewport size is determined by block-progression-dimension
  -         // and inline-progression-dimension
  -
  -         // if replaced then use height then ignore block-progression-dimension
  -         //int h = this.propertyList.get("height").getLength().mvalue();
  -
  -         // use specified line-height then ignore dimension in height direction
  -         boolean hasLH = 
false;//propertyList.get("line-height").getSpecifiedValue() != null;
  -
  -         Length len;
  -
  -         int bpd = -1;
  -         int ipd = -1;
  -         boolean bpdauto = false;
  -         if (hasLH) {
  -             bpd = 
node.getProperty(Constants.PR_LINE_HEIGHT).getLength().getValue();
  -         } else {
  -             // this property does not apply when the line-height applies
  -             // isn't the block-progression-dimension always in the same
  -             // direction as the line height?
  -             len = node.getProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION | 
Constants.CP_OPTIMUM).getLength();
  -             if (!len.isAuto()) {
  -                 bpd = len.getValue();
  -             } else {
  -                 len = node.getProperty(Constants.PR_HEIGHT).getLength();
  -                 if (!len.isAuto()) {
  -                     bpd = len.getValue();
  -                 }
  -             }
  -         }
  -
  -         len = node.getProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION | 
Constants.CP_OPTIMUM).getLength();
  -         if (!len.isAuto()) {
  -             ipd = len.getValue();
  -         } else {
  -             len = node.getProperty(Constants.PR_WIDTH).getLength();
  -             if (!len.isAuto()) {
  -                 ipd = len.getValue();
  -             }
  -         }
  -
  -         // if auto then use the intrinsic size of the content scaled
  -         // to the content-height and content-width
  -         int cwidth = -1;
  -         int cheight = -1;
  -         len = node.getProperty(Constants.PR_CONTENT_WIDTH).getLength();
  -         if (!len.isAuto()) {
  -             /*if(len.scaleToFit()) {
  -                 if(ipd != -1) {
  -                     cwidth = ipd;
  -                 }
  -             } else {*/
  -             cwidth = len.getValue();
  -         }
  -         len = node.getProperty(Constants.PR_CONTENT_HEIGHT).getLength();
  -         if (!len.isAuto()) {
  -             /*if(len.scaleToFit()) {
  -                 if(bpd != -1) {
  -                     cwidth = bpd;
  -                 }
  -             } else {*/
  -             cheight = len.getValue();
  -         }
  -
  -         Point2D csize = new Point2D.Float(cwidth == -1 ? -1 : cwidth / 1000f,
  -                                           cheight == -1 ? -1 : cheight / 1000f);
  -         Point2D size = child.getDimension(csize);
  -         if (size == null) {
  -             // error
  -             return null;
  -         }
  -         if (cwidth == -1) {
  -             cwidth = (int)size.getX() * 1000;
  -         }
  -         if (cheight == -1) {
  -             cheight = (int)size.getY() * 1000;
  -         }
  -         int scaling = node.getProperty(Constants.PR_SCALING).getEnum();
  -         if (scaling == Constants.Scaling.UNIFORM) {
  -             // adjust the larger
  -             double rat1 = cwidth / (size.getX() * 1000f);
  -             double rat2 = cheight / (size.getY() * 1000f);
  -             if (rat1 < rat2) {
  -                 // reduce cheight
  -                 cheight = (int)(rat1 * size.getY() * 1000);
  -             } else {
  -                 cwidth = (int)(rat2 * size.getX() * 1000);
  -             }
  -         }
  -
  -         if (ipd == -1) {
  -             ipd = cwidth;
  -         }
  -         if (bpd == -1) {
  -             bpd = cheight;
  -         }
  -
  -         boolean clip = false;
  -         if (cwidth > ipd || cheight > bpd) {
  -             int overflow = node.getProperty(Constants.PR_OVERFLOW).getEnum();
  -             if (overflow == Constants.Overflow.HIDDEN) {
  -                 clip = true;
  -             } else if (overflow == Constants.Overflow.ERROR_IF_OVERFLOW) {
  -                 node.getLogger().error("Instream foreign object overflows the 
viewport: clipping");
  -                 clip = true;
  -             }
  -         }
  -
  -         int xoffset = node.computeXOffset(ipd, cwidth);
  -         int yoffset = node.computeYOffset(bpd, cheight);
  -
  -         Rectangle2D placement = new Rectangle2D.Float(xoffset, yoffset, cwidth, 
cheight);
  -
  -         org.w3c.dom.Document doc = child.getDOMDocument();
  -         String ns = child.getDocumentNamespace();
  -
  -         node.childNodes = null;
  -         ForeignObject foreign = new ForeignObject(doc, ns);
  -
  -         Viewport areaCurrent = new Viewport(foreign);
  -         areaCurrent.setWidth(ipd);
  -         areaCurrent.setHeight(bpd);
  -         areaCurrent.setContentPosition(placement);
  -         areaCurrent.setClip(clip);
  -         areaCurrent.setOffset(0);
  -
  -         return areaCurrent;
        }
   }
  
  
  
  1.1                  
xml-fop/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java
  
  Index: InstreamForeignObjectLM.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed 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: InstreamForeignObjectLM.java,v 1.1 2004/08/14 18:36:21 gmazza Exp $ */
  
  package org.apache.fop.layoutmgr;
  
  // Java
  import java.awt.geom.Point2D;
  import java.awt.geom.Rectangle2D;
  
  // FOP
  import org.apache.fop.datatypes.Length;
  import org.apache.fop.fo.XMLObj;
  import org.apache.fop.fo.flow.InstreamForeignObject;
  import org.apache.fop.area.inline.ForeignObject;
  import org.apache.fop.area.inline.InlineArea;
  import org.apache.fop.area.inline.Viewport;
  
  /**
   * LayoutManager for the fo:basic-link formatting object
   */
  public class InstreamForeignObjectLM extends LeafNodeLayoutManager {
  
      InstreamForeignObject ifoNode;
      
      /**
       * Constructor
       * @param node the formatting object that creates this area
       */
      public InstreamForeignObjectLM(InstreamForeignObject node) {
          super(node);
          ifoNode = node;
          Viewport areaCurrent = getInlineArea();
          setCurrentArea(areaCurrent);
          setAlignment(node.getProperty(PR_VERTICAL_ALIGN).getEnum());
          setLead(areaCurrent.getHeight());
      }
  
      /**
       * Get the inline area created by this element.
       *
       * @return the viewport inline area
       */
      private Viewport getInlineArea() {
          XMLObj child = (XMLObj) ifoNode.childNodes.get(0);
  
          // viewport size is determined by block-progression-dimension
          // and inline-progression-dimension
  
          // if replaced then use height then ignore block-progression-dimension
          //int h = this.propertyList.get("height").getLength().mvalue();
  
          // use specified line-height then ignore dimension in height direction
          boolean hasLH = false;//propertyList.get("line-height").getSpecifiedValue() 
!= null;
  
          Length len;
  
          int bpd = -1;
          int ipd = -1;
          boolean bpdauto = false;
          if (hasLH) {
              bpd = ifoNode.getProperty(PR_LINE_HEIGHT).getLength().getValue();
          } else {
              // this property does not apply when the line-height applies
              // isn't the block-progression-dimension always in the same
              // direction as the line height?
              len = ifoNode.getProperty(PR_BLOCK_PROGRESSION_DIMENSION | 
CP_OPTIMUM).getLength();
              if (!len.isAuto()) {
                  bpd = len.getValue();
              } else {
                  len = ifoNode.getProperty(PR_HEIGHT).getLength();
                  if (!len.isAuto()) {
                      bpd = len.getValue();
                  }
              }
          }
  
          len = ifoNode.getProperty(PR_INLINE_PROGRESSION_DIMENSION | 
CP_OPTIMUM).getLength();
          if (!len.isAuto()) {
              ipd = len.getValue();
          } else {
              len = ifoNode.getProperty(PR_WIDTH).getLength();
              if (!len.isAuto()) {
                  ipd = len.getValue();
              }
          }
  
          // if auto then use the intrinsic size of the content scaled
          // to the content-height and content-width
          int cwidth = -1;
          int cheight = -1;
          len = ifoNode.getProperty(PR_CONTENT_WIDTH).getLength();
          if (!len.isAuto()) {
              /*if(len.scaleToFit()) {
                  if(ipd != -1) {
                      cwidth = ipd;
                  }
              } else {*/
              cwidth = len.getValue();
          }
          len = ifoNode.getProperty(PR_CONTENT_HEIGHT).getLength();
          if (!len.isAuto()) {
              /*if(len.scaleToFit()) {
                  if(bpd != -1) {
                      cwidth = bpd;
                  }
              } else {*/
              cheight = len.getValue();
          }
  
          Point2D csize = new Point2D.Float(cwidth == -1 ? -1 : cwidth / 1000f,
                                            cheight == -1 ? -1 : cheight / 1000f);
          Point2D size = child.getDimension(csize);
          if (size == null) {
              // error
              return null;
          }
          if (cwidth == -1) {
              cwidth = (int)size.getX() * 1000;
          }
          if (cheight == -1) {
              cheight = (int)size.getY() * 1000;
          }
          int scaling = ifoNode.getProperty(PR_SCALING).getEnum();
          if (scaling == Scaling.UNIFORM) {
              // adjust the larger
              double rat1 = cwidth / (size.getX() * 1000f);
              double rat2 = cheight / (size.getY() * 1000f);
              if (rat1 < rat2) {
                  // reduce cheight
                  cheight = (int)(rat1 * size.getY() * 1000);
              } else {
                  cwidth = (int)(rat2 * size.getX() * 1000);
              }
          }
  
          if (ipd == -1) {
              ipd = cwidth;
          }
          if (bpd == -1) {
              bpd = cheight;
          }
  
          boolean clip = false;
          if (cwidth > ipd || cheight > bpd) {
              int overflow = ifoNode.getProperty(PR_OVERFLOW).getEnum();
              if (overflow == Overflow.HIDDEN) {
                  clip = true;
              } else if (overflow == Overflow.ERROR_IF_OVERFLOW) {
                  ifoNode.getLogger().error("Instream foreign object overflows the 
viewport: clipping");
                  clip = true;
              }
          }
  
          int xoffset = ifoNode.computeXOffset(ipd, cwidth);
          int yoffset = ifoNode.computeYOffset(bpd, cheight);
  
          Rectangle2D placement = new Rectangle2D.Float(xoffset, yoffset, cwidth, 
cheight);
  
          org.w3c.dom.Document doc = child.getDOMDocument();
          String ns = child.getDocumentNamespace();
  
          ifoNode.childNodes = null;
          ForeignObject foreign = new ForeignObject(doc, ns);
  
          Viewport areaCurrent = new Viewport(foreign);
          areaCurrent.setWidth(ipd);
          areaCurrent.setHeight(bpd);
          areaCurrent.setContentPosition(placement);
          areaCurrent.setClip(clip);
          areaCurrent.setOffset(0);
  
          return areaCurrent;
      }
  }
  
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to