]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
GOCA improvements:
authorJeremias Maerki <jeremias@apache.org>
Sun, 11 Jan 2009 11:15:34 +0000 (11:15 +0000)
committerJeremias Maerki <jeremias@apache.org>
Sun, 11 Jan 2009 11:15:34 +0000 (11:15 +0000)
Improved font size and line width calculation.
Removed superfluous AFPGraphics2D.setFontInfo() method.
Avoid ClassCastException inside SVG filter operations when not an AFPGraphics2D is passed in.
Fixed line width state handling (it appears as if after a new segment the line width is reset. Found that out empirically. Didn't find the corresponding reference in the spec).

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

src/java/org/apache/fop/afp/AFPGraphics2D.java
src/java/org/apache/fop/afp/modca/GraphicsObject.java
src/java/org/apache/fop/afp/svg/AFPTextHandler.java
src/java/org/apache/fop/afp/svg/AFPTextPainter.java

index ee160fecade2e645cb55acea97708c3383a73bf7..6f552ae5b87b66015a73fd76a165eb96abe5d10e 100644 (file)
@@ -47,11 +47,7 @@ import java.io.IOException;
 import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.fop.afp.goca.GraphicsSetLineType;
-import org.apache.fop.afp.modca.GraphicsObject;
-import org.apache.fop.afp.svg.AFPGraphicsConfiguration;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.svg.NativeImageHandler;
+
 import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageSize;
 import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
@@ -61,6 +57,13 @@ 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;
+import org.apache.fop.afp.modca.GraphicsObject;
+import org.apache.fop.afp.svg.AFPGraphicsConfiguration;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.svg.NativeImageHandler;
 
 /**
  * This is a concrete implementation of <tt>AbstractGraphics2D</tt> (and
@@ -180,6 +183,32 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
         this.gc = gc;
     }
 
+    private int getResolution() {
+        return this.paintingState.getResolution();
+    }
+
+    /**
+     * Converts a length value to an absolute value.
+     * Please note that this only uses the "ScaleY" factor, so this will result
+     * in a bad value should "ScaleX" and "ScaleY" be different.
+     * @param length the length
+     * @return the absolute length
+     */
+    public double convertToAbsoluteLength(double length) {
+        AffineTransform current = getTransform();
+        double mult = getResolution() / (double)UnitConv.IN2PT;
+        double factor = -current.getScaleY() / mult;
+        return length * factor;
+    }
+
+    /** IBM's AFP Workbench paints lines that are wider than expected. We correct manually. */
+    private static final double GUESSED_WIDTH_CORRECTION = 1.7;
+
+    private static final double SPEC_NORMAL_LINE_WIDTH = UnitConv.in2pt(0.01); //"approx" 0.01 inch
+    private static final double NORMAL_LINE_WIDTH
+        = SPEC_NORMAL_LINE_WIDTH * GUESSED_WIDTH_CORRECTION;
+
+
     /**
      * Apply the stroke to the AFP graphics object.
      * This takes the java stroke and outputs the appropriate settings
@@ -193,7 +222,17 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
 
             // set line width
             float lineWidth = basicStroke.getLineWidth();
-            graphicsObj.setLineWidth(Math.round(lineWidth / 2));
+            if (false) {
+                //Old approach. Retained until verified problems with 1440 resolution
+                graphicsObj.setLineWidth(Math.round(lineWidth / 2));
+            } else {
+                double absoluteLineWidth = lineWidth * Math.abs(getTransform().getScaleY());
+                double multiplier = absoluteLineWidth / NORMAL_LINE_WIDTH;
+                graphicsObj.setLineWidth((int)Math.round(multiplier));
+                //TODO Use GSFLW instead of GSLW for higher accuracy?
+            }
+
+            //No line join, miter limit and end cap support in GOCA. :-(
 
             // set line type/style (note: this is an approximation at best!)
             float[] dashArray = basicStroke.getDashArray();
@@ -650,15 +689,6 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
         return this.paintingState;
     }
 
-    /**
-     * Sets the FontInfo
-     *
-     * @param the FontInfo
-     */
-    public void setFontInfo(FontInfo fontInfo) {
-        this.fontInfo = fontInfo;
-    }
-
     /**
      * Returns the FontInfo
      *
@@ -687,7 +717,7 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
     /** {@inheritDoc} */
     public void addNativeImage(org.apache.xmlgraphics.image.loader.Image image,
             float x, float y, float width, float height) {
-        log.debug("NYI: addNativeImage() "+ "image=" + image
+        log.debug("NYI: addNativeImage() " + "image=" + image
                 + ",x=" + x + ",y=" + y + ",width=" + width + ",height=" + height);
     }
 
index 24b3f949e183333950ab55ceda6adf2849a1b718..a18ee1f074ed37712a1cf224591dd040af167505 100644 (file)
@@ -179,20 +179,20 @@ public class GraphicsObject extends AbstractDataObject {
     }
 
     /**
-     * Sets whether the following shape is to be filled
+     * Sets whether the following shape is to be filled.
      *
      * @param fill true if the following shape is to be filled
      */
     public void setFill(boolean fill) {
-        setPatternSymbol(fill ?
-                GraphicsSetPatternSymbol.SOLID_FILL :
-                    GraphicsSetPatternSymbol.NO_FILL);
+        setPatternSymbol(fill
+                ? GraphicsSetPatternSymbol.SOLID_FILL
+                : GraphicsSetPatternSymbol.NO_FILL);
     }
 
     /**
-     * Sets the fill pattern of the next shape
+     * Sets the fill pattern of the next shape.
      *
-     * @param the fill pattern of the next shape
+     * @param patternSymbol the fill pattern of the next shape
      */
     public void setPatternSymbol(byte patternSymbol) {
         if (patternSymbol != graphicsState.patternSymbol) {
@@ -332,6 +332,7 @@ public class GraphicsObject extends AbstractDataObject {
      */
     public void newSegment() {
         getData().newSegment();
+        graphicsState.lineWidth = 0; //Looks like a new segment invalidates the graphics state
     }
 
     /** {@inheritDoc} */
@@ -366,7 +367,7 @@ public class GraphicsObject extends AbstractDataObject {
     }
 
     /** the internal graphics state */
-    private class GraphicsState {
+    private static class GraphicsState {
         /** the current color */
         private Color color;
 
index f44fde2696fd8ad8bc1d207734e6fc93644d0c09..b7393a3b2beed93ceb3eba2518ffd007b9a6929e 100644 (file)
@@ -25,6 +25,7 @@ import java.io.IOException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.afp.AFPGraphics2D;
 import org.apache.fop.afp.AFPPaintingState;
 import org.apache.fop.afp.fonts.AFPFont;
@@ -77,7 +78,6 @@ public class AFPTextHandler implements FOPTextHandler {
      * @return a font reference
      */
     private int registerPageFont(AFPPageFonts pageFonts, String internalFontName, int fontSize) {
-        FontInfo fontInfo = getFontInfo();
         AFPFont afpFont = (AFPFont)fontInfo.getFonts().get(internalFontName);
         // register if necessary
         AFPFontAttributes afpFontAttributes = pageFonts.registerFont(
@@ -101,37 +101,45 @@ public class AFPTextHandler implements FOPTextHandler {
      * {@inheritDoc}
      */
     public void drawString(Graphics2D g, String str, float x, float y) throws IOException {
-        log.debug("drawString() str=" + str + ", x=" + x + ", y=" + y);
-        AFPGraphics2D g2d = (AFPGraphics2D)g;
-        GraphicsObject graphicsObj = g2d.getGraphicsObject();
-        Color color = g2d.getColor();
-
-        // set the color
-        AFPPaintingState paintingState = g2d.getPaintingState();
-        if (paintingState.setColor(color)) {
-            graphicsObj.setColor(color);
+        if (log.isDebugEnabled()) {
+            log.debug("drawString() str=" + str + ", x=" + x + ", y=" + y);
         }
-
-        // set the character set
-        int fontReference = 0;
-        AFPPageFonts pageFonts = paintingState.getPageFonts();
-        if (overrideFont != null) {
-            String internalFontName = overrideFont.getFontName();
-            int fontSize = overrideFont.getFontSize();
+        if (g instanceof AFPGraphics2D) {
+            AFPGraphics2D g2d = (AFPGraphics2D)g;
+            GraphicsObject graphicsObj = g2d.getGraphicsObject();
+            Color color = g2d.getColor();
+
+            // set the color
+            AFPPaintingState paintingState = g2d.getPaintingState();
+            if (paintingState.setColor(color)) {
+                graphicsObj.setColor(color);
+            }
+
+            // set the character set
+            int fontReference = 0;
+            int fontSize;
+            String internalFontName;
+            AFPPageFonts pageFonts = paintingState.getPageFonts();
+            if (overrideFont != null) {
+                internalFontName = overrideFont.getFontName();
+                fontSize = overrideFont.getFontSize();
+            } else {
+                java.awt.Font awtFont = g2d.getFont();
+                Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont);
+                internalFontName = fopFont.getFontName();
+                fontSize = fopFont.getFontSize();
+            }
+            fontSize = (int)Math.round(
+                    g2d.convertToAbsoluteLength(fontSize));
             fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
+            graphicsObj.setCharacterSet(fontReference);
+
+            // add the character string
+            graphicsObj.addString(str, Math.round(x), Math.round(y));
         } else {
-            java.awt.Font awtFont = g2d.getFont();
-//            AffineTransform fontTransform = awtFont.getTransform();
-            FontInfo fontInfo = getFontInfo();
-            Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont);
-            String internalFontName = fopFont.getFontName();
-            int fontSize = fopFont.getFontSize();
-            fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
+            //Inside Batik's SVG filter operations, you won't get an AFPGraphics2D
+            g.drawString(str, x, y);
         }
-        graphicsObj.setCharacterSet(fontReference);
-
-        // add the character string
-        graphicsObj.addString(str, Math.round(x), Math.round(y));
     }
 
     /**
index c6a38b1b5f10b8719e456ba61cc9bd7ca982db30..3c6f034ec2b6b47dbaac4a6c9351babab9790c4c 100644 (file)
@@ -19,6 +19,9 @@
 
 package org.apache.fop.afp.svg;
 
+import java.awt.Graphics2D;
+
+import org.apache.fop.afp.AFPGraphics2D;
 import org.apache.fop.svg.AbstractFOPTextPainter;
 import org.apache.fop.svg.FOPTextHandler;
 
@@ -41,4 +44,9 @@ public class AFPTextPainter extends AbstractFOPTextPainter {
         super(nativeTextHandler);
     }
 
+    /** {@inheritDoc} */
+    protected boolean isSupportedGraphics2D(Graphics2D g2d) {
+        return g2d instanceof AFPGraphics2D;
+    }
+
 }