From f6fafddeff005039538d90c825f723ba69f73564 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Sun, 11 Jan 2009 11:15:34 +0000 Subject: [PATCH] GOCA improvements: 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 --- .../org/apache/fop/afp/AFPGraphics2D.java | 62 +++++++++++++----- .../apache/fop/afp/modca/GraphicsObject.java | 15 +++-- .../apache/fop/afp/svg/AFPTextHandler.java | 64 +++++++++++-------- .../apache/fop/afp/svg/AFPTextPainter.java | 8 +++ 4 files changed, 98 insertions(+), 51 deletions(-) diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java index ee160feca..6f552ae5b 100644 --- a/src/java/org/apache/fop/afp/AFPGraphics2D.java +++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java @@ -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 AbstractGraphics2D (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); } diff --git a/src/java/org/apache/fop/afp/modca/GraphicsObject.java b/src/java/org/apache/fop/afp/modca/GraphicsObject.java index 24b3f949e..a18ee1f07 100644 --- a/src/java/org/apache/fop/afp/modca/GraphicsObject.java +++ b/src/java/org/apache/fop/afp/modca/GraphicsObject.java @@ -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; diff --git a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java index f44fde269..b7393a3b2 100644 --- a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java +++ b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java @@ -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)); } /** diff --git a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java index c6a38b1b5..3c6f034ec 100644 --- a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java +++ b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java @@ -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; + } + } -- 2.39.5