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.

PSImageHandlerGraphics2D.java 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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.ps;
  19. import java.awt.Dimension;
  20. import java.awt.Rectangle;
  21. import java.awt.geom.AffineTransform;
  22. import java.awt.geom.Dimension2D;
  23. import java.awt.geom.Rectangle2D;
  24. import java.io.IOException;
  25. import org.apache.xmlgraphics.image.loader.Image;
  26. import org.apache.xmlgraphics.image.loader.ImageFlavor;
  27. import org.apache.xmlgraphics.image.loader.ImageInfo;
  28. import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
  29. import org.apache.xmlgraphics.java2d.GeneralGraphics2DImagePainter;
  30. import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
  31. import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
  32. import org.apache.xmlgraphics.ps.FormGenerator;
  33. import org.apache.xmlgraphics.ps.PSGenerator;
  34. import org.apache.xmlgraphics.ps.PSProcSets;
  35. import org.apache.fop.render.RenderingContext;
  36. /**
  37. * Image handler implementation which handles vector graphics (Java2D) for PostScript output.
  38. */
  39. public class PSImageHandlerGraphics2D implements PSImageHandler {
  40. private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
  41. ImageFlavor.GRAPHICS2D
  42. };
  43. /** {@inheritDoc} */
  44. public void handleImage(RenderingContext context, Image image, Rectangle pos)
  45. throws IOException {
  46. PSRenderingContext psContext = (PSRenderingContext)context;
  47. PSGenerator gen = psContext.getGenerator();
  48. ImageGraphics2D imageG2D = (ImageGraphics2D)image;
  49. Graphics2DImagePainter painter = imageG2D.getGraphics2DImagePainter();
  50. float fx = (float)pos.getX() / 1000f;
  51. float fy = (float)pos.getY() / 1000f;
  52. float fwidth = (float)pos.getWidth() / 1000f;
  53. float fheight = (float)pos.getHeight() / 1000f;
  54. // get the 'width' and 'height' attributes of the SVG document
  55. Dimension dim = painter.getImageSize();
  56. float imw = (float)dim.getWidth() / 1000f;
  57. float imh = (float)dim.getHeight() / 1000f;
  58. float sx = fwidth / imw;
  59. float sy = fheight / imh;
  60. gen.commentln("%FOPBeginGraphics2D");
  61. gen.saveGraphicsState();
  62. final boolean clip = false;
  63. if (clip) {
  64. // Clip to the image area.
  65. gen.writeln("newpath");
  66. gen.defineRect(fx, fy, fwidth, fheight);
  67. gen.writeln("clip");
  68. }
  69. // transform so that the coordinates (0,0) is from the top left
  70. // and positive is down and to the right. (0,0) is where the
  71. // viewBox puts it.
  72. gen.concatMatrix(sx, 0, 0, sy, fx, fy);
  73. final boolean textAsShapes = false;
  74. PSGraphics2D graphics = (painter instanceof GeneralGraphics2DImagePainter)
  75. ? (PSGraphics2D) ((GeneralGraphics2DImagePainter) painter).getGraphics(textAsShapes, gen)
  76. : new PSGraphics2D(textAsShapes, gen);
  77. graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
  78. AffineTransform transform = new AffineTransform();
  79. // scale to viewbox
  80. transform.translate(fx, fy);
  81. gen.getCurrentState().concatMatrix(transform);
  82. Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
  83. painter.paint(graphics, area);
  84. gen.restoreGraphicsState();
  85. gen.commentln("%FOPEndGraphics2D");
  86. }
  87. /** {@inheritDoc} */
  88. public void generateForm(RenderingContext context, Image image, final PSImageFormResource form)
  89. throws IOException {
  90. PSRenderingContext psContext = (PSRenderingContext)context;
  91. PSGenerator gen = psContext.getGenerator();
  92. final ImageGraphics2D imageG2D = (ImageGraphics2D)image;
  93. ImageInfo info = image.getInfo();
  94. FormGenerator formGen = buildFormGenerator(gen.getPSLevel(), form, info, imageG2D);
  95. formGen.generate(gen);
  96. }
  97. /** {@inheritDoc} */
  98. public int getPriority() {
  99. return 200;
  100. }
  101. /** {@inheritDoc} */
  102. public Class getSupportedImageClass() {
  103. return ImageGraphics2D.class;
  104. }
  105. /** {@inheritDoc} */
  106. public ImageFlavor[] getSupportedImageFlavors() {
  107. return FLAVORS;
  108. }
  109. /** {@inheritDoc} */
  110. public boolean isCompatible(RenderingContext targetContext, Image image) {
  111. if (targetContext instanceof PSRenderingContext) {
  112. return (image == null || image instanceof ImageGraphics2D);
  113. }
  114. return false;
  115. }
  116. private FormGenerator buildFormGenerator(int psLanguageLevel, final PSImageFormResource form,
  117. final ImageInfo info, final ImageGraphics2D imageG2D) {
  118. String imageDescription = info.getMimeType() + " " + info.getOriginalURI();
  119. final Dimension2D dimensionsPt = info.getSize().getDimensionPt();
  120. final Dimension2D dimensionsMpt = info.getSize().getDimensionMpt();
  121. FormGenerator formGen;
  122. if (psLanguageLevel <= 2) {
  123. formGen = new EPSFormGenerator(form.getName(), imageDescription, dimensionsPt) {
  124. @Override
  125. void doGeneratePaintProc(PSGenerator gen) throws IOException {
  126. paintImageG2D(imageG2D, dimensionsMpt, gen);
  127. }
  128. };
  129. } else {
  130. formGen = new EPSFormGenerator(form.getName(), imageDescription, dimensionsPt) {
  131. @Override
  132. protected void generateAdditionalDataStream(PSGenerator gen) throws IOException {
  133. gen.writeln("/" + form.getName() + ":Data currentfile <<");
  134. gen.writeln(" /Filter /SubFileDecode");
  135. gen.writeln(" /DecodeParms << /EODCount 0 /EODString (%FOPEndOfData) >>");
  136. gen.writeln(">> /ReusableStreamDecode filter");
  137. paintImageG2D(imageG2D, dimensionsMpt, gen);
  138. gen.writeln("%FOPEndOfData");
  139. gen.writeln("def");
  140. }
  141. @Override
  142. void doGeneratePaintProc(PSGenerator gen) throws IOException {
  143. gen.writeln(form.getName() + ":Data 0 setfileposition");
  144. gen.writeln(form.getName() + ":Data cvx exec");
  145. }
  146. };
  147. }
  148. return formGen;
  149. }
  150. private abstract static class EPSFormGenerator extends FormGenerator {
  151. EPSFormGenerator(String formName, String title, Dimension2D dimensions) {
  152. super(formName, title, dimensions);
  153. }
  154. protected void paintImageG2D(final ImageGraphics2D imageG2D, Dimension2D dimensionsMpt,
  155. PSGenerator gen) throws IOException {
  156. PSGraphics2DAdapter adapter = new PSGraphics2DAdapter(gen, false);
  157. adapter.paintImage(imageG2D.getGraphics2DImagePainter(),
  158. null,
  159. 0, 0,
  160. (int) Math.round(dimensionsMpt.getWidth()),
  161. (int) Math.round(dimensionsMpt.getHeight()));
  162. }
  163. @Override
  164. protected final void generatePaintProc(PSGenerator gen) throws IOException {
  165. gen.getResourceTracker().notifyResourceUsageOnPage(
  166. PSProcSets.EPS_PROCSET);
  167. gen.writeln("BeginEPSF");
  168. doGeneratePaintProc(gen);
  169. gen.writeln("EndEPSF");
  170. }
  171. abstract void doGeneratePaintProc(PSGenerator gen) throws IOException;
  172. }
  173. }