1 51 package org.apache.fop.svg; 52 53 import java.awt.Dimension ; 54 55 import java.awt.geom.AffineTransform ; 56 import java.awt.geom.Dimension2D ; 57 import java.awt.geom.Rectangle2D ; 58 59 import java.awt.*; 60 61 import java.net.MalformedURLException ; 62 import java.net.URL ; 63 64 import org.apache.fop.apps.FOPException; 65 66 import org.apache.batik.bridge.BridgeContext; 67 import org.apache.batik.bridge.BridgeException; 68 import org.apache.batik.bridge.GVTBuilder; 69 import org.apache.batik.bridge.UserAgent; 70 import org.apache.batik.bridge.ViewBox; 71 72 import org.apache.batik.dom.svg.SAXSVGDocumentFactory; 73 import org.apache.batik.dom.svg.SVGDOMImplementation; 74 import org.apache.batik.dom.svg.SVGOMDocument; 75 import org.apache.batik.dom.util.DocumentFactory; 76 77 import org.apache.batik.gvt.GraphicsNode; 78 79 import org.apache.batik.transcoder.TranscoderException; 80 import org.apache.batik.transcoder.TranscoderOutput; 81 import org.apache.batik.transcoder.TranscodingHints; 82 import org.apache.batik.transcoder.XMLAbstractTranscoder; 83 import org.apache.batik.transcoder.image.resources.Messages; 84 85 import org.apache.batik.transcoder.keys.StringKey; 86 import org.apache.batik.transcoder.image.*; 87 88 import org.apache.batik.util.SVGConstants; 89 import org.apache.batik.util.XMLResourceDescriptor; 90 91 import org.apache.batik.bridge.*; 92 import org.apache.batik.gvt.*; 93 import org.apache.batik.gvt.renderer.*; 94 95 import org.apache.fop.svg.*; 96 97 import org.w3c.dom.DOMImplementation ; 98 import org.w3c.dom.Document ; 99 import org.w3c.dom.svg.SVGDocument; 100 import org.w3c.dom.svg.SVGSVGElement; 101 102 129 public class PDFTranscoder extends XMLAbstractTranscoder { 130 131 public static final TranscodingHints.Key KEY_STROKE_TEXT = 132 new StringKey(); 133 134 137 protected UserAgent userAgent = new ImageTranscoderUserAgent(); 138 139 142 public PDFTranscoder() { 143 hints.put(KEY_DOCUMENT_ELEMENT_NAMESPACE_URI, 144 SVGConstants.SVG_NAMESPACE_URI); 145 hints.put(KEY_DOCUMENT_ELEMENT, SVGConstants.SVG_SVG_TAG); 146 hints.put(KEY_DOM_IMPLEMENTATION, 147 SVGDOMImplementation.getDOMImplementation()); 148 } 149 150 158 protected void transcode(Document document, String uri, 159 TranscoderOutput output) 160 throws TranscoderException { 161 162 if (!(document instanceof SVGOMDocument)) { 163 throw new TranscoderException(Messages.formatMessage("notsvg", 164 null)); 165 } 166 SVGDocument svgDoc = (SVGDocument)document; 167 SVGSVGElement root = svgDoc.getRootElement(); 168 String parserClassname = (String )hints.get(KEY_XML_PARSER_CLASSNAME); 170 171 boolean stroke = true; 172 if (hints.containsKey(KEY_STROKE_TEXT)) { 173 stroke = ((Boolean )hints.get(KEY_STROKE_TEXT)).booleanValue(); 174 } 175 176 GVTBuilder builder = new GVTBuilder(); 178 BridgeContext ctx = new BridgeContext(userAgent); 179 TextPainter textPainter = null; 180 textPainter = new StrokingTextPainter(); 181 ctx.setTextPainter(textPainter); 182 183 PDFAElementBridge pdfAElementBridge = new PDFAElementBridge(); 184 AffineTransform currentTransform = new AffineTransform (1, 0, 0, 1, 0, 0); 185 pdfAElementBridge.setCurrentTransform(currentTransform); 186 ctx.putBridge(pdfAElementBridge); 187 ctx.putBridge(new PDFImageElementBridge()); 188 GraphicsNode gvtRoot; 189 try { 190 gvtRoot = builder.build(ctx, svgDoc); 191 } catch (BridgeException ex) { 192 throw new TranscoderException(ex); 193 } 194 float docWidth = (float)ctx.getDocumentSize().getWidth(); 196 float docHeight = (float)ctx.getDocumentSize().getHeight(); 197 ctx = null; 198 builder = null; 199 200 float imgWidth = -1; 202 if (hints.containsKey(ImageTranscoder.KEY_WIDTH)) { 203 imgWidth = 204 ((Float )hints.get(ImageTranscoder.KEY_WIDTH)).floatValue(); 205 } 206 float imgHeight = -1; 207 if (hints.containsKey(ImageTranscoder.KEY_HEIGHT)) { 208 imgHeight = 209 ((Float )hints.get(ImageTranscoder.KEY_HEIGHT)).floatValue(); 210 } 211 float width, height; 212 if (imgWidth > 0 && imgHeight > 0) { 213 width = imgWidth; 214 height = imgHeight; 215 } else if (imgHeight > 0) { 216 width = (docWidth * imgHeight) / docHeight; 217 height = imgHeight; 218 } else if (imgWidth > 0) { 219 width = imgWidth; 220 height = (docHeight * imgWidth) / docWidth; 221 } else { 222 width = docWidth; 223 height = docHeight; 224 } 225 AffineTransform Px; 227 String ref = null; 228 try { 229 ref = new URL (uri).getRef(); 230 } catch (MalformedURLException ex) { 231 } 233 234 try { 235 Px = ViewBox.getViewTransform(ref, root, width, height); 236 } catch (BridgeException ex) { 237 throw new TranscoderException(ex); 238 } 239 240 if (Px.isIdentity() && (width != docWidth || height != docHeight)) { 241 float d = Math.max(docWidth, docHeight); 244 float dd = Math.max(width, height); 245 float scale = dd / d; 246 Px = AffineTransform.getScaleInstance(scale, scale); 247 } 248 if (hints.containsKey(ImageTranscoder.KEY_AOI)) { 250 Rectangle2D aoi = (Rectangle2D )hints.get(ImageTranscoder.KEY_AOI); 251 aoi = Px.createTransformedShape(aoi).getBounds2D(); 253 AffineTransform Mx = new AffineTransform (); 254 double sx = width / aoi.getWidth(); 255 double sy = height / aoi.getHeight(); 256 Mx.scale(sx, sy); 257 double tx = -aoi.getX(); 258 double ty = -aoi.getY(); 259 Mx.translate(tx, ty); 260 Px.preConcatenate(Mx); 263 } 264 int w = (int)width; 266 int h = (int)height; 267 268 PDFDocumentGraphics2D graphics; 269 try { 270 graphics = new PDFDocumentGraphics2D(stroke, 271 output.getOutputStream(), w, h); 272 } catch (FOPException ex) { 273 throw new TranscoderException(ex); 274 } 275 graphics.setSVGDimension(docWidth, docHeight); 276 currentTransform.setTransform(1, 0, 0, -1, 0, height); 277 if (!stroke) { 278 textPainter = new PDFTextPainter(graphics.getFontState()); 279 ctx.setTextPainter(textPainter); 280 } 281 282 if (hints.containsKey(ImageTranscoder.KEY_BACKGROUND_COLOR)) { 283 graphics.setBackgroundColor((Color)hints.get(ImageTranscoder.KEY_BACKGROUND_COLOR)); 284 } 285 graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); 286 287 gvtRoot.paint(graphics); 288 289 try { 290 graphics.finish(); 291 } catch (Exception ex) { 292 ex.printStackTrace(); 293 throw new TranscoderException(ex); 294 } 295 } 296 297 305 protected DocumentFactory createDocumentFactory(DOMImplementation domImpl, 306 String parserClassname) { 307 return new SAXSVGDocumentFactory(parserClassname); 308 } 309 310 314 317 protected class ImageTranscoderUserAgent extends UserAgentAdapter { 318 319 public boolean isXMLParserValidating() { 320 return true; 321 } 322 323 326 public Dimension2D getViewportSize() { 327 return new Dimension (400, 400); 328 } 329 330 333 public void displayError(String message) { 334 try { 335 getErrorHandler().error(new TranscoderException(message)); 336 } catch (TranscoderException ex) { 337 throw new RuntimeException (); 338 } 339 } 340 341 344 public void displayError(Exception e) { 345 try { 346 getErrorHandler().error(new TranscoderException(e)); 347 } catch (TranscoderException ex) { 348 throw new RuntimeException (); 349 } 350 } 351 352 355 public void displayMessage(String message) { 356 try { 357 getErrorHandler().warning(new TranscoderException(message)); 358 } catch (TranscoderException ex) { 359 throw new RuntimeException (); 360 } 361 } 362 363 367 public float getPixelToMM() { 368 if (getTranscodingHints().containsKey(ImageTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER)) { 369 return ((Float )getTranscodingHints().get(ImageTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER)).floatValue(); 370 } else { 371 return 0.26458333333333333333333333333333f; } 374 } 375 376 380 public String getLanguages() { 381 if (getTranscodingHints().containsKey(ImageTranscoder.KEY_LANGUAGE)) { 382 return (String )getTranscodingHints().get(ImageTranscoder.KEY_LANGUAGE); 383 } else { 384 return "en"; 385 } 386 } 387 388 public String getMedia() { 389 return "print"; 390 } 391 392 396 public String getUserStyleSheetURI() { 397 return (String )getTranscodingHints().get(ImageTranscoder.KEY_USER_STYLESHEET_URI); 398 } 399 400 403 public String getXMLParserClassName() { 404 if (getTranscodingHints().containsKey(KEY_XML_PARSER_CLASSNAME)) { 405 return (String )getTranscodingHints().get(KEY_XML_PARSER_CLASSNAME); 406 } else { 407 return XMLResourceDescriptor.getXMLParserClassName(); 408 } 409 } 410 411 } 412 413 } 414 | Popular Tags |