]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Moved IFState instance variable into AbstractIFPainter as all implementations use it.
authorJeremias Maerki <jeremias@apache.org>
Thu, 23 Oct 2008 10:03:27 +0000 (10:03 +0000)
committerJeremias Maerki <jeremias@apache.org>
Thu, 23 Oct 2008 10:03:27 +0000 (10:03 +0000)
Refactored default image handling methods in AbstractIFPainter a bit to make them more universal.
Fixed a small mistake in Java2DImageHandlerRenderedImage.
Added configurator code for new PCL implementation.
Fixed smaller issues in PCLGenerator.
Added support for painting images (e-g and i-f-o) as bitmaps (depends on rev 707329 in XML Graphics Commons).
Added support for text with custom fonts to be painted as bitmaps.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@707331 13f79535-47bb-0310-9956-ffa450edef68

17 files changed:
src/java/META-INF/services/org.apache.fop.render.ImageHandler
src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
src/java/org/apache/fop/render/java2d/Java2DImageHandlerRenderedImage.java
src/java/org/apache/fop/render/java2d/Java2DPainter.java
src/java/org/apache/fop/render/java2d/Java2DRenderingContext.java
src/java/org/apache/fop/render/pcl/HardcodedFonts.java [new file with mode: 0644]
src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java
src/java/org/apache/fop/render/pcl/PCLGenerator.java
src/java/org/apache/fop/render/pcl/PCLImageHandlerRenderedImage.java [new file with mode: 0644]
src/java/org/apache/fop/render/pcl/PCLPainter.java
src/java/org/apache/fop/render/pcl/PCLRenderer.java
src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
src/java/org/apache/fop/render/pcl/PCLRenderingContext.java [new file with mode: 0644]
src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
src/java/org/apache/fop/render/pdf/PDFPainter.java
src/sandbox/org/apache/fop/render/svg/SVGPainter.java

index d9f2ccbba26af03e2d5177f0dc7c25b099167182..11144f3bc371fda5c3fdc942797337a67c5430aa 100644 (file)
@@ -5,3 +5,4 @@ org.apache.fop.render.pdf.PDFImageHandlerRawCCITTFax
 org.apache.fop.render.pdf.PDFImageHandlerSVG\r
 org.apache.fop.render.java2d.Java2DImageHandlerRenderedImage\r
 org.apache.fop.render.java2d.Java2DImageHandlerGraphics2D\r
+org.apache.fop.render.pcl.PCLImageHandlerRenderedImage\r
index a54e62bd01f0cc2fb64ef42fd6eb0eb1eb995582..55ed514e02e8bdefd82bbd7b01305c365e712888 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.apache.fop.render.intermediate;
 
+import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
@@ -33,6 +34,7 @@ import org.w3c.dom.Document;
 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.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageManager;
@@ -57,6 +59,9 @@ public abstract class AbstractIFPainter implements IFPainter {
     /** non-URI that can be used in feedback messages that an image is an instream-object */
     protected static final String INSTREAM_OBJECT_URI = "(instream-object)";
 
+    /** Holds the intermediate format state */
+    protected IFState state;
+
 
     /**
      * Default constructor.
@@ -118,31 +123,84 @@ public abstract class AbstractIFPainter implements IFPainter {
 
         //Load and convert the image to a supported format
         RenderingContext context = createRenderingContext();
-        Map hints = ImageUtil.getDefaultHints(sessionContext);
+        Map hints = createDefaultImageProcessingHints(sessionContext);
         org.apache.xmlgraphics.image.loader.Image img = manager.getImage(
                     info, imageHandlerRegistry.getSupportedFlavors(context),
                     hints, sessionContext);
 
+        try {
+            drawImage(img, rect, context);
+        } catch (IOException ioe) {
+            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
+                    getUserAgent().getEventBroadcaster());
+            eventProducer.imageWritingError(this, ioe);
+        }
+    }
+
+    /**
+     * Creates the default map of processing hints for the image loading framework.
+     * @param sessionContext the session context for access to resolution information
+     * @return the default processing hints
+     */
+    protected Map createDefaultImageProcessingHints(ImageSessionContext sessionContext) {
+        return ImageUtil.getDefaultHints(sessionContext);
+    }
+
+    /**
+     * Draws an image using a suitable image handler.
+     * @param image the image to be painted (it needs to of a supported image flavor)
+     * @param rect the rectangle in which to paint the image
+     * @param context a suitable rendering context
+     * @throws IOException in case of an I/O error while handling/writing the image
+     * @throws ImageException if an error occurs while converting the image to a suitable format
+     */
+    protected void drawImage(Image image, Rectangle rect,
+            RenderingContext context) throws IOException, ImageException {
+        drawImage(image, rect, context, false, null);
+    }
+
+    /**
+     * Draws an image using a suitable image handler.
+     * @param image the image to be painted (it needs to of a supported image flavor)
+     * @param rect the rectangle in which to paint the image
+     * @param context a suitable rendering context
+     * @param convert true to run the image through image conversion if that is necessary
+     * @param additionalHints additional image processing hints
+     * @throws IOException in case of an I/O error while handling/writing the image
+     * @throws ImageException if an error occurs while converting the image to a suitable format
+     */
+    protected void drawImage(Image image, Rectangle rect,
+            RenderingContext context, boolean convert, Map additionalHints)
+                    throws IOException, ImageException {
+        ImageManager manager = getFopFactory().getImageManager();
+        ImageHandlerRegistry imageHandlerRegistry = getFopFactory().getImageHandlerRegistry();
+
+        Image effImage;
+        if (convert) {
+            Map hints = createDefaultImageProcessingHints(getUserAgent().getImageSessionContext());
+            if (additionalHints != null) {
+                hints.putAll(additionalHints);
+            }
+            effImage = manager.convertImage(image,
+                    imageHandlerRegistry.getSupportedFlavors(context), hints);
+        } else {
+            effImage = image;
+        }
+
         //First check for a dynamically registered handler
-        ImageHandler handler = imageHandlerRegistry.getHandler(context, img);
+        ImageHandler handler = imageHandlerRegistry.getHandler(context, effImage);
         if (handler == null) {
             throw new UnsupportedOperationException(
                     "No ImageHandler available for image: "
-                        + info + " (" + img.getClass().getName() + ")");
+                        + effImage.getInfo() + " (" + effImage.getClass().getName() + ")");
         }
 
         if (log.isDebugEnabled()) {
             log.debug("Using ImageHandler: " + handler.getClass().getName());
         }
-        try {
-            //TODO foreign attributes
-            handler.handleImage(context, img, rect);
-        } catch (IOException ioe) {
-            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
-                    getUserAgent().getEventBroadcaster());
-            eventProducer.imageWritingError(this, ioe);
-            return;
-        }
+
+        //TODO foreign attributes
+        handler.handleImage(context, effImage, rect);
     }
 
     /**
@@ -203,5 +261,27 @@ public abstract class AbstractIFPainter implements IFPainter {
         }
     }
 
+    /** {@inheritDoc} */
+    public void setFont(String family, String style, Integer weight, String variant, Integer size,
+            Color color) throws IFException {
+        if (family != null) {
+            state.setFontFamily(family);
+        }
+        if (style != null) {
+            state.setFontStyle(style);
+        }
+        if (weight != null) {
+            state.setFontWeight(weight.intValue());
+        }
+        if (variant != null) {
+            state.setFontVariant(variant);
+        }
+        if (size != null) {
+            state.setFontSize(size.intValue());
+        }
+        if (color != null) {
+            state.setTextColor(color);
+        }
+    }
 
 }
index 9c2d24c32ebb28b082c91a9b8e56369063c3799f..80d57fc59478fdc481bb9d5aa15bc64e4a0197f3 100644 (file)
@@ -30,7 +30,6 @@ import java.io.IOException;
 import org.apache.xmlgraphics.image.loader.Image;
 import org.apache.xmlgraphics.image.loader.ImageFlavor;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
 import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
 
 import org.apache.fop.render.ImageHandler;
