Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

PDFState.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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.pdf;
  19. import java.awt.Paint;
  20. import java.awt.Shape;
  21. import java.awt.geom.Area;
  22. import java.awt.geom.GeneralPath;
  23. import java.util.Iterator;
  24. import org.apache.fop.AbstractData;
  25. import org.apache.fop.AbstractState;
  26. /**
  27. * This keeps information about the current state when writing to pdf.
  28. * It allows for creating new graphics states with the q operator.
  29. * This class is only used to store the information about the state
  30. * the caller needs to handle the actual pdf operators.
  31. *
  32. * When setting the state for pdf there are three possible ways of
  33. * handling the situation.
  34. * The values can be set to override previous or default values.
  35. * A new state can be added and then the values set.
  36. * The current state can be popped and values will return to a
  37. * previous state then the necessary values can be overridden.
  38. * The current transform behaves differently to other values as the
  39. * matrix is combined with the current resolved value.
  40. * It is impossible to optimise the result without analysing the all
  41. * the possible combinations after completing.
  42. */
  43. public class PDFState extends org.apache.fop.AbstractState {
  44. private static final long serialVersionUID = 5384726143906371279L;
  45. /**
  46. * PDF State for storing graphics state.
  47. */
  48. public PDFState() {
  49. }
  50. /**
  51. * Set the current paint.
  52. * This checks if the paint will change and then sets the current paint.
  53. *
  54. * @param p the new paint
  55. * @return true if the new paint changes the current paint
  56. */
  57. public boolean setPaint(Paint p) {
  58. Paint paint = ((PDFData)getData()).paint;
  59. if (paint == null) {
  60. if (p != null) {
  61. ((PDFData)getData()).paint = p;
  62. return true;
  63. }
  64. } else if (!paint.equals(p)) {
  65. ((PDFData)getData()).paint = p;
  66. return true;
  67. }
  68. return false;
  69. }
  70. /**
  71. * Check if the clip will change the current state.
  72. * A clip is assumed to be used in a situation where it will add
  73. * to any clip in the current or parent states.
  74. * A clip cannot be cleared, this can only be achieved by going to
  75. * a parent level with the correct clip.
  76. * If the clip is different then it may start a new state so that
  77. * it can return to the previous clip.
  78. *
  79. * @param cl the clip shape to check
  80. * @return true if the clip will change the current clip.
  81. */
  82. public boolean checkClip(Shape cl) {
  83. Shape clip = ((PDFData)getData()).clip;
  84. if (clip == null) {
  85. if (cl != null) {
  86. return true;
  87. }
  88. } else if (!new Area(clip).equals(new Area(cl))) {
  89. return true;
  90. }
  91. //TODO check for clips that are larger than the current
  92. return false;
  93. }
  94. /**
  95. * Set the current clip.
  96. * This either sets a new clip or sets the clip to the intersect of
  97. * the old clip and the new clip.
  98. *
  99. * @param cl the new clip in the current state
  100. */
  101. public void setClip(Shape cl) {
  102. Shape clip = ((PDFData)getData()).clip;
  103. if (clip != null) {
  104. Area newClip = new Area(clip);
  105. newClip.intersect(new Area(cl));
  106. ((PDFData)getData()).clip = new GeneralPath(newClip);
  107. } else {
  108. ((PDFData)getData()).clip = cl;
  109. }
  110. }
  111. /**
  112. * Get the current stack level.
  113. *
  114. * @return the current stack level
  115. */
  116. public int getStackLevel() {
  117. return getStateStack().size();
  118. }
  119. /**
  120. * Get the graphics state.
  121. * This gets the combination of all graphic states for
  122. * the current context.
  123. * This is the graphic state set with the gs operator not
  124. * the other graphic state changes.
  125. *
  126. * @return the calculated ExtGState in the current context
  127. */
  128. public PDFGState getGState() {
  129. PDFGState defaultState = PDFGState.DEFAULT;
  130. PDFGState state;
  131. PDFGState newState = new PDFGState();
  132. newState.addValues(defaultState);
  133. for (Iterator it = getStateStack().iterator(); it.hasNext();) {
  134. PDFData data = (PDFData)it.next();
  135. state = data.gstate;
  136. if (state != null) {
  137. newState.addValues(state);
  138. }
  139. }
  140. if (((PDFData)getData()).gstate != null) {
  141. newState.addValues(((PDFData)getData()).gstate);
  142. }
  143. return newState;
  144. }
  145. /** {@inheritDoc} */
  146. protected AbstractData instantiateData() {
  147. return new PDFData();
  148. }
  149. /** {@inheritDoc} */
  150. protected AbstractState instantiateState() {
  151. return new PDFState();
  152. }
  153. /**
  154. * Push the current state onto the stack.
  155. * This call should be used when the q operator is used
  156. * so that the state is known when popped.
  157. */
  158. public void push() {
  159. AbstractData data = getData();
  160. AbstractData copy = (AbstractData)data.clone();
  161. data.clearTransform();
  162. getStateStack().add(copy);
  163. }
  164. private class PDFData extends org.apache.fop.AbstractData {
  165. private static final long serialVersionUID = 3527950647293177764L;
  166. private Paint paint = null;
  167. private Paint backPaint = null;
  168. private int lineCap = 0;
  169. private int lineJoin = 0;
  170. private float miterLimit = 0;
  171. private boolean text = false;
  172. private int dashOffset = 0;
  173. private Shape clip = null;
  174. private PDFGState gstate = null;
  175. /** {@inheritDoc} */
  176. public Object clone() {
  177. PDFData obj = (PDFData)super.clone();
  178. obj.paint = this.paint;
  179. obj.backPaint = this.paint;
  180. obj.lineCap = this.lineCap;
  181. obj.lineJoin = this.lineJoin;
  182. obj.miterLimit = this.miterLimit;
  183. obj.text = this.text;
  184. obj.dashOffset = this.dashOffset;
  185. obj.clip = this.clip;
  186. obj.gstate = this.gstate;
  187. return obj;
  188. }
  189. /** {@inheritDoc} */
  190. public String toString() {
  191. return super.toString()
  192. + ", paint=" + paint
  193. + ", backPaint=" + backPaint
  194. + ", lineCap=" + lineCap
  195. + ", miterLimit=" + miterLimit
  196. + ", text=" + text
  197. + ", dashOffset=" + dashOffset
  198. + ", clip=" + clip
  199. + ", gstate=" + gstate;
  200. }
  201. /** {@inheritDoc} */
  202. protected AbstractData instantiate() {
  203. return new PDFData();
  204. }
  205. }
  206. }