jeremias 2005/01/24 02:43:19 Modified: src/java/org/apache/fop/fo/flow ExternalGraphic.java src/java/org/apache/fop/fo PropertyList.java src/java/org/apache/fop/area Trait.java src/java/org/apache/fop/layoutmgr TraitSetter.java src/java/org/apache/fop/fo/properties CommonBorderPaddingBackground.java src/java/org/apache/fop/render/pdf PDFRenderer.java Log: Early preloading of images (during FO tree building). This wasn't consistent before (bg-images were loaded by the renderer). background-position-* implemented where possible (area IPD and BPD must be set for percentages to work) Fixed placement bug for images (bad rounding or coordinates). Revision Changes Path 1.53 +27 -37 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.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- ExternalGraphic.java 20 Jan 2005 14:08:20 -0000 1.52 +++ ExternalGraphic.java 24 Jan 2005 10:43:19 -0000 1.53 @@ -121,8 +121,19 @@ verticalAlign = pList.get(PR_VERTICAL_ALIGN).getEnum(); width = pList.get(PR_WIDTH).getLength(); - //Additional processing + //Additional processing: preload image url = ImageFactory.getURL(getSrc()); + ImageFactory fact = ImageFactory.getInstance(); + fopimage = fact.getImage(url, getUserAgent()); + if (fopimage == null) { + getLogger().error("Image not available: " + getSrc()); + } else { + // load dimensions + if (!fopimage.load(FopImage.DIMENSIONS)) { + getLogger().error("Cannot read image dimensions: " + getSrc()); + } + } + //TODO Report to caller so he can decide to throw an exception } /** @@ -143,84 +154,84 @@ } /** - * Return the Common Border, Padding, and Background Properties. + * @return the Common Border, Padding, and Background Properties. */ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { return commonBorderPaddingBackground; } /** - * Return the Common Margin Properties-Inline. + * @return the Common Margin Properties-Inline. */ public CommonMarginInline getCommonMarginInline() { return commonMarginInline; } /** - * Return the "block-progression-dimension" property. + * @return the "block-progression-dimension" property. */ public LengthRangeProperty getBlockProgressionDimension() { return blockProgressionDimension; } /** - * Return the "content-height" property. + * @return the "content-height" property. */ public Length getContentHeight() { return contentHeight; } /** - * Return the "content-width" property. + * @return the "content-width" property. */ public Length getContentWidth() { return contentWidth; } /** - * Return the "display-align" property. + * @return the "display-align" property. */ public int getDisplayAlign() { return displayAlign; } /** - * Return the "height" property. + * @return the "height" property. */ public Length getHeight() { return height; } /** - * Return the "id" property. + * @return the "id" property. */ public String getId() { return id; } /** - * Return the "inline-progression-dimension" property. + * @return the "inline-progression-dimension" property. */ public LengthRangeProperty getInlineProgressionDimension() { return inlineProgressionDimension; } /** - * Return the "overflow" property. + * @return the "overflow" property. */ public int getOverflow() { return overflow; } /** - * Return the "scaling" property. + * @return the "scaling" property. */ public int getScaling() { return scaling; } /** - * Return the "src" property. + * @return the "src" property. */ public String getSrc() { return src; @@ -234,21 +245,21 @@ } /** - * Return the "text-align" property. + * @return the "text-align" property. */ public int getTextAlign() { return textAlign; } /** - * Return the "width" property. + * @return the "width" property. */ public Length getWidth() { return width; } /** - * Return the "vertical-align" property. + * @return the "vertical-align" property. */ public int getVerticalAlign() { return verticalAlign; @@ -282,29 +293,9 @@ } /** - * 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.getIntrinsicWidth(); } else { @@ -316,7 +307,6 @@ * @see org.apache.fop.fo.IntrinsicSizeAccess#getIntrinsicHeight() */ public int getIntrinsicHeight() { - prepareIntrinsicSize(); if (fopimage != null) { return fopimage.getIntrinsicHeight(); } else { 1.43 +1 -1 xml-fop/src/java/org/apache/fop/fo/PropertyList.java Index: PropertyList.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/fo/PropertyList.java,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- PropertyList.java 24 Nov 2004 21:07:29 -0000 1.42 +++ PropertyList.java 24 Jan 2005 10:43:19 -0000 1.43 @@ -459,7 +459,7 @@ * @return a BorderAndPadding object */ public CommonBorderPaddingBackground getBorderPaddingBackgroundProps() throws PropertyException { - return new CommonBorderPaddingBackground(this); + return new CommonBorderPaddingBackground(this, getFObj()); } 1.8 +20 -0 xml-fop/src/java/org/apache/fop/area/Trait.java Index: Trait.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/area/Trait.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- Trait.java 17 Jan 2005 10:30:16 -0000 1.7 +++ Trait.java 24 Jan 2005 10:43:19 -0000 1.8 @@ -19,6 +19,7 @@ package org.apache.fop.area; import org.apache.fop.datatypes.ColorType; +import org.apache.fop.image.FopImage; import org.apache.fop.traits.BorderProps; import java.io.Serializable; @@ -410,6 +411,9 @@ /** The background image url if any. */ private String url = null; + + /** The background image if any. */ + private FopImage fopimage = null; /** Background repeat enum for images. */ private int repeat; @@ -453,6 +457,14 @@ } /** + * Returns the FopImage representing the background image + * @return the background image, null if n/a + */ + public FopImage getFopImage() { + return fopimage; + } + + /** * Returns the vertical offset for images. * @return the vertical offset */ @@ -490,6 +502,14 @@ */ public void setURL(String url) { this.url = url; + } + + /** + * Sets the FopImage to use as the background image. + * @param fopimage The FopImage to use + */ + public void setFopImage(FopImage fopimage) { + this.fopimage = fopimage; } /** 1.13 +46 -4 xml-fop/src/java/org/apache/fop/layoutmgr/TraitSetter.java Index: TraitSetter.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/TraitSetter.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- TraitSetter.java 12 Jan 2005 12:03:00 -0000 1.12 +++ TraitSetter.java 24 Jan 2005 10:43:19 -0000 1.13 @@ -18,17 +18,24 @@ package org.apache.fop.layoutmgr; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.fop.traits.BorderProps; import org.apache.fop.area.Area; import org.apache.fop.area.Trait; +import org.apache.fop.fo.Constants; import org.apache.fop.fo.properties.CommonMarginBlock; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.PercentLength; /** * This is a helper class used for setting common traits on areas. */ public class TraitSetter { + /** logger */ + protected static Log log = LogFactory.getLog(TraitSetter.class); + /** * Sets border and padding traits on areas. * @param area area to set the traits on @@ -152,6 +159,7 @@ * Add background to an area. * Layout managers that create areas with a background can use this to * add the background to the area. + * Note: The area's IPD and BPD must be set before calling this method. * @param area the area to set the traits on * @param backProps the background properties */ @@ -159,18 +167,52 @@ Trait.Background back = new Trait.Background(); back.setColor(backProps.backgroundColor); - if (backProps.backgroundImage != null) { + if (backProps.getFopImage() != null) { back.setURL(backProps.backgroundImage); + back.setFopImage(backProps.getFopImage()); back.setRepeat(backProps.backgroundRepeat); if (backProps.backgroundPositionHorizontal != null) { - back.setHoriz(backProps.backgroundPositionHorizontal.getValue()); + if (back.getRepeat() == Constants.EN_NOREPEAT + || back.getRepeat() == Constants.EN_REPEATY) { + if (backProps.backgroundPositionHorizontal instanceof PercentLength) { + if (area.getIPD() > 0) { + int width = area.getIPD(); + width += backProps.getPaddingStart(false); + width += backProps.getPaddingEnd(false); + back.setHoriz((int)((width - back.getFopImage().getIntrinsicWidth()) + * ((PercentLength)backProps.backgroundPositionHorizontal).value())); + } else { + //TODO Area IPD has to be set for this to work + log.warn("Horizontal background image positioning ignored"); + } + } else { + back.setHoriz(backProps.backgroundPositionHorizontal.getValue()); + } + } } if (backProps.backgroundPositionVertical != null) { - back.setVertical(backProps.backgroundPositionVertical.getValue()); + if (back.getRepeat() == Constants.EN_NOREPEAT + || back.getRepeat() == Constants.EN_REPEATX) { + if (backProps.backgroundPositionVertical instanceof PercentLength) { + if (area.getBPD() > 0) { + int height = area.getBPD(); + height += backProps.getPaddingBefore(false); + height += backProps.getPaddingAfter(false); + back.setVertical( + (int)((height - back.getFopImage().getIntrinsicHeight()) + * ((PercentLength)backProps.backgroundPositionVertical).value())); + } else { + //TODO Area BPD has to be set for this to work + log.warn("Vertical background image positioning ignored"); + } + } else { + back.setVertical(backProps.backgroundPositionVertical.getValue()); + } + } } } - if (back.getColor() != null || back.getURL() != null) { + if (back.getColor() != null || back.getFopImage() != null) { area.addTrait(Trait.BACKGROUND, back); } } 1.8 +44 -7 xml-fop/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java Index: CommonBorderPaddingBackground.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- CommonBorderPaddingBackground.java 12 Jan 2005 11:57:02 -0000 1.7 +++ CommonBorderPaddingBackground.java 24 Jan 2005 10:43:19 -0000 1.8 @@ -21,8 +21,11 @@ import org.apache.fop.datatypes.ColorType; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; +import org.apache.fop.image.FopImage; +import org.apache.fop.image.ImageFactory; /** * Stores all common border and padding properties. @@ -59,9 +62,17 @@ */ public Length backgroundPositionVertical; + + private FopImage fopimage; + + + /** the "before" edge */ public static final int BEFORE = 0; + /** the "after" edge */ public static final int AFTER = 1; + /** the "start" edge */ public static final int START = 2; + /** the "end" edge */ public static final int END = 3; private static class BorderInfo implements Cloneable { @@ -82,8 +93,10 @@ /** * Construct a CommonBorderPaddingBackground object. * @param pList The PropertyList to get properties from. + * @param fobj The FO to create this instance for. + * @throws PropertyException if there's an error while binding the properties */ - public CommonBorderPaddingBackground(PropertyList pList) throws PropertyException { + public CommonBorderPaddingBackground(PropertyList pList, FObj fobj) throws PropertyException { backgroundAttachment = pList.get(Constants.PR_BACKGROUND_ATTACHMENT).getEnum(); backgroundColor = pList.get(Constants.PR_BACKGROUND_COLOR).getColorType(); if (backgroundColor.getAlpha() == 0) { @@ -95,8 +108,25 @@ backgroundImage = null; } else { backgroundRepeat = pList.get(Constants.PR_BACKGROUND_REPEAT).getEnum(); - backgroundPositionHorizontal = pList.get(Constants.PR_BACKGROUND_POSITION_HORIZONTAL).getLength(); - backgroundPositionVertical = pList.get(Constants.PR_BACKGROUND_POSITION_VERTICAL).getLength(); + backgroundPositionHorizontal = pList.get( + Constants.PR_BACKGROUND_POSITION_HORIZONTAL).getLength(); + backgroundPositionVertical = pList.get( + Constants.PR_BACKGROUND_POSITION_VERTICAL).getLength(); + + //Additional processing: preload image + String url = ImageFactory.getURL(backgroundImage); + ImageFactory fact = ImageFactory.getInstance(); + fopimage = fact.getImage(url, fobj.getUserAgent()); + if (fopimage == null) { + fobj.getLogger().error("Background image not available: " + backgroundImage); + } else { + // load dimensions + if (!fopimage.load(FopImage.DIMENSIONS)) { + fobj.getLogger().error("Cannot read background image dimensions: " + + backgroundImage); + } + } + //TODO Report to caller so he can decide to throw an exception } initBorderInfo(pList, BEFORE, @@ -123,9 +153,8 @@ } private void initBorderInfo(PropertyList pList, int side, - int colorProp, int styleProp, int widthProp, int paddingProp) - throws PropertyException - { + int colorProp, int styleProp, int widthProp, int paddingProp) + throws PropertyException { padding[side] = pList.get(paddingProp).getCondLength(); // If style = none, force width to 0, don't get Color (spec 7.7.20) int style = pList.get(styleProp).getEnum(); @@ -134,6 +163,14 @@ pList.get(widthProp).getCondLength(), pList.get(colorProp).getColorType()); } + } + + /** + * @return the background image as a preloaded FopImage, null if there is + * no background image. + */ + public FopImage getFopImage() { + return this.fopimage; } public int getBorderStartWidth(boolean bDiscard) { 1.75 +22 -22 xml-fop/src/java/org/apache/fop/render/pdf/PDFRenderer.java Index: PDFRenderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/render/pdf/PDFRenderer.java,v retrieving revision 1.74 retrieving revision 1.75 diff -u -r1.74 -r1.75 --- PDFRenderer.java 20 Jan 2005 15:18:23 -0000 1.74 +++ PDFRenderer.java 24 Jan 2005 10:43:19 -0000 1.75 @@ -83,6 +83,7 @@ import org.apache.fop.render.RendererContext; import org.apache.fop.traits.BorderProps; import org.apache.fop.fo.Constants; +import org.apache.fop.fo.properties.ColorTypeProperty; /* @@ -603,12 +604,11 @@ + paddRectWidth + " " + paddRectHeight + " re\n"); currentStream.add("f\n"); } - if (back.getURL() != null) { - ImageFactory fact = ImageFactory.getInstance(); - FopImage fopimage = fact.getImage(back.getURL(), userAgent); + if (back.getFopImage() != null) { + FopImage fopimage = back.getFopImage(); if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) { saveGraphicsState(); - clip(startx, starty, width, height); + clip(sx, sy, paddRectWidth, paddRectHeight); int horzCount = (int)((paddRectWidth * 1000 / fopimage.getIntrinsicWidth()) + 1.0f); int vertCount = (int)((paddRectHeight @@ -1244,10 +1244,10 @@ protected void putImage(String url, Rectangle2D pos) { PDFXObject xobject = pdfDoc.getImage(url); if (xobject != null) { - int w = (int) pos.getWidth() / 1000; - int h = (int) pos.getHeight() / 1000; - placeImage((int) pos.getX() / 1000, - (int) pos.getY() / 1000, w, h, xobject.getXNumber()); + float w = (float) pos.getWidth() / 1000f; + float h = (float) pos.getHeight() / 1000f; + placeImage((float)pos.getX() / 1000f, + (float)pos.getY() / 1000f, w, h, xobject.getXNumber()); return; } @@ -1292,10 +1292,10 @@ int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber(); fact.releaseImage(url, userAgent); - int w = (int) pos.getWidth() / 1000; - int h = (int) pos.getHeight() / 1000; - placeImage((int) pos.getX() / 1000, - (int) pos.getY() / 1000, w, h, xobj); + float w = (float)pos.getWidth() / 1000f; + float h = (float)pos.getHeight() / 1000f; + placeImage((float) pos.getX() / 1000, + (float) pos.getY() / 1000, w, h, xobj); } else { if (!fopimage.load(FopImage.BITMAP)) { return; @@ -1304,10 +1304,10 @@ int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber(); fact.releaseImage(url, userAgent); - int w = (int) pos.getWidth() / 1000; - int h = (int) pos.getHeight() / 1000; - placeImage((int) pos.getX() / 1000, - (int) pos.getY() / 1000, w, h, xobj); + float w = (float) pos.getWidth() / 1000f; + float h = (float) pos.getHeight() / 1000f; + placeImage((float) pos.getX() / 1000f, + (float) pos.getY() / 1000f, w, h, xobj); } // output new data @@ -1326,13 +1326,13 @@ * @param h height for image * @param xobj object number of the referenced image */ - protected void placeImage(int x, int y, int w, int h, int xobj) { + protected void placeImage(float x, float y, float w, float h, int xobj) { saveGraphicsState(); - currentStream.add(((float) w) + " 0 0 " - + ((float) -h) + " " - + (((float) currentIPPosition) / 1000f + x) + " " - + (((float)(currentBPPosition + 1000 * h)) / 1000f - + y) + " cm\n" + "/Im" + xobj + " Do\n"); + currentStream.add(w + " 0 0 " + + -h + " " + + (currentIPPosition / 1000f + x) + " " + + (currentBPPosition / 1000f + h + y) + + " cm\n" + "/Im" + xobj + " Do\n"); restoreGraphicsState(); }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]