You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Java2DSVGHandler.java 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. /* $Id$ */
  18. package org.apache.fop.render.java2d;
  19. import java.awt.geom.AffineTransform;
  20. import java.io.IOException;
  21. import java.util.Map;
  22. import org.apache.batik.bridge.BridgeContext;
  23. import org.apache.batik.bridge.GVTBuilder;
  24. import org.apache.batik.gvt.GraphicsNode;
  25. import org.apache.commons.logging.Log;
  26. import org.apache.commons.logging.LogFactory;
  27. import org.apache.fop.render.AbstractGenericSVGHandler;
  28. import org.apache.fop.render.Renderer;
  29. import org.apache.fop.render.RendererContext;
  30. import org.apache.fop.render.RendererContextConstants;
  31. import org.apache.fop.svg.SVGEventProducer;
  32. import org.apache.fop.svg.SVGUserAgent;
  33. import org.w3c.dom.Document;
  34. /**
  35. * Java2D XML handler for SVG (uses Apache Batik).
  36. * This handler handles XML for foreign objects when rendering to Java2D.
  37. * The properties from the Java2D renderer are subject to change.
  38. */
  39. public class Java2DSVGHandler extends AbstractGenericSVGHandler
  40. implements Java2DRendererContextConstants {
  41. /** logging instance */
  42. private static Log log = LogFactory.getLog(Java2DSVGHandler.class);
  43. /**
  44. * Create a new Java2D XML handler for use by the Java2D renderer and its subclasses.
  45. */
  46. public Java2DSVGHandler() {
  47. //nop
  48. }
  49. /**
  50. * Get the pdf information from the render context.
  51. *
  52. * @param context the renderer context
  53. * @return the pdf information retrieved from the context
  54. */
  55. public static Java2DInfo getJava2DInfo(RendererContext context) {
  56. Java2DInfo pdfi = new Java2DInfo();
  57. pdfi.state = (Java2DGraphicsState)context.getProperty(JAVA2D_STATE);
  58. pdfi.width = ((Integer)context.getProperty(WIDTH)).intValue();
  59. pdfi.height = ((Integer)context.getProperty(HEIGHT)).intValue();
  60. pdfi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue();
  61. pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
  62. Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
  63. if (foreign != null
  64. && BITMAP.equalsIgnoreCase((String)foreign.get(CONVERSION_MODE))) {
  65. pdfi.paintAsBitmap = true;
  66. }
  67. return pdfi;
  68. }
  69. /**
  70. * Java2D information structure for drawing the XML document.
  71. */
  72. public static class Java2DInfo {
  73. /** see Java2D_STATE */
  74. public Java2DGraphicsState state;
  75. /** see Java2D_WIDTH */
  76. public int width;
  77. /** see Java2D_HEIGHT */
  78. public int height;
  79. /** see Java2D_XPOS */
  80. public int currentXPosition;
  81. /** see Java2D_YPOS */
  82. public int currentYPosition;
  83. public boolean paintAsBitmap;
  84. /** {@inheritDoc} */
  85. public String toString() {
  86. return "Java2DInfo {"
  87. + "state = " + state + ", "
  88. + "width = " + width + ", "
  89. + "height = " + height + ", "
  90. + "currentXPosition = " + currentXPosition + ", "
  91. + "currentYPosition = " + currentYPosition + ", "
  92. + "paintAsBitmap = " + paintAsBitmap + "}";
  93. }
  94. }
  95. /** {@inheritDoc} */
  96. protected void renderSVGDocument(RendererContext context,
  97. Document doc) {
  98. Java2DInfo info = getJava2DInfo(context);
  99. if (log.isDebugEnabled()) {
  100. log.debug("renderSVGDocument(" + context + ", " + doc + ", " + info + ")");
  101. }
  102. // fallback paint as bitmap
  103. if (info.paintAsBitmap) {
  104. try {
  105. super.renderSVGDocument(context, doc);
  106. } catch (IOException ioe) {
  107. SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
  108. context.getUserAgent().getEventBroadcaster());
  109. eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc));
  110. }
  111. return;
  112. }
  113. int x = info.currentXPosition;
  114. int y = info.currentYPosition;
  115. SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
  116. GVTBuilder builder = new GVTBuilder();
  117. BridgeContext ctx = new BridgeContext(ua);
  118. GraphicsNode root;
  119. try {
  120. root = builder.build(ctx, doc);
  121. } catch (Exception e) {
  122. SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
  123. context.getUserAgent().getEventBroadcaster());
  124. eventProducer.svgNotBuilt(this, e, getDocumentURI(doc));
  125. return;
  126. }
  127. // If no viewbox is defined in the svg file, a viewbox of 100x100 is
  128. // assumed, as defined in SVGUserAgent.getViewportSize()
  129. float iw = (float) ctx.getDocumentSize().getWidth() * 1000f;
  130. float ih = (float) ctx.getDocumentSize().getHeight() * 1000f;
  131. float w = info.width;
  132. float h = info.height;
  133. AffineTransform origTransform = info.state.getGraph().getTransform();
  134. // correct integer roundoff
  135. info.state.getGraph().translate(x / 1000f, y / 1000f);
  136. //SVGSVGElement svg = ((SVGDocument) doc).getRootElement();
  137. // Aspect ratio preserved by layout engine, not here
  138. AffineTransform at = AffineTransform.getScaleInstance(w / iw, h / ih);
  139. if (!at.isIdentity()) {
  140. info.state.getGraph().transform(at);
  141. }
  142. try {
  143. root.paint(info.state.getGraph());
  144. } catch (Exception e) {
  145. SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
  146. context.getUserAgent().getEventBroadcaster());
  147. eventProducer.svgRenderingError(this, e, getDocumentURI(doc));
  148. }
  149. info.state.getGraph().setTransform(origTransform);
  150. }
  151. /** {@inheritDoc} */
  152. public boolean supportsRenderer(Renderer renderer) {
  153. return (renderer instanceof Java2DRenderer);
  154. }
  155. }