From 622e2d3e2eedaa22e560a937616b79d898c6c4b3 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 9 Jul 2008 12:56:41 +0000 Subject: [PATCH] Bugzilla #39980: Fixed image scaling for RTF output. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_95@675150 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/render/rtf/RTFHandler.java | 100 ++++++-------- .../rtf/rtflib/rtfdoc/RtfExternalGraphic.java | 124 +++++++++++++----- status.xml | 3 + 3 files changed, 137 insertions(+), 90 deletions(-) diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java index d023e1fe4..d54379e77 100644 --- a/src/java/org/apache/fop/render/rtf/RTFHandler.java +++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java @@ -20,6 +20,8 @@ package org.apache.fop.render.rtf; // Java +import java.awt.Dimension; +import java.awt.Rectangle; import java.awt.geom.Point2D; import java.io.IOException; import java.io.InputStream; @@ -50,10 +52,12 @@ import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.datatypes.LengthBase; +import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FOEventHandler; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FOText; +import org.apache.fop.fo.FObj; import org.apache.fop.fo.XMLObj; import org.apache.fop.fo.flow.AbstractGraphics; import org.apache.fop.fo.flow.BasicLink; @@ -87,6 +91,7 @@ import org.apache.fop.fo.pagination.StaticContent; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.EnumLength; import org.apache.fop.fonts.FontSetup; +import org.apache.fop.layoutmgr.inline.ImageLayout; import org.apache.fop.layoutmgr.table.ColumnSetup; import org.apache.fop.render.DefaultFontResolver; import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer; @@ -1112,7 +1117,7 @@ public class RTFHandler extends FOEventHandler { throws IOException { byte[] rawData = null; - ImageInfo info = image.getInfo(); + final ImageInfo info = image.getInfo(); if (image instanceof ImageRawStream) { ImageRawStream rawImage = (ImageRawStream)image; @@ -1130,6 +1135,25 @@ public class RTFHandler extends FOEventHandler { return; } + //Set up percentage calculations + this.percentManager.setDimension(abstractGraphic); + PercentBaseContext pContext = new PercentBaseContext() { + + public int getBaseLength(int lengthBase, FObj fobj) { + switch (lengthBase) { + case LengthBase.IMAGE_INTRINSIC_WIDTH: + return info.getSize().getWidthMpt(); + case LengthBase.IMAGE_INTRINSIC_HEIGHT: + return info.getSize().getHeightMpt(); + default: + return percentManager.getBaseLength(lengthBase, fobj); + } + } + + }; + ImageLayout layout = new ImageLayout(abstractGraphic, pContext, + image.getInfo().getSize().getDimensionMpt()); + final IRtfTextrunContainer c = (IRtfTextrunContainer)builderContext.getContainer( IRtfTextrunContainer.class, true, this); @@ -1142,63 +1166,23 @@ public class RTFHandler extends FOEventHandler { } rtfGraphic.setImageData(rawData); - //set scaling - if (abstractGraphic.getScaling() == Constants.EN_UNIFORM) { - rtfGraphic.setScaling ("uniform"); - } - - //get width - int width = 0; - if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) { - width = info.getSize().getWidthMpt(); - } else { - width = abstractGraphic.getWidth().getValue(); - } - - //get height - int height = 0; - if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) { - height = info.getSize().getHeightMpt(); - } else { - height = abstractGraphic.getHeight().getValue(); - } - - //get content-width - int contentwidth = 0; - if (abstractGraphic.getContentWidth().getEnum() - == Constants.EN_AUTO) { - contentwidth = info.getSize().getWidthMpt(); - } else if (abstractGraphic.getContentWidth().getEnum() - == Constants.EN_SCALE_TO_FIT) { - contentwidth = width; - } else { - //TODO: check, if the value is a percent value - contentwidth = abstractGraphic.getContentWidth().getValue(); - } - - //get content-width - int contentheight = 0; - if (abstractGraphic.getContentHeight().getEnum() - == Constants.EN_AUTO) { - - contentheight = info.getSize().getHeightMpt(); - - } else if (abstractGraphic.getContentHeight().getEnum() - == Constants.EN_SCALE_TO_FIT) { - - contentheight = height; - } else { - //TODO: check, if the value is a percent value - contentheight = abstractGraphic.getContentHeight().getValue(); - } - - //set width in rtf - //newGraphic.setWidth((long) (contentwidth / 1000f) + FixedLength.POINT); - rtfGraphic.setWidth((long) (contentwidth / 50f) + "twips"); - - //set height in rtf - //newGraphic.setHeight((long) (contentheight / 1000f) + FixedLength.POINT); - rtfGraphic.setHeight((long) (contentheight / 50f) + "twips"); + FoUnitsConverter converter = FoUnitsConverter.getInstance(); + Dimension viewport = layout.getViewportSize(); + Rectangle placement = layout.getPlacement(); + int cropLeft = Math.round(converter.convertMptToTwips(-placement.x)); + int cropTop = Math.round(converter.convertMptToTwips(-placement.y)); + int cropRight = Math.round(converter.convertMptToTwips( + -1 * (viewport.width - placement.x - placement.width))); + int cropBottom = Math.round(converter.convertMptToTwips( + -1 * (viewport.height - placement.y - placement.height))); + rtfGraphic.setCropping(cropLeft, cropTop, cropRight, cropBottom); + + int width = Math.round(converter.convertMptToTwips(viewport.width)); + int height = Math.round(converter.convertMptToTwips(viewport.height)); + width += cropLeft + cropRight; + height += cropTop + cropBottom; + rtfGraphic.setWidthTwips(width); + rtfGraphic.setHeightTwips(height); //TODO: make this configurable: // int compression = m_context.m_options.getRtfExternalGraphicCompressionRate (); diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java index 932198676..6123ac563 100644 --- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java +++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -65,7 +65,7 @@ public class RtfExternalGraphic extends RtfElement { super(reason); } } - + ////////////////////////////////////////////////// // Supported Formats ////////////////////////////////////////////////// @@ -83,7 +83,7 @@ public class RtfExternalGraphic extends RtfElement { public static boolean isFormat(byte[] data) { return false; } - + /** * Convert image data if necessary - for example when format is not supported by rtf. * @@ -93,7 +93,7 @@ public class RtfExternalGraphic extends RtfElement { public FormatBase convert(FormatBase format, byte[] data) { return format; } - + /** * Determine image file format. * @@ -118,7 +118,7 @@ public class RtfExternalGraphic extends RtfElement { return null; } } - + /** * Get image type. * @@ -127,7 +127,7 @@ public class RtfExternalGraphic extends RtfElement { public int getType() { return ImageConstants.I_NOT_SUPPORTED; } - + /** * Get rtf tag. * @@ -137,7 +137,7 @@ public class RtfExternalGraphic extends RtfElement { return ""; } } - + private static class FormatGIF extends FormatBase { public static boolean isFormat(byte[] data) { // Indentifier "GIF8" on position 0 @@ -145,12 +145,12 @@ public class RtfExternalGraphic extends RtfElement { return ImageUtil.compareHexValues(pattern, data, 0, true); } - + public int getType() { return ImageConstants.I_GIF; } } - + private static class FormatEMF extends FormatBase { public static boolean isFormat(byte[] data) { // No offical Indentifier known @@ -158,28 +158,28 @@ public class RtfExternalGraphic extends RtfElement { return ImageUtil.compareHexValues(pattern, data, 0, true); } - + public int getType() { return ImageConstants.I_EMF; } - + public String getRtfTag() { return "emfblip"; } } - + private static class FormatBMP extends FormatBase { public static boolean isFormat(byte[] data) { byte [] pattern = new byte [] {(byte) 0x42, (byte) 0x4D}; return ImageUtil.compareHexValues(pattern, data, 0, true); } - + public int getType() { return ImageConstants.I_BMP; } } - + private static class FormatJPG extends FormatBase { public static boolean isFormat(byte[] data) { // Indentifier "0xFFD8" on position 0 @@ -187,16 +187,16 @@ public class RtfExternalGraphic extends RtfElement { return ImageUtil.compareHexValues(pattern, data, 0, true); } - + public int getType() { return ImageConstants.I_JPG; } - + public String getRtfTag() { return "jpegblip"; } } - + private static class FormatPNG extends FormatBase { public static boolean isFormat(byte[] data) { // Indentifier "PNG" on position 1 @@ -204,16 +204,16 @@ public class RtfExternalGraphic extends RtfElement { return ImageUtil.compareHexValues(pattern, data, 1, true); } - + public int getType() { return ImageConstants.I_PNG; } - + public String getRtfTag() { return "pngblip"; } } - + ////////////////////////////////////////////////// // @@ Members ////////////////////////////////////////////////// @@ -269,6 +269,9 @@ public class RtfExternalGraphic extends RtfElement { */ protected boolean scaleUniform = false; + /** cropping on left/top/right/bottom edges for \piccrop*N */ + private int[] cropValues = new int[4]; + /** * Graphic compression rate */ @@ -370,7 +373,7 @@ public class RtfExternalGraphic extends RtfElement { throw new ExternalGraphicException("The attribute 'src' of " + " has a invalid value: '" + url + "' (" + e + ")"); - } + } } if (imagedata == null) { @@ -383,8 +386,8 @@ public class RtfExternalGraphic extends RtfElement { if (imageformat != null) { imageformat = imageformat.convert(imageformat, imagedata); } - - if (imageformat == null + + if (imageformat == null || imageformat.getType() == ImageConstants.I_NOT_SUPPORTED || "".equals(imageformat.getRtfTag())) { throw new ExternalGraphicException("The tag " @@ -406,6 +409,7 @@ public class RtfExternalGraphic extends RtfElement { computeImageSize(); writeSizeInfo(); + writeAttributes(getRtfAttributes(), null); for (int i = 0; i < imagedata.length; i++) { int iData = imagedata [i]; @@ -465,17 +469,17 @@ public class RtfExternalGraphic extends RtfElement { } } else if (imageformat.getType() == ImageConstants.I_EMF) { int i = 0; - + i = ImageUtil.getIntFromByteArray(imagedata, 151, 4, false); if (i != 0 ) { - width = i; + width = i; } - + i = ImageUtil.getIntFromByteArray(imagedata, 155, 4, false); if (i != 0 ) { height = i; } - + } } @@ -519,6 +523,19 @@ public class RtfExternalGraphic extends RtfElement { writeControlWord("picscaley" + widthDesired * 100 / width); } } + + if (this.cropValues[0] != 0) { + writeOneAttribute("piccropl", new Integer(this.cropValues[0])); + } + if (this.cropValues[1] != 0) { + writeOneAttribute("piccropt", new Integer(this.cropValues[1])); + } + if (this.cropValues[2] != 0) { + writeOneAttribute("piccropr", new Integer(this.cropValues[2])); + } + if (this.cropValues[3] != 0) { + writeOneAttribute("piccropb", new Integer(this.cropValues[3])); + } } ////////////////////////////////////////////////// @@ -545,6 +562,24 @@ public class RtfExternalGraphic extends RtfElement { this.perCentW = ImageUtil.isPercent(theWidth); } + /** + * Sets the desired width of the image. + * @param twips The desired image width (in twips) + */ + public void setWidthTwips(int twips) { + this.widthDesired = twips; + this.perCentW = false; + } + + /** + * Sets the desired height of the image. + * @param twips The desired image height (in twips) + */ + public void setHeightTwips(int twips) { + this.heightDesired = twips; + this.perCentH = false; + } + /** * Sets the flag whether the image size shall be adjusted. * @@ -553,11 +588,36 @@ public class RtfExternalGraphic extends RtfElement { * false no adjustment */ public void setScaling(String value) { - if (value.equalsIgnoreCase("uniform")) { - this.scaleUniform = true; - } + setUniformScaling("uniform".equalsIgnoreCase(value)); } - + + /** + * Sets the flag whether the image size shall be adjusted. + * + * @param uniform + * true image width or height shall be adjusted automatically\n + * false no adjustment + */ + public void setUniformScaling(boolean uniform) { + this.scaleUniform = uniform; + } + + /** + * Sets cropping values for all four edges for the \piccrop*N commands. + * A positive value crops toward the center of the picture; + * a negative value crops away from the center, adding a space border around the picture + * @param left left cropping value (in twips) + * @param top top cropping value (in twips) + * @param right right cropping value (in twips) + * @param bottom bottom cropping value (in twips) + */ + public void setCropping(int left, int top, int right, int bottom) { + this.cropValues[0] = left; + this.cropValues[1] = top; + this.cropValues[2] = right; + this.cropValues[3] = bottom; + } + /** * Sets the binary imagedata of the image. * diff --git a/status.xml b/status.xml index 752e2f1ca..4ba13f756 100644 --- a/status.xml +++ b/status.xml @@ -60,6 +60,9 @@ --> + + Fixed image scaling for RTF output. + Added support for fo:leader for RTF output (no full support!). Fixes problems with empty leaders being used to force empty lines among other issues. -- 2.39.5