Author: jeremias
Date: Wed Aug  6 11:40:47 2008
New Revision: 683364

URL: http://svn.apache.org/viewvc?rev=683364&view=rev
Log:
Fix for kerning (switched to SVG semantics, now working correctly for both SVG 
and PDF)
Introduced a special SVG image handler (the successor to PDFSVGHandler).
Fixed placement of patterns and links in SVGs for PDF output (the 
transformations for viewbox and group were not recorded in the state).

Added:
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
   (contents, props changed)
      - copied, changed from r680381, 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java
Modified:
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/META-INF/services/org.apache.fop.render.ImageHandler
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFRenderer.java

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/META-INF/services/org.apache.fop.render.ImageHandler
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/META-INF/services/org.apache.fop.render.ImageHandler?rev=683364&r1=683363&r2=683364&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/META-INF/services/org.apache.fop.render.ImageHandler
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/META-INF/services/org.apache.fop.render.ImageHandler
 Wed Aug  6 11:40:47 2008
@@ -2,3 +2,4 @@
 org.apache.fop.render.pdf.PDFImageHandlerRenderedImage
 org.apache.fop.render.pdf.PDFImageHandlerRawJPEG
 org.apache.fop.render.pdf.PDFImageHandlerRawCCITTFax
+org.apache.fop.render.pdf.PDFImageHandlerSVG

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java?rev=683364&r1=683363&r2=683364&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java
 Wed Aug  6 11:40:47 2008
@@ -670,14 +670,14 @@
                 glyphAdjust -= tls;
             }
             curX += font.getCharWidth(ch);
