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]