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 7.9KB

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