@@ -49,7 +48,7 @@ public class Java2DImageHandlerRenderedImage implements ImageHandler {
 
     /** {@inheritDoc} */
     public Class getSupportedImageClass() {
-        return ImageRawStream.class;
+        return ImageRendered.class;
     }
 
     /** {@inheritDoc} */
index 9a68f62d0d4684ccd4882850f8f40c70a1878e6f..013be3f869d8b0ead6568ded1c307c415b7a0e46 100644 (file)
@@ -62,9 +62,6 @@ public class Java2DPainter extends AbstractIFPainter {
     /** The font information */
     protected FontInfo fontInfo;
 
-    /** Holds the intermediate format state */
-    protected IFState state;
-
     private Java2DBorderPainter borderPainter;
 
     /** The current state, holds a Graphics2D and its context */
@@ -78,9 +75,24 @@ public class Java2DPainter extends AbstractIFPainter {
      * @param fontInfo the font information
      */
     public Java2DPainter(Graphics2D g2d, FOUserAgent userAgent, FontInfo fontInfo) {
+        this(g2d, userAgent, fontInfo, null);
+    }
+
+    /**
+     * Special constructor for embedded use (when another painter uses Java2DPainter
+     * to convert part of a document into a bitmap, for example).
+     * @param g2d the target Graphics2D instance
+     * @param userAgent the user agent
+     * @param fontInfo the font information
+     */
+    public Java2DPainter(Graphics2D g2d, FOUserAgent userAgent, FontInfo fontInfo, IFState state) {
         super();
         this.userAgent = userAgent;
-        this.state = IFState.create();
+        if (state != null) {
+            this.state = state.push();
+        } else {
+            this.state = IFState.create();
+        }
         this.fontInfo = fontInfo;
         this.g2dState = new Java2DGraphicsState(g2d, fontInfo, g2d.getTransform());
         this.borderPainter = new Java2DBorderPainter(this);
@@ -227,31 +239,6 @@ public class Java2DPainter extends AbstractIFPainter {
         g2d.drawGlyphVector(gv, x, y);
     }
 
-    /** {@inheritDoc} */
-    public void setFont(String family, String style, Integer weight, String variant, Integer size,
-            Color color) throws IFException {
-        if (family != null) {
-            state.setFontFamily(family);
-        }
-        if (style != null) {
-            state.setFontStyle(style);
-        }
-        if (weight != null) {
-            state.setFontWeight(weight.intValue());
-        }
-        if (variant != null) {
-            state.setFontVariant(variant);
-        }
-        if (size != null) {
-            state.setFontSize(size.intValue());
-        }
-        if (color != null) {
-            state.setTextColor(color);
-        }
-    }
-
-    //----------------------------------------------------------------------------------------------
-
     /** Saves the current graphics state on the stack. */
     protected void saveGraphicsState() {
         g2dStateStack.push(g2dState);
index 7bc55502ade88785296f47890b721ac1b279cc79..86655434fb84c31f3ff9ed1d1abfc6af6ca1908f 100644 (file)
@@ -26,7 +26,7 @@ import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.render.AbstractRenderingContext;
 
 /**
- * Rendering context for PDF production.
+ * Rendering context for Java2D painting.
  */
 public class Java2DRenderingContext extends AbstractRenderingContext {
 
diff --git a/src/java/org/apache/fop/render/pcl/HardcodedFonts.java b/src/java/org/apache/fop/render/pcl/HardcodedFonts.java
new file mode 100644 (file)
index 0000000..a1c5a60
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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.pcl;
+
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class hold code for selecting a set of hard-coded fonts available in practically all
+ * PCL implementations. We hope this can be improved in the future.
+ */
+class HardcodedFonts {
+
+    /** logging instance */
+    private static Log log = LogFactory.getLog(HardcodedFonts.class);
+
+    /**
+     * Sets the current font (NOTE: Hard-coded font mappings ATM!)
+     * @param name the font name (internal F* names for now)
+     * @param size the font size (in millipoints)
+     * @param text the text to be rendered (used to determine if there are non-printable chars)
+     * @return true if the font can be mapped to PCL
+     * @throws IOException if an I/O problem occurs
+     */
+    public static boolean setFont(PCLGenerator gen, String name, int size, String text)
+                throws IOException {
+        byte[] encoded = text.getBytes("ISO-8859-1");
+        for (int i = 0, c = encoded.length; i < c; i++) {
+            if (encoded[i] == 0x3F && text.charAt(i) != '?') {
+                return false;
+            }
+        }
+        return selectFont(gen, name, size);
+    }
+
+    private static boolean selectFont(PCLGenerator gen, String name, int size) throws IOException {
+        int fontcode = 0;
+        if (name.length() > 1 && name.charAt(0) == 'F') {
+            try {
+                fontcode = Integer.parseInt(name.substring(1));
+            } catch (Exception e) {
+                log.error(e);
+            }
+        }
+        //Note "(ON" selects ISO 8859-1 symbol set as used by PCLGenerator
+        String formattedSize = gen.formatDouble2(size / 1000.0);
+        switch (fontcode) {
+        case 1:     // F1 = Helvetica
+            // gen.writeCommand("(8U");
+            // gen.writeCommand("(s1p" + formattedSize + "v0s0b24580T");
+            // Arial is more common among PCL5 printers than Helvetica - so use Arial
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s0b16602T");
+            break;
+        case 2:     // F2 = Helvetica Oblique
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s0b16602T");
+            break;
+        case 3:     // F3 = Helvetica Bold
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s3b16602T");
+            break;
+        case 4:     // F4 = Helvetica Bold Oblique
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s3b16602T");
+            break;
+        case 5:     // F5 = Times Roman
+            // gen.writeCommand("(8U");
+            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
+            // Times New is more common among PCL5 printers than Times - so use Times New
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s0b16901T");
+            break;
+        case 6:     // F6 = Times Italic
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s0b16901T");
+            break;
+        case 7:     // F7 = Times Bold
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s3b16901T");
+            break;
+        case 8:     // F8 = Times Bold Italic
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s3b16901T");
+            break;
+        case 9:     // F9 = Courier
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
+                    + "h0s0b4099T");
+            break;
+        case 10:    // F10 = Courier Oblique
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
+                    + "h1s0b4099T");
+            break;
+        case 11:    // F11 = Courier Bold
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
+                    + "h0s3b4099T");
+            break;
+        case 12:    // F12 = Courier Bold Oblique
+
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
+                    + "h1s3b4099T");
+            break;
+        case 13:    // F13 = Symbol
+
+            return false;
+            //gen.writeCommand("(19M");
+            //gen.writeCommand("(s1p" + formattedSize + "v0s0b16686T");
+            // ECMA Latin 1 Symbol Set in Times Roman???
+            // gen.writeCommand("(9U");
+            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
+            //break;
+        case 14:    // F14 = Zapf Dingbats
+
+            return false;
+            //gen.writeCommand("(14L");
+            //gen.writeCommand("(s1p" + formattedSize + "v0s0b45101T");
+            //break;
+        default:
+            //gen.writeCommand("(0N");
+            //gen.writeCommand("(s" + formattedSize + "V");
+            return false;
+        }
+        return true;
+    }
+
+}
index ce032ace58f3891bda230a996c408bcd70095bdf..0c1a3a14aaea15d9ec2b44793c57ab0f988459b2 100644 (file)
@@ -78,7 +78,7 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
 
     /** {@inheritDoc} */
     public IFDocumentHandlerConfigurator getConfigurator() {
-        return null; //No configurator, yet.
+        return new PCLRendererConfigurator(getUserAgent());
     }
 
     PCLRenderingUtil getPCLUtil() {
index 5d42d33205677200a60485da7ede900be471ffb9..4a937d7b1e00fcc61cd03f09952b61647fd9c909 100644 (file)
@@ -52,7 +52,7 @@ public class PCLDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
 
     /** {@inheritDoc} */
     public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) {
-        return null;
+        return new PCLRendererConfigurator(userAgent);
     }
 
 }
index 3a451c9ad6fb43ccfbbb69327051f8ef90bcc55f..eac1af3d025a8860523d80139a543a04c309eda0 100644 (file)
@@ -601,7 +601,7 @@ public class PCLGenerator {
      * @return true if it's a grayscale image
      */
     public static boolean isGrayscaleImage(RenderedImage img) {
-        return (img.getColorModel().getColorSpace().getNumComponents() == 1);
+        return (img.getColorModel().getNumColorComponents() == 1);
     }
 
     private MonochromeBitmapConverter createMonochromeBitmapConverter() {
@@ -751,6 +751,7 @@ public class PCLGenerator {
         Dimension orgDim = new Dimension(img.getWidth(), img.getHeight());
         Dimension effDim = getAdjustedDimension(orgDim, targetResolution, effResolution);
         boolean scaled = !orgDim.equals(effDim);
+        //ImageWriterUtil.saveAsPNG(img, new java.io.File("D:/text-0-org.png"));
 
         boolean monochrome = isMonochromeImage(img);
         if (!monochrome) {
@@ -770,6 +771,12 @@ public class PCLGenerator {
                 if (!isGrayscaleImage(img) || img.getColorModel().hasAlpha()) {
                     src = new BufferedImage(effDim.width, effDim.height,
                             BufferedImage.TYPE_BYTE_GRAY);
+                    Graphics2D g2d = src.createGraphics();
+                    try {
+                        clearBackground(g2d, effDim);
+                    } finally {
+                        g2d.dispose();
+                    }
                     ColorConvertOp op = new ColorConvertOp(
                             ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
                     op.filter((BufferedImage)img, src);
@@ -782,6 +789,8 @@ public class PCLGenerator {
                         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();
@@ -824,6 +833,12 @@ public class PCLGenerator {
         }
     }
 
+    private void clearBackground(Graphics2D g2d, Dimension effDim) {
+        //white background
+        g2d.setBackground(Color.WHITE);
+        g2d.clearRect(0, 0, effDim.width, effDim.height);
+    }
+
     /**
      * Paint a bitmap at the current cursor position. The bitmap must be a monochrome
      * (1-bit) bitmap image.
diff --git a/src/java/org/apache/fop/render/pcl/PCLImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/pcl/PCLImageHandlerRenderedImage.java
new file mode 100644 (file)
index 0000000..ce8c26a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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.pcl;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.geom.Point2D;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
+
+import org.apache.fop.render.ImageHandler;
+import org.apache.fop.render.RenderingContext;
+
+/**
+ * Image handler implementation that paints {@code RenderedImage} instances in PCL.
+ */
+public class PCLImageHandlerRenderedImage implements ImageHandler {
+
+    /** {@inheritDoc} */
+    public int getPriority() {
+        return 300;
+    }
+
+    /** {@inheritDoc} */
+    public Class getSupportedImageClass() {
+        return ImageRendered.class;
+    }
+
+    /** {@inheritDoc} */
+    public ImageFlavor[] getSupportedImageFlavors() {
+        return new ImageFlavor[] {
+            ImageFlavor.BUFFERED_IMAGE,
+            ImageFlavor.RENDERED_IMAGE,
+        };
+    }
+
+    /** {@inheritDoc} */
+    public void handleImage(RenderingContext context, Image image, Rectangle pos)
+            throws IOException {
+        PCLRenderingContext pclContext = (PCLRenderingContext)context;
+        ImageRendered imageRend = (ImageRendered)image;
+        PCLGenerator gen = pclContext.getPCLGenerator();
+
+        RenderedImage ri = imageRend.getRenderedImage();
+        Point2D transPoint = pclContext.transformedPoint(pos.x, pos.y);
+        gen.setCursorPos(transPoint.getX(), transPoint.getY());
+        gen.paintBitmap(ri, new Dimension(pos.width, pos.height),
+                pclContext.isSourceTransparencyEnabled());
+    }
+
+    /** {@inheritDoc} */
+    public boolean isCompatible(RenderingContext targetContext, Image image) {
+        return (image == null || image instanceof ImageRendered)
+                && targetContext instanceof PCLRenderingContext;
+    }
+
+}
index d4e04175e7684daf6db407aabfd2292d6d2846d6..490ec7f7aff418b3ea50918453694c886608a7db 100644 (file)
@@ -21,11 +21,13 @@ package org.apache.fop.render.pcl;
 
 import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Graphics2D;
 import java.awt.Paint;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.util.Map;
 import java.util.Stack;
@@ -35,20 +37,26 @@ import org.w3c.dom.Document;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageProcessingHints;
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
 import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
 
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.pdf.PDFXObject;
 import org.apache.fop.render.RenderingContext;
 import org.apache.fop.render.intermediate.AbstractIFPainter;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFState;
+import org.apache.fop.render.java2d.FontMetricsMapper;
+import org.apache.fop.render.java2d.Java2DPainter;
 import org.apache.fop.traits.BorderProps;
 import org.apache.fop.traits.RuleStyle;
 import org.apache.fop.util.CharUtilities;
-import org.apache.fop.util.UnitConv;
 
 /**
  * {@code IFPainter} implementation that produces PCL 5.
@@ -58,10 +66,9 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
     /** logging instance */
     private static Log log = LogFactory.getLog(PCLPainter.class);
 
-    private PCLDocumentHandler parent;
+    private final boolean DEBUG = false;
 
-    /** Holds the intermediate format state */
-    protected IFState state;
+    private PCLDocumentHandler parent;
 
     /** The PCL generator */
     private PCLGenerator gen;
@@ -142,56 +149,25 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
 
     /** {@inheritDoc} */
     public void drawImage(String uri, Rectangle rect, Map foreignAttributes) throws IFException {
-        /*
-        PDFXObject xobject = pdfDoc.getXObject(uri);
-        if (xobject != null) {
-            placeImage(rect, xobject);
-            return;
-        }
-
-        drawImageUsingURI(uri, rect);
-
-        flushPDFDoc();
-        */
+        drawImageUsingURI(uri, rect/*, foreignAttributes*/);
     }
 
     /** {@inheritDoc} */
     protected RenderingContext createRenderingContext() {
-        /*
         PCLRenderingContext pdfContext = new PCLRenderingContext(
-                getUserAgent(), generator, currentPage, getFontInfo());
-        return pdfContext;
-        */
-        return null;
-    }
+                getUserAgent(), this.gen, getPCLUtil()) {
 
-    /**
-     * Places a previously registered image at a certain place on the page.
-     * @param x X coordinate
-     * @param y Y coordinate
-     * @param w width for image
-     * @param h height for image
-     * @param xobj the image XObject
-     */
-    private void placeImage(Rectangle rect, PDFXObject xobj) {
-        /*
-        generator.saveGraphicsState();
-        generator.add(format(rect.width) + " 0 0 "
-                          + format(-rect.height) + " "
-                          + format(rect.x) + " "
-                          + format(rect.y + rect.height )
-                          + " cm " + xobj.getName() + " Do\n");
-        generator.restoreGraphicsState();
-        */
+            public Point2D transformedPoint(int x, int y) {
+                return PCLPainter.this.transformedPoint(x, y);
+            }
+
+        };
+        return pdfContext;
     }
 
     /** {@inheritDoc} */
     public void drawImage(Document doc, Rectangle rect, Map foreignAttributes) throws IFException {
-        /*
         drawImageUsingDocument(doc, rect);
-
-        flushPDFDoc();
-        */
     }
 
     /** {@inheritDoc} */
@@ -257,14 +233,21 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
             String fontKey = parent.getFontInfo().getInternalFontKey(triplet);
             boolean pclFont = getPCLUtil().isAllTextAsBitmaps()
                         ? false
-                        : setFont(fontKey, state.getFontSize(), text);
-            if (true || pclFont) {
+                        : HardcodedFonts.setFont(gen, fontKey, state.getFontSize(), text);
+            if (pclFont) {
                 drawTextNative(x, y, dx, text, triplet);
             } else {
                 drawTextAsBitmap(x, y, dx, dy, text, triplet);
+                if (DEBUG) {
+                    state.setTextColor(Color.GRAY);
+                    HardcodedFonts.setFont(gen, "F1", state.getFontSize(), text);
+                    drawTextNative(x, y, dx, text, triplet);
+                }
             }
         } catch (IOException ioe) {
             throw new IFException("I/O error in drawText()", ioe);
+        } catch (ImageException ime) {
+            throw new IFException("Image processing error in drawText()", ime);
         }
     }
 
@@ -319,78 +302,113 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
 
     }
 
-    private void drawTextAsBitmap(int x, int y, int[] dx, int[] dy,
-            String text, FontTriplet triplet) throws IOException {
-        /*
+    private static final double SAFETY_MARGIN_FACTOR = 0.05;
+
+    private Rectangle getTextBoundingRect(int x, int y, int[] dx, int[] dy, String text,
+            Font font, FontMetricsMapper metrics) {
+        int maxAscent = metrics.getMaxAscent(font.getFontSize()) / 1000;
+        int descent = metrics.getDescender(font.getFontSize()) / 1000; //is negative
+        int safetyMargin = (int)(SAFETY_MARGIN_FACTOR * font.getFontSize());
+        Rectangle boundingRect = new Rectangle(
+                x, y - maxAscent - safetyMargin,
+                0, maxAscent - descent + 2 * safetyMargin);
+
+        int l = text.length();
+        int dxl = (dx != null ? dx.length : 0);
+
+        if (dx != null && dxl > 0 && dx[0] != 0) {
+            boundingRect.setLocation(boundingRect.x - (int)Math.ceil(dx[0] / 10f), boundingRect.y);
+        }
+        float width = 0.0f;
+        for (int i = 0; i < l; i++) {
+            char orgChar = text.charAt(i);
+            float glyphAdjust = 0;
+            int cw = font.getCharWidth(orgChar);
+
+            if (dx != null && i < dxl - 1) {
+                glyphAdjust += dx[i + 1];
+            }
+
+            width += cw - glyphAdjust;
+        }
+        int extraWidth = font.getFontSize() / 3;
+        boundingRect.setSize(
+                (int)Math.ceil(width) + extraWidth,
+                boundingRect.height);
+        return boundingRect;
+    }
+
+    private void drawTextAsBitmap(final int x, final int y, final int[] dx, final int[] dy,
+            final String text, FontTriplet triplet) throws IOException, ImageException {
         //Use Java2D to paint different fonts via bitmap
-        final Font font = getFontFromArea(text);
-        final int baseline = text.getBaselineOffset();
+        final Font font = parent.getFontInfo().getFontInstance(triplet, state.getFontSize());
+        //final Font font = getFontFromArea(text);
+        //final int baseline = text.getBaselineOffset();
 
         //for cursive fonts, so the text isn't clipped
-        int extraWidth = font.getFontSize() / 3;
-        final FontMetricsMapper mapper = (FontMetricsMapper)fontInfo.getMetricsFor(
+        final FontMetricsMapper mapper = (FontMetricsMapper)parent.getFontInfo().getMetricsFor(
                 font.getFontName());
-        int maxAscent = mapper.getMaxAscent(font.getFontSize()) / 1000;
-        final int additionalBPD = maxAscent - baseline;
-
-        Graphics2DAdapter g2a = getGraphics2DAdapter();
-        final Rectangle paintRect = new Rectangle(
-                rx, currentBPPosition + text.getOffset() - additionalBPD,
-                text.getIPD() + extraWidth, text.getBPD() + additionalBPD);
-        RendererContext rc = createRendererContext(paintRect.x, paintRect.y,
-                paintRect.width, paintRect.height, null);
+        final int maxAscent = mapper.getMaxAscent(font.getFontSize()) / 1000;
+        final int ascent = mapper.getAscender(font.getFontSize()) / 1000;
+        final int descent = mapper.getDescender(font.getFontSize()) / 1000;
+        int safetyMargin = (int)(SAFETY_MARGIN_FACTOR * font.getFontSize());
+        final int baselineOffset = maxAscent + safetyMargin;
+
+        final Rectangle boundingRect = getTextBoundingRect(x, y, dx, dy, text, font, mapper);
+
         Map atts = new java.util.HashMap();
         atts.put(CONV_MODE, "bitmap");
         atts.put(SRC_TRANSPARENCY, "true");
-        rc.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, atts);
+        //rc.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, atts);
 
+        final Dimension dim = boundingRect.getSize();
         Graphics2DImagePainter painter = new Graphics2DImagePainter() {
 
             public void paint(Graphics2D g2d, Rectangle2D area) {
-                g2d.setFont(mapper.getFont(font.getFontSize()));
-                g2d.translate(0, baseline + additionalBPD);
-                g2d.scale(1000, 1000);
-                g2d.setColor(col);
-                Java2DRenderer.renderText(text, g2d, font);
-                renderTextDecoration(g2d, mapper, fontsize, text, 0, 0);
+                if (DEBUG) {
+                    g2d.setBackground(Color.LIGHT_GRAY);
+                    g2d.clearRect(0, 0, (int)area.getWidth(), (int)area.getHeight());
+                }
+                g2d.translate(0, -y + baselineOffset);
+
+                if (DEBUG) {
+                    Rectangle rect = new Rectangle(x, y - maxAscent, 3000, maxAscent);
+                    g2d.draw(rect);
+                    rect = new Rectangle(x, y - ascent, 2000, ascent);
+                    g2d.draw(rect);
+                    rect = new Rectangle(x, y, 1000, - descent);
+                    g2d.draw(rect);
+                }
+                Java2DPainter painter = new Java2DPainter(g2d,
+                        getUserAgent(), parent.getFontInfo(), state);
+                try {
+                    painter.drawText(x, y, dx, dy, text);
+                } catch (IFException e) {
+                    //This should never happen with the Java2DPainter
+                    throw new RuntimeException("Unexpected error while painting text", e);
+                }
             }
 
             public Dimension getImageSize() {
-                return paintRect.getSize();
+                return dim.getSize();
             }
 
         };
-        g2a.paintImage(painter, rc,
-                paintRect.x, paintRect.y, paintRect.width, paintRect.height);
-        currentIPPosition = saveIP + text.getAllocIPD();
-        */
+        ImageInfo info = new ImageInfo(null, null);
+        ImageSize size = new ImageSize();
+        size.setSizeInMillipoints(boundingRect.width, boundingRect.height);
+        info.setSize(size);
+        ImageGraphics2D img = new ImageGraphics2D(info, painter);
+
+        Rectangle rect = boundingRect;
+        Map hints = new java.util.HashMap();
+        hints.put(ImageProcessingHints.BITMAP_TYPE_INTENT,
+                ImageProcessingHints.BITMAP_TYPE_INTENT_GRAY);
+        PCLRenderingContext context = (PCLRenderingContext)createRenderingContext();
+        context.setSourceTransparencyEnabled(true);
+        drawImage(img, rect, context, true, hints);
     }
 
-    /** {@inheritDoc} */
-    public void setFont(String family, String style, Integer weight, String variant, Integer size,
-            Color color) throws IFException {
-        if (family != null) {
-            state.setFontFamily(family);
-        }
-        if (style != null) {
-            state.setFontStyle(style);
-        }
-        if (weight != null) {
-            state.setFontWeight(weight.intValue());
-        }
-        if (variant != null) {
-            state.setFontVariant(variant);
-        }
-        if (size != null) {
-            state.setFontSize(size.intValue());
-        }
-        if (color != null) {
-            state.setTextColor(color);
-        }
-    }
-
-    //----------------------------------------------------------------------------------------------
-
     /** Saves the current graphics state on the stack. */
     private void saveGraphicsState() {
         graphicContextStack.push(graphicContext);
@@ -410,52 +428,8 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
     }
 
     private Point2D transformedPoint(int x, int y) {
-        AffineTransform at = graphicContext.getTransform();
-        if (log.isTraceEnabled()) {
-            log.trace("Current transform: " + at);
-        }
-        Point2D.Float orgPoint = new Point2D.Float(x, y);
-        Point2D.Float transPoint = new Point2D.Float();
-        at.transform(orgPoint, transPoint);
-        //At this point we have the absolute position in FOP's coordinate system
-
-        //Now get PCL coordinates taking the current print direction and the logical page
-        //into account.
-        Dimension pageSize = currentPageDefinition.getPhysicalPageSize();
-        Rectangle logRect = currentPageDefinition.getLogicalPageRect();
-        switch (currentPrintDirection) {
-        case 0:
-            transPoint.x -= logRect.x;
-            transPoint.y -= logRect.y;
-            break;
-        case 90:
-            float ty = transPoint.x;
-            transPoint.x = pageSize.height - transPoint.y;
-            transPoint.y = ty;
-            transPoint.x -= logRect.y;
-            transPoint.y -= logRect.x;
-            break;
-        case 180:
-            transPoint.x = pageSize.width - transPoint.x;
-            transPoint.y = pageSize.height - transPoint.y;
-            transPoint.x -= pageSize.width - logRect.x - logRect.width;
-            transPoint.y -= pageSize.height - logRect.y - logRect.height;
-            //The next line is odd and is probably necessary due to the default value of the
-            //Text Length command: "1/2 inch less than maximum text length"
-            //I wonder why this isn't necessary for the 90 degree rotation. *shrug*
-            transPoint.y -= UnitConv.in2mpt(0.5);
-            break;
-        case 270:
-            float tx = transPoint.y;
-            transPoint.y = pageSize.width - transPoint.x;
-            transPoint.x = tx;
-            transPoint.x -= pageSize.height - logRect.y - logRect.height;
-            transPoint.y -= pageSize.width - logRect.x - logRect.width;
-            break;
-        default:
-            throw new IllegalStateException("Illegal print direction: " + currentPrintDirection);
-        }
-        return transPoint;
+        return PCLRenderingUtil.transformedPoint(x, y, graphicContext.getTransform(),
+                currentPageDefinition, currentPrintDirection);
     }
 
     private void changePrintDirection() throws IOException {
@@ -479,123 +453,4 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
         gen.setCursorPos(transPoint.getX(), transPoint.getY());
     }
 
-    /**
-     * Sets the current font (NOTE: Hard-coded font mappings ATM!)
-     * @param name the font name (internal F* names for now)
-     * @param size the font size (in millipoints)
-     * @param text the text to be rendered (used to determine if there are non-printable chars)
-     * @return true if the font can be mapped to PCL
-     * @throws IOException if an I/O problem occurs
-     */
-    public boolean setFont(String name, int size, String text) throws IOException {
-        byte[] encoded = text.getBytes("ISO-8859-1");
-        for (int i = 0, c = encoded.length; i < c; i++) {
-            if (encoded[i] == 0x3F && text.charAt(i) != '?') {
-                return false;
-            }
-        }
-        int fontcode = 0;
-        if (name.length() > 1 && name.charAt(0) == 'F') {
-            try {
-                fontcode = Integer.parseInt(name.substring(1));
-            } catch (Exception e) {
-                log.error(e);
-            }
-        }
-        //Note "(ON" selects ISO 8859-1 symbol set as used by PCLGenerator
-        String formattedSize = gen.formatDouble2(size / 1000.0);
-        switch (fontcode) {
-        case 1:     // F1 = Helvetica
-            // gen.writeCommand("(8U");
-            // gen.writeCommand("(s1p" + formattedSize + "v0s0b24580T");
-            // Arial is more common among PCL5 printers than Helvetica - so use Arial
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s0b16602T");
-            break;
-        case 2:     // F2 = Helvetica Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s0b16602T");
-            break;
-        case 3:     // F3 = Helvetica Bold
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s3b16602T");
-            break;
-        case 4:     // F4 = Helvetica Bold Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s3b16602T");
-            break;
-        case 5:     // F5 = Times Roman
-            // gen.writeCommand("(8U");
-            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
-            // Times New is more common among PCL5 printers than Times - so use Times New
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s0b16901T");
-            break;
-        case 6:     // F6 = Times Italic
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s0b16901T");
-            break;
-        case 7:     // F7 = Times Bold
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s3b16901T");
-            break;
-        case 8:     // F8 = Times Bold Italic
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s3b16901T");
-            break;
-        case 9:     // F9 = Courier
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h0s0b4099T");
-            break;
-        case 10:    // F10 = Courier Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h1s0b4099T");
-            break;
-        case 11:    // F11 = Courier Bold
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h0s3b4099T");
-            break;
-        case 12:    // F12 = Courier Bold Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h1s3b4099T");
-            break;
-        case 13:    // F13 = Symbol
-
-            return false;
-            //gen.writeCommand("(19M");
-            //gen.writeCommand("(s1p" + formattedSize + "v0s0b16686T");
-            // ECMA Latin 1 Symbol Set in Times Roman???
-            // gen.writeCommand("(9U");
-            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
-            //break;
-        case 14:    // F14 = Zapf Dingbats
-
-            return false;
-            //gen.writeCommand("(14L");
-            //gen.writeCommand("(s1p" + formattedSize + "v0s0b45101T");
-            //break;
-        default:
-            //gen.writeCommand("(0N");
-            //gen.writeCommand("(s" + formattedSize + "V");
-            return false;
-        }
-        return true;
-    }
-
 }
index 44631af4f4993f1ec01098c708a1477ec70193d2..95ebc8c942d677684433c6332e1414d6ff69141f 100644 (file)
@@ -26,13 +26,11 @@ import java.awt.Dimension;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.RenderingHints;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Line2D;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
 import java.awt.image.RenderedImage;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -62,6 +60,7 @@ import org.apache.xmlgraphics.util.QName;
 import org.apache.xmlgraphics.util.UnitConv;
 
 import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
@@ -95,6 +94,7 @@ import org.apache.fop.render.java2d.Base14FontCollection;
 import org.apache.fop.render.java2d.ConfiguredFontCollection;
 import org.apache.fop.render.java2d.FontMetricsMapper;
 import org.apache.fop.render.java2d.InstalledFontCollection;
+import org.apache.fop.render.java2d.Java2DFontMetrics;
 import org.apache.fop.render.java2d.Java2DRenderer;
 import org.apache.fop.render.pcl.extensions.PCLElementMapping;
 import org.apache.fop.traits.BorderProps;
@@ -132,28 +132,10 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
     private java.awt.Color currentFillColor = null;
 
     /**
-     * Controls whether appearance is more important than speed. False can cause some FO feature
-     * to be ignored (like the advanced borders).
+     * Utility class which enables all sorts of features that are not directly connected to the
+     * normal rendering process.
      */
-    private boolean qualityBeforeSpeed = false;
-
-    /**
-     * Controls whether all text should be painted as text. This is a fallback setting in case
-     * the mixture of native and bitmapped text does not provide the necessary quality.
-     */
-    private boolean allTextAsBitmaps = false;
-
-    /**
-     * Controls whether an RGB canvas is used when converting Java2D graphics to bitmaps.
-     * This can be used to work around problems with Apache Batik, for example, but setting
-     * this to true will increase memory consumption.
-     */
-    private final boolean useColorCanvas = false;
-
-    /**
-     * Controls whether the generation of PJL commands gets disabled.
-     */
-    private boolean disabledPJL = false;
+    private PCLRenderingUtil pclUtil;
 
     /** contains the pageWith of the last printed page */
     private long pageWidth = 0;
@@ -166,13 +148,23 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
     public PCLRenderer() {
     }
 
+    /** {@inheritDoc} */
+    public void setUserAgent(FOUserAgent agent) {
+        super.setUserAgent(agent);
+        this.pclUtil = new PCLRenderingUtil(getUserAgent());
+    }
+
+    PCLRenderingUtil getPCLUtil() {
+        return this.pclUtil;
+    }
+
     /**
      * Configures the renderer to trade speed for quality if desired. One example here is the way
      * that borders are rendered.
      * @param qualityBeforeSpeed true if quality is more important than speed
      */
     public void setQualityBeforeSpeed(boolean qualityBeforeSpeed) {
-        this.qualityBeforeSpeed = qualityBeforeSpeed;
+        pclUtil.setQualityBeforeSpeed(qualityBeforeSpeed);
     }
 
     /**
@@ -180,7 +172,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
      * @param disable true to disable PJL commands
      */
     public void setPJLDisabled(boolean disable) {
-        this.disabledPJL = disable;
+        pclUtil.setPJLDisabled(disable);
     }
 
     /**
@@ -188,7 +180,16 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
      * @return true if PJL generation is disabled.
      */
     public boolean isPJLDisabled() {
-        return this.disabledPJL;
+        return pclUtil.isPJLDisabled();
+    }
+
+    /**
+     * Controls whether all text should be generated as bitmaps or only text for which there's
+     * no native font.
+     * @param allTextAsBitmaps true if all text should be painted as bitmaps
+     */
+    public void setAllTextAsBitmaps(boolean allTextAsBitmaps) {
+        pclUtil.setAllTextAsBitmaps(allTextAsBitmaps);
     }
 
     /**
@@ -199,12 +200,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
         //The PCLRenderer uses the Java2D FontSetup which needs a special font setup
         //create a temp Image to test font metrics on
         fontInfo = inFontInfo;
-        BufferedImage fontImage = new BufferedImage(100, 100,
-                BufferedImage.TYPE_INT_RGB);
-        Graphics2D graphics2D = fontImage.createGraphics();
-        //The next line is important to get accurate font metrics!
-        graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
-                RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
 
         FontCollection[] fontCollections = new FontCollection[] {
                 new Base14FontCollection(graphics2D),
@@ -248,125 +244,6 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
         }
     }
 
-    /**
-     * Sets the current font (NOTE: Hard-coded font mappings ATM!)
-     * @param name the font name (internal F* names for now)
-     * @param size the font size
-     * @param text the text to be rendered (used to determine if there are non-printable chars)
-     * @return true if the font can be mapped to PCL
-     * @throws IOException if an I/O problem occurs
-     */
-    public boolean setFont(String name, float size, String text) throws IOException {
-        byte[] encoded = text.getBytes("ISO-8859-1");
-        for (int i = 0, c = encoded.length; i < c; i++) {
-            if (encoded[i] == 0x3F && text.charAt(i) != '?') {
-                return false;
-            }
-        }
-        int fontcode = 0;
-        if (name.length() > 1 && name.charAt(0) == 'F') {
-            try {
-                fontcode = Integer.parseInt(name.substring(1));
-            } catch (Exception e) {
-                log.error(e);
-            }
-        }
-        //Note "(ON" selects ISO 8859-1 symbol set as used by PCLGenerator
-        String formattedSize = gen.formatDouble2(size / 1000);
-        switch (fontcode) {
-        case 1:     // F1 = Helvetica
-            // gen.writeCommand("(8U");
-            // gen.writeCommand("(s1p" + formattedSize + "v0s0b24580T");
-            // Arial is more common among PCL5 printers than Helvetica - so use Arial
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s0b16602T");
-            break;
-        case 2:     // F2 = Helvetica Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s0b16602T");
-            break;
-        case 3:     // F3 = Helvetica Bold
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s3b16602T");
-            break;
-        case 4:     // F4 = Helvetica Bold Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s3b16602T");
-            break;
-        case 5:     // F5 = Times Roman
-            // gen.writeCommand("(8U");
-            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
-            // Times New is more common among PCL5 printers than Times - so use Times New
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s0b16901T");
-            break;
-        case 6:     // F6 = Times Italic
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s0b16901T");
-            break;
-        case 7:     // F7 = Times Bold
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v0s3b16901T");
-            break;
-        case 8:     // F8 = Times Bold Italic
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s1p" + formattedSize + "v1s3b16901T");
-            break;
-        case 9:     // F9 = Courier
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h0s0b4099T");
-            break;
-        case 10:    // F10 = Courier Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h1s0b4099T");
-            break;
-        case 11:    // F11 = Courier Bold
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h0s3b4099T");
-            break;
-        case 12:    // F12 = Courier Bold Oblique
-
-            gen.writeCommand("(0N");
-            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f))
-                    + "h1s3b4099T");
-            break;
-        case 13:    // F13 = Symbol
-
-            return false;
-            //gen.writeCommand("(19M");
-            //gen.writeCommand("(s1p" + formattedSize + "v0s0b16686T");
-            // ECMA Latin 1 Symbol Set in Times Roman???
-            // gen.writeCommand("(9U");
-            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
-            //break;
-        case 14:    // F14 = Zapf Dingbats
-
-            return false;
-            //gen.writeCommand("(14L");
-            //gen.writeCommand("(s1p" + formattedSize + "v0s0b45101T");
-            //break;
-        default:
-            //gen.writeCommand("(0N");
-            //gen.writeCommand("(s" + formattedSize + "V");
-            return false;
-        }
-        return true;
-    }
-
     /** {@inheritDoc} */
     public void startRenderer(OutputStream outputStream) throws IOException {
         log.debug("Rendering areas to PCL...");
@@ -491,52 +368,8 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
     }
 
     private Point2D transformedPoint(int x, int y) {
-        AffineTransform at = graphicContext.getTransform();
-        if (log.isTraceEnabled()) {
-            log.trace("Current transform: " + at);
-        }
-        Point2D.Float orgPoint = new Point2D.Float(x, y);
-        Point2D.Float transPoint = new Point2D.Float();
-        at.transform(orgPoint, transPoint);
-        //At this point we have the absolute position in FOP's coordinate system
-
-        //Now get PCL coordinates taking the current print direction and the logical page
-        //into account.
-        Dimension pageSize = currentPageDefinition.getPhysicalPageSize();
-        Rectangle logRect = currentPageDefinition.getLogicalPageRect();
-        switch (currentPrintDirection) {
-        case 0:
-            transPoint.x -= logRect.x;
-            transPoint.y -= logRect.y;
-            break;
-        case 90:
-            float ty = transPoint.x;
-            transPoint.x = pageSize.height - transPoint.y;
-            transPoint.y = ty;
-            transPoint.x -= logRect.y;
-            transPoint.y -= logRect.x;
-            break;
-        case 180:
-            transPoint.x = pageSize.width - transPoint.x;
-            transPoint.y = pageSize.height - transPoint.y;
-            transPoint.x -= pageSize.width - logRect.x - logRect.width;
-            transPoint.y -= pageSize.height - logRect.y - logRect.height;
-            //The next line is odd and is probably necessary due to the default value of the
-            //Text Length command: "1/2 inch less than maximum text length"
-            //I wonder why this isn't necessary for the 90 degree rotation. *shrug*
-            transPoint.y -= UnitConv.in2mpt(0.5);
-            break;
-        case 270:
-            float tx = transPoint.y;
-            transPoint.y = pageSize.width - transPoint.x;
-            transPoint.x = tx;
-            transPoint.x -= pageSize.height - logRect.y - logRect.height;
-            transPoint.y -= pageSize.width - logRect.x - logRect.width;
-            break;
-        default:
-            throw new IllegalStateException("Illegal print direction: " + currentPrintDirection);
-        }
-        return transPoint;
+        return PCLRenderingUtil.transformedPoint(x, y, graphicContext.getTransform(),
+                currentPageDefinition, currentPrintDirection);
     }
 
     private void changePrintDirection() {
@@ -640,9 +473,9 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
         try {
 
             final Color col = (Color)text.getTrait(Trait.COLOR);
-            boolean pclFont = allTextAsBitmaps
+            boolean pclFont = pclUtil.isAllTextAsBitmaps()
                     ? false
-                    : setFont(fontname, fontsize, text.getText());
+                    : HardcodedFonts.setFont(gen, fontname, fontsize, text.getText());
             if (pclFont) {
                 //this.currentFill = col;
                 if (col != null) {
@@ -1132,7 +965,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
         RendererContext context = super.createRendererContext(
                 x, y, width, height, foreignAttributes);
         context.setProperty(PCLRendererContextConstants.PCL_COLOR_CANVAS,
-                Boolean.valueOf(this.useColorCanvas));
+                Boolean.valueOf(pclUtil.isColorCanvasEnabled()));
         return context;
     }
 
@@ -1354,7 +1187,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
         if (bpsBefore == null && bpsAfter == null && bpsStart == null && bpsEnd == null) {
             return; //no borders to paint
         }
-        if (qualityBeforeSpeed) {
+        if (pclUtil.isQualityBeforeSpeed()) {
             drawQualityBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
         } else {
             drawFastBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
@@ -1673,15 +1506,4 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants {
         super.renderLeader(area);
     }
 
-    /**
-     * Controls whether all text should be generated as bitmaps or only text for which there's
-     * no native font.
-     * @param allTextAsBitmaps true if all text should be painted as bitmaps
-     */
-    public void setAllTextAsBitmaps(boolean allTextAsBitmaps) {
-        this.allTextAsBitmaps = allTextAsBitmaps;
-    }
-
-
-
 }
index 6d57825cd5871a8b9bf511e93245ee80dd5311a2..a97f551bb7d1bedad04e31ce5ac8356ef9cd6286 100644 (file)
 
 package org.apache.fop.render.pcl;
 
+import java.awt.Graphics2D;
+import java.util.List;
+
 import org.apache.avalon.framework.configuration.Configuration;
 
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontEventAdapter;
+import org.apache.fop.fonts.FontEventListener;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.render.DefaultFontResolver;
 import org.apache.fop.render.PrintRendererConfigurator;
 import org.apache.fop.render.Renderer;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.java2d.Base14FontCollection;
+import org.apache.fop.render.java2d.ConfiguredFontCollection;
+import org.apache.fop.render.java2d.InstalledFontCollection;
+import org.apache.fop.render.java2d.Java2DFontMetrics;
 
 /**
  * PCL Renderer configurator
  */
-public class PCLRendererConfigurator extends PrintRendererConfigurator {
+public class PCLRendererConfigurator extends PrintRendererConfigurator
+            implements IFDocumentHandlerConfigurator {
 
     /**
      * Default constructor
@@ -50,30 +67,75 @@ public class PCLRendererConfigurator extends PrintRendererConfigurator {
         if (cfg != null) {
             PCLRenderer pclRenderer = (PCLRenderer)renderer;
 
-            String rendering = cfg.getChild("rendering").getValue(null);
-            if ("quality".equalsIgnoreCase(rendering)) {
-                pclRenderer.setQualityBeforeSpeed(true);
-            } else if ("speed".equalsIgnoreCase(rendering)) {
-                pclRenderer.setQualityBeforeSpeed(false);
-            } else if (rendering != null) {
-                throw new FOPException(
-                        "Valid values for 'rendering' are 'quality' and 'speed'. Value found: "
-                            + rendering);
-            }
-
-            String textRendering = cfg.getChild("text-rendering").getValue(null);
-            if ("bitmap".equalsIgnoreCase(textRendering)) {
-                pclRenderer.setAllTextAsBitmaps(true);
-            } else if ("auto".equalsIgnoreCase(textRendering)) {
-                pclRenderer.setAllTextAsBitmaps(false);
-            } else if (textRendering != null) {
-                throw new FOPException(
-                        "Valid values for 'text-rendering' are 'auto' and 'bitmap'. Value found: "
-                            + textRendering);
-            }
-
-            pclRenderer.setPJLDisabled(cfg.getChild("disable-pjl").getValueAsBoolean(false));
+            PCLRenderingUtil pclUtil = pclRenderer.getPCLUtil();
+            configure(cfg, pclUtil);
         }
         super.configure(renderer);
     }
+
+    private void configure(Configuration cfg, PCLRenderingUtil pclUtil) throws FOPException {
+        String rendering = cfg.getChild("rendering").getValue(null);
+        if ("quality".equalsIgnoreCase(rendering)) {
+            pclUtil.setQualityBeforeSpeed(true);
+        } else if ("speed".equalsIgnoreCase(rendering)) {
+            pclUtil.setQualityBeforeSpeed(false);
+        } else if (rendering != null) {
+            throw new FOPException(
+                    "Valid values for 'rendering' are 'quality' and 'speed'. Value found: "
+                        + rendering);
+        }
+
+        String textRendering = cfg.getChild("text-rendering").getValue(null);
+        if ("bitmap".equalsIgnoreCase(textRendering)) {
+            pclUtil.setAllTextAsBitmaps(true);
+        } else if ("auto".equalsIgnoreCase(textRendering)) {
+            pclUtil.setAllTextAsBitmaps(false);
+        } else if (textRendering != null) {
+            throw new FOPException(
+                    "Valid values for 'text-rendering' are 'auto' and 'bitmap'. Value found: "
+                        + textRendering);
+        }
+
+        pclUtil.setPJLDisabled(cfg.getChild("disable-pjl").getValueAsBoolean(false));
+    }
+
+    // ---=== IFDocumentHandler configuration ===---
+
+    /** {@inheritDoc} */
+    public void configure(IFDocumentHandler documentHandler) throws FOPException {
+        Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
+        if (cfg != null) {
+            PCLDocumentHandler pclDocumentHandler = (PCLDocumentHandler)documentHandler;
+            PCLRenderingUtil pclUtil = pclDocumentHandler.getPCLUtil();
+            configure(cfg, pclUtil);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
+                throws FOPException {
+        FontManager fontManager = userAgent.getFactory().getFontManager();
+
+        Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
+
+        List fontCollections = new java.util.ArrayList();
+        fontCollections.add(new Base14FontCollection(graphics2D));
+        fontCollections.add(new InstalledFontCollection(graphics2D));
+
+        Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
+        if (cfg != null) {
+            FontResolver fontResolver = new DefaultFontResolver(userAgent);
+            FontEventListener listener = new FontEventAdapter(
+                    userAgent.getEventBroadcaster());
+            List fontList = buildFontList(cfg, fontResolver, listener);
+            fontCollections.add(new ConfiguredFontCollection(fontResolver, fontList));
+        }
+
+        fontManager.setup(fontInfo,
+                (FontCollection[])fontCollections.toArray(
+                        new FontCollection[fontCollections.size()]));
+        documentHandler.setFontInfo(fontInfo);
+    }
+
+
 }
diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderingContext.java b/src/java/org/apache/fop/render/pcl/PCLRenderingContext.java
new file mode 100644 (file)
index 0000000..4c41cbf
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.pcl;
+
+import java.awt.geom.Point2D;
+
+import org.apache.xmlgraphics.util.MimeConstants;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.AbstractRenderingContext;
+
+/**
+ * Rendering context for PCL production. The class is abstract and must be subclassed to
+ * provide the missing functionality.
+ */
+public abstract class PCLRenderingContext extends AbstractRenderingContext {
+
+    private PCLGenerator generator;
+    private PCLRenderingUtil pclUtil;
+    private boolean sourceTransparency = false;
+
+    /**
+     * Main constructor.
+     * @param userAgent the user agent
+     * @param generator the PCL generator
+     */
+    public PCLRenderingContext(FOUserAgent userAgent,
+            PCLGenerator generator, PCLRenderingUtil pclUtil) {
+        super(userAgent);
+        this.generator = generator;
+        this.pclUtil = pclUtil;
+    }
+
+    /** {@inheritDoc} */
+    public String getMimeType() {
+        return MimeConstants.MIME_PCL; //not applicable
+    }
+
+    /**
+     * Returns the PCL generator.
+     * @return the PCL generator
+     */
+    public PCLGenerator getPCLGenerator() {
+        return this.generator;
+    }
+
+    /**
+     * Returns the PCL rendering utility.
+     * @return the PCL rendering utility.
+     */
+    public PCLRenderingUtil getPCLUtil() {
+        return this.pclUtil;
+    }
+
+    /**
+     * Indicates whether source transparency should be enabled when painting bitmaps.
+     * @return true when source transparency is enabled
+     */
+    public boolean isSourceTransparencyEnabled() {
+        return this.sourceTransparency;
+    }
+
+    /**
+     * Enables or disables source transparency when painting bitmaps.
+     * @param value true to enable source transparency, false to disable
+     */
+    public void setSourceTransparencyEnabled(boolean value) {
+        this.sourceTransparency = value;
+    }
+
+    /**
+     * Transforms a point into the PCL coordinate system.
+     * @param x the X coordinate
+     * @param y the Y coordinate
+     * @return the transformed point in PCL coordinates
+     */
+    public abstract Point2D transformedPoint(int x, int y);
+
+}
index 63906232d9ec3491ca0ec75f60ba6d62fb1d3294..01ca79fff5ed95806a35b9b2122250a35a88ba71 100644 (file)
 
 package org.apache.fop.render.pcl;
 
+import java.awt.Dimension;
+import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.xmlgraphics.util.UnitConv;
+
 import org.apache.fop.apps.FOUserAgent;
 
 /**
@@ -65,16 +70,6 @@ public class PCLRenderingUtil {
         initialize();
     }
 
-    private static boolean booleanValueOf(Object obj) {
-        if (obj instanceof Boolean) {
-            return ((Boolean)obj).booleanValue();
-        } else if (obj instanceof String) {
-            return Boolean.valueOf((String)obj).booleanValue();
-        } else {
-            throw new IllegalArgumentException("Boolean or \"true\" or \"false\" expected.");
-        }
-    }
-
     private void initialize() {
     }
 
@@ -95,6 +90,14 @@ public class PCLRenderingUtil {
         this.qualityBeforeSpeed = qualityBeforeSpeed;
     }
 
+    /**
+     * Indicates whether quality is more important than speed.
+     * @return true if quality is favored over speed
+     */
+    public boolean isQualityBeforeSpeed() {
+        return this.qualityBeforeSpeed;
+    }
+
     /**
      * Controls whether PJL commands shall be generated by the PCL renderer.
      * @param disable true to disable PJL commands
@@ -111,6 +114,15 @@ public class PCLRenderingUtil {
         return this.disabledPJL;
     }
 
+    /**
+     * Controls whether all text should be generated as bitmaps or only text for which there's
+     * no native font.
+     * @param allTextAsBitmaps true if all text should be painted as bitmaps
+     */
+    public void setAllTextAsBitmaps(boolean allTextAsBitmaps) {
+        this.allTextAsBitmaps = allTextAsBitmaps;
+    }
+
     /**
      * Indicates whether all text shall be painted as bitmaps.
      * @return true if all text shall be painted as bitmaps
@@ -119,6 +131,14 @@ public class PCLRenderingUtil {
         return this.allTextAsBitmaps;
     }
 
+    /**
+     * Indicates whether a color canvas is used when creating bitmap images.
+     * @return true if a color canvas is used.
+     */
+    public boolean isColorCanvasEnabled() {
+        return this.useColorCanvas;
+    }
+
     /**
      * Determines the print direction based on the given transformation matrix. This method
      * only detects right angles (0, 90, 180, 270). If any other angle is determined, 0 is
@@ -143,5 +163,63 @@ public class PCLRenderingUtil {
         return newDir;
     }
 
+    /**
+     * Returns a coordinate in PCL's coordinate system when given a coordinate in the user
+     * coordinate system.
+     * @param x the X coordinate
+     * @param y the Y coordinate
+     * @param transform the currently valid transformation matrix
+     * @param pageDefinition the currently valid page definition
+     * @param printDirection the currently valid print direction
+     * @return the transformed point
+     */
+    public static Point2D transformedPoint(int x, int y, AffineTransform transform,
+            PCLPageDefinition pageDefinition, int printDirection) {
+        if (log.isTraceEnabled()) {
+            log.trace("Current transform: " + transform);
+        }
+        Point2D.Float orgPoint = new Point2D.Float(x, y);
+        Point2D.Float transPoint = new Point2D.Float();
+        transform.transform(orgPoint, transPoint);
+        //At this point we have the absolute position in FOP's coordinate system
+
+        //Now get PCL coordinates taking the current print direction and the logical page
+        //into account.
+        Dimension pageSize = pageDefinition.getPhysicalPageSize();
+        Rectangle logRect = pageDefinition.getLogicalPageRect();
+        switch (printDirection) {
+        case 0:
+            transPoint.x -= logRect.x;
+            transPoint.y -= logRect.y;
+            break;
+        case 90:
+            float ty = transPoint.x;
+            transPoint.x = pageSize.height - transPoint.y;
+            transPoint.y = ty;
+            transPoint.x -= logRect.y;
+            transPoint.y -= logRect.x;
+            break;
+        case 180:
+            transPoint.x = pageSize.width - transPoint.x;
+            transPoint.y = pageSize.height - transPoint.y;
+            transPoint.x -= pageSize.width - logRect.x - logRect.width;
+            transPoint.y -= pageSize.height - logRect.y - logRect.height;
+            //The next line is odd and is probably necessary due to the default value of the
+            //Text Length command: "1/2 inch less than maximum text length"
+            //I wonder why this isn't necessary for the 90 degree rotation. *shrug*
+            transPoint.y -= UnitConv.in2mpt(0.5);
+            break;
+        case 270:
+            float tx = transPoint.y;
+            transPoint.y = pageSize.width - transPoint.x;
+            transPoint.x = tx;
+            transPoint.x -= pageSize.height - logRect.y - logRect.height;
+            transPoint.y -= pageSize.width - logRect.x - logRect.width;
+            break;
+        default:
+            throw new IllegalStateException("Illegal print direction: " + printDirection);
+        }
+        return transPoint;
+    }
 
 }
index 5273220e7c19672a563060e38144a1aca1ba0a55..5baaedbead4684d672bcfa9100e80664dcefb885 100644 (file)
@@ -62,9 +62,6 @@ public class PDFPainter extends AbstractIFPainter {
 
     private PDFDocumentHandler documentHandler;
 
-    /** Holds the intermediate format state */
-    protected IFState state;
-
     /** The current content generator */
     protected PDFContentGenerator generator;
 
@@ -324,27 +321,4 @@ public class PDFPainter extends AbstractIFPainter {
         textutil.writeTJ();
     }
 
-    /** {@inheritDoc} */
-    public void setFont(String family, String style, Integer weight, String variant, Integer size,
-            Color color) throws IFException {
-        if (family != null) {
-            state.setFontFamily(family);
-        }
-        if (style != null) {
-            state.setFontStyle(style);
-        }
-        if (weight != null) {
-            state.setFontWeight(weight.intValue());
-        }
-        if (variant != null) {
-            state.setFontVariant(variant);
-        }
-        if (size != null) {
-            state.setFontSize(size.intValue());
-        }
-        if (color != null) {
-            state.setTextColor(color);
-        }
-    }
-
 }
index e0d12d9c7ae12d26966616c6c2ad51fa1a83f7b7..c9b7b7e3b93a92ac84aad15d5a228e75b398f14f 100644 (file)
@@ -68,9 +68,6 @@ public class SVGPainter extends AbstractIFPainter implements SVGConstants {
     /** logging instance */
     private static Log log = LogFactory.getLog(SVGPainter.class);
 
-    /** Holds the intermediate format state */
-    protected IFState state;
-
     private AbstractSVGDocumentHandler parent;
 
     /** The SAX content handler that receives the generated XML events. */
@@ -350,29 +347,6 @@ public class SVGPainter extends AbstractIFPainter implements SVGConstants {
         }
     }
 
-    /** {@inheritDoc} */
-    public void setFont(String family, String style, Integer weight, String variant, Integer size,
-            Color color) throws IFException {
-        if (family != null) {
-            state.setFontFamily(family);
-        }
-        if (style != null) {
-            state.setFontStyle(style);
-        }
-        if (weight != null) {
-            state.setFontWeight(weight.intValue());
-        }
-        if (variant != null) {
-            state.setFontVariant(variant);
-        }
-        if (size != null) {
-            state.setFontSize(size.intValue());
-        }
-        if (color != null) {
-            state.setTextColor(color);
-        }
-    }
-
     private void leaveTextMode() throws SAXException {
         assert this.mode == MODE_TEXT;
         handler.endElement("g");