diff options
Diffstat (limited to 'src/java/org/apache/fop')
20 files changed, 494 insertions, 124 deletions
diff --git a/src/java/org/apache/fop/afp/AFPDataObjectFactory.java b/src/java/org/apache/fop/afp/AFPDataObjectFactory.java index 80cb40713..f6de7b5b4 100644 --- a/src/java/org/apache/fop/afp/AFPDataObjectFactory.java +++ b/src/java/org/apache/fop/afp/AFPDataObjectFactory.java @@ -21,6 +21,9 @@ package org.apache.fop.afp; import java.awt.geom.Rectangle2D; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; + import org.apache.fop.afp.ioca.ImageContent; import org.apache.fop.afp.modca.AbstractDataObject; import org.apache.fop.afp.modca.AbstractNamedAFPObject; @@ -35,8 +38,6 @@ import org.apache.fop.afp.modca.Registry; import org.apache.fop.afp.modca.ResourceObject; import org.apache.fop.afp.modca.triplets.MappingOptionTriplet; import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet; -import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** * Factory for high level data objects (Image/Graphics etc) @@ -117,6 +118,7 @@ public class AFPDataObjectFactory { } else { imageObj.setIDESize((byte) imageObjectInfo.getBitsPerPixel()); } + imageObj.setSubtractive(imageObjectInfo.isSubtractive()); imageObj.setData(imageObjectInfo.getData()); diff --git a/src/java/org/apache/fop/afp/AFPImageObjectInfo.java b/src/java/org/apache/fop/afp/AFPImageObjectInfo.java index f3677534f..45ea5fc1f 100644 --- a/src/java/org/apache/fop/afp/AFPImageObjectInfo.java +++ b/src/java/org/apache/fop/afp/AFPImageObjectInfo.java @@ -34,6 +34,8 @@ public class AFPImageObjectInfo extends AFPDataObjectInfo { /** compression type if any */ private int compression = -1; + private boolean subtractive; + /** * Default constructor */ @@ -104,12 +106,29 @@ public class AFPImageObjectInfo extends AFPDataObjectInfo { this.compression = compression; } + /** + * Set either additive or subtractive mode (used for ASFLAG). + * @param subtractive true for subtractive mode, false for additive mode + */ + public void setSubtractive(boolean subtractive) { + this.subtractive = subtractive; + } + + /** + * Indicates whether additive or subtractive mode is set. + * @return true for subtractive mode, false for additive mode + */ + public boolean isSubtractive() { + return subtractive; + } + /** {@inheritDoc} */ public String toString() { return "AFPImageObjectInfo{" + super.toString() + ", compression=" + compression + ", color=" + color + ", bitsPerPixel=" + bitsPerPixel + + ", " + (isSubtractive() ? "subtractive" : "additive") + "}"; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/afp/ioca/ImageContent.java b/src/java/org/apache/fop/afp/ioca/ImageContent.java index 40e51578b..bdb2455d9 100644 --- a/src/java/org/apache/fop/afp/ioca/ImageContent.java +++ b/src/java/org/apache/fop/afp/ioca/ImageContent.java @@ -68,6 +68,9 @@ public class ImageContent extends AbstractStructuredObject { /** the image color model */ private byte colorModel = (byte)0x01; + /** additive/subtractive setting for ASFLAG */ + private boolean subtractive = false; + /** the image data */ private byte[] data; @@ -123,6 +126,14 @@ public class ImageContent extends AbstractStructuredObject { } /** + * Set either additive or subtractive mode (used for ASFLAG). + * @param subtractive true for subtractive mode, false for additive mode + */ + public void setSubtractive(boolean subtractive) { + this.subtractive = subtractive; + } + + /** * Set the image data (can be byte array or inputstream) * * @param imageData the image data @@ -243,12 +254,16 @@ public class ImageContent extends AbstractStructuredObject { * @return byte[] The data stream. */ private byte[] getIDEStructureParameter() { + byte flags = 0x00; + if (subtractive) { + flags |= 1 << 7; + } if (colorModel != 0 && size == 24) { final byte bits = (byte)(size / 3); final byte[] ideStructData = new byte[] { (byte)0x9B, // ID 0x00, // Length - 0x00, // FLAGS + flags, // FLAGS 0x00, // Reserved colorModel, // COLOR MODEL 0x00, // Reserved @@ -260,6 +275,20 @@ public class ImageContent extends AbstractStructuredObject { }; ideStructData[1] = (byte)(ideStructData.length - 2); return ideStructData; + } else if (size == 1) { + final byte[] ideStructData = new byte[] { + (byte)0x9B, // ID + 0x00, // Length + flags, // FLAGS + 0x00, // Reserved + colorModel, // COLOR MODEL + 0x00, // Reserved + 0x00, // Reserved + 0x00, // Reserved + 1 + }; + ideStructData[1] = (byte)(ideStructData.length - 2); + return ideStructData; } return new byte[0]; } diff --git a/src/java/org/apache/fop/afp/ioca/ImageSegment.java b/src/java/org/apache/fop/afp/ioca/ImageSegment.java index 9fb544719..5ecbc63bb 100644 --- a/src/java/org/apache/fop/afp/ioca/ImageSegment.java +++ b/src/java/org/apache/fop/afp/ioca/ImageSegment.java @@ -114,6 +114,14 @@ public class ImageSegment extends AbstractNamedAFPObject { } /** + * Set either additive or subtractive mode (used for ASFLAG). + * @param subtractive true for subtractive mode, false for additive mode + */ + public void setSubtractive(boolean subtractive) { + getImageContent().setSubtractive(subtractive); + } + + /** * Set the data image data. * * @param data the image data diff --git a/src/java/org/apache/fop/afp/modca/AbstractPageObject.java b/src/java/org/apache/fop/afp/modca/AbstractPageObject.java index 8ad8308a7..60dea2dde 100644 --- a/src/java/org/apache/fop/afp/modca/AbstractPageObject.java +++ b/src/java/org/apache/fop/afp/modca/AbstractPageObject.java @@ -60,9 +60,6 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen /** The list of tag logical elements */ protected List/*<TagLogicalElement>*/ tagLogicalElements = null; - /** The list of the include page segments */ - protected List/*<IncludePageSegment>*/ includePageSegments = null; - /** The list of objects within this resource container */ protected List/*<AbstractStructuredAFPObject>*/ objects = new java.util.ArrayList(); @@ -253,19 +250,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen */ public void createIncludePageSegment(String name, int x, int y) { IncludePageSegment ips = factory.createIncludePageSegment(name, x, y); - getIncludePageSegments().add(ips); - } - - /** - * Returns the include page segments list - * - * @return the include page segments list - */ - private List getIncludePageSegments() { - if (this.includePageSegments == null) { - this.includePageSegments = new java.util.ArrayList/*<IncludePageSegment>*/(); - } - return this.includePageSegments; + addObject(ips); } /** diff --git a/src/java/org/apache/fop/afp/modca/ImageObject.java b/src/java/org/apache/fop/afp/modca/ImageObject.java index 24ac0cb22..b11d478cc 100644 --- a/src/java/org/apache/fop/afp/modca/ImageObject.java +++ b/src/java/org/apache/fop/afp/modca/ImageObject.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.OutputStream; import org.apache.commons.io.output.ByteArrayOutputStream; + import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPImageObjectInfo; import org.apache.fop.afp.Factory; @@ -114,9 +115,17 @@ public class ImageObject extends AbstractDataObject { } /** + * Set either additive or subtractive mode (used for ASFLAG). + * @param subtractive true for subtractive mode, false for additive mode + */ + public void setSubtractive(boolean subtractive) { + getImageSegment().setSubtractive(subtractive); + } + + /** * Set the data of the image. * - * @param data the image data + * @param imageData the image data */ public void setData(byte[] imageData) { getImageSegment().setData(imageData); diff --git a/src/java/org/apache/fop/afp/modca/Overlay.java b/src/java/org/apache/fop/afp/modca/Overlay.java index ea9619b20..0179c94a7 100644 --- a/src/java/org/apache/fop/afp/modca/Overlay.java +++ b/src/java/org/apache/fop/afp/modca/Overlay.java @@ -72,7 +72,6 @@ public class Overlay extends PageObject { getActiveEnvironmentGroup().writeToStream(os); - writeObjects(includePageSegments, os); writeObjects(tagLogicalElements, os); writeObjects(objects, os); } diff --git a/src/java/org/apache/fop/afp/modca/PageObject.java b/src/java/org/apache/fop/afp/modca/PageObject.java index 33852d90b..6c2547f0b 100644 --- a/src/java/org/apache/fop/afp/modca/PageObject.java +++ b/src/java/org/apache/fop/afp/modca/PageObject.java @@ -185,7 +185,6 @@ public class PageObject extends AbstractResourceGroupContainer { getActiveEnvironmentGroup().writeToStream(os); - writeObjects(includePageSegments, os); writeObjects(tagLogicalElements, os); writeObjects(objects, os); } diff --git a/src/java/org/apache/fop/area/AreaTreeObject.java b/src/java/org/apache/fop/area/AreaTreeObject.java index 5929e7c4e..bab27f411 100644 --- a/src/java/org/apache/fop/area/AreaTreeObject.java +++ b/src/java/org/apache/fop/area/AreaTreeObject.java @@ -26,6 +26,8 @@ import java.util.Map; import org.apache.xmlgraphics.util.QName; +import org.apache.fop.fo.extensions.ExtensionAttachment; + /** * Abstract base class for all area tree objects. */ @@ -36,7 +38,7 @@ public abstract class AreaTreeObject { /** Extension attachments */ protected List/*<ExtensionAttachment>*/ extensionAttachments = null; - + /** * Sets a foreign attribute. * @param name the qualified name of the attribute @@ -87,21 +89,46 @@ public abstract class AreaTreeObject { return Collections.EMPTY_MAP; } } - + + private void prepareExtensionAttachmentContainer() { + if (this.extensionAttachments == null) { + this.extensionAttachments = new java.util.ArrayList/*<ExtensionAttachment>*/(); + } + } + /** - * Set extension attachments from a List + * Adds a new ExtensionAttachment instance to this page. + * @param attachment the ExtensionAttachment + */ + public void addExtensionAttachment(ExtensionAttachment attachment) { + prepareExtensionAttachmentContainer(); + extensionAttachments.add(attachment); + } + + /** + * Set extension attachments from a List * @param extensionAttachments a List with extension attachments */ public void setExtensionAttachments(List extensionAttachments) { - this.extensionAttachments = extensionAttachments; + prepareExtensionAttachmentContainer(); + this.extensionAttachments.addAll(extensionAttachments); } /** @return the extension attachments associated with this area */ public List getExtensionAttachments() { - if (this.foreignAttributes != null) { + if (this.extensionAttachments != null) { return Collections.unmodifiableList(this.extensionAttachments); } else { return Collections.EMPTY_LIST; } - } + } + + /** + * Indicates whether this area tree object has any extension attachments. + * @return true if there are extension attachments + */ + public boolean hasExtensionAttachments() { + return this.extensionAttachments != null && !this.extensionAttachments.isEmpty(); + } + } diff --git a/src/java/org/apache/fop/area/PageViewport.java b/src/java/org/apache/fop/area/PageViewport.java index a7523530b..321ca4c03 100644 --- a/src/java/org/apache/fop/area/PageViewport.java +++ b/src/java/org/apache/fop/area/PageViewport.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -36,7 +35,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.fo.Constants; -import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fo.pagination.SimplePageMaster; /** @@ -87,10 +85,6 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl private Map markerLastEnd = null; private Map markerLastAny = null; - //Arbitrary attachments to the page from extensions that need to pass information - //down to the renderers. - private List/*<ExtensionAttachment>*/ extensionAttachments = null; - /** * logging instance */ @@ -105,7 +99,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl */ public PageViewport(SimplePageMaster spm, int pageNumber, String pageStr, boolean blank) { this.simplePageMasterName = spm.getMasterName(); - this.extensionAttachments = spm.getExtensionAttachments(); + setExtensionAttachments(spm.getExtensionAttachments()); this.blank = blank; int pageWidth = spm.getPageWidth().getValue(); int pageHeight = spm.getPageHeight().getValue(); @@ -122,8 +116,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl */ public PageViewport(PageViewport original) { if (original.extensionAttachments != null) { - this.extensionAttachments - = new java.util.ArrayList/*<ExtensionAttachment>*/(original.extensionAttachments); + setExtensionAttachments(original.extensionAttachments); } this.pageIndex = original.pageIndex; this.pageNumber = original.pageNumber; @@ -583,26 +576,6 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl return this.simplePageMasterName; } - /** - * Adds a new ExtensionAttachment instance to this page. - * @param attachment the ExtensionAttachment - */ - public void addExtensionAttachment(ExtensionAttachment attachment) { - if (this.extensionAttachments == null) { - this.extensionAttachments = new java.util.ArrayList/*<ExtensionAttachment>*/(); - } - extensionAttachments.add(attachment); - } - - /** @return the list of extension attachments for this page */ - public List getExtensionAttachments() { - if (this.extensionAttachments == null) { - return Collections.EMPTY_LIST; - } else { - return this.extensionAttachments; - } - } - /** @return True if this is a blank page. */ public boolean isBlank() { return this.blank; @@ -671,8 +644,4 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl return getPage().getRegionViewport(id).getRegionReference(); } - /** @return whether this page viewport has any extension attachments */ - public boolean hasExtensionAttachments() { - return this.extensionAttachments != null && !this.extensionAttachments.isEmpty(); - } } diff --git a/src/java/org/apache/fop/events/model/package.html b/src/java/org/apache/fop/events/model/package.html new file mode 100644 index 000000000..4d915721b --- /dev/null +++ b/src/java/org/apache/fop/events/model/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + 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. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<HTML> +<TITLE>org.apache.fop.events.model Package</TITLE> +<BODY> +<P>Model classes for the event subsystem.</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/src/java/org/apache/fop/events/package.html b/src/java/org/apache/fop/events/package.html new file mode 100644 index 000000000..d2e6d63de --- /dev/null +++ b/src/java/org/apache/fop/events/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + 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. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<HTML> +<TITLE>org.apache.fop.events Package</TITLE> +<BODY> +<P>Subsystem for reporting events inside FOP to client applications.</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/substitute/package.html b/src/java/org/apache/fop/fonts/substitute/package.html new file mode 100644 index 000000000..c144ca1f8 --- /dev/null +++ b/src/java/org/apache/fop/fonts/substitute/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + 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. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<HTML> +<TITLE>org.apache.fop.fonts.substitute Package</TITLE> +<BODY> +<P>Font substitution facilities.</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java b/src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java index ea92f748b..62aba3790 100644 --- a/src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java +++ b/src/java/org/apache/fop/image/loader/batik/Graphics2DImagePainterImpl.java @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + package org.apache.fop.image.loader.batik; import java.awt.Dimension; @@ -10,7 +29,7 @@ import org.apache.batik.gvt.GraphicsNode; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** - * A generic graphics 2D image painter implementation + * A graphics 2D image painter implementation for painting SVG images using Batik. */ public class Graphics2DImagePainterImpl implements Graphics2DImagePainter { diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java index a618b9edc..354dbef90 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java @@ -20,10 +20,13 @@ package org.apache.fop.render.afp; import java.awt.Rectangle; +import java.awt.image.ColorModel; import java.awt.image.RenderedImage; import java.io.IOException; import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; @@ -37,12 +40,16 @@ import org.apache.fop.afp.AFPObjectAreaInfo; import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.render.ImageHandler; import org.apache.fop.render.RenderingContext; +import org.apache.fop.util.BitmapImageUtil; /** * PDFImageHandler implementation which handles RenderedImage instances. */ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements ImageHandler { + /** logging instance */ + private static Log log = LogFactory.getLog(AFPImageHandlerRenderedImage.class); + private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE @@ -82,29 +89,74 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima int dataWidth = renderedImage.getWidth(); imageObjectInfo.setDataWidth(dataWidth); - //TODO This needs to be improved: Buffering whole images in memory is bad. - //Images with fewer bits per pixel than the required output format are unnecessarily - //increased in size (extreme case: 1-bit images are blown up to 24 bits if color is - //enabled). For grayscale output, encoding is even a two-step process which - //needs to be streamlined to a single step. The resulting bitmap is then still buffered - //in memory. To reduce AFP file size, investigate using a compression scheme. + //TODO To reduce AFP file size, investigate using a compression scheme. //Currently, all image data is uncompressed. + + int maxPixelSize = paintingState.getBitsPerPixel(); + if (paintingState.isColorImages()) { + maxPixelSize *= 3; //RGB only at the moment + } + + ColorModel cm = renderedImage.getColorModel(); + if (log.isTraceEnabled()) { + log.trace("ColorModel: " + cm); + } + int pixelSize = cm.getPixelSize(); + if (cm.hasAlpha()) { + pixelSize -= 8; + } + //TODO Add support for CMYK images + + byte[] imageData = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, baos); - byte[] imageData = baos.toByteArray(); - - boolean colorImages = paintingState.isColorImages(); - imageObjectInfo.setColor(colorImages); - - // convert to grayscale - if (!colorImages) { - baos.reset(); - int bitsPerPixel = paintingState.getBitsPerPixel(); - imageObjectInfo.setBitsPerPixel(bitsPerPixel); - ImageEncodingHelper.encodeRGBAsGrayScale( - imageData, dataWidth, dataHeight, bitsPerPixel, baos); + boolean allowDirectEncoding = true; + if (allowDirectEncoding && pixelSize <= maxPixelSize) { + //Attempt to encode without resampling the image + ImageEncodingHelper helper = new ImageEncodingHelper(renderedImage); + ColorModel encodedColorModel = helper.getEncodedColorModel(); + boolean directEncode = true; + if (helper.getEncodedColorModel().getPixelSize() > maxPixelSize) { + directEncode = false; //pixel size needs to be reduced + } + if (BitmapImageUtil.getColorIndexSize(renderedImage) > 2) { + directEncode = false; //Lookup tables are not implemented, yet + } + if (directEncode) { + log.debug("Encoding image directly..."); + imageObjectInfo.setBitsPerPixel(encodedColorModel.getPixelSize()); + if (BitmapImageUtil.isMonochromeImage(renderedImage) + && !BitmapImageUtil.isZeroBlack(renderedImage)) { + log.trace("set subtractive mode"); + imageObjectInfo.setSubtractive(true); + } + + helper.encode(baos); + imageData = baos.toByteArray(); + } + } + if (imageData == null) { + log.debug("Encoding image via RGB..."); + //Convert image to 24bit RGB + ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, baos); imageData = baos.toByteArray(); + + boolean colorImages = paintingState.isColorImages(); + imageObjectInfo.setColor(colorImages); + + // convert to grayscale + if (!colorImages) { + log.debug("Converting RGB image to grayscale..."); + baos.reset(); + int bitsPerPixel = paintingState.getBitsPerPixel(); + imageObjectInfo.setBitsPerPixel(bitsPerPixel); + //TODO this should be done off the RenderedImage to avoid buffering the + //intermediate 24bit image + ImageEncodingHelper.encodeRGBAsGrayScale( + imageData, dataWidth, dataHeight, bitsPerPixel, baos); + imageData = baos.toByteArray(); + } } + imageObjectInfo.setData(imageData); // set object area info diff --git a/src/java/org/apache/fop/render/pcl/PCLGenerator.java b/src/java/org/apache/fop/render/pcl/PCLGenerator.java index 67dcce1fb..6ae3a9eff 100644 --- a/src/java/org/apache/fop/render/pcl/PCLGenerator.java +++ b/src/java/org/apache/fop/render/pcl/PCLGenerator.java @@ -47,6 +47,8 @@ import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.xmlgraphics.image.GraphicsUtil; import org.apache.xmlgraphics.util.UnitConv; +import org.apache.fop.util.BitmapImageUtil; + /** * This class provides methods for generating PCL print files. */ @@ -534,7 +536,7 @@ public class PCLGenerator { * @return the gray value */ public final int convertToGray(int r, int g, int b) { - return (r * 30 + g * 59 + b * 11) / 100; + return BitmapImageUtil.convertToGray(r, g, b); } /** @@ -586,14 +588,8 @@ public class PCLGenerator { * @return true if it's a monochrome image */ public static boolean isMonochromeImage(RenderedImage img) { - ColorModel cm = img.getColorModel(); - if (cm instanceof IndexColorModel) { - IndexColorModel icm = (IndexColorModel)cm; - return icm.getMapSize() == 2; - } else { - return false; + return BitmapImageUtil.isMonochromeImage(img); } - } /** * Indicates whether an image is a grayscale image. @@ -601,7 +597,7 @@ public class PCLGenerator { * @return true if it's a grayscale image */ public static boolean isGrayscaleImage(RenderedImage img) { - return (img.getColorModel().getNumColorComponents() == 1); + return BitmapImageUtil.isGrayscaleImage(img); } private static int jaiAvailable = -1; //no synchronization necessary, not critical @@ -816,21 +812,8 @@ public class PCLGenerator { } } if (src == null) { - src = new BufferedImage(effDim.width, effDim.height, - BufferedImage.TYPE_BYTE_GRAY); - Graphics2D g2d = src.createGraphics(); - try { - clearBackground(g2d, effDim); - - AffineTransform at = new AffineTransform(); - double sx = effDim.getWidth() / orgDim.getWidth(); - double sy = effDim.getHeight() / orgDim.getHeight(); - at.scale(sx, sy); - g2d.drawRenderedImage(img, at); - } finally { - g2d.dispose(); + src = BitmapImageUtil.convertToGrayscale(img, effDim); } - } MonochromeBitmapConverter converter = createMonochromeBitmapConverter(); converter.setHint("quality", "false"); @@ -841,23 +824,10 @@ public class PCLGenerator { setTransparencyMode(sourceTransparency || mask != null, true); paintMonochromeBitmap(red, effResolution); } else { - //TODO untested! RenderedImage effImg = img; if (scaled) { - BufferedImage buf = new BufferedImage(effDim.width, effDim.height, - BufferedImage.TYPE_BYTE_BINARY); - Graphics2D g2d = buf.createGraphics(); - try { - AffineTransform at = new AffineTransform(); - double sx = effDim.getWidth() / orgDim.getWidth(); - double sy = effDim.getHeight() / orgDim.getHeight(); - at.scale(sx, sy); - g2d.drawRenderedImage(img, at); - } finally { - g2d.dispose(); + effImg = BitmapImageUtil.convertToMonochrome(img, effDim); } - effImg = buf; - } setSourceTransparencyMode(sourceTransparency); selectCurrentPattern(0, 0); //Solid black paintMonochromeBitmap(effImg, effResolution); diff --git a/src/java/org/apache/fop/servlet/FopServlet.java b/src/java/org/apache/fop/servlet/FopServlet.java index 9b2326032..304cf21b9 100644 --- a/src/java/org/apache/fop/servlet/FopServlet.java +++ b/src/java/org/apache/fop/servlet/FopServlet.java @@ -37,11 +37,10 @@ import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.commons.logging.impl.SimpleLog; +import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; @@ -78,8 +77,6 @@ public class FopServlet extends HttpServlet { /** Name of the parameter used for the XSLT file */ protected static final String XSLT_REQUEST_PARAM = "xslt"; - /** Logger to give to FOP */ - protected SimpleLog log = null; /** The TransformerFactory used to create Transformer instances */ protected TransformerFactory transFactory = null; /** The FopFactory used to create Fop instances */ @@ -91,8 +88,6 @@ public class FopServlet extends HttpServlet { * {@inheritDoc} */ public void init() throws ServletException { - this.log = new SimpleLog("FOP/Servlet"); - log.setLevel(SimpleLog.LOG_LEVEL_WARN); this.uriResolver = new ServletContextURIResolver(getServletContext()); this.transFactory = TransformerFactory.newInstance(); this.transFactory.setURIResolver(this.uriResolver); diff --git a/src/java/org/apache/fop/text/linebreak/package.html b/src/java/org/apache/fop/text/linebreak/package.html new file mode 100644 index 000000000..3eca305f0 --- /dev/null +++ b/src/java/org/apache/fop/text/linebreak/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + 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. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<HTML> +<TITLE>org.apache.fop.text.linebreak Package</TITLE> +<BODY> +<P>Unicode linebreaking algorithm.</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/src/java/org/apache/fop/util/BitmapImageUtil.java b/src/java/org/apache/fop/util/BitmapImageUtil.java new file mode 100644 index 000000000..5805b8521 --- /dev/null +++ b/src/java/org/apache/fop/util/BitmapImageUtil.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.util; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.RenderedImage; + +/** + * Utility method for dealing with bitmap images. + */ +public class BitmapImageUtil { + + /** + * Indicates whether an image is a monochrome (1 bit black and white) image. + * @param img the image + * @return true if it's a monochrome image + */ + public static final boolean isMonochromeImage(RenderedImage img) { + return (getColorIndexSize(img) == 2); + } + + /** + * Indicates whether a zero bit indicates a black/dark pixel for a monochrome image. + * @param img the image (must be 1 bit monochrome) + * @return true if a zero bit indicates a black/dark pixel, false for a white/bright pixel + */ + public static final boolean isZeroBlack(RenderedImage img) { + if (!isMonochromeImage(img)) { + throw new IllegalArgumentException("Image is not a monochrome image!"); + } + IndexColorModel icm = (IndexColorModel)img.getColorModel(); + int gray0 = convertToGray(icm.getRGB(0)); + int gray1 = convertToGray(icm.getRGB(1)); + return gray0 < gray1; + } + + /** + * Convert an RGB color value to a grayscale from 0 to 100. + * @param r the red component + * @param g the green component + * @param b the blue component + * @return the gray value + */ + public static final int convertToGray(int r, int g, int b) { + return (r * 30 + g * 59 + b * 11) / 100; + } + + /** + * Convert an RGB color value to a grayscale from 0 to 100. + * @param rgb the RGB value + * @return the gray value + */ + public static final int convertToGray(int rgb) { + int r = (rgb & 0xFF0000) >> 16; + int g = (rgb & 0xFF00) >> 8; + int b = rgb & 0xFF; + return convertToGray(r, g, b); + } + + /** + * Returns the size of the color index if the given image has one. + * @param img the image + * @return the size of the color index or 0 if there's no color index + */ + public static final int getColorIndexSize(RenderedImage img) { + ColorModel cm = img.getColorModel(); + if (cm instanceof IndexColorModel) { + IndexColorModel icm = (IndexColorModel)cm; + return icm.getMapSize(); + } else { + return 0; + } + } + + /** + * Indicates whether an image is a grayscale image. + * @param img the image + * @return true if it's a grayscale image + */ + public static final boolean isGrayscaleImage(RenderedImage img) { + return (img.getColorModel().getNumColorComponents() == 1); + } + + /** + * Converts an image to sRGB. Optionally, the image can be scaled. + * @param img the image to be converted + * @param targetDimension the new target dimensions or null if no scaling is necessary + * @return the sRGB image + */ + public static final BufferedImage convertTosRGB(RenderedImage img, + Dimension targetDimension) { + return convertAndScaleImage(img, targetDimension, BufferedImage.TYPE_INT_RGB); + } + + /** + * Converts an image to a grayscale (8 bits) image. Optionally, the image can be scaled. + * @param img the image to be converted + * @param targetDimension the new target dimensions or null if no scaling is necessary + * @return the grayscale image + */ + public static final BufferedImage convertToGrayscale(RenderedImage img, + Dimension targetDimension) { + return convertAndScaleImage(img, targetDimension, BufferedImage.TYPE_BYTE_GRAY); + } + + /** + * Converts an image to a monochrome 1-bit image. Optionally, the image can be scaled. + * @param img the image to be converted + * @param targetDimension the new target dimensions or null if no scaling is necessary + * @return the monochrome image + */ + public static final BufferedImage convertToMonochrome(RenderedImage img, + Dimension targetDimension) { + return convertAndScaleImage(img, targetDimension, BufferedImage.TYPE_BYTE_BINARY); + } + + private static BufferedImage convertAndScaleImage(RenderedImage img, + Dimension targetDimension, int imageType) { + Dimension bmpDimension = targetDimension; + if (bmpDimension == null) { + bmpDimension = new Dimension(img.getWidth(), img.getHeight()); + } + BufferedImage target = new BufferedImage(bmpDimension.width, bmpDimension.height, + imageType); + transferImage(img, target); + return target; + } + + private static void transferImage(RenderedImage source, BufferedImage target) { + Graphics2D g2d = target.createGraphics(); + try { + g2d.setBackground(Color.white); + g2d.setColor(Color.black); + g2d.clearRect(0, 0, target.getWidth(), target.getHeight()); + + AffineTransform at = new AffineTransform(); + if (source.getWidth() != target.getWidth() + || source.getHeight() != target.getHeight()) { + double sx = target.getWidth() / (double)source.getWidth(); + double sy = target.getHeight() / (double)source.getHeight(); + at.scale(sx, sy); + } + g2d.drawRenderedImage(source, at); + } finally { + g2d.dispose(); + } + } + + +} diff --git a/src/java/org/apache/fop/util/text/package.html b/src/java/org/apache/fop/util/text/package.html new file mode 100644 index 000000000..e8ba8044f --- /dev/null +++ b/src/java/org/apache/fop/util/text/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + 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. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<HTML> +<TITLE>org.apache.fop.util.text Package</TITLE> +<BODY> +<P>Message formatting classes.</P> +</BODY> +</HTML>
\ No newline at end of file |