]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
1.) Layout initialization logic for fo:table, fo:table-header, and fo:table-footer
authorGlen Mazza <gmazza@apache.org>
Fri, 13 Aug 2004 00:03:49 +0000 (00:03 +0000)
committerGlen Mazza <gmazza@apache.org>
Fri, 13 Aug 2004 00:03:49 +0000 (00:03 +0000)
moved from AddLMVisitor to fo.Table.

2.) Layout logic for fo:external-graphic moved from fo.ExternalGraphic to
layoutmgr.ExternalGraphicLayoutManager.

3.) Partial implementation of validateChildNode() for fo:footnote.

4.) fox:destination commented out from images.fo sample until purpose, content
model better defined.  Also needs a Maker class.  (Does not appear to work
in either maintenance or HEAD.)

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197867 13f79535-47bb-0310-9956-ffa450edef68

examples/fo/basic/images.fo
src/java/org/apache/fop/fo/flow/ExternalGraphic.java
src/java/org/apache/fop/fo/flow/Footnote.java
src/java/org/apache/fop/fo/flow/Table.java
src/java/org/apache/fop/fo/flow/TableRow.java
src/java/org/apache/fop/layoutmgr/AddLMVisitor.java
src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java

index 72529dddb5a8ed6cf47bf1de5f90e859af9a856f..12db1237f75c8da0b8ba47f4256a3736db643dde 100644 (file)
 <fo:flow flow-name="xsl-region-body">
 <fo:block font-size="18pt" font-weight="bold">1. FOP test for images</fo:block>
 <fo:block id="N2531">
-  <fox:destination internal-destination="N2531"/>
+  <!--fox:destination internal-destination="N2531"/-->
   <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em">A GIF image in FOP</fo:block>
   <fo:block>
     <fo:external-graphic src="file:../graphics/xml_feather.gif"/>
   </fo:block>
 </fo:block>
 <fo:block id="N2535">
-  <fox:destination internal-destination="N2535"/>
+  <!--fox:destination internal-destination="N2535"/-->
   <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em">A transparent GIF image in FOP</fo:block>
   <fo:block>
     <fo:external-graphic src="file:../graphics/xml_feather_transparent.gif"/>
   </fo:block>
 </fo:block>
 <fo:block id="N2545">
-  <fox:destination internal-destination="N2545"/>
+  <!--fox:destination internal-destination="N2545"/-->
   <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em">A JPEG image in FOP</fo:block>
   <fo:block>
     <fo:external-graphic src="file:../graphics/fop.jpg"/>
   </fo:block>
 </fo:block>
 <fo:block id="N2550">
-  <fox:destination internal-destination="N2550"/>
+  <!--fox:destination internal-destination="N2550"/-->
   <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em">A BMP image in FOP</fo:block>
   <fo:block>
     <fo:external-graphic src="file:../graphics/linux.bmp"/>
   </fo:block>
 </fo:block>
 <fo:block id="N2559">
-  <fox:destination internal-destination="N2559"/>
+  <!--fox:destination internal-destination="N2559"/-->
   <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em"/>
   This section is only required to show that the layout still works.
 </fo:block>
@@ -94,7 +94,7 @@
 
 <fo:flow flow-name="xsl-region-body">
 <fo:block id="AppendixA" font-size="18pt" font-weight="bold">A. Appendix</fo:block>
-  <fox:destination internal-destination="AppendixA"/>
+  <!--fox:destination internal-destination="AppendixA"/-->
 </fo:flow>
 
 </fo:page-sequence>
index 4a37eab8a6371d01ec17208afc32d7b8550bf812..581ab9fc20a023d2c8eb8029e662de33e3f1c612 100644 (file)
@@ -20,7 +20,6 @@ package org.apache.fop.fo.flow;
 
 // Java
 import java.util.List;
-import java.awt.geom.Rectangle2D;
 
 // XML
 import org.xml.sax.Attributes;
@@ -28,12 +27,8 @@ import org.xml.sax.Locator;
 import org.xml.sax.SAXParseException;
 
 // FOP
