aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/fop/datatypes/LengthBase.java16
-rw-r--r--src/java/org/apache/fop/fo/FOPropertyMapping.java2
-rw-r--r--src/java/org/apache/fop/fo/IntrinsicSizeAccess.java37
-rw-r--r--src/java/org/apache/fop/fo/flow/ExternalGraphic.java64
-rw-r--r--src/java/org/apache/fop/fo/flow/InstreamForeignObject.java52
-rw-r--r--src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java42
-rw-r--r--src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java58
7 files changed, 203 insertions, 68 deletions
diff --git a/src/java/org/apache/fop/datatypes/LengthBase.java b/src/java/org/apache/fop/datatypes/LengthBase.java
index 45df34d8c..c6e229b89 100644
--- a/src/java/org/apache/fop/datatypes/LengthBase.java
+++ b/src/java/org/apache/fop/datatypes/LengthBase.java
@@ -20,6 +20,7 @@ package org.apache.fop.datatypes;
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 class LengthBase implements PercentBase {
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 @@ public class LengthBase implements PercentBase {
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;
diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java
index 14878037f..127e2668d 100644
--- a/src/java/org/apache/fop/fo/FOPropertyMapping.java
+++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java
@@ -1418,6 +1418,7 @@ public class FOPropertyMapping implements Constants {
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 @@ public class FOPropertyMapping implements Constants {
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
diff --git a/src/java/org/apache/fop/fo/IntrinsicSizeAccess.java b/src/java/org/apache/fop/fo/IntrinsicSizeAccess.java
new file mode 100644
index 000000000..07e2e2afa
--- /dev/null
+++ b/src/java/org/apache/fop/fo/IntrinsicSizeAccess.java
@@ -0,0 +1,37 @@
+/*
+ * 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$ */
+
+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();
+
+}
diff --git a/src/java/org/apache/fop/fo/flow/ExternalGraphic.java b/src/java/org/apache/fop/fo/flow/ExternalGraphic.java
index 55c5a567d..7d609028e 100644
--- a/src/java/org/apache/fop/fo/flow/ExternalGraphic.java
+++ b/src/java/org/apache/fop/fo/flow/ExternalGraphic.java
@@ -27,6 +27,7 @@ import org.apache.fop.apps.FOPException;
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.CommonMarginInline;
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 @@ import org.apache.fop.layoutmgr.ExternalGraphicLayoutManager;
* 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 @@ public class ExternalGraphic extends FObj {
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 @@ public class ExternalGraphic extends FObj {
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 @@ public class ExternalGraphic extends FObj {
}
/**
+ * @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 class ExternalGraphic extends FObj {
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;
+ }
+ }
+
}
diff --git a/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java b/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
index 60c36f271..f8ffccbd0 100644
--- a/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
+++ b/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
@@ -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.apps.FOPException;
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.CommonMarginInline;
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 @@ public class InstreamForeignObject extends FObj {
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 class InstreamForeignObject extends FObj {
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;
+ }
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java
index 033b131a8..bad48b8a1 100644
--- a/src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/ExternalGraphicLayoutManager.java
@@ -27,16 +27,14 @@ 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.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 @@ public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
* @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 @@ public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
}
}
- // 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 @@ public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
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 @@ public class ExternalGraphicLayoutManager extends LeafNodeLayoutManager {
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;
}
diff --git a/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java b/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java
index 15d87f848..dce3fa461 100644
--- a/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java
+++ b/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java
@@ -104,46 +104,46 @@ public class InstreamForeignObjectLM extends LeafNodeLayoutManager {
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());
+ }
}
}