您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

PDFImageElementBridge.java 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Copyright 1999-2005 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* $Id$ */
  17. package org.apache.fop.svg;
  18. import org.apache.batik.bridge.SVGImageElementBridge;
  19. import java.awt.Shape;
  20. import java.awt.Graphics2D;
  21. import java.awt.geom.Rectangle2D;
  22. import java.io.BufferedInputStream;
  23. import java.io.InputStream;
  24. import org.w3c.dom.Element;
  25. import org.apache.batik.bridge.BridgeContext;
  26. import org.apache.batik.gvt.AbstractGraphicsNode;
  27. import org.apache.batik.gvt.GraphicsNode;
  28. import org.apache.batik.util.ParsedURL;
  29. import org.apache.fop.image.JpegImage;
  30. import org.apache.fop.image.FopImage;
  31. import org.apache.fop.image.analyser.ImageReaderFactory;
  32. /**
  33. * Bridge class for the <image> element when jpeg images.
  34. *
  35. * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
  36. */
  37. public class PDFImageElementBridge extends SVGImageElementBridge {
  38. /**
  39. * Constructs a new bridge for the &lt;image> element.
  40. */
  41. public PDFImageElementBridge() { }
  42. /**
  43. * Create the raster image node.
  44. * THis checks if it is a jpeg file and creates a jpeg node
  45. * so the jpeg can be inserted directly into the pdf document.
  46. * @param ctx the bridge context
  47. * @param imageElement the svg element for the image
  48. * @param purl the parsed url for the image resource
  49. * @return a new graphics node
  50. */
  51. protected GraphicsNode createImageGraphicsNode
  52. (BridgeContext ctx, Element imageElement, ParsedURL purl) {
  53. try {
  54. InputStream is = purl.openStream();
  55. if (!is.markSupported()) {
  56. is = new BufferedInputStream(is, 1024);
  57. }
  58. is.mark(3);
  59. byte [] data = new byte[3];
  60. is.read(data);
  61. is.reset();
  62. if ((data[0] == (byte)0xFF)
  63. && (data[1] == (byte)0xD8)
  64. && (data[2] == (byte)0xFF)) {
  65. FopImage.ImageInfo ii = ImageReaderFactory.make
  66. (purl.toString(), is, null);
  67. JpegImage jpeg = new JpegImage(ii);
  68. jpeg.load(FopImage.ORIGINAL_DATA);
  69. PDFJpegNode node = new PDFJpegNode(jpeg, ctx, imageElement, purl);
  70. Rectangle2D imgBounds = getImageBounds(ctx, imageElement);
  71. Rectangle2D bounds = node.getPrimitiveBounds();
  72. float [] vb = new float[4];
  73. vb[0] = 0; // x
  74. vb[1] = 0; // y
  75. vb[2] = (float) bounds.getWidth(); // width
  76. vb[3] = (float) bounds.getHeight(); // height
  77. // handles the 'preserveAspectRatio', 'overflow' and 'clip'
  78. // and sets the appropriate AffineTransform to the image node
  79. initializeViewport(ctx, imageElement, node, vb, imgBounds);
  80. return node;
  81. }
  82. } catch (Exception ex) {
  83. //TODO Handle this exception
  84. }
  85. return superCreateGraphicsNode(ctx, imageElement, purl);
  86. }
  87. /**
  88. * @see org.apache.batik.bridge.SVGImageElementBridge
  89. */
  90. protected GraphicsNode superCreateGraphicsNode
  91. (BridgeContext ctx, Element imageElement, ParsedURL purl) {
  92. return super.createImageGraphicsNode(ctx, imageElement, purl);
  93. }
  94. /**
  95. * A PDF jpeg node.
  96. * This holds a jpeg image so that it can be drawn into
  97. * the PDFGraphics2D.
  98. */
  99. public class PDFJpegNode extends AbstractGraphicsNode {
  100. private JpegImage jpeg;
  101. private BridgeContext ctx;
  102. private Element imageElement;
  103. private ParsedURL purl;
  104. private GraphicsNode origGraphicsNode = null;
  105. /**
  106. * Create a new pdf jpeg node for drawing jpeg images
  107. * into pdf graphics.
  108. * @param j the jpeg image
  109. * @param ctx the bridge context
  110. * @param imageElement the SVG image element
  111. * @param purl the URL to the image
  112. */
  113. public PDFJpegNode(JpegImage j, BridgeContext ctx,
  114. Element imageElement, ParsedURL purl) {
  115. this.jpeg = j;
  116. this.ctx = ctx;
  117. this.imageElement = imageElement;
  118. this.purl = purl;
  119. }
  120. /**
  121. * Get the outline of this image.
  122. * @return the outline shape which is the primitive bounds
  123. */
  124. public Shape getOutline() {
  125. return getPrimitiveBounds();
  126. }
  127. /**
  128. * Paint this jpeg image.
  129. * As this is used for inserting jpeg into pdf
  130. * it adds the jpeg image to the PDFGraphics2D.
  131. * @param g2d the graphics to draw the image on
  132. */
  133. public void primitivePaint(Graphics2D g2d) {
  134. if (g2d instanceof PDFGraphics2D) {
  135. PDFGraphics2D pdfg = (PDFGraphics2D) g2d;
  136. float x = 0;
  137. float y = 0;
  138. try {
  139. float width = jpeg.getWidth();
  140. float height = jpeg.getHeight();
  141. pdfg.addJpegImage(jpeg, x, y, width, height);
  142. } catch (Exception e) {
  143. //TODO Handle this exception properly
  144. e.printStackTrace();
  145. }
  146. } else {
  147. // Not going directly into PDF so use
  148. // original implementation so filters etc work.
  149. if (origGraphicsNode == null) {
  150. // Haven't constructed baseclass Graphics Node,
  151. // so do so now.
  152. origGraphicsNode
  153. = PDFImageElementBridge.this.superCreateGraphicsNode
  154. (ctx, imageElement, purl);
  155. }
  156. origGraphicsNode.primitivePaint(g2d);
  157. }
  158. }
  159. /**
  160. * Get the geometrix bounds of the image.
  161. * @return the primitive bounds
  162. */
  163. public Rectangle2D getGeometryBounds() {
  164. return getPrimitiveBounds();
  165. }
  166. /**
  167. * Get the primitive bounds of this bridge element.
  168. * @return the bounds of the jpeg image
  169. */
  170. public Rectangle2D getPrimitiveBounds() {
  171. try {
  172. return new Rectangle2D.Double(0, 0, jpeg.getWidth(),
  173. jpeg.getHeight());
  174. } catch (Exception e) {
  175. //TODO Handle this exception properly
  176. e.printStackTrace();
  177. }
  178. return null;
  179. }
  180. /**
  181. * Returns the bounds of the sensitive area covered by this node,
  182. * This includes the stroked area but does not include the effects
  183. * of clipping, masking or filtering.
  184. * @return the bounds of the sensitive area
  185. */
  186. public Rectangle2D getSensitiveBounds() {
  187. //No interactive features, just return primitive bounds
  188. return getPrimitiveBounds();
  189. }
  190. }
  191. }