jeremias    2004/12/28 10:03:12

  Modified:    src/java/org/apache/fop/fo/flow ExternalGraphic.java
                        InstreamForeignObject.java
               src/java/org/apache/fop/fo FOPropertyMapping.java
               src/java/org/apache/fop/layoutmgr
                        InstreamForeignObjectLM.java
                        ExternalGraphicLayoutManager.java
               src/java/org/apache/fop/datatypes LengthBase.java
  Added:       src/java/org/apache/fop/fo IntrinsicSizeAccess.java
  Log:
  Support for percentages on external-graphic and instream-foreign-object for 
the content-height and content-width attributes.
  
  Revision  Changes    Path
  1.50      +63 -1     
xml-fop/src/java/org/apache/fop/fo/flow/ExternalGraphic.java
  
  Index: ExternalGraphic.java
  ===================================================================
  RCS file: 
/home/cvs/xml-fop/src/java/org/apache/fop/fo/flow/ExternalGraphic.java,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- ExternalGraphic.java      24 Dec 2004 12:06:26 -0000      1.49
  +++ ExternalGraphic.java      28 Dec 2004 18:03:12 -0000      1.50
  @@ -27,6 +27,7 @@
   import org.apache.fop.datatypes.Length;
   import org.apache.fop.fo.FONode;
   import org.apache.fop.fo.FObj;
  +import org.apache.fop.fo.IntrinsicSizeAccess;
   import org.apache.fop.fo.PropertyList;
   import org.apache.fop.fo.ValidationException;
   import org.apache.fop.fo.properties.CommonAccessibility;
  @@ -36,6 +37,8 @@
   import org.apache.fop.fo.properties.CommonRelativePosition;
   import org.apache.fop.fo.properties.KeepProperty;
   import org.apache.fop.fo.properties.LengthRangeProperty;
  +import org.apache.fop.image.FopImage;
  +import org.apache.fop.image.ImageFactory;
   import org.apache.fop.layoutmgr.ExternalGraphicLayoutManager;
   
   /**
  @@ -43,7 +46,8 @@
    * This FO node handles the external graphic. It creates an image
    * inline area that can be added to the area tree.
    */
  -public class ExternalGraphic extends FObj {
  +public class ExternalGraphic extends FObj implements IntrinsicSizeAccess {
  +    
       // The value of properties relevant for fo:external-graphic.
       private CommonAccessibility commonAccessibility;
       private CommonAural commonAural;
  @@ -75,6 +79,10 @@
       private Length width;
       // End of property values
   
  +    //Additional values
  +    private String url;
  +    private FopImage fopimage;
  +    
       /**
        * Create a new External graphic node.
        *
  @@ -116,6 +124,9 @@
           textAlign = pList.get(PR_TEXT_ALIGN).getEnum();
           verticalAlign = pList.get(PR_VERTICAL_ALIGN).getEnum();
           width = pList.get(PR_WIDTH).getLength();
  +        
  +        //Additional processing
  +        url = ImageFactory.getURL(getSrc());
       }
   
       /**
  @@ -220,6 +231,13 @@
       }
   
       /**
  +     * @return Get the resulting URL based on the src property.
  +     */
  +    public String getURL() {
  +        return url;
  +    }
  +
  +    /**
        * Return the "text-align" property.
        */
       public int getTextAlign() {
  @@ -253,4 +271,48 @@
       public int getNameId() {
           return FO_EXTERNAL_GRAPHIC;
       }
  +
  +    /**
  +     * Preloads the image so the intrinsic size is available.
  +     */
  +    private void prepareIntrinsicSize() {
  +        if (fopimage == null) {
  +            ImageFactory fact = ImageFactory.getInstance();
  +            fopimage = fact.getImage(getURL(), getUserAgent());
  +            if (fopimage == null) {
  +                getLogger().error("Image not available: " + getURL());
  +            } else {
  +                // load dimensions
  +                if (!fopimage.load(FopImage.DIMENSIONS)) {
  +                    getLogger().error("Cannot read image dimensions: " + 
getURL());
  +                }
  +            }
  +            //TODO Report to caller so he can decide to throw an exception
  +        }
  +    }
  +    
  +    /**
  +     * @see org.apache.fop.fo.IntrinsicSizeAccess#getIntrinsicWidth()
  +     */
  +    public int getIntrinsicWidth() {
  +        prepareIntrinsicSize();
  +        if (fopimage != null) {
  +            return fopimage.getWidth() * 1000;
  +        } else {
  +            return 0;
  +        }
  +    }
  +
  +    /**
  +     * @see org.apache.fop.fo.IntrinsicSizeAccess#getIntrinsicHeight()
  +     */
  +    public int getIntrinsicHeight() {
  +        prepareIntrinsicSize();
  +        if (fopimage != null) {
  +            return fopimage.getHeight() * 1000;
  +        } else {
  +            return 0;
  +        }
  +    }
  +    
   }
  
  
  
  1.38      +48 -4     
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.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- InstreamForeignObject.java        28 Dec 2004 13:55:14 -0000      1.37
  +++ InstreamForeignObject.java        28 Dec 2004 18:03:12 -0000      1.38
  @@ -18,8 +18,7 @@
   
   package org.apache.fop.fo.flow;
   
  -// Java
  -import java.util.List;
  +import java.awt.geom.Point2D;
   
   import org.xml.sax.Locator;
   
  @@ -27,8 +26,10 @@
   import org.apache.fop.datatypes.Length;
   import org.apache.fop.fo.FONode;
   import org.apache.fop.fo.FObj;
  +import org.apache.fop.fo.IntrinsicSizeAccess;
   import org.apache.fop.fo.PropertyList;
   import org.apache.fop.fo.ValidationException;
  +import org.apache.fop.fo.XMLObj;
   import org.apache.fop.fo.properties.CommonAccessibility;
   import org.apache.fop.fo.properties.CommonAural;
   import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
  @@ -36,14 +37,14 @@
   import org.apache.fop.fo.properties.CommonRelativePosition;
   import org.apache.fop.fo.properties.KeepProperty;
   import org.apache.fop.fo.properties.LengthRangeProperty;
  -import org.apache.fop.layoutmgr.InstreamForeignObjectLM;
   
   /**
    * The instream-foreign-object flow formatting object.
    * This is an atomic inline object that contains
    * xml data.
    */
  -public class InstreamForeignObject extends FObj {
  +public class InstreamForeignObject extends FObj implements 
IntrinsicSizeAccess {
  +    
       // The value of properties relevant for fo:instream-foreign-object.
       private CommonAccessibility commonAccessibility;
       private CommonAural commonAural;
  @@ -74,6 +75,9 @@
       private Length width;
       // End of property values
   
  +    //Additional value
  +    private Point2D intrinsicDimensions;
  +    
       /**
        * constructs an instream-foreign-object object (called by Maker).
        *
  @@ -280,4 +284,44 @@
       public int getNameId() {
           return FO_INSTREAM_FOREIGN_OBJECT;
       }
  +
  +    /**
  +     * Preloads the image so the intrinsic size is available.
  +     */
  +    private void prepareIntrinsicSize() {
  +        if (intrinsicDimensions == null) {
  +            XMLObj child = (XMLObj)childNodes.get(0);
  +            Point2D csize = new Point2D.Float(-1, -1);
  +            intrinsicDimensions = child.getDimension(csize);
  +            if (intrinsicDimensions == null) {
  +                getLogger().error("Intrinsic dimensions of "
  +                        + " instream-foreign-object could not be 
determined");
  +            }
  +        }
  +    }
  +
  +    /**
  +     * @see org.apache.fop.fo.IntrinsicSizeAccess#getIntrinsicWidth()
  +     */
  +    public int getIntrinsicWidth() {
  +        prepareIntrinsicSize();
  +        if (intrinsicDimensions != null) {
  +            return (int)(intrinsicDimensions.getX() * 1000);
  +        } else {
  +            return 0;
  +        }
  +    }
  +
  +    /**
  +     * @see org.apache.fop.fo.IntrinsicSizeAccess#getIntrinsicHeight()
  +     */
  +    public int getIntrinsicHeight() {
  +        prepareIntrinsicSize();
  +        if (intrinsicDimensions != null) {
  +            return (int)(intrinsicDimensions.getY() * 1000);
  +        } else {
  +            return 0;
  +        }
  +    }
  +    
   }
  
  
  
  1.38      +3 -1      xml-fop/src/java/org/apache/fop/fo/FOPropertyMapping.java
  
  Index: FOPropertyMapping.java
  ===================================================================
  RCS file: 
/home/cvs/xml-fop/src/java/org/apache/fop/fo/FOPropertyMapping.java,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- FOPropertyMapping.java    24 Nov 2004 21:07:29 -0000      1.37
  +++ FOPropertyMapping.java    28 Dec 2004 18:03:12 -0000      1.38
  @@ -1418,6 +1418,7 @@
           l.addEnum("auto", makeEnumProperty(EN_AUTO, "AUTO"));
           l.addEnum("scale-to-fit", makeEnumProperty(EN_SCALE_TO_FIT, 
"SCALE_TO_FIT"));
           l.setDefault("auto");
  +        l.setPercentBase(LengthBase.IMAGE_INTRINSIC_HEIGHT);
           addPropertyMaker("content-height", l);
   
           // content-width
  @@ -1426,6 +1427,7 @@
           l.addEnum("auto", makeEnumProperty(EN_AUTO, "AUTO"));
           l.addEnum("scale-to-fit", makeEnumProperty(EN_SCALE_TO_FIT, 
"SCALE_TO_FIT"));
           l.setDefault("auto");
  +        l.setPercentBase(LengthBase.IMAGE_INTRINSIC_WIDTH);
           addPropertyMaker("content-width", l);
   
           // height
  
  
  
  1.1                  
xml-fop/src/java/org/apache/fop/fo/IntrinsicSizeAccess.java
  
  Index: IntrinsicSizeAccess.java
  ===================================================================
  /*
   * Copyright 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: IntrinsicSizeAccess.java,v 1.1 2004/12/28 18:03:12 jeremias Exp $ */
  
  package org.apache.fop.fo;
  
  /**
   * This interface defines the interface for LengthBase to access the intrinsic
   * size of an image (for external-graphic and instream-foreign-object).
   */
  public interface IntrinsicSizeAccess {
  
      /**
       * @return the intrinsic width of an image (in millipoints).
       */
      int getIntrinsicWidth();
      
      /**
       * @return the intrinsic height of an image (in millipoints).
       */
      int getIntrinsicHeight();
      
  }
  
  
  
  1.12      +30 -30    
xml-fop/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java
  
  Index: InstreamForeignObjectLM.java
  ===================================================================
  RCS file: 
/home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- InstreamForeignObjectLM.java      28 Dec 2004 13:55:14 -0000      1.11
  +++ InstreamForeignObjectLM.java      28 Dec 2004 18:03:12 -0000      1.12
  @@ -104,46 +104,46 @@
           int cheight = -1;
           len = fobj.getContentWidth();
           if (len.getEnum() != EN_AUTO) {
  -            /*if(len.scaleToFit()) {
  -                if(ipd != -1) {
  +            if (len.getEnum() == EN_SCALE_TO_FIT) {
  +                if (ipd != -1) {
                       cwidth = ipd;
                   }
  -            } else {*/
  -            cwidth = len.getValue();
  +            } else {
  +                cwidth = len.getValue();
  +            }
           }
           len = fobj.getContentHeight();
           if (len.getEnum() != EN_AUTO) {
  -            /*if(len.scaleToFit()) {
  -                if(bpd != -1) {
  +            if (len.getEnum() == EN_SCALE_TO_FIT) {
  +                if (bpd != -1) {
                       cwidth = bpd;
                   }
  -            } else {*/
  -            cheight = len.getValue();
  +            } 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 = fobj.getScaling();
  -        if (scaling == EN_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);
  +        if ((scaling == EN_UNIFORM) || (cwidth == -1) || cheight == -1) {
  +            if (cwidth == -1 && cheight == -1) {
  +                cwidth = fobj.getIntrinsicWidth();
  +                cheight = fobj.getIntrinsicHeight();
  +            } else if (cwidth == -1) {
  +                cwidth = (int)(fobj.getIntrinsicWidth() * (double)cheight 
  +                    / fobj.getIntrinsicHeight());
  +            } else if (cheight == -1) {
  +                cheight = (int)(fobj.getIntrinsicHeight() * (double)cwidth 
  +                    / fobj.getIntrinsicWidth());
               } else {
  -                cwidth = (int)(rat2 * size.getX() * 1000);
  +                // adjust the larger
  +                double rat1 = cwidth / fobj.getIntrinsicWidth();
  +                double rat2 = cheight / fobj.getIntrinsicHeight();
  +                if (rat1 < rat2) {
  +                    // reduce cheight
  +                    cheight = (int)(rat1 * fobj.getIntrinsicHeight());
  +                } else if (rat1 > rat2) {
  +                    cwidth = (int)(rat2 * fobj.getIntrinsicWidth());
  +                }
               }
           }
   
  
  
  
  1.15      +13 -31    
xml-fop/src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java
  
  Index: ExternalGraphicLayoutManager.java
  ===================================================================
  RCS file: 
/home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- ExternalGraphicLayoutManager.java 24 Nov 2004 21:07:30 -0000      1.14
  +++ ExternalGraphicLayoutManager.java 28 Dec 2004 18:03:12 -0000      1.15
  @@ -27,16 +27,14 @@
   import org.apache.fop.area.inline.Viewport;
   import org.apache.fop.datatypes.Length;
   import org.apache.fop.fo.flow.ExternalGraphic;
  -import org.apache.fop.image.FopImage;
  -import org.apache.fop.image.ImageFactory;
   
   /**
    * LayoutManager for the fo:external-graphic formatting object
    */
   public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
  +    
       private ExternalGraphic fobj;
   
  -    private String url;
       private int breakAfter;
       private int breakBefore;
       private int align;
  @@ -70,8 +68,6 @@
        * @todo see if can simplify property handling logic
        */
       private void setup() {
  -        url = ImageFactory.getURL(fobj.getSrc());
  -
           // assume lr-tb for now and just use the .optimum value of the range
           Length ipd = 
fobj.getInlineProgressionDimension().getOptimum().getLength();
           if (ipd.getEnum() != EN_AUTO) {
  @@ -92,9 +88,6 @@
               }
           }
   
  -        // if we need to load this image to get its size
  -        FopImage fopimage = null;
  -
           int cwidth = -1;
           int cheight = -1;
           Length ch = fobj.getContentHeight();
  @@ -120,35 +113,24 @@
   
           int scaling = fobj.getScaling();
           if ((scaling == EN_UNIFORM) || (cwidth == -1) || cheight == -1) {
  -            ImageFactory fact = ImageFactory.getInstance();
  -            fopimage = fact.getImage(url, fobj.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);
  +                cwidth = fobj.getIntrinsicWidth();
  +                cheight = fobj.getIntrinsicHeight();
               } else if (cwidth == -1) {
  -                cwidth = (int)(fopimage.getWidth() * cheight) / 
fopimage.getHeight();
  +                cwidth = (int)(fobj.getIntrinsicWidth() * (double)cheight 
  +                    / fobj.getIntrinsicHeight());
               } else if (cheight == -1) {
  -                cheight = (int)(fopimage.getHeight() * cwidth) / 
fopimage.getWidth();
  +                cheight = (int)(fobj.getIntrinsicHeight() * (double)cwidth 
  +                    / fobj.getIntrinsicWidth());
               } else {
                   // adjust the larger
  -                double rat1 = cwidth / (fopimage.getWidth() * 1000f);
  -                double rat2 = cheight / (fopimage.getHeight() * 1000f);
  +                double rat1 = cwidth / fobj.getIntrinsicWidth();
  +                double rat2 = cheight / fobj.getIntrinsicHeight();
                   if (rat1 < rat2) {
                       // reduce cheight
  -                    cheight = (int)(rat1 * fopimage.getHeight() * 1000);
  +                    cheight = (int)(rat1 * fobj.getIntrinsicHeight());
                   } else if (rat1 > rat2) {
  -                    cwidth = (int)(rat2 * fopimage.getWidth() * 1000);
  +                    cwidth = (int)(rat2 * fobj.getIntrinsicWidth());
                   }
               }
           }
  @@ -165,7 +147,7 @@
               if (overflow == EN_HIDDEN) {
                   clip = true;
               } else if (overflow == EN_ERROR_IF_OVERFLOW) {
  -                fobj.getLogger().error("Image: " + url
  +                fobj.getLogger().error("Image: " + fobj.getURL()
                                     + " overflows the viewport, clipping to 
viewport");
                   clip = true;
               }
  
  
  
  1.9       +12 -4     xml-fop/src/java/org/apache/fop/datatypes/LengthBase.java
  
  Index: LengthBase.java
  ===================================================================
  RCS file: 
/home/cvs/xml-fop/src/java/org/apache/fop/datatypes/LengthBase.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- LengthBase.java   28 Oct 2004 10:00:19 -0000      1.8
  +++ LengthBase.java   28 Dec 2004 18:03:12 -0000      1.9
  @@ -20,6 +20,7 @@
   
   import org.apache.fop.fo.Constants;
   import org.apache.fop.fo.FObj;
  +import org.apache.fop.fo.IntrinsicSizeAccess;
   import org.apache.fop.fo.PropertyList;
   import org.apache.fop.fo.expr.PropertyException;
   
  @@ -43,11 +44,16 @@
       public static final int BLOCK_WIDTH = 5;
       /** constant for a containing block percent-based length */
       public static final int BLOCK_HEIGHT = 6;
  +    /** constant for a image intrinsic percent-based length */
  +    public static final int IMAGE_INTRINSIC_WIDTH = 7;
  +    /** constant for a image intrinsic percent-based length */
  +    public static final int IMAGE_INTRINSIC_HEIGHT = 8;
   
       /** array of valid percent-based length types */
       public static final int[] PERCENT_BASED_LENGTH_TYPES
  -            = { CUSTOM_BASE, FONTSIZE, INH_FONTSIZE, CONTAINING_BOX,
  -                CONTAINING_REFAREA } ;
  +            = {CUSTOM_BASE, FONTSIZE, INH_FONTSIZE, CONTAINING_BOX,
  +               CONTAINING_REFAREA, 
  +               IMAGE_INTRINSIC_WIDTH, IMAGE_INTRINSIC_HEIGHT};
   
       /**
        * FO parent of the FO for which this property is to be calculated.
  @@ -122,13 +128,15 @@
           case BLOCK_HEIGHT:
               return 
parentFO.getLayoutDimension(PercentBase.BLOCK_BPD).intValue();
           case CONTAINING_REFAREA:    // example: start-indent, end-indent
  -         {
               //FONode fo;
               //for (fo = parentFO; fo != null && 
!fo.generatesReferenceAreas();
               //        fo = fo.getParent());
               //return (((fo != null) && (fo instanceof FObj)) ? 
((FObj)fo).getContentWidth() : 0);
               return 0;
  -        }
  +        case IMAGE_INTRINSIC_WIDTH:
  +            return 
((IntrinsicSizeAccess)propertyList.getFObj()).getIntrinsicWidth();
  +        case IMAGE_INTRINSIC_HEIGHT:
  +            return 
((IntrinsicSizeAccess)propertyList.getFObj()).getIntrinsicHeight();
           case CUSTOM_BASE:
               //log.debug("!!! LengthBase.getBaseLength() called on 
CUSTOM_BASE type !!!");
               return 0;
  
  
  

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

Reply via email to