-import org.apache.fop.area.inline.Image;
-import org.apache.fop.datatypes.Length;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.image.ImageFactory;
 import org.apache.fop.layoutmgr.ExternalGraphicLayoutManager;
 
 /**
@@ -43,17 +38,6 @@ import org.apache.fop.layoutmgr.ExternalGraphicLayoutManager;
  */
 public class ExternalGraphic extends FObj {
     private String url;
-    private int breakAfter;
-    private int breakBefore;
-    private int align;
-    private int startIndent;
-    private int endIndent;
-    private int spaceBefore;
-    private int spaceAfter;
-    private int viewWidth = -1;
-    private int viewHeight = -1;
-    private boolean clip = false;
-    private Rectangle2D placement = null;
 
     /**
      * Create a new External graphic node.
@@ -78,182 +62,18 @@ public class ExternalGraphic extends FObj {
      */
     protected void addProperties(Attributes attlist) throws SAXParseException {
         super.addProperties(attlist);
-        getFOInputHandler().image(this);
-    }
-
-    /**
-     * Setup this image.
-     * This gets the sizes for the image and the dimensions and clipping.
-     * @todo move logic to LM class and/or addProperties() as appropriate
-     */
-    private void setup() {
         url = this.propertyList.get(PR_SRC).getString();
-        if (url == null) {
-            return;
-        }
-        url = ImageFactory.getURL(url);
-
-        // assume lr-tb for now and just use the .optimum value of the range
-        Length ipd = propertyList.get(PR_INLINE_PROGRESSION_DIMENSION).
-                                    getLengthRange().getOptimum().getLength();
-        if (!ipd.isAuto()) {
-            viewWidth = ipd.getValue();
-        } else {
-            ipd = propertyList.get(PR_WIDTH).getLength();
-            if (!ipd.isAuto()) {
-                viewWidth = ipd.getValue();
-            }
-        }
-        Length bpd = propertyList.get(PR_BLOCK_PROGRESSION_DIMENSION | CP_OPTIMUM).getLength();
-        if (!bpd.isAuto()) {
-            viewHeight = bpd.getValue();
-        } else {
-            bpd = propertyList.get(PR_HEIGHT).getLength();
-            if (!bpd.isAuto()) {
-                viewHeight = bpd.getValue();
-            }
-        }
-
-        // if we need to load this image to get its size
-        FopImage fopimage = null;
-
-        int cwidth = -1;
-        int cheight = -1;
-        Length ch = propertyList.get(PR_CONTENT_HEIGHT).getLength();
-        if (!ch.isAuto()) {
-            /*if (ch.scaleToFit()) {
-                if (viewHeight != -1) {
-                    cheight = viewHeight;
-                }
-            } else {*/
-            cheight = ch.getValue();
-        }
-        Length cw = propertyList.get(PR_CONTENT_WIDTH).getLength();
-        if (!cw.isAuto()) {
-            /*if (cw.scaleToFit()) {
-                if (viewWidth != -1) {
-                    cwidth = viewWidth;
-                }
-            } else {*/
-            cwidth = cw.getValue();
-        }
-
-        int scaling = propertyList.get(PR_SCALING).getEnum();
-        if ((scaling == Scaling.UNIFORM) || (cwidth == -1) || cheight == -1) {
-            ImageFactory fact = ImageFactory.getInstance();
-            fopimage = fact.getImage(url, getUserAgent());
-            if (fopimage == null) {
-                // error
-                url = null;
-                return;
-            }
-            // load dimensions
-            if (!fopimage.load(FopImage.DIMENSIONS)) {
-                // error
-                url = null;
-                return;
-            }
-            if (cwidth == -1 && cheight == -1) {
-                cwidth = (int)(fopimage.getWidth() * 1000);
-                cheight = (int)(fopimage.getHeight() * 1000);
-            } else if (cwidth == -1) {
-                cwidth = (int)(fopimage.getWidth() * cheight) / fopimage.getHeight();
-            } else if (cheight == -1) {
-                cheight = (int)(fopimage.getHeight() * cwidth) / fopimage.getWidth();
-            } else {
-                // adjust the larger
-                double rat1 = cwidth / (fopimage.getWidth() * 1000f);
-                double rat2 = cheight / (fopimage.getHeight() * 1000f);
-                if (rat1 < rat2) {
-                    // reduce cheight
-                    cheight = (int)(rat1 * fopimage.getHeight() * 1000);
-                } else {
-                    cwidth = (int)(rat2 * fopimage.getWidth() * 1000);
-                }
-            }
-        }
-
-        if (viewWidth == -1) {
-            viewWidth = cwidth;
-        }
-        if (viewHeight == -1) {
-            viewHeight = cheight;
-        }
-
-        if (cwidth > viewWidth || cheight > viewHeight) {
-            int overflow = propertyList.get(PR_OVERFLOW).getEnum();
-            if (overflow == Overflow.HIDDEN) {
-                clip = true;
-            } else if (overflow == Overflow.ERROR_IF_OVERFLOW) {
-                getLogger().error("Image: " + url
-                                  + " overflows the viewport, clipping to viewport");
-                clip = true;
-            }
-        }
-
-        int xoffset = 0;
-        int yoffset = 0;
-        int da = propertyList.get(PR_DISPLAY_ALIGN).getEnum();
-        switch(da) {
-            case DisplayAlign.BEFORE:
-            break;
-            case DisplayAlign.AFTER:
-                yoffset = viewHeight - cheight;
-            break;
-            case DisplayAlign.CENTER:
-                yoffset = (viewHeight - cheight) / 2;
-            break;
-            case DisplayAlign.AUTO:
-            default:
-            break;
-        }
-
-        int ta = propertyList.get(PR_TEXT_ALIGN).getEnum();
-        switch(ta) {
-            case TextAlign.CENTER:
-                xoffset = (viewWidth - cwidth) / 2;
-            break;
-            case TextAlign.END:
-                xoffset = viewWidth - cwidth;
-            break;
-            case TextAlign.START:
-            break;
-            case TextAlign.JUSTIFY:
-            default:
-            break;
-        }
-        placement = new Rectangle2D.Float(xoffset, yoffset, cwidth, cheight);
-    }
-
-    /**
-     * @return the ViewHeight (in millipoints??)
-     * @todo check that each of these accessors are needed
-     */
-    public int getViewHeight() {
-        return viewHeight;
+        getFOInputHandler().image(this);
     }
 
     public String getURL() {
         return url;
     }
 
-    public int getViewWidth() {
-        return viewWidth;
-    }
-
-    public boolean getClip() {
-        return clip;
-    }
-
-    public Rectangle2D getPlacement() {
-        return placement;
-    }
-
     /**
      * @see org.apache.fop.fo.FObj#addLayoutManager(List)
     */
     public void addLayoutManager(List list) {
-        setup();
         if (getURL() != null) {
             ExternalGraphicLayoutManager lm = new ExternalGraphicLayoutManager(this);
             list.add(lm);
index 515755fd83e3cf5b596f7b3e3a1811ff32b2ffe6..024c49ff1120cdfffd93341a915f8311a1134400 100644 (file)
@@ -23,7 +23,7 @@ import java.util.List;
 
 // XML
 import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
+import org.xml.sax.Locator;
 import org.xml.sax.SAXParseException;
 
 // FOP
@@ -37,7 +37,7 @@ import org.apache.fop.fo.FObj;
 public class Footnote extends FObj {
 
     private Inline inlineFO = null;
-    private FootnoteBody body;
+    private FootnoteBody footnoteBody;
 
     /**
      * @param parent FONode that is the parent of this object
@@ -54,17 +54,53 @@ public class Footnote extends FObj {
         getFOInputHandler().startFootnote(this);
     }
 
+    /**
+     * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+     * XSL Content Model: (inline,footnote-body)
+     * @todo: implement additional constraint: An fo:footnote is not permitted
+     *      to have an fo:float, fo:footnote, or fo:marker as a descendant.
+     * @todo: implement additional constraint: An an fo:footnote is not 
+     *      permitted to have as a descendant an fo:block-container that 
+     *      generates an absolutely positioned area.
+     */
+    protected void validateChildNode(Locator loc, String nsURI, String localName) 
+        throws SAXParseException {
+            if (nsURI == FO_URI && localName.equals("inline")) {
+                if (inlineFO != null) {
+                    tooManyNodesError(loc, "fo:inline");
+                }
+            } else if (nsURI == FO_URI && localName.equals("footnote-body")) {
+                if (inlineFO == null) {
+                    nodesOutOfOrderError(loc, "fo:inline", "fo:footnote-body");
+                } else if (footnoteBody != null) {
+                    tooManyNodesError(loc, "fo:footnote-body");
+                }                
+            } else {
+                invalidChildError(loc, nsURI, localName);
+            }
+    }
+
+    /**
+     * Make sure content model satisfied, if so then tell the
+     * StructureRenderer that we are at the end of the flow.
+     * @see org.apache.fop.fo.FONode#end
+     */
+    protected void endOfNode() throws SAXParseException {
+        super.endOfNode();
+        if (inlineFO == null || footnoteBody == null) {
+            missingChildElementError("(inline,footnote-body)");
+        }
+        getFOInputHandler().endFootnote(this);
+    }
+
     /**
      * @see org.apache.fop.fo.FONode#addChildNode(FONode)
      */
     public void addChildNode(FONode child) {
-        String name = child.getName();
-        if ("fo:inline".equals(name)) {
-            inlineFO = (Inline)child;
-        } else if ("fo:footnote-body".equals(name)) {
-            body = (FootnoteBody)child;
-        } else {
-            getLogger().error("invalid child of footnote: " + name);
+        if (((FObj)child).getNameId() == FO_INLINE) {
+            inlineFO = (Inline) child;
+        } else if (((FObj)child).getNameId() == FO_FOOTNOTE_BODY) {
+            footnoteBody = (FootnoteBody) child;
         }
     }
 
@@ -76,11 +112,6 @@ public class Footnote extends FObj {
         return inlineFO;
     }
 
-    protected void endOfNode() throws SAXParseException {
-        super.endOfNode();
-        getFOInputHandler().endFootnote(this);
-    }
-    
     /**
      * @see org.apache.fop.fo.FObj#addLayoutManager(List)
      */
@@ -92,6 +123,9 @@ public class Footnote extends FObj {
         getInlineFO().addLayoutManager(list);
     }
 
+    /**
+     * @see org.apache.fop.fo.FObj#getName()
+     */
     public String getName() {
         return "fo:footnote";
     }
index b28fea9826aed4792c894bc03e5c63cb0866cc51..e6402ecdab69439afac77e4cb2b13cc4d68b6059 100644 (file)
@@ -19,6 +19,8 @@
 package org.apache.fop.fo.flow;
 
 // Java
+import java.util.List;
+import java.util.ListIterator;
 import java.util.ArrayList;
 
 // XML
@@ -29,7 +31,9 @@ import org.xml.sax.SAXParseException;
 import org.apache.fop.datatypes.ColorType;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
-import org.apache.fop.layoutmgr.AddLMVisitor;
+import org.apache.fop.layoutmgr.table.TableLayoutManager;
+import org.apache.fop.layoutmgr.table.Body;
+import org.apache.fop.layoutmgr.table.Column;
 import org.apache.fop.fo.properties.CommonAccessibility;
 import org.apache.fop.fo.properties.CommonAural;
 import org.apache.fop.fo.properties.CommonBackground;
@@ -37,12 +41,11 @@ import org.apache.fop.fo.properties.CommonBorderAndPadding;
 import org.apache.fop.fo.properties.CommonMarginBlock;
 import org.apache.fop.fo.properties.CommonRelativePosition;
 import org.apache.fop.fo.properties.LengthRangeProperty;
-import org.apache.fop.fo.LMVisited;
 
 /**
  * Class modelling the fo:table object. See Sec. 6.7.3 of the XSL-FO Standard.
  */
-public class Table extends FObj implements LMVisited {
+public class Table extends FObj {
     private static final int MINCOLWIDTH = 10000; // 10pt
 
     /** collection of columns in this table */
@@ -104,6 +107,10 @@ public class Table extends FObj implements LMVisited {
         getFOInputHandler().startTable(this);
     }
 
+    protected void endOfNode() throws SAXParseException {
+        getFOInputHandler().endTable(this);
+    }
+
     /**
      * @see org.apache.fop.fo.FONode#addChildNode(FONode)
      */
@@ -130,29 +137,52 @@ public class Table extends FObj implements LMVisited {
         return false;
     }
 
-    public ArrayList getColumns() {
+    private ArrayList getColumns() {
         return columns;
     }
 
-    public TableBody getTableHeader() {
+    private TableBody getTableHeader() {
         return tableHeader;
     }
 
-    public TableBody getTableFooter() {
+    private TableBody getTableFooter() {
         return tableFooter;
     }
 
     /**
-     * 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)
+     * @todo see if can/should move much of this logic into TableLayoutManager
+     *      and/or TableBody and TableColumn FO subclasses.
      */
-    public void acceptVisitor(AddLMVisitor aLMV) {
-        aLMV.serveTable(this);
+    public void addLayoutManager(List list) {
+        TableLayoutManager tlm = new TableLayoutManager(this);
+        ArrayList columns = getColumns();
+        if (columns != null) {
+            ArrayList columnLMs = new ArrayList();
+            ListIterator iter = columns.listIterator();
+            while (iter.hasNext()) {
+                columnLMs.add(getTableColumnLayoutManager((TableColumn)iter.next()));
+            }
+            tlm.setColumns(columnLMs);
+        }
+        if (getTableHeader() != null) {
+            tlm.setTableHeader(getTableBodyLayoutManager(getTableHeader()));
+        }
+        if (getTableFooter() != null) {
+            tlm.setTableFooter(getTableBodyLayoutManager(getTableFooter()));
+        }
+        list.add(tlm);
     }
 
-    protected void endOfNode() throws SAXParseException {
-        getFOInputHandler().endTable(this);
+    public Column getTableColumnLayoutManager(TableColumn node) {
+         node.initialize();
+         Column clm = new Column(node);
+         return clm;
+    }
+    
+    public Body getTableBodyLayoutManager(TableBody node) {
+         Body blm = new Body(node);
+         return blm;
     }
 
     public String getName() {
index 3e05c43ef30f60791c2d4e0fff3395ab2514999b..31d262651e1e301d9d7ceab03af452c429ac3451 100644 (file)
@@ -67,6 +67,11 @@ public class TableRow extends FObj {
         getFOInputHandler().startRow(this);
     }
 
+
+    protected void endOfNode() throws SAXParseException {
+        getFOInputHandler().endRow(this);
+    }
+
     /**
      * @return keepWithPrevious
      */
@@ -110,11 +115,10 @@ public class TableRow extends FObj {
         Row rlm = new Row(this);
         list.add(rlm);          
     }
-
-     protected void endOfNode() throws SAXParseException {
-        getFOInputHandler().endRow(this);
-    }
     
+    /**
+     * @see org.apache.fop.fo.FObj#getName()
+     */
     public String getName() {
         return "fo:table-row";
     }
index 6b179f2576253f03fb032c9ffaf851165cc692ee..7c9eccba77f716619aa0bf6340f7fcfc97010f6e 100644 (file)
@@ -21,7 +21,6 @@ package org.apache.fop.layoutmgr;
 
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.ListIterator;
 
@@ -44,19 +43,7 @@ import org.apache.fop.fo.flow.Character;
 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.Table;
-import org.apache.fop.fo.flow.TableAndCaption;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
 import org.apache.fop.fo.flow.Wrapper;
-import org.apache.fop.fo.pagination.Title;
-import org.apache.fop.fo.properties.CommonBackground;
-import org.apache.fop.fo.properties.CommonBorderAndPadding;
-import org.apache.fop.layoutmgr.table.Body;
-import org.apache.fop.layoutmgr.table.Column;
-import org.apache.fop.layoutmgr.table.TableLayoutManager;
 import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.fo.LMVisited;
 
@@ -405,35 +392,4 @@ public class AddLMVisitor {
 
          return areaCurrent;
      }
-
-     public void serveTable(Table node) {
-         TableLayoutManager tlm = new TableLayoutManager(node);
-         ArrayList columns = node.getColumns();
-         if (columns != null) {
-             ArrayList columnLMs = new ArrayList();
-             ListIterator iter = columns.listIterator();
-             while (iter.hasNext()) {
-                 columnLMs.add(getTableColumnLayoutManager((TableColumn)iter.next()));
-             }
-             tlm.setColumns(columnLMs);
-         }
-         if (node.getTableHeader() != null) {
-             tlm.setTableHeader(getTableBodyLayoutManager(node.getTableHeader()));
-         }
-         if (node.getTableFooter() != null) {
-             tlm.setTableFooter(getTableBodyLayoutManager(node.getTableFooter()));
-         }
-         currentLMList.add(tlm);
-     }
-
-     public LayoutManager getTableColumnLayoutManager(TableColumn node) {
-         node.initialize();
-         Column clm = new Column(node);
-         return clm;
-     }
-
-     public Body getTableBodyLayoutManager(TableBody node) {
-         Body blm = new Body(node);
-         return blm;
-     }
 }
index 7eacb32d54c0013bba25bfe0d9b8a49c80654fe6..73698e1f2286602ad476895dc3024131f1ed98ed 100644 (file)
 
 package org.apache.fop.layoutmgr;
 
+// Java
+import java.awt.geom.Rectangle2D;
+
+// FOP
 import org.apache.fop.area.inline.Image;
 import org.apache.fop.area.inline.InlineArea;
 import org.apache.fop.area.inline.Viewport;
+import org.apache.fop.datatypes.Length;
 import org.apache.fop.fo.flow.ExternalGraphic;
 import org.apache.fop.fo.properties.CommonBorderAndPadding;
 import org.apache.fop.fo.properties.CommonBackground;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
 
 /**
  * LayoutManager for the fo:external-graphic formatting object
@@ -32,6 +39,19 @@ public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
 
     ExternalGraphic graphic = null;
 
+    private String url;
+    private int breakAfter;
+    private int breakBefore;
+    private int align;
+    private int startIndent;
+    private int endIndent;
+    private int spaceBefore;
+    private int spaceAfter;
+    private int viewWidth = -1;
+    private int viewHeight = -1;
+    private boolean clip = false;
+    private Rectangle2D placement = null;
+
     /**
      * Constructor
      *
@@ -41,10 +61,151 @@ public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
         super(node);
 
         graphic = node;
+        setup();
         InlineArea area = getExternalGraphicInlineArea();
         setCurrentArea(area);
         setAlignment(graphic.getProperty(PR_VERTICAL_ALIGN).getEnum());
-        setLead(graphic.getViewHeight());
+        setLead(viewHeight);
+    }
+
+    /**
+     * Setup this image.
+     * This gets the sizes for the image and the dimensions and clipping.
+     * @todo see if can simplify property handling logic
+     */
+    private void setup() {
+        url = ImageFactory.getURL(graphic.getURL());
+
+        // assume lr-tb for now and just use the .optimum value of the range
+        Length ipd = graphic.getPropertyList().get(PR_INLINE_PROGRESSION_DIMENSION).
+                                    getLengthRange().getOptimum().getLength();
+        if (!ipd.isAuto()) {
+            viewWidth = ipd.getValue();
+        } else {
+            ipd = graphic.getPropertyList().get(PR_WIDTH).getLength();
+            if (!ipd.isAuto()) {
+                viewWidth = ipd.getValue();
+            }
+        }
+        Length bpd = graphic.getPropertyList().get(PR_BLOCK_PROGRESSION_DIMENSION | CP_OPTIMUM).getLength();
+        if (!bpd.isAuto()) {
+            viewHeight = bpd.getValue();
+        } else {
+            bpd = graphic.getPropertyList().get(PR_HEIGHT).getLength();
+            if (!bpd.isAuto()) {
+                viewHeight = bpd.getValue();
+            }
+        }
+
+        // if we need to load this image to get its size
+        FopImage fopimage = null;
+
+        int cwidth = -1;
+        int cheight = -1;
+        Length ch = graphic.getPropertyList().get(PR_CONTENT_HEIGHT).getLength();
+        if (!ch.isAuto()) {
+            /*if (ch.scaleToFit()) {
+                if (viewHeight != -1) {
+                    cheight = viewHeight;
+                }
+            } else {*/
+            cheight = ch.getValue();
+        }
+        Length cw = graphic.getPropertyList().get(PR_CONTENT_WIDTH).getLength();
+        if (!cw.isAuto()) {
+            /*if (cw.scaleToFit()) {
+                if (viewWidth != -1) {
+                    cwidth = viewWidth;
+                }
+            } else {*/
+            cwidth = cw.getValue();
+        }
+
+        int scaling = graphic.getPropertyList().get(PR_SCALING).getEnum();
+        if ((scaling == Scaling.UNIFORM) || (cwidth == -1) || cheight == -1) {
+            ImageFactory fact = ImageFactory.getInstance();
+            fopimage = fact.getImage(url, graphic.getUserAgent());
+            if (fopimage == null) {
+                // error
+                url = null;
+                return;
+            }
+            // load dimensions
+            if (!fopimage.load(FopImage.DIMENSIONS)) {
+                // error
+                url = null;
+                return;
+            }
+            if (cwidth == -1 && cheight == -1) {
+                cwidth = (int)(fopimage.getWidth() * 1000);
+                cheight = (int)(fopimage.getHeight() * 1000);
+            } else if (cwidth == -1) {
+                cwidth = (int)(fopimage.getWidth() * cheight) / fopimage.getHeight();
+            } else if (cheight == -1) {
+                cheight = (int)(fopimage.getHeight() * cwidth) / fopimage.getWidth();
+            } else {
+                // adjust the larger
+                double rat1 = cwidth / (fopimage.getWidth() * 1000f);
+                double rat2 = cheight / (fopimage.getHeight() * 1000f);
+                if (rat1 < rat2) {
+                    // reduce cheight
+                    cheight = (int)(rat1 * fopimage.getHeight() * 1000);
+                } else {
+                    cwidth = (int)(rat2 * fopimage.getWidth() * 1000);
+                }
+            }
+        }
+
+        if (viewWidth == -1) {
+            viewWidth = cwidth;
+        }
+        if (viewHeight == -1) {
+            viewHeight = cheight;
+        }
+
+        if (cwidth > viewWidth || cheight > viewHeight) {
+            int overflow = graphic.getPropertyList().get(PR_OVERFLOW).getEnum();
+            if (overflow == Overflow.HIDDEN) {
+                clip = true;
+            } else if (overflow == Overflow.ERROR_IF_OVERFLOW) {
+                graphic.getLogger().error("Image: " + url
+                                  + " overflows the viewport, clipping to viewport");
+                clip = true;
+            }
+        }
+
+        int xoffset = 0;
+        int yoffset = 0;
+        int da = graphic.getPropertyList().get(PR_DISPLAY_ALIGN).getEnum();
+        switch(da) {
+            case DisplayAlign.BEFORE:
+            break;
+            case DisplayAlign.AFTER:
+                yoffset = viewHeight - cheight;
+            break;
+            case DisplayAlign.CENTER:
+                yoffset = (viewHeight - cheight) / 2;
+            break;
+            case DisplayAlign.AUTO:
+            default:
+            break;
+        }
+
+        int ta = graphic.getPropertyList().get(PR_TEXT_ALIGN).getEnum();
+        switch(ta) {
+            case TextAlign.CENTER:
+                xoffset = (viewWidth - cwidth) / 2;
+            break;
+            case TextAlign.END:
+                xoffset = viewWidth - cwidth;
+            break;
+            case TextAlign.START:
+            break;
+            case TextAlign.JUSTIFY:
+            default:
+            break;
+        }
+        placement = new Rectangle2D.Float(xoffset, yoffset, cwidth, cheight);
     }
 
      /**
@@ -56,10 +217,10 @@ public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
      public InlineArea getExternalGraphicInlineArea() {
          Image imArea = new Image(graphic.getURL());
          Viewport vp = new Viewport(imArea);
-         vp.setWidth(graphic.getViewWidth());
-         vp.setHeight(graphic.getViewHeight());
-         vp.setClip(graphic.getClip());
-         vp.setContentPosition(graphic.getPlacement());
+         vp.setWidth(viewWidth);
+         vp.setHeight(viewHeight);
+         vp.setClip(clip);
+         vp.setContentPosition(placement);
          vp.setOffset(0);
 
          // Common Border, Padding, and Background Properties