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.

PCLRenderingUtil.java 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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.pcl;
  19. import java.awt.Dimension;
  20. import java.awt.Rectangle;
  21. import java.awt.geom.AffineTransform;
  22. import java.awt.geom.Point2D;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import org.apache.xmlgraphics.util.UnitConv;
  26. import org.apache.fop.apps.FOUserAgent;
  27. /**
  28. * Utility class for handling all sorts of peripheral tasks around PCL generation.
  29. */
  30. public class PCLRenderingUtil {
  31. /** logging instance */
  32. private static Log log = LogFactory.getLog(PCLRenderingUtil.class);
  33. private FOUserAgent userAgent;
  34. /**
  35. * Controls whether appearance is more important than speed. "SPEED" can cause some FO feature
  36. * to be ignored (like the advanced borders).
  37. */
  38. private PCLRenderingMode renderingMode = PCLRenderingMode.SPEED;
  39. /** Controls the dithering quality when rendering gray or color images. */
  40. private float ditheringQuality = 0.5f;
  41. /**
  42. * Controls whether an RGB canvas is used when converting Java2D graphics to bitmaps.
  43. * This can be used to work around problems with Apache Batik, for example, but setting
  44. * this to true will increase memory consumption.
  45. */
  46. private boolean useColorCanvas;
  47. /**
  48. * Controls whether the generation of PJL commands gets disabled.
  49. */
  50. private boolean disabledPJL;
  51. /**
  52. * Controls whether all text should be painted as text. This is a fallback setting in case the mixture of native and
  53. * bitmapped text does not provide the necessary quality.
  54. */
  55. private boolean allTextAsBitmaps;
  56. PCLRenderingUtil(FOUserAgent userAgent) {
  57. this.userAgent = userAgent;
  58. initialize();
  59. }
  60. private void initialize() {
  61. }
  62. /**
  63. * Returns the user agent.
  64. * @return the user agent
  65. */
  66. public FOUserAgent getUserAgent() {
  67. return this.userAgent;
  68. }
  69. /**
  70. * Configures the renderer to trade speed for quality if desired. One example here is the way
  71. * that borders are rendered.
  72. * @param mode one of the {@link PCLRenderingMode}.* constants
  73. */
  74. public void setRenderingMode(PCLRenderingMode mode) {
  75. this.renderingMode = mode;
  76. this.ditheringQuality = mode.getDefaultDitheringQuality();
  77. }
  78. /**
  79. * Returns the selected rendering mode.
  80. * @return the rendering mode
  81. */
  82. public PCLRenderingMode getRenderingMode() {
  83. return this.renderingMode;
  84. }
  85. /**
  86. * Returns the dithering quality to be used when encoding gray or color images.
  87. * @return the quality (0.0f..1.0f)
  88. */
  89. public float getDitheringQuality() {
  90. return this.ditheringQuality;
  91. }
  92. /**
  93. * Controls whether PJL commands shall be generated by the PCL renderer.
  94. * @param disable true to disable PJL commands
  95. */
  96. public void setPJLDisabled(boolean disable) {
  97. this.disabledPJL = disable;
  98. }
  99. /**
  100. * Indicates whether PJL generation is disabled.
  101. * @return true if PJL generation is disabled.
  102. */
  103. public boolean isPJLDisabled() {
  104. return this.disabledPJL;
  105. }
  106. /**
  107. * Controls whether all text should be generated as bitmaps or only text for which there's no native font.
  108. * @param allTextAsBitmaps true if all text should be painted as bitmaps
  109. */
  110. public void setAllTextAsBitmaps(boolean allTextAsBitmaps) {
  111. this.allTextAsBitmaps = allTextAsBitmaps;
  112. }
  113. /**
  114. * Indicates whether all text shall be painted as bitmaps.
  115. * @return true if all text shall be painted as bitmaps
  116. */
  117. public boolean isAllTextAsBitmaps() {
  118. return this.allTextAsBitmaps;
  119. }
  120. /**
  121. * Indicates whether a color canvas is used when creating bitmap images.
  122. * @return true if a color canvas is used.
  123. */
  124. public boolean isColorCanvasEnabled() {
  125. return this.useColorCanvas;
  126. }
  127. /**
  128. * Determines the print direction based on the given transformation matrix. This method
  129. * only detects right angles (0, 90, 180, 270). If any other angle is determined, 0 is
  130. * returned.
  131. * @param transform the transformation matrix
  132. * @return the angle in degrees of the print direction.
  133. */
  134. public static int determinePrintDirection(AffineTransform transform) {
  135. int newDir;
  136. if (transform.getScaleX() == 0 && transform.getScaleY() == 0
  137. && transform.getShearX() == 1 && transform.getShearY() == -1) {
  138. newDir = 90;
  139. } else if (transform.getScaleX() == -1 && transform.getScaleY() == -1
  140. && transform.getShearX() == 0 && transform.getShearY() == 0) {
  141. newDir = 180;
  142. } else if (transform.getScaleX() == 0 && transform.getScaleY() == 0
  143. && transform.getShearX() == -1 && transform.getShearY() == 1) {
  144. newDir = 270;
  145. } else {
  146. newDir = 0;
  147. }
  148. return newDir;
  149. }
  150. /**
  151. * Returns a coordinate in PCL's coordinate system when given a coordinate in the user
  152. * coordinate system.
  153. * @param x the X coordinate
  154. * @param y the Y coordinate
  155. * @param transform the currently valid transformation matrix
  156. * @param pageDefinition the currently valid page definition
  157. * @param printDirection the currently valid print direction
  158. * @return the transformed point
  159. */
  160. public static Point2D transformedPoint(int x, int y, AffineTransform transform,
  161. PCLPageDefinition pageDefinition, int printDirection) {
  162. if (log.isTraceEnabled()) {
  163. log.trace("Current transform: " + transform);
  164. }
  165. Point2D.Float orgPoint = new Point2D.Float(x, y);
  166. Point2D.Float transPoint = new Point2D.Float();
  167. transform.transform(orgPoint, transPoint);
  168. //At this point we have the absolute position in FOP's coordinate system
  169. //Now get PCL coordinates taking the current print direction and the logical page
  170. //into account.
  171. Dimension pageSize = pageDefinition.getPhysicalPageSize();
  172. Rectangle logRect = pageDefinition.getLogicalPageRect();
  173. switch (printDirection) {
  174. case 0:
  175. transPoint.x -= logRect.x;
  176. transPoint.y -= logRect.y;
  177. break;
  178. case 90:
  179. float ty = transPoint.x;
  180. transPoint.x = pageSize.height - transPoint.y;
  181. transPoint.y = ty;
  182. transPoint.x -= logRect.y;
  183. transPoint.y -= logRect.x;
  184. break;
  185. case 180:
  186. transPoint.x = pageSize.width - transPoint.x;
  187. transPoint.y = pageSize.height - transPoint.y;
  188. transPoint.x -= pageSize.width - logRect.x - logRect.width;
  189. transPoint.y -= pageSize.height - logRect.y - logRect.height;
  190. //The next line is odd and is probably necessary due to the default value of the
  191. //Text Length command: "1/2 inch less than maximum text length"
  192. //I wonder why this isn't necessary for the 90 degree rotation. *shrug*
  193. transPoint.y -= UnitConv.in2mpt(0.5);
  194. break;
  195. case 270:
  196. float tx = transPoint.y;
  197. transPoint.y = pageSize.width - transPoint.x;
  198. transPoint.x = tx;
  199. transPoint.x -= pageSize.height - logRect.y - logRect.height;
  200. transPoint.y -= pageSize.width - logRect.x - logRect.width;
  201. break;
  202. default:
  203. throw new IllegalStateException("Illegal print direction: " + printDirection);
  204. }
  205. return transPoint;
  206. }
  207. }