-            if (letterAdjust != null && i < l - 1) {
-                glyphAdjust -= letterAdjust[i + 1];
+            if (letterAdjust != null && i < l) {
+                glyphAdjust -= letterAdjust[i];
             }
 
             float adjust = glyphAdjust / fontSize;
 
             if (adjust != 0) {
-                dx[i] = Math.round(adjust);
+                dx[i] = Math.round(adjust * -10);
                 if (dx[i] != 0) {
                     hasDX = true;
                 }

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java?rev=683364&r1=683363&r2=683364&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
 Wed Aug  6 11:40:47 2008
@@ -185,23 +185,27 @@
     }
 
     /**
-     * Concatenates the given transformation matrix with the current one.
-     * @param transform the transformation matrix (in points)
-     */
-    public void concatenate(AffineTransform transform) {
-        concatenate(transform, false);
+     * Converts a transformation matrix from millipoints to points.
+     * @param transform the transformation matrix (in millipoints)
+     * @return the converted transformation matrix (in points)
+     */
+    public AffineTransform toPoints(AffineTransform transform) {
+        final double[] matrix = new double[6];
+        transform.getMatrix(matrix);
+        //Convert from millipoints to points
+        matrix[4] /= 1000;
+        matrix[5] /= 1000;
+        return new AffineTransform(matrix);
     }
 
     /**
      * Concatenates the given transformation matrix with the current one.
-     * @param transform the transformation matrix
-     * @param convertMillipoints true if the coordinates are in millipoints 
and need to be
-     *          converted to points
+     * @param transform the transformation matrix (in points)
      */
-    public void concatenate(AffineTransform transform, boolean 
convertMillipoints) {
+    public void concatenate(AffineTransform transform) {
         if (!transform.isIdentity()) {
             currentState.concatenate(transform);
-            currentStream.add(CTMHelper.toPDFString(transform, 
convertMillipoints) + " cm\n");
+            currentStream.add(CTMHelper.toPDFString(transform, false) + " 
cm\n");
         }
     }
 

Copied: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
 (from r680381, 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java)
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java?p2=xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java&p1=xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java&r1=680381&r2=683364&rev=683364&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
 Wed Aug  6 11:40:47 2008
@@ -19,41 +19,157 @@
 
 package org.apache.fop.render.pdf;
 
-import java.awt.Point;
+import java.awt.Color;
 import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
 import java.io.IOException;
-import java.util.Map;
 
-import org.w3c.dom.Document;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.util.SVGConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import org.apache.xmlgraphics.image.loader.Image;
 import org.apache.xmlgraphics.image.loader.ImageFlavor;
 import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
 
-import org.apache.fop.pdf.PDFXObject;
-import org.apache.fop.render.RendererContext;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.image.loader.batik.BatikImageFlavors;
+import org.apache.fop.render.ImageHandler;
+import org.apache.fop.render.RenderingContext;
+import org.apache.fop.svg.PDFAElementBridge;
+import org.apache.fop.svg.PDFBridgeContext;
+import org.apache.fop.svg.PDFGraphics2D;
+import org.apache.fop.svg.SVGEventProducer;
+import org.apache.fop.svg.SVGUserAgent;
 
 /**
- * PDFImageHandler implementation which handles XML-based images.
+ * Image Handler implementation which handles SVG images.
  */
-public class PDFImageHandlerXML implements PDFImageHandler {
+public class PDFImageHandlerSVG implements ImageHandler {
 
-    private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
-        ImageFlavor.XML_DOM,
-    };
+    /** logging instance */
+    private static Log log = LogFactory.getLog(PDFImageHandlerSVG.class);
 
     /** [EMAIL PROTECTED] */
-    public PDFXObject generateImage(RendererContext context, Image image,
-            Point origin, Rectangle pos)
-            throws IOException {
-        PDFRenderer renderer = (PDFRenderer)context.getRenderer();
-        ImageXMLDOM imgXML = (ImageXMLDOM)image;
-        Document doc = imgXML.getDocument();
-        String ns = imgXML.getRootNamespace();
-        Map foreignAttributes = (Map)context.getProperty(
-                PDFRendererContextConstants.FOREIGN_ATTRIBUTES);
-        renderer.renderDocument(doc, ns, pos, foreignAttributes);
-        return null;
+    public void handleImage(RenderingContext context, Image image, Rectangle 
pos)
+                throws IOException {
+        PDFRenderingContext pdfContext = (PDFRenderingContext)context;
+        PDFContentGenerator generator = pdfContext.getGenerator();
+        ImageXMLDOM imageSVG = (ImageXMLDOM)image;
+
+        FOUserAgent userAgent = context.getUserAgent();
+        final float deviceResolution = userAgent.getTargetResolution();
+        if (log.isDebugEnabled()) {
+            log.debug("Generating SVG at " + deviceResolution + "dpi.");
+        }
+
+        final float uaResolution = userAgent.getSourceResolution();
+        SVGUserAgent ua = new SVGUserAgent(userAgent, new AffineTransform());
+
+        //Scale for higher resolution on-the-fly images from Batik
+        double s = uaResolution / deviceResolution;
+        AffineTransform resolutionScaling = new AffineTransform();
+        resolutionScaling.scale(s, s);
+
+        GVTBuilder builder = new GVTBuilder();
+
+        //Controls whether text painted by Batik is generated using text or 
path operations
+        boolean strokeText = false;
+        //TODO connect with configuration elsewhere.
+
+        BridgeContext ctx = new PDFBridgeContext(ua,
+                (strokeText ? null : pdfContext.getFontInfo()),
+                userAgent.getFactory().getImageManager(),
+                userAgent.getImageSessionContext(),
+                new AffineTransform());
+
+        GraphicsNode root;
+        try {
+            root = builder.build(ctx, imageSVG.getDocument());
+            builder = null;
+        } catch (Exception e) {
+            SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
+                    context.getUserAgent().getEventBroadcaster());
+            eventProducer.svgNotBuilt(this, e, 
image.getInfo().getOriginalURI());
+            return;
+        }
+        // get the 'width' and 'height' attributes of the SVG document
+        float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
+        float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
+
+        float sx = pos.width / (float)w;
+        float sy = pos.height / (float)h;
+
+        //Scaling and translation for the bounding box of the image
+        AffineTransform scaling = new AffineTransform(
+                sx, 0, 0, sy, pos.x / 1000f, pos.y / 1000f);
+
+        //Transformation matrix that establishes the local coordinate system 
for the SVG graphic
+        //in relation to the current coordinate system
+        AffineTransform imageTransform = new AffineTransform();
+        imageTransform.concatenate(scaling);
+        imageTransform.concatenate(resolutionScaling);
+
+        /*
+         * Clip to the svg area.
+         * Note: To have the svg overlay (under) a text area then use
+         * an fo:block-container
+         */
+        generator.comment("SVG setup");
+        generator.saveGraphicsState();
+        generator.setColor(Color.black, false);
+        generator.setColor(Color.black, true);
+
+        if (!scaling.isIdentity()) {
+            generator.comment("viewbox");
+            generator.add(CTMHelper.toPDFString(scaling, false) + " cm\n");
+        }
+
+        //SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
+
+        PDFGraphics2D graphics = new PDFGraphics2D(true, 
pdfContext.getFontInfo(),
+                generator.getDocument(),
+                generator.getResourceContext(), 
pdfContext.getPage().referencePDF(),
+                "", 0);
+        graphics.setGraphicContext(new 
org.apache.xmlgraphics.java2d.GraphicContext());
+
+        if (!resolutionScaling.isIdentity()) {
+            generator.comment("resolution scaling for " + uaResolution
+                        + " -> " + deviceResolution + "\n");
+            generator.add(
+                    CTMHelper.toPDFString(resolutionScaling, false) + " cm\n");
+            graphics.scale(1 / s, 1 / s);
+        }
+
+        generator.comment("SVG start");
+
+        //Save state and update coordinate system for the SVG image
+        generator.getState().push();
+        generator.getState().concatenate(imageTransform);
+
+        //Now that we have the complete transformation matrix for the image, 
we can update the
+        //transformation matrix for the AElementBridge.
+        PDFAElementBridge aBridge = (PDFAElementBridge)ctx.getBridge(
+                SVGDOMImplementation.SVG_NAMESPACE_URI, 
SVGConstants.SVG_A_TAG);
+        
aBridge.getCurrentTransform().setTransform(generator.getState().getTransform());
+
+        graphics.setPDFState(generator.getState());
+        graphics.setOutputStream(generator.getOutputStream());
+        try {
+            root.paint(graphics);
+            generator.add(graphics.getString());
+        } catch (Exception e) {
+            SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
+                    context.getUserAgent().getEventBroadcaster());
+            eventProducer.svgRenderingError(this, e, 
image.getInfo().getOriginalURI());
+        }
+        generator.getState().pop();
+        generator.restoreGraphicsState();
+        generator.comment("SVG end");
     }
 
     /** [EMAIL PROTECTED] */
@@ -68,7 +184,17 @@
 
     /** [EMAIL PROTECTED] */
     public ImageFlavor[] getSupportedImageFlavors() {
-        return FLAVORS;
+        return new ImageFlavor[] {
+                BatikImageFlavors.SVG_DOM
+            };
+    }
+
+    /** [EMAIL PROTECTED] */
+    public boolean isCompatible(RenderingContext targetContext, Image image) {
+        return (image == null
+                || (image instanceof ImageXMLDOM
+                        && 
image.getFlavor().isCompatible(BatikImageFlavors.SVG_DOM))
+                && targetContext instanceof PDFRenderingContext);
     }
 
 }

Propchange: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Wed Aug  6 11:40:47 2008
@@ -0,0 +1 @@
+/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java:603620-680380

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java?rev=683364&r1=683363&r2=683364&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java
 Wed Aug  6 11:40:47 2008
@@ -209,8 +209,8 @@
         this.generator = new PDFContentGenerator(this.pdfDoc, 
this.outputStream, this.currentPage);
         // Transform the PDF's default coordinate system (0,0 at lower left) 
to the PDFPainter's
         AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 
0,
-                size.height);
-        generator.concatenate(basicPageTransform, true);
+                size.height / 1000f);
+        generator.concatenate(basicPageTransform);
     }
 
     /** [EMAIL PROTECTED] */
@@ -260,7 +260,7 @@
     public void startViewport(AffineTransform transform, Dimension size, 
Rectangle clipRect)
             throws IFException {
         generator.saveGraphicsState();
-        generator.add(CTMHelper.toPDFString(transform, true) + " cm\n");
+        generator.concatenate(generator.toPoints(transform));
         if (clipRect != null) {
             StringBuffer sb = new StringBuffer();
             sb.append(format(clipRect.x)).append(' ');
@@ -279,7 +279,7 @@
     /** [EMAIL PROTECTED] */
     public void startGroup(AffineTransform transform) throws IFException {
         generator.saveGraphicsState();
-        generator.add(CTMHelper.toPDFString(transform, true) + " cm\n");
+        generator.concatenate(generator.toPoints(transform));
     }
 
     /** [EMAIL PROTECTED] */
@@ -470,7 +470,7 @@
         int dxl = (dx != null ? dx.length : 0);
 
         if (dx != null && dxl > 0 && dx[0] != 0) {
-            textutil.adjustGlyphTJ(dx[0] / fontSize);
+            textutil.adjustGlyphTJ(dx[0]);
         }
         for (int i = 0; i < l; i++) {
             char orgChar = text.charAt(i);
@@ -504,7 +504,7 @@
             }
 
             if (glyphAdjust != 0) {
-                textutil.adjustGlyphTJ(glyphAdjust / fontSize);
+                textutil.adjustGlyphTJ(-glyphAdjust / 10f);
             }
 
         }

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFRenderer.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFRenderer.java?rev=683364&r1=683363&r2=683364&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFRenderer.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFRenderer.java
 Wed Aug  6 11:40:47 2008
@@ -34,6 +34,7 @@
 import java.util.Map;
 
 import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
@@ -1296,8 +1297,9 @@
             info = manager.getImageInfo(uri, sessionContext);
 
             Map hints = ImageUtil.getDefaultHints(sessionContext);
+            ImageFlavor[] supportedFlavors = 
imageHandlerRegistry.getSupportedFlavors();
             org.apache.xmlgraphics.image.loader.Image img = manager.getImage(
-                        info, imageHandlerRegistry.getSupportedFlavors(), 
hints, sessionContext);
+                        info, supportedFlavors, hints, sessionContext);
 
             //First check for a dynamically registered handler
             PDFImageHandler handler = 
imageHandlerRegistry.getHandler(img.getClass());



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to