Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

Java2DGraphicsState.java 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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.BasicStroke;
  20. import java.awt.Color;
  21. import java.awt.Graphics2D;
  22. import java.awt.Paint;
  23. import java.awt.Shape;
  24. import java.awt.geom.AffineTransform;
  25. import java.awt.geom.Area;
  26. import java.awt.geom.GeneralPath;
  27. import org.apache.xmlgraphics.java2d.color.ColorUtil;
  28. import org.apache.fop.fo.Constants;
  29. import org.apache.fop.fonts.FontInfo;
  30. /**
  31. * Keeps information about the current state of the Graphics2D currentGraphics.
  32. * It is also used as a stack to hold a graphics context.
  33. * <p>
  34. * The graphics context is updated with the updateXXX() methods.
  35. */
  36. public class Java2DGraphicsState {
  37. /** Holds the datas of the current state */
  38. private Graphics2D currentGraphics;
  39. private BasicStroke currentStroke;
  40. private float currentStrokeWidth;
  41. private int currentStrokeStyle;
  42. /** Font configuration, passed from AWTRenderer */
  43. private FontInfo fontInfo;
  44. /** Initial AffinTransform passed by the renderer, includes scaling-info */
  45. private AffineTransform initialTransform;
  46. /**
  47. * State for storing graphics state.
  48. * @param graphics the graphics associated with the BufferedImage
  49. * @param fontInfo the FontInfo from the renderer
  50. * @param at the initial AffineTransform containing the scale transformation
  51. */
  52. public Java2DGraphicsState(Graphics2D graphics, FontInfo fontInfo,
  53. AffineTransform at) {
  54. this.fontInfo = fontInfo;
  55. this.currentGraphics = graphics;
  56. this.initialTransform = at;
  57. currentGraphics.setTransform(at);
  58. }
  59. /**
  60. * Copy constructor.
  61. * @param org the instance to copy
  62. */
  63. public Java2DGraphicsState(Java2DGraphicsState org) {
  64. this.currentGraphics = (Graphics2D)org.currentGraphics.create();
  65. this.fontInfo = org.fontInfo;
  66. this.initialTransform = org.initialTransform;
  67. this.currentStroke = org.currentStroke;
  68. this.currentStrokeStyle = org.currentStrokeStyle;
  69. this.currentStrokeWidth = org.currentStrokeWidth;
  70. }
  71. /**
  72. * @return the currently valid state
  73. */
  74. public Graphics2D getGraph() {
  75. return currentGraphics;
  76. }
  77. /** Frees resources allocated by the current Graphics2D instance. */
  78. public void dispose() {
  79. this.currentGraphics.dispose();
  80. this.currentGraphics = null;
  81. }
  82. /**
  83. * Set the current background color. Check if the background color will
  84. * change and then set the new color.
  85. *
  86. * @param col the new color as a java.awt.Color
  87. * @return true if the background color has changed
  88. */
  89. public boolean updateColor(Color col) {
  90. if (!ColorUtil.isSameColor(col, getGraph().getColor())) {
  91. getGraph().setColor(col);
  92. return true;
  93. } else {
  94. return false;
  95. }
  96. }
  97. /**
  98. * @return the current java.awt.Color
  99. */
  100. public java.awt.Color getColor() {
  101. return currentGraphics.getColor();
  102. }
  103. /**
  104. * Set the current font name. Check if the font name will change and then
  105. * set the new name.
  106. *
  107. * @param name the new font name
  108. * @param size the font size
  109. * @return true if the new Font changes the current Font
  110. */
  111. public boolean updateFont(String name, int size) {
  112. FontMetricsMapper mapper = (FontMetricsMapper) fontInfo.getMetricsFor(name);
  113. boolean updateName = (!mapper.getFontName().equals(
  114. getGraph().getFont().getFontName()));
  115. boolean updateSize = (size != (getGraph().getFont().getSize() * 1000));
  116. if (updateName || updateSize) {
  117. // the font name and/or the font size have changed
  118. java.awt.Font font = mapper.getFont(size);
  119. currentGraphics.setFont(font);
  120. return true;
  121. } else {
  122. return false;
  123. }
  124. }
  125. /** @return the current java.awt.Font */
  126. public java.awt.Font getFont() {
  127. return currentGraphics.getFont();
  128. }
  129. /**
  130. * Sets the current Stroke. The line width should be set with
  131. * updateLineWidth() before calling this method
  132. *
  133. * @param width the line width
  134. * @param style the constant for the style of the line as an int
  135. * @return true if the new Stroke changes the current Stroke
  136. */
  137. public boolean updateStroke(float width, int style) {
  138. boolean update = false;
  139. // only update if necessary
  140. if ((width != currentStrokeWidth) || (style != currentStrokeStyle)) {
  141. update = true;
  142. switch (style) {
  143. case Constants.EN_DOTTED:
  144. currentStroke = new BasicStroke(width, BasicStroke.CAP_ROUND,
  145. BasicStroke.JOIN_BEVEL, 0f, new float[] {0, 2 * width}, width);
  146. currentGraphics.setStroke(currentStroke);
  147. currentStrokeWidth = width;
  148. currentStrokeStyle = style;
  149. break;
  150. case Constants.EN_DASHED:
  151. currentStroke = new BasicStroke(width, BasicStroke.CAP_BUTT,
  152. BasicStroke.JOIN_BEVEL, 0f, new float[] {8f, 2f}, 0f);
  153. currentGraphics.setStroke(currentStroke);
  154. currentStrokeWidth = width;
  155. currentStrokeStyle = style;
  156. break;
  157. default: // EN_SOLID:
  158. currentStroke = new BasicStroke(width);
  159. currentGraphics.setStroke(currentStroke);
  160. currentStrokeWidth = width;
  161. currentStrokeStyle = style;
  162. break;
  163. }
  164. }
  165. return update;
  166. }
  167. /** @return the currently active Stroke */
  168. public BasicStroke getStroke() {
  169. return (BasicStroke) currentGraphics.getStroke();
  170. }
  171. /**
  172. * Set the current paint. This checks if the paint will change and then sets
  173. * the current paint.
  174. *
  175. * @param p the new paint
  176. * @return true if the new paint changes the current paint
  177. */
  178. public boolean updatePaint(Paint p) {
  179. Paint currentPaint = getGraph().getPaint();
  180. if (currentPaint == null) {
  181. if (p != null) {
  182. getGraph().setPaint(p);
  183. return true;
  184. }
  185. } else if (p instanceof Color && currentPaint instanceof Color) {
  186. if (!ColorUtil.isSameColor((Color)p, (Color)currentPaint)) {
  187. getGraph().setPaint(p);
  188. return true;
  189. }
  190. } else if (!p.equals(currentPaint)) {
  191. getGraph().setPaint(p);
  192. return true;
  193. }
  194. return false;
  195. }
  196. /**
  197. * Set the current clip. This either sets a new clip or sets the clip to the
  198. * intersect of the old clip and the new clip.
  199. *
  200. * @param cl the new clip in the current state
  201. * @return true if the clip shape needed to be updated
  202. */
  203. public boolean updateClip(Shape cl) {
  204. if (getGraph().getClip() != null) {
  205. Area newClip = new Area(getGraph().getClip());
  206. newClip.intersect(new Area(cl));
  207. getGraph().setClip(new GeneralPath(newClip));
  208. } else {
  209. getGraph().setClip(cl);
  210. }
  211. return true; // TODO only update if necessary
  212. }
  213. /**
  214. * Composes an AffineTransform object with the Transform in this Graphics2D
  215. * according to the rule last-specified-first-applied.
  216. * @see java.awt.Graphics2D#transform(AffineTransform)
  217. *
  218. * @param tf the transform to concatenate to the current level transform
  219. */
  220. public void transform(AffineTransform tf) {
  221. if (!tf.isIdentity()) {
  222. getGraph().transform(tf);
  223. }
  224. }
  225. /**
  226. * Get the current transform. This gets the combination of all transforms in
  227. * the current state.
  228. *
  229. * @return the calculate combined transform for the current state
  230. */
  231. public AffineTransform getTransform() {
  232. return getGraph().getTransform();
  233. }
  234. /** {@inheritDoc} */
  235. @Override
  236. public String toString() {
  237. String s = "Java2DGraphicsState " + currentGraphics.toString()
  238. + ", Stroke (width: " + currentStrokeWidth + " style: "
  239. + currentStrokeStyle + "), " + getTransform();
  240. return s;
  241. }
  242. }