KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > ps > PSSVGHandler


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: PSSVGHandler.java 426576 2006-07-28 15:44:37Z jeremias $ */
19
20 package org.apache.fop.render.ps;
21
22 // Java
23
import java.awt.geom.AffineTransform JavaDoc;
24 import java.io.IOException JavaDoc;
25
26 // DOM
27
import org.w3c.dom.Document JavaDoc;
28 import org.w3c.dom.svg.SVGDocument;
29 import org.w3c.dom.svg.SVGSVGElement;
30
31 // Batik
32
import org.apache.avalon.framework.configuration.Configuration;
33 import org.apache.batik.bridge.GVTBuilder;
34 import org.apache.batik.bridge.BridgeContext;
35 import org.apache.batik.bridge.ViewBox;
36 import org.apache.batik.dom.svg.SVGDOMImplementation;
37 import org.apache.batik.gvt.GraphicsNode;
38
39 // FOP
40
import org.apache.fop.fonts.FontInfo;
41 import org.apache.fop.render.Renderer;
42 import org.apache.fop.render.XMLHandler;
43 import org.apache.fop.render.RendererContext;
44 import org.apache.fop.svg.SVGUserAgent;
45 import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
46 import org.apache.xmlgraphics.ps.PSGenerator;
47
48 // Commons-Logging
49
import org.apache.commons.logging.Log;
50 import org.apache.commons.logging.LogFactory;
51
52 /**
53  * PostScript XML handler for SVG. Uses Apache Batik for SVG processing.
54  * This handler handles XML for foreign objects when rendering to PostScript.
55  * It renders SVG to the PostScript document using the PSGraphics2D.
56  * The properties from the PostScript renderer are subject to change.
57  *
58  * @version $Id: PSSVGHandler.java 426576 2006-07-28 15:44:37Z jeremias $
59  */

60 public class PSSVGHandler implements XMLHandler, PSRendererContextConstants {
61
62     /** logging instance */
63     private static Log log = LogFactory.getLog(PSSVGHandler.class);
64
65     /**
66      * Create a new PostScript XML handler for use by the PostScript renderer.
67      */

68     public PSSVGHandler() {
69     }
70
71     /** @see org.apache.fop.render.XMLHandler */
72     public void handleXML(RendererContext context,
73                 Document JavaDoc doc, String JavaDoc ns) throws Exception JavaDoc {
74         PSInfo psi = getPSInfo(context);
75
76         if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) {
77             renderSVGDocument(context, doc, psi);
78         }
79     }
80
81     /**
82      * Get the pdf information from the render context.
83      *
84      * @param context the renderer context
85      * @return the pdf information retrieved from the context
86      */

87     public static PSInfo getPSInfo(RendererContext context) {
88         PSInfo psi = new PSInfo();
89         psi.psGenerator = (PSGenerator)context.getProperty(PS_GENERATOR);
90         psi.fontInfo = (org.apache.fop.fonts.FontInfo) context.getProperty(PS_FONT_INFO);
91         psi.width = ((Integer JavaDoc)context.getProperty(WIDTH)).intValue();
92         psi.height = ((Integer JavaDoc)context.getProperty(HEIGHT)).intValue();
93         psi.currentXPosition = ((Integer JavaDoc)context.getProperty(XPOS)).intValue();
94         psi.currentYPosition = ((Integer JavaDoc)context.getProperty(YPOS)).intValue();
95         psi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION);
96         return psi;
97     }
98
99     /**
100      * PostScript information structure for drawing the XML document.
101      */

102     public static class PSInfo {
103
104         /** see PS_GENERATOR */
105         private PSGenerator psGenerator;
106         /** see PS_FONT_INFO */
107         private org.apache.fop.fonts.FontInfo fontInfo;
108         /** see WIDTH */
109         private int width;
110         /** see HEIGHT */
111         private int height;
112         /** see XPOS */
113         private int currentXPosition;
114         /** see YPOS */
115         private int currentYPosition;
116         /** see HANDLER_CONFIGURATION */
117         private Configuration cfg;
118
119         /**
120          * Returns the PSGenerator.
121          * @return PSGenerator
122          */

123         public PSGenerator getPSGenerator() {
124             return psGenerator;
125         }
126
127         /**
128          * Sets the PSGenerator.
129          * @param psGenerator The PSGenerator to set
130          */

131         public void setPsGenerator(PSGenerator psGenerator) {
132             this.psGenerator = psGenerator;
133         }
134
135         /**
136          * Returns the fontInfo.
137          * @return FontInfo
138          */

139         public FontInfo getFontInfo() {
140             return fontInfo;
141         }
142
143         /**
144          * Sets the fontInfo.
145          * @param fontInfo The fontInfo to set
146          */

147         public void setFontInfo(FontInfo fontInfo) {
148             this.fontInfo = fontInfo;
149         }
150
151         /**
152          * Returns the currentXPosition.
153          * @return int
154          */

155         public int getCurrentXPosition() {
156             return currentXPosition;
157         }
158
159         /**
160          * Sets the currentXPosition.
161          * @param currentXPosition The currentXPosition to set
162          */

163         public void setCurrentXPosition(int currentXPosition) {
164             this.currentXPosition = currentXPosition;
165         }
166
167         /**
168          * Returns the currentYPosition.
169          * @return int
170          */

171         public int getCurrentYPosition() {
172             return currentYPosition;
173         }
174
175         /**
176          * Sets the currentYPosition.
177          * @param currentYPosition The currentYPosition to set
178          */

179         public void setCurrentYPosition(int currentYPosition) {
180             this.currentYPosition = currentYPosition;
181         }
182
183         /**
184          * Returns the width.
185          * @return int
186          */

187         public int getWidth() {
188             return width;
189         }
190
191         /**
192          * Sets the width.
193          * @param width The pageWidth to set
194          */

195         public void setWidth(int width) {
196             this.width = width;
197         }
198
199         /**
200          * Returns the height.
201          * @return int
202          */

203         public int getHeight() {
204             return height;
205         }
206
207         /**
208          * Sets the height.
209          * @param height The height to set
210          */

211         public void setHeight(int height) {
212             this.height = height;
213         }
214
215         /**
216          * Returns the height.
217          * @return int
218          */

219         public Configuration getHandlerConfiguration() {
220             return this.cfg;
221         }
222
223         /**
224          * Sets the handler configuration.
225          * @param cfg the configuration object
226          */

227         public void setHandlerConfiguration(Configuration cfg) {
228             this.cfg = cfg;
229         }
230
231     }
232
233     /**
234      * Render the svg document.
235      * @param context the renderer context
236      * @param doc the svg document
237      * @param psInfo the pdf information of the current context
238      */

239     protected void renderSVGDocument(RendererContext context,
240             Document JavaDoc doc, PSInfo psInfo) {
241         int xOffset = psInfo.currentXPosition;
242         int yOffset = psInfo.currentYPosition;
243         PSGenerator gen = psInfo.psGenerator;
244
245         //Controls whether text painted by Batik is generated using text or path operations
246
boolean strokeText = false;
247         Configuration cfg = psInfo.getHandlerConfiguration();
248         if (cfg != null) {
249             strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
250         }
251
252         SVGUserAgent ua
253              = new SVGUserAgent(
254                 context.getUserAgent().getSourcePixelUnitToMillimeter(),
255                 new AffineTransform JavaDoc());
256
257         PSGraphics2D graphics = new PSGraphics2D(strokeText, gen);
258         graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
259
260         GVTBuilder builder = new GVTBuilder();
261         NativeTextHandler nativeTextHandler = null;
262         BridgeContext ctx = new BridgeContext(ua);
263         if (!strokeText) {
264             nativeTextHandler = new NativeTextHandler(graphics, psInfo.getFontInfo());
265             graphics.setCustomTextHandler(nativeTextHandler);
266             PSTextPainter textPainter = new PSTextPainter(nativeTextHandler);
267             ctx.setTextPainter(textPainter);
268             PSTextElementBridge tBridge = new PSTextElementBridge(textPainter);
269             ctx.putBridge(tBridge);
270         }
271
272         GraphicsNode root;
273         try {
274             root = builder.build(ctx, doc);
275         } catch (Exception JavaDoc e) {
276             log.error("SVG graphic could not be built: "
277                                    + e.getMessage(), e);
278             return;
279         }
280         // get the 'width' and 'height' attributes of the SVG document
281
float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
282         float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
283
284         float sx = psInfo.getWidth() / (float)w;
285         float sy = psInfo.getHeight() / (float)h;
286
287         ctx = null;
288         builder = null;
289
290         try {
291             gen.commentln("%FOPBeginSVG");
292             gen.saveGraphicsState();
293             /*
294              * Clip to the svg area.
295              * Note: To have the svg overlay (under) a text area then use
296              * an fo:block-container
297              */

298             gen.writeln("newpath");
299             gen.defineRect(xOffset / 1000f, yOffset / 1000f,
300                     psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f);
301             gen.writeln("clip");
302             
303             // transform so that the coordinates (0,0) is from the top left
304
// and positive is down and to the right. (0,0) is where the
305
// viewBox puts it.
306
gen.concatMatrix(sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f);
307
308             SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
309             AffineTransform JavaDoc at = ViewBox.getPreserveAspectRatioTransform(svg,
310                     psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f);
311             /*
312             if (!at.isIdentity()) {
313                 double[] vals = new double[6];
314                 at.getMatrix(vals);
315                 gen.concatMatrix(vals);
316             }*/

317
318             AffineTransform JavaDoc transform = new AffineTransform JavaDoc();
319             // scale to viewbox
320
transform.translate(xOffset, yOffset);
321             gen.getCurrentState().concatMatrix(transform);
322             try {
323                 root.paint(graphics);
324             } catch (Exception JavaDoc e) {
325                 log.error("SVG graphic could not be rendered: "
326                                        + e.getMessage(), e);
327             }
328
329             gen.restoreGraphicsState();
330             gen.commentln("%FOPEndSVG");
331         } catch (IOException JavaDoc ioe) {
332             log.error("SVG graphic could not be rendered: "
333                                    + ioe.getMessage(), ioe);
334         }
335     }
336
337     /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
338     public boolean supportsRenderer(Renderer renderer) {
339         return (renderer instanceof PSRenderer);
340     }
341     
342     /** @see org.apache.fop.render.XMLHandler#getNamespace() */
343     public String JavaDoc getNamespace() {
344         return SVGDOMImplementation.SVG_NAMESPACE_URI;
345     }
346
347 }
348
349
Popular Tags