From 4ee77618596ee10c97e368add8f7a883d3cf0c8a Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Fri, 4 Jun 2010 09:03:57 +0000 Subject: Bugfix for formatting of floating point numbers which could lead to invalid PDFs. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@951333 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/pdf/PDFNumber.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/java/org/apache') diff --git a/src/java/org/apache/fop/pdf/PDFNumber.java b/src/java/org/apache/fop/pdf/PDFNumber.java index 3c103f3f2..5bc648ced 100644 --- a/src/java/org/apache/fop/pdf/PDFNumber.java +++ b/src/java/org/apache/fop/pdf/PDFNumber.java @@ -88,7 +88,7 @@ public class PDFNumber extends PDFObject { if (hasObjectNumber()) { sb.append(getObjectID()); } - sb.append(getNumber().toString()); + sb.append(doubleOut(getNumber().doubleValue(), 10)); if (hasObjectNumber()) { sb.append("\nendobj\n"); } -- cgit v1.2.3 From e3d79c1a636ec9a35082db9ea151b5953d3e9cad Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 8 Jun 2010 19:01:56 +0000 Subject: Bugzilla #42306: Fix for AWT viewer to correctly track page numbers in continuous display mode. Submitted by: Richard Wheeldon Modifications to original patch: - Small adjustments for out code conventions. - Added some missing Javadocs. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@952770 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/render/awt/viewer/PageChangeEvent.java | 61 ++++++++++++++++++++++ .../fop/render/awt/viewer/PageChangeListener.java | 36 +++++++++++++ .../fop/render/awt/viewer/PreviewDialog.java | 21 ++++++-- .../apache/fop/render/awt/viewer/PreviewPanel.java | 60 +++++++++++++++++++++ status.xml | 3 ++ 5 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 src/java/org/apache/fop/render/awt/viewer/PageChangeEvent.java create mode 100644 src/java/org/apache/fop/render/awt/viewer/PageChangeListener.java (limited to 'src/java/org/apache') diff --git a/src/java/org/apache/fop/render/awt/viewer/PageChangeEvent.java b/src/java/org/apache/fop/render/awt/viewer/PageChangeEvent.java new file mode 100644 index 000000000..045ce7fe4 --- /dev/null +++ b/src/java/org/apache/fop/render/awt/viewer/PageChangeEvent.java @@ -0,0 +1,61 @@ +/* + * 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.render.awt.viewer; + +import java.util.EventObject; + +/** + * Swing event fired whenever the current page selection of a + * {@link PreviewPanel} changes. Page numbers are 0-based. + */ +public class PageChangeEvent extends EventObject { + + private int oldPage; + private int newPage; + + /** + * Creates an new page change event. + * @param panel the preview panel the event is produced for. + * @param oldPage the old page (zero based) + * @param newPage the new page (zero based) + */ + public PageChangeEvent(PreviewPanel panel, int oldPage, int newPage) { + super(panel); + this.oldPage = oldPage; + this.newPage = newPage; + } + + /** + * Returns the new page. + * @return the new page (zero based) + */ + public int getNewPage() { + return newPage; + } + + /** + * Returns the old page. + * @return the old page (zero based) + */ + public int getOldPage() { + return oldPage; + } + +} diff --git a/src/java/org/apache/fop/render/awt/viewer/PageChangeListener.java b/src/java/org/apache/fop/render/awt/viewer/PageChangeListener.java new file mode 100644 index 000000000..b350f891d --- /dev/null +++ b/src/java/org/apache/fop/render/awt/viewer/PageChangeListener.java @@ -0,0 +1,36 @@ +/* + * 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.render.awt.viewer; + +import java.util.EventListener; + +/** + * Swing listener interface for classes which wish to receive + * notification of page change events. + */ +public interface PageChangeListener extends EventListener { + + /** + * Called whenever the current page is changed. + * @param pce the page change event + */ + void pageChanged(PageChangeEvent pce); + +} diff --git a/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java b/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java index e3f510853..031021a6f 100644 --- a/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java +++ b/src/java/org/apache/fop/render/awt/viewer/PreviewDialog.java @@ -171,6 +171,11 @@ public class PreviewDialog extends JFrame implements StatusListener { //Page view stuff previewPanel = new PreviewPanel(foUserAgent, renderable, renderer); getContentPane().add(previewPanel, BorderLayout.CENTER); + previewPanel.addPageChangeListener(new PageChangeListener() { + public void pageChanged(PageChangeEvent pce) { + new ShowInfo().run(); + } + }); // Keyboard shortcuts - pgup/pgdn InputMap im = previewPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); @@ -260,6 +265,7 @@ public class PreviewDialog extends JFrame implements StatusListener { * Creates and initialize the AWT Viewer main window. * @param foUserAgent the FO user agent * @param renderable the target for the rendering + * @param asMainWindow true if the window shall act as the main application window. * @return the newly initialized preview dialog */ public static PreviewDialog createPreviewDialog(FOUserAgent foUserAgent, @@ -530,12 +536,18 @@ public class PreviewDialog extends JFrame implements StatusListener { goToPage(currentPage); } - /** Scales page image */ + /** + * Scales page image. + * @param scaleFactor the scale factor + */ public void setScale(double scaleFactor) { scale.setSelectedItem(percentFormat.format(scaleFactor) + "%"); previewPanel.setScaleFactor(scaleFactor / 100d); } + /** + * Sets the scaling so the contents fit into the window. + */ public void setScaleToFitWindow() { try { setScale(previewPanel.getScaleToFitWindow() * 100); @@ -544,6 +556,9 @@ public class PreviewDialog extends JFrame implements StatusListener { } } + /** + * Sets the scaling so the contents are spread over the whole width available. + */ public void setScaleToFitWidth() { try { setScale(previewPanel.getScaleToFitWidth() * 100); @@ -569,7 +584,7 @@ public class PreviewDialog extends JFrame implements StatusListener { //Restore originally configured target resolution float saveResolution = foUserAgent.getTargetResolution(); foUserAgent.setTargetResolution(this.configuredTargetResolution); - + PrinterJob pj = PrinterJob.getPrinterJob(); pj.setPageable(renderer); if (!showDialog || pj.printDialog()) { @@ -579,7 +594,7 @@ public class PreviewDialog extends JFrame implements StatusListener { e.printStackTrace(); } } - + foUserAgent.setTargetResolution(saveResolution); } diff --git a/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java b/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java index f8152a978..2303c0e8e 100644 --- a/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java +++ b/src/java/org/apache/fop/render/awt/viewer/PreviewPanel.java @@ -19,11 +19,14 @@ package org.apache.fop.render.awt.viewer; +import java.awt.Adjustable; import java.awt.Color; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Point; import java.awt.Toolkit; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; @@ -166,6 +169,8 @@ public class PreviewPanel extends JPanel { previewArea = new JScrollPane(gridPanel); previewArea.getViewport().setBackground(Color.gray); + previewArea.getVerticalScrollBar().addAdjustmentListener(new PageNumberListener()); + // FIXME should add scroll wheel support here at some point. scroller = new ViewportScroller(previewArea.getViewport()); previewArea.addMouseListener(scroller); @@ -188,6 +193,7 @@ public class PreviewPanel extends JPanel { * @param number the page number */ public void setPage(int number) { + int oldPage = currentPage; if (displayMode == CONTINUOUS || displayMode == CONT_FACING) { currentPage = number; gridPanel.scrollRectToVisible(pagePanels[currentPage].getBounds()); @@ -196,6 +202,7 @@ public class PreviewPanel extends JPanel { firstPage = currentPage; } showPage(); + firePageChange(oldPage, currentPage); } /** @@ -236,6 +243,42 @@ public class PreviewPanel extends JPanel { reload(); } + /** + * Add a listener to receive notification of page change events. Events will + * be fired whenever the currentPage value is changed. The values recorded + * are 0-based. + * @param l the page change listener to add + */ + public void addPageChangeListener(PageChangeListener l) { + listenerList.add(PageChangeListener.class, l); + } + + /** + * Removes a page change listener. + * @param l the page change listener to remove + */ + public void removePageChangeListener(PageChangeListener l) { + listenerList.remove(PageChangeListener.class, l); + } + + /** + * Notify all registered listeners of a page change event. + * @param oldPage the old page + * @param newPage the new page + */ + protected void firePageChange(int oldPage, int newPage) { + Object[] listeners = listenerList.getListenerList(); + PageChangeEvent e = null; + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == PageChangeListener.class) { + if (e == null) { + e = new PageChangeEvent(this, newPage, oldPage); + } + ((PageChangeListener)listeners[i + 1]).pageChanged(e); + } + } + } + /** * Allows any mouse drag on the page area to scroll the display window. */ @@ -352,6 +395,23 @@ public class PreviewPanel extends JPanel { } } + private class PageNumberListener implements AdjustmentListener { + public void adjustmentValueChanged(AdjustmentEvent e) { + if (displayMode == PreviewPanel.CONTINUOUS || displayMode == PreviewPanel.CONT_FACING) { + Adjustable a = e.getAdjustable(); + int value = +e.getValue(); + int min = a.getMinimum(); + int max = a.getMaximum(); + int page = ( (renderer.getNumberOfPages() * value) / (max - min) ); + if (page != currentPage) { + int oldPage = currentPage; + currentPage = page; + firePageChange(oldPage, currentPage); + } + } + } + } + /** * Scales page image * @param scale [0;1] diff --git a/status.xml b/status.xml index f309c8f45..acc40d878 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,9 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Fix for AWT viewer to correctly track page numbers in continuous display mode. + Bugfix for formatting of floating point numbers which could lead to invalid PDFs. -- cgit v1.2.3 From 1fae69d5fdafcf8ba313087e5afa67d203af6482 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Fri, 11 Jun 2010 12:31:45 +0000 Subject: AFP Output: Fix for bitmap images inside an SVG or G2D graphic (printer errors) and positioning fix for bitmaps from G2D graphics. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@953684 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/afp/AFPGraphics2D.java | 27 +++++++++----------------- status.xml | 4 ++++ 2 files changed, 13 insertions(+), 18 deletions(-) (limited to 'src/java/org/apache') diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java index fdfde8cca..b8d7158cf 100644 --- a/src/java/org/apache/fop/afp/AFPGraphics2D.java +++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java @@ -584,6 +584,10 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand int dataWidth = renderedImage.getWidth(); imageObjectInfo.setDataWidth(dataWidth); + int resolution = paintingState.getResolution(); + imageObjectInfo.setDataWidthRes(resolution); + imageObjectInfo.setDataHeightRes(resolution); + boolean colorImages = paintingState.isColorImages(); imageObjectInfo.setColor(colorImages); @@ -598,6 +602,10 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand ImageEncodingHelper.encodeRGBAsGrayScale( imageData, dataWidth, dataHeight, bitsPerPixel, boas); imageData = boas.toByteArray(); + if (bitsPerPixel == 1) { + //FS10 should generate a page seqment to avoid problems + imageObjectInfo.setCreatePageSegment(true); + } } imageObjectInfo.setData(imageData); @@ -612,7 +620,6 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand objectAreaInfo.setWidth(width); objectAreaInfo.setHeight(height); - int resolution = paintingState.getResolution(); objectAreaInfo.setWidthRes(resolution); objectAreaInfo.setHeightRes(resolution); @@ -667,23 +674,7 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand boolean drawn = drawBufferedImage(img, bufferedImage, width, height, observer); if (drawn) { - AffineTransform at = gc.getTransform(); - float[] srcPts = new float[] {x, y}; - float[] dstPts = new float[srcPts.length]; - at.transform(srcPts, 0, dstPts, 0, 1); - x = Math.round(dstPts[X]); - y = Math.round(dstPts[Y]); - try { - // get image object info - AFPImageObjectInfo imageObjectInfo - = createImageObjectInfo(bufferedImage, x, y, width, height); - - // create image resource - resourceManager.createObject(imageObjectInfo); - return true; - } catch (IOException ioe) { - handleIOException(ioe); - } + drawRenderedImage(bufferedImage, new AffineTransform()); } return false; } diff --git a/status.xml b/status.xml index acc40d878..f933e8a64 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,10 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + AFP Output: Fix for bitmap images inside an SVG or G2D graphic (printer errors) and + positioning fix for bitmaps from G2D graphics. + Fix for AWT viewer to correctly track page numbers in continuous display mode. -- cgit v1.2.3 From 97aa2c35b008616df914162cb398ee017cc5169c Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Sat, 12 Jun 2010 08:19:48 +0000 Subject: AFP Output Changes: - Fixed positioning of Java2D-based images (when GOCA is enabled). GraphicsDataDescriptor had a bit order bug. The Graphics2D image handler didn't save state and reposition the image origin. - Switched bitmap image handling in AFPGraphics2D to (re-)use AFPImageHandlerRenderedImage so it can profit from it's advanced image conversion functionality. This also avoids some bugs with certain image formats. - Added enhanced dithering functionality for images that need to be converted to bi-level images. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@953952 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/trunk/output.xml | 23 ++++- src/java/org/apache/fop/afp/AFPGraphics2D.java | 108 +++++---------------- src/java/org/apache/fop/afp/AFPPaintingState.java | 22 +++++ .../fop/afp/modca/GraphicsDataDescriptor.java | 4 +- .../org/apache/fop/render/afp/AFPCustomizable.java | 7 ++ .../apache/fop/render/afp/AFPDocumentHandler.java | 7 +- .../fop/render/afp/AFPImageHandlerGraphics2D.java | 9 ++ .../render/afp/AFPImageHandlerRenderedImage.java | 8 +- .../org/apache/fop/render/afp/AFPRenderer.java | 5 + .../fop/render/afp/AFPRendererConfigurator.java | 15 +++ .../apache/fop/util/bitmap/BitmapImageUtil.java | 47 +++++++++ status.xml | 7 ++ 12 files changed, 169 insertions(+), 93 deletions(-) (limited to 'src/java/org/apache') diff --git a/src/documentation/content/xdocs/trunk/output.xml b/src/documentation/content/xdocs/trunk/output.xml index 54ed357a0..7a91992ca 100644 --- a/src/documentation/content/xdocs/trunk/output.xml +++ b/src/documentation/content/xdocs/trunk/output.xml @@ -531,9 +531,10 @@ out = proc.getOutputStream();]]> latest features. We're trying to make AFP output work in as many environments as possible. However, to make AFP output work on older environments it is recommended to set to configuration to 1 bit per pixel (see below on how to do this). In this case, all images - are converted to bi-level images using IOCA function set 10 (FS10). If a higher number of - bits per pixel is configured, FOP has to switch to at least FS11 which may not work - everywhere. + are converted to bi-level images using IOCA function set 10 (FS10) and are enclosed in + page-segments since some implementation cannot deal with IOCA objects directly. + If a higher number of bits per pixel is configured, FOP has to switch to at least FS11 + which may not work everywhere.

@@ -724,8 +725,20 @@ Note that the value of the encoding attribute in the example is the double-byte colors. This will only have an effect if the color mode is set to "color". Example:

-]]> + ]]> +

+ When the color mode is set to 1 bit (bi-level), the "dithering-quality" attribute can + be used to select the level of quality to use when converting images to bi-level images. + Valid values for this attribute are floating point numbers from 0.0 (fastest) to + 1.0 (best), or special values: "minimum" (=0.0), "maximum" (1.0), + "medium" (0.5, the default). For the higher settings to work as expected, JAI needs to + be present in the classpath. If JAI is present, 0.0 results in a minimal darkness-level + switching between white and black. 0.5 does bayer-based dithering and 1.0 will use + error-diffusion dithering. The higher the value, the higher the quality and the slower + the processing of the images. +

+ ]]>
Shading diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java index b8d7158cf..fa9c0d7bf 100644 --- a/src/java/org/apache/fop/afp/AFPGraphics2D.java +++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java @@ -45,7 +45,6 @@ import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.io.IOException; -import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -56,8 +55,6 @@ import org.apache.xmlgraphics.java2d.AbstractGraphics2D; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.java2d.StrokingTextHandler; import org.apache.xmlgraphics.java2d.TextHandler; -import org.apache.xmlgraphics.ps.ImageEncodingHelper; -import org.apache.xmlgraphics.util.MimeConstants; import org.apache.xmlgraphics.util.UnitConv; import org.apache.fop.afp.goca.GraphicsSetLineType; @@ -65,6 +62,8 @@ import org.apache.fop.afp.modca.GraphicsObject; import org.apache.fop.afp.svg.AFPGraphicsConfiguration; import org.apache.fop.afp.util.CubicBezierApproximator; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.render.afp.AFPImageHandlerRenderedImage; +import org.apache.fop.render.afp.AFPRenderingContext; import org.apache.fop.svg.NativeImageHandler; /** @@ -559,75 +558,6 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand BufferedImage.TYPE_INT_ARGB); } - private AFPImageObjectInfo createImageObjectInfo( - RenderedImage img, int x, int y, int width, int height) throws IOException { - ImageInfo imageInfo = new ImageInfo(null, "image/unknown"); - ImageSize size = new ImageSize(img.getWidth(), img.getHeight(), 72); - imageInfo.setSize(size); - - ImageRendered imageRendered = new ImageRendered(imageInfo, img, null); - RenderedImage renderedImage = imageRendered.getRenderedImage(); - - // create image object info - AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo(); - - imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45); - - int bitsPerPixel = paintingState.getBitsPerPixel(); - imageObjectInfo.setBitsPerPixel(bitsPerPixel); - - imageObjectInfo.setResourceInfo(resourceInfo); - - int dataHeight = renderedImage.getHeight(); - imageObjectInfo.setDataHeight(dataHeight); - - int dataWidth = renderedImage.getWidth(); - imageObjectInfo.setDataWidth(dataWidth); - - int resolution = paintingState.getResolution(); - imageObjectInfo.setDataWidthRes(resolution); - imageObjectInfo.setDataHeightRes(resolution); - - boolean colorImages = paintingState.isColorImages(); - imageObjectInfo.setColor(colorImages); - - ByteArrayOutputStream boas = new ByteArrayOutputStream(); - ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, boas); - byte[] imageData = boas.toByteArray(); - - // convert to grayscale - if (!colorImages) { - boas.reset(); - imageObjectInfo.setBitsPerPixel(bitsPerPixel); - ImageEncodingHelper.encodeRGBAsGrayScale( - imageData, dataWidth, dataHeight, bitsPerPixel, boas); - imageData = boas.toByteArray(); - if (bitsPerPixel == 1) { - //FS10 should generate a page seqment to avoid problems - imageObjectInfo.setCreatePageSegment(true); - } - } - imageObjectInfo.setData(imageData); - - if (imageInfo != null) { - imageObjectInfo.setUri(imageInfo.getOriginalURI()); - } - - // create object area info - AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(); - objectAreaInfo.setX(x); - objectAreaInfo.setY(y); - objectAreaInfo.setWidth(width); - objectAreaInfo.setHeight(height); - - objectAreaInfo.setWidthRes(resolution); - objectAreaInfo.setHeightRes(resolution); - - imageObjectInfo.setObjectAreaInfo(objectAreaInfo); - - return imageObjectInfo; - } - /** * Draws an AWT image into a BufferedImage using an AWT Graphics2D implementation * @@ -667,7 +597,6 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand /** {@inheritDoc} */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { - // draw with AWT Graphics2D Dimension imageSize = new Dimension(width, height); BufferedImage bufferedImage = buildBufferedImage(imageSize); @@ -684,20 +613,33 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand int imgWidth = img.getWidth(); int imgHeight = img.getHeight(); - AffineTransform at = paintingState.getData().getTransform(); AffineTransform gat = gc.getTransform(); int graphicsObjectHeight = graphicsObj.getObjectEnvironmentGroup().getObjectAreaDescriptor().getHeight(); - int x = (int)Math.round(at.getTranslateX() + gat.getTranslateX()); - int y = (int)Math.round(at.getTranslateY() - (gat.getTranslateY() - graphicsObjectHeight)); - int width = (int)Math.round(imgWidth * gat.getScaleX()); - int height = (int)Math.round(imgHeight * -gat.getScaleY()); + + double toMillipointFactor = UnitConv.IN2PT * 1000 / (double)paintingState.getResolution(); + double x = gat.getTranslateX(); + double y = -(gat.getTranslateY() - graphicsObjectHeight); + x = toMillipointFactor * x; + y = toMillipointFactor * y; + double w = toMillipointFactor * imgWidth * gat.getScaleX(); + double h = toMillipointFactor * imgHeight * -gat.getScaleY(); + + AFPImageHandlerRenderedImage handler = new AFPImageHandlerRenderedImage(); + ImageInfo imageInfo = new ImageInfo(null, null); + imageInfo.setSize(new ImageSize( + img.getWidth(), img.getHeight(), paintingState.getResolution())); + imageInfo.getSize().calcSizeFromPixels(); + ImageRendered red = new ImageRendered(imageInfo, img, null); + Rectangle targetPos = new Rectangle( + (int)Math.round(x), + (int)Math.round(y), + (int)Math.round(w), + (int)Math.round(h)); + AFPRenderingContext context = new AFPRenderingContext(null, + resourceManager, paintingState, fontInfo, null); try { - // get image object info - AFPImageObjectInfo imageObjectInfo - = createImageObjectInfo(img, x, y, width, height); - // create image resource - resourceManager.createObject(imageObjectInfo); + handler.handleImage(context, red, targetPos); } catch (IOException ioe) { handleIOException(ioe); } diff --git a/src/java/org/apache/fop/afp/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java index a19874183..4e314e5d9 100644 --- a/src/java/org/apache/fop/afp/AFPPaintingState.java +++ b/src/java/org/apache/fop/afp/AFPPaintingState.java @@ -51,6 +51,9 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState /** color image support */ private boolean colorImages = false; + /** dithering quality setting (0.0f..1.0f) */ + private float ditheringQuality; + /** color image handler */ private ColorConverter colorConverter = GrayScaleColorConverter.getInstance(); @@ -233,6 +236,25 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState return this.cmykImagesSupported; } + /** + * Gets the dithering quality setting to use when converting images to monochrome images. + * @return the dithering quality (a value between 0.0f and 1.0f) + */ + public float getDitheringQuality() { + return this.ditheringQuality; + } + + /** + * Sets the dithering quality setting to use when converting images to monochrome images. + * @param quality Defines the desired quality level for the conversion. + * Valid values: a value between 0.0f (fastest) and 1.0f (best) + */ + public void setDitheringQuality(float quality) { + quality = Math.max(quality, 0.0f); + quality = Math.min(quality, 1.0f); + this.ditheringQuality = quality; + } + /** * Sets the output/device resolution * diff --git a/src/java/org/apache/fop/afp/modca/GraphicsDataDescriptor.java b/src/java/org/apache/fop/afp/modca/GraphicsDataDescriptor.java index 5495e2e9c..5fa3b70a9 100644 --- a/src/java/org/apache/fop/afp/modca/GraphicsDataDescriptor.java +++ b/src/java/org/apache/fop/afp/modca/GraphicsDataDescriptor.java @@ -104,8 +104,8 @@ public class GraphicsDataDescriptor extends AbstractDescriptor { return data; } - private static final int ABS = 2; - private static final int IMGRES = 8; + private static final int ABS = 64; + private static final int IMGRES = 16; /** * Returns the window specification data diff --git a/src/java/org/apache/fop/render/afp/AFPCustomizable.java b/src/java/org/apache/fop/render/afp/AFPCustomizable.java index 5f3fe6823..93aaa8b1a 100644 --- a/src/java/org/apache/fop/render/afp/AFPCustomizable.java +++ b/src/java/org/apache/fop/render/afp/AFPCustomizable.java @@ -64,6 +64,13 @@ public interface AFPCustomizable { */ void setShadingMode(AFPShadingMode shadingMode); + /** + * Sets the dithering quality setting to use when converting images to monochrome images. + * @param quality Defines the desired quality level for the conversion. + * Valid values: a value between 0.0f (fastest) and 1.0f (best) + */ + void setDitheringQuality(float quality); + /** * Sets the output/device resolution * diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java index 3fec25d8d..21d4faf56 100644 --- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java @@ -46,8 +46,8 @@ import org.apache.fop.fonts.FontManager; import org.apache.fop.render.afp.extensions.AFPElementMapping; import org.apache.fop.render.afp.extensions.AFPIncludeFormMap; import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap; -import org.apache.fop.render.afp.extensions.AFPPageSetup; import org.apache.fop.render.afp.extensions.AFPPageOverlay; +import org.apache.fop.render.afp.extensions.AFPPageSetup; import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler; import org.apache.fop.render.intermediate.IFDocumentHandler; import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator; @@ -361,6 +361,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler paintingState.setCMYKImagesSupported(value); } + /** {@inheritDoc} */ + public void setDitheringQuality(float quality) { + this.paintingState.setDitheringQuality(quality); + } + /** {@inheritDoc} */ public void setShadingMode(AFPShadingMode shadingMode) { this.shadingMode = shadingMode; diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java index 32a95b445..aaaecf2ea 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java @@ -20,6 +20,7 @@ package org.apache.fop.render.afp; import java.awt.Rectangle; +import java.awt.geom.AffineTransform; import java.io.IOException; import org.apache.xmlgraphics.image.loader.Image; @@ -136,6 +137,12 @@ public class AFPImageHandlerGraphics2D extends AFPImageHandler implements ImageH setDefaultResourceLevel(graphicsObjectInfo, afpContext.getResourceManager()); + AFPPaintingState paintingState = afpContext.getPaintingState(); + paintingState.save(); // save + AffineTransform placement = new AffineTransform(); + placement.translate(pos.x, pos.y); + paintingState.concatenate(placement); + // Image content ImageGraphics2D imageG2D = (ImageGraphics2D)image; boolean textAsShapes = false; //TODO Make configurable @@ -152,6 +159,8 @@ public class AFPImageHandlerGraphics2D extends AFPImageHandler implements ImageH // Create image afpContext.getResourceManager().createObject(graphicsObjectInfo); + + paintingState.restore(); // resume } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java index 330f78d63..cb7b23da2 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java @@ -101,6 +101,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima maxPixelSize *= 3; //RGB is maximum } } + float ditheringQuality = paintingState.getDitheringQuality(); RenderedImage renderedImage = imageRendered.getRenderedImage(); ImageInfo imageInfo = imageRendered.getInfo(); @@ -130,9 +131,13 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima log.debug("Resample from " + intrinsicSize.getDimensionPx() + " to " + resampledDim); } - renderedImage = BitmapImageUtil.convertToMonochrome(renderedImage, resampledDim); + renderedImage = BitmapImageUtil.convertToMonochrome(renderedImage, + resampledDim, ditheringQuality); effIntrinsicSize = new ImageSize( resampledDim.width, resampledDim.height, resolution); + } else if (ditheringQuality >= 0.5f) { + renderedImage = BitmapImageUtil.convertToMonochrome(renderedImage, + intrinsicSize.getDimensionPx(), ditheringQuality); } } @@ -157,7 +162,6 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima if (cm.hasAlpha()) { pixelSize -= 8; } - //TODO Add support for CMYK images byte[] imageData = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index d88deadfe..1f373023c 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -838,6 +838,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCust paintingState.setCMYKImagesSupported(value); } + /** {@inheritDoc} */ + public void setDitheringQuality(float quality) { + this.paintingState.setDitheringQuality(quality); + } + /** {@inheritDoc} */ public void setShadingMode(AFPShadingMode shadingMode) { this.shadingMode = shadingMode; diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java index 23f413813..1720667df 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java @@ -390,6 +390,21 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator customizable.setBitsPerPixel(bitsPerPixel); } + String dithering = imagesCfg.getAttribute("dithering-quality", "medium"); + float dq = 0.5f; + if (dithering.startsWith("min")) { + dq = 0.0f; + } else if (dithering.startsWith("max")) { + dq = 1.0f; + } else { + try { + dq = Float.parseFloat(dithering); + } catch (NumberFormatException nfe) { + //ignore and leave the default above + } + } + customizable.setDitheringQuality(dq); + // native image support boolean nativeImageSupport = imagesCfg.getAttributeAsBoolean("native", false); customizable.setNativeImagesSupported(nativeImageSupport); diff --git a/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java b/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java index cb46395ca..c08076316 100644 --- a/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java +++ b/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java @@ -135,6 +135,53 @@ public class BitmapImageUtil { */ public static final BufferedImage convertToMonochrome(RenderedImage img, Dimension targetDimension) { + return toBufferedImage(convertToMonochrome(img, targetDimension, 0.0f)); + } + + /** + * 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 + * @param quality Defines the desired quality level for the conversion. + * Valid values: a value between 0.0f (fastest) and 1.0f (best) + * @return the monochrome image + */ + public static final RenderedImage convertToMonochrome(RenderedImage img, + Dimension targetDimension, float quality) { + if (!isMonochromeImage(img)) { + if (quality >= 0.5f) { + BufferedImage bi; + Dimension orgDim = new Dimension(img.getWidth(), img.getHeight()); + if (targetDimension != null && !orgDim.equals(targetDimension)) { + //Scale only before dithering + ColorModel cm = img.getColorModel(); + BufferedImage tgt = new BufferedImage(cm, + cm.createCompatibleWritableRaster( + targetDimension.width, targetDimension.height), + cm.isAlphaPremultiplied(), null); + transferImage(img, tgt); + bi = tgt; + } else { + bi = toBufferedImage(img); + } + //Now convert to monochrome (dithering if available) + MonochromeBitmapConverter converter = createDefaultMonochromeBitmapConverter(); + if (quality >= 0.8f) { + //Activates error diffusion if JAI is available + converter.setHint("quality", Boolean.TRUE.toString()); + //Need to convert to grayscale first since otherwise, there may be encoding + //problems later with the images JAI can generate. + bi = convertToGrayscale(bi, targetDimension); + } + try { + return converter.convertToMonochrome(bi); + } catch (Exception e) { + //Provide a fallback if exotic formats are encountered + bi = convertToGrayscale(bi, targetDimension); + return converter.convertToMonochrome(bi); + } + } + } return convertAndScaleImage(img, targetDimension, BufferedImage.TYPE_BYTE_BINARY); } diff --git a/status.xml b/status.xml index f933e8a64..353b8059b 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,13 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + AFP Output: Fixed positioning of Java2D-based images (when GOCA is enabled). + + + AFP Output: Added enhanced dithering functionality for images that are converted to + bi-level images. + AFP Output: Fix for bitmap images inside an SVG or G2D graphic (printer errors) and positioning fix for bitmaps from G2D graphics. -- cgit v1.2.3 From 2150f3f35acbe14ca11c60a948d7a8d8df1b7769 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Mon, 14 Jun 2010 15:21:18 +0000 Subject: Color-related classes were moved to the org.apache.xmlgraphics.java2d.color package. Updated XML Graphics Commons Snapshot. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@954512 13f79535-47bb-0310-9956-ffa450edef68 --- lib/xmlgraphics-commons-1.4svn.jar | Bin 568485 -> 572607 bytes src/java/org/apache/fop/afp/AFPPaintingState.java | 6 +++--- .../org/apache/fop/afp/modca/GraphicsObject.java | 2 +- src/java/org/apache/fop/pdf/PDFColor.java | 4 ++-- src/java/org/apache/fop/svg/PDFGraphics2D.java | 4 ++-- src/java/org/apache/fop/util/ColorUtil.java | 10 +++++----- .../org/apache/fop/traits/BorderPropsTestCase.java | 4 ++-- .../org/apache/fop/util/ColorUtilTestCase.java | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/java/org/apache') diff --git a/lib/xmlgraphics-commons-1.4svn.jar b/lib/xmlgraphics-commons-1.4svn.jar index 4f82992d3..c99758f16 100644 Binary files a/lib/xmlgraphics-commons-1.4svn.jar and b/lib/xmlgraphics-commons-1.4svn.jar differ diff --git a/src/java/org/apache/fop/afp/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java index 4e314e5d9..e92a6cdb2 100644 --- a/src/java/org/apache/fop/afp/AFPPaintingState.java +++ b/src/java/org/apache/fop/afp/AFPPaintingState.java @@ -24,9 +24,9 @@ import java.awt.Point; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.xmlgraphics.java2d.ColorConverter; -import org.apache.xmlgraphics.java2d.DefaultColorConverter; -import org.apache.xmlgraphics.java2d.GrayScaleColorConverter; +import org.apache.xmlgraphics.java2d.color.ColorConverter; +import org.apache.xmlgraphics.java2d.color.DefaultColorConverter; +import org.apache.xmlgraphics.java2d.color.GrayScaleColorConverter; import org.apache.fop.afp.fonts.AFPPageFonts; import org.apache.fop.util.AbstractPaintingState; diff --git a/src/java/org/apache/fop/afp/modca/GraphicsObject.java b/src/java/org/apache/fop/afp/modca/GraphicsObject.java index cdc0a44bc..b677a0f7c 100644 --- a/src/java/org/apache/fop/afp/modca/GraphicsObject.java +++ b/src/java/org/apache/fop/afp/modca/GraphicsObject.java @@ -25,7 +25,7 @@ import java.io.OutputStream; import java.util.Iterator; import java.util.List; -import org.apache.xmlgraphics.java2d.ColorConverter; +import org.apache.xmlgraphics.java2d.color.ColorConverter; import org.apache.fop.afp.AFPDataObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; diff --git a/src/java/org/apache/fop/pdf/PDFColor.java b/src/java/org/apache/fop/pdf/PDFColor.java index c4a8e5be6..42a9c7223 100644 --- a/src/java/org/apache/fop/pdf/PDFColor.java +++ b/src/java/org/apache/fop/pdf/PDFColor.java @@ -26,8 +26,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.apache.xmlgraphics.java2d.CMYKColorSpace; -import org.apache.xmlgraphics.java2d.ColorExt; +import org.apache.xmlgraphics.java2d.color.CMYKColorSpace; +import org.apache.xmlgraphics.java2d.color.ColorExt; /** * PDF Color object. diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index e25fbbdbe..f0084da09 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -66,8 +66,8 @@ import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG; import org.apache.xmlgraphics.image.loader.impl.ImageRendered; import org.apache.xmlgraphics.java2d.AbstractGraphics2D; -import org.apache.xmlgraphics.java2d.ColorExt; import org.apache.xmlgraphics.java2d.GraphicContext; +import org.apache.xmlgraphics.java2d.color.ColorExt; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -762,7 +762,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand //currentStream.write(currentColour.getColorSpaceOut(fill)); } else { throw new UnsupportedOperationException( - "Color Space not supported by PDFGraphics2D"); + "Color Space not supported by PDFGraphics2D: " + c.getColorSpace()); } } diff --git a/src/java/org/apache/fop/util/ColorUtil.java b/src/java/org/apache/fop/util/ColorUtil.java index 4ec858ca6..656d9ef98 100644 --- a/src/java/org/apache/fop/util/ColorUtil.java +++ b/src/java/org/apache/fop/util/ColorUtil.java @@ -27,8 +27,8 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.xmlgraphics.java2d.CMYKColorSpace; -import org.apache.xmlgraphics.java2d.ColorExt; +import org.apache.xmlgraphics.java2d.color.CMYKColorSpace; +import org.apache.xmlgraphics.java2d.color.ColorExt; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.expr.PropertyException; @@ -682,7 +682,7 @@ public final class ColorUtil { * @return the modified color */ public static Color lightenColor(Color col, float factor) { - return org.apache.xmlgraphics.java2d.ColorUtil.lightenColor(col, factor); + return org.apache.xmlgraphics.java2d.color.ColorUtil.lightenColor(col, factor); } /** @@ -701,7 +701,7 @@ public final class ColorUtil { * @return true if it is a gray value */ public static boolean isGray(Color col) { - return org.apache.xmlgraphics.java2d.ColorUtil.isGray(col); + return org.apache.xmlgraphics.java2d.color.ColorUtil.isGray(col); } /** @@ -711,6 +711,6 @@ public final class ColorUtil { */ public static Color toCMYKGrayColor(float black) { - return org.apache.xmlgraphics.java2d.ColorUtil.toCMYKGrayColor(black); + return org.apache.xmlgraphics.java2d.color.ColorUtil.toCMYKGrayColor(black); } } diff --git a/test/java/org/apache/fop/traits/BorderPropsTestCase.java b/test/java/org/apache/fop/traits/BorderPropsTestCase.java index 3a80b13fb..3332d11f2 100644 --- a/test/java/org/apache/fop/traits/BorderPropsTestCase.java +++ b/test/java/org/apache/fop/traits/BorderPropsTestCase.java @@ -23,8 +23,8 @@ import java.awt.Color; import junit.framework.TestCase; -import org.apache.xmlgraphics.java2d.CMYKColorSpace; -import org.apache.xmlgraphics.java2d.ColorExt; +import org.apache.xmlgraphics.java2d.color.CMYKColorSpace; +import org.apache.xmlgraphics.java2d.color.ColorExt; import org.apache.fop.fo.Constants; import org.apache.fop.util.ColorUtil; diff --git a/test/java/org/apache/fop/util/ColorUtilTestCase.java b/test/java/org/apache/fop/util/ColorUtilTestCase.java index 5d76412b8..83163c888 100644 --- a/test/java/org/apache/fop/util/ColorUtilTestCase.java +++ b/test/java/org/apache/fop/util/ColorUtilTestCase.java @@ -24,8 +24,8 @@ import java.awt.color.ColorSpace; import junit.framework.TestCase; -import org.apache.xmlgraphics.java2d.CMYKColorSpace; -import org.apache.xmlgraphics.java2d.ColorExt; +import org.apache.xmlgraphics.java2d.color.CMYKColorSpace; +import org.apache.xmlgraphics.java2d.color.ColorExt; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; -- cgit v1.2.3