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.

PDFPattern.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  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.io.IOException;
  20. import java.io.OutputStream;
  21. import java.util.List;
  22. /**
  23. * class representing a PDF Function.
  24. *
  25. * PDF Functions represent parameterized mathematical formulas and sampled representations with
  26. * arbitrary resolution. Functions are used in two areas: device-dependent
  27. * rasterization information for halftoning and transfer
  28. * functions, and color specification for smooth shading (a PDF 1.3 feature).
  29. *
  30. * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range.
  31. */
  32. public class PDFPattern extends PDFPathPaint {
  33. /**
  34. * The resources associated with this pattern
  35. */
  36. protected PDFResources resources;
  37. /**
  38. * Either one (1) for tiling, or two (2) for shading.
  39. */
  40. protected int patternType = 2; // Default
  41. /**
  42. * The name of the pattern such as "Pa1" or "Pattern1"
  43. */
  44. protected String patternName;
  45. /**
  46. * 1 for colored pattern, 2 for uncolored
  47. */
  48. protected int paintType = 2;
  49. /**
  50. * 1 for constant spacing, 2 for no distortion, and 3 for fast rendering
  51. */
  52. protected int tilingType = 1;
  53. /**
  54. * List of Doubles representing the Bounding box rectangle
  55. */
  56. protected List bBox;
  57. /**
  58. * Horizontal spacing
  59. */
  60. protected double xStep = -1;
  61. /**
  62. * Vertical spacing
  63. */
  64. protected double yStep = -1;
  65. /**
  66. * The Shading object comprising the Type 2 pattern
  67. */
  68. protected PDFShading shading;
  69. /**
  70. * List of Integers represetning the Extended unique Identifier
  71. */
  72. protected List xUID;
  73. /**
  74. * TODO use PDFGState
  75. * String representing the extended Graphics state.
  76. * Probably will never be used like this.
  77. */
  78. protected StringBuffer extGState;
  79. /**
  80. * List of Doubles representing the Transformation matrix.
  81. */
  82. protected List matrix;
  83. /**
  84. * The stream of a pattern
  85. */
  86. protected StringBuffer patternDataStream;
  87. /**
  88. * Create a tiling pattern (type 1).
  89. *
  90. * @param theResources the resources associated with this pattern
  91. * @param thePatternType the type of pattern, which is 1 for tiling.
  92. * @param thePaintType 1 or 2, colored or uncolored.
  93. * @param theTilingType 1, 2, or 3, constant spacing, no distortion, or faster tiling
  94. * @param theBBox List of Doubles: The pattern cell bounding box
  95. * @param theXStep horizontal spacing
  96. * @param theYStep vertical spacing
  97. * @param theMatrix Optional List of Doubles transformation matrix
  98. * @param theXUID Optional vector of Integers that uniquely identify the pattern
  99. * @param thePatternDataStream The stream of pattern data to be tiled.
  100. */
  101. public PDFPattern(PDFResources theResources, int thePatternType,
  102. int thePaintType, int theTilingType, List theBBox,
  103. double theXStep, double theYStep,
  104. List theMatrix, List theXUID,
  105. StringBuffer thePatternDataStream) {
  106. super();
  107. this.resources = theResources;
  108. // This next parameter is implicit to all constructors, and is
  109. // not directly passed.
  110. this.patternType = 1; // thePatternType;
  111. this.paintType = thePaintType;
  112. this.tilingType = theTilingType;
  113. this.bBox = theBBox;
  114. this.xStep = theXStep;
  115. this.yStep = theYStep;
  116. this.matrix = theMatrix;
  117. this.xUID = theXUID;
  118. this.patternDataStream = thePatternDataStream;
  119. }
  120. /**
  121. * Create a type 2 pattern (smooth shading)
  122. *
  123. * @param thePatternType the type of the pattern, which is 2, smooth shading
  124. * @param shading the Shading object that comprises this pattern
  125. * @param theXUID optional:the extended unique Identifier if used.
  126. * @param theExtGState optional: the extended graphics state, if used.
  127. * @param theMatrix Optional:List of Doubles that specify the matrix.
  128. */
  129. public PDFPattern(int thePatternType, PDFShading shading,
  130. List theXUID, StringBuffer theExtGState,
  131. List theMatrix) {
  132. super();
  133. this.patternType = 2; // thePatternType;
  134. this.shading = shading;
  135. this.xUID = theXUID;
  136. // this isn't really implemented, so it should always be null.
  137. // I just don't want to have to add a new parameter once it is implemented.
  138. this.extGState = theExtGState; // always null
  139. this.matrix = theMatrix;
  140. }
  141. /**
  142. * Get the name of the pattern
  143. *
  144. * @return String representing the name of the pattern.
  145. */
  146. public String getName() {
  147. return (this.patternName);
  148. }
  149. /**
  150. * Sets the name of the pattern.
  151. * @param name the name of the pattern. Can be anything
  152. * without spaces. "Pattern1" or "Pa1" are good examples.
  153. */
  154. public void setName(String name) {
  155. if (name.indexOf(" ") >= 0) {
  156. throw new IllegalArgumentException(
  157. "Pattern name must not contain any spaces");
  158. }
  159. this.patternName = name;
  160. }
  161. /**
  162. * Get the PDF command for setting to this pattern.
  163. *
  164. * @param fillNotStroke if true fill otherwise stroke
  165. * @return the PDF string for setting the pattern
  166. */
  167. public String getColorSpaceOut(boolean fillNotStroke) {
  168. if (fillNotStroke) { // fill but no stroke
  169. return ("/Pattern cs /" + this.getName() + " scn \n");
  170. } else { // stroke (or border)
  171. return ("/Pattern CS /" + this.getName() + " SCN \n");
  172. }
  173. }
  174. /**
  175. * represent as PDF. Whatever the FunctionType is, the correct
  176. * representation spits out. The sets of required and optional
  177. * attributes are different for each type, but if a required
  178. * attribute's object was constructed as null, then no error
  179. * is raised. Instead, the malformed PDF that was requested
  180. * by the construction is dutifully output.
  181. * This policy should be reviewed.
  182. *
  183. * @param stream the stream to write to
  184. * @throws IOException if there is an error writing to the stream
  185. * @return the PDF string.
  186. */
  187. public int output(OutputStream stream) throws IOException {
  188. int vectorSize = 0;
  189. int tempInt = 0;
  190. byte[] buffer;
  191. StringBuffer p = new StringBuffer(64);
  192. p.append("<< \n/Type /Pattern \n");
  193. if (this.resources != null) {
  194. p.append("/Resources " + this.resources.referencePDF() + " \n");
  195. }
  196. p.append("/PatternType " + this.patternType + " \n");
  197. PDFStream pdfStream = null;
  198. StreamCache encodedStream = null;
  199. if (this.patternType == 1) {
  200. p.append("/PaintType " + this.paintType + " \n");
  201. p.append("/TilingType " + this.tilingType + " \n");
  202. if (this.bBox != null) {
  203. vectorSize = this.bBox.size();
  204. p.append("/BBox [ ");
  205. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  206. p.append(PDFNumber.doubleOut((Double)this.bBox.get(tempInt)));
  207. p.append(" ");
  208. }
  209. p.append("] \n");
  210. }
  211. p.append("/XStep " + PDFNumber.doubleOut(Double.valueOf(this.xStep))
  212. + " \n");
  213. p.append("/YStep " + PDFNumber.doubleOut(Double.valueOf(this.yStep))
  214. + " \n");
  215. if (this.matrix != null) {
  216. vectorSize = this.matrix.size();
  217. p.append("/Matrix [ ");
  218. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  219. p.append(PDFNumber.doubleOut(
  220. (Double) this.matrix.get(tempInt), 8));
  221. p.append(" ");
  222. }
  223. p.append("] \n");
  224. }
  225. if (this.xUID != null) {
  226. vectorSize = this.xUID.size();
  227. p.append("/XUID [ ");
  228. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  229. p.append((this.xUID.get(tempInt)) + " ");
  230. }
  231. p.append("] \n");
  232. }
  233. // don't forget the length of the stream.
  234. if (this.patternDataStream != null) {
  235. pdfStream = new PDFStream();
  236. pdfStream.setDocument(getDocumentSafely());
  237. pdfStream.add(this.patternDataStream.toString());
  238. pdfStream.setObjectNumber(getObjectNumber());
  239. pdfStream.getFilterList().addDefaultFilters(
  240. getDocument().getFilterMap(),
  241. PDFFilterList.CONTENT_FILTER);
  242. getDocument().applyEncryption(pdfStream);
  243. encodedStream = pdfStream.encodeStream();
  244. p.append(pdfStream.getFilterList().buildFilterDictEntries());
  245. p.append("/Length " + encodedStream.getSize() + " \n");
  246. }
  247. } else {
  248. // if (this.patternType ==2)
  249. // Smooth Shading...
  250. if (this.shading != null) {
  251. p.append("/Shading " + this.shading.referencePDF() + " \n");
  252. }
  253. if (this.xUID != null) {
  254. vectorSize = this.xUID.size();
  255. p.append("/XUID [ ");
  256. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  257. p.append((this.xUID.get(tempInt)) + " ");
  258. }
  259. p.append("] \n");
  260. }
  261. if (this.extGState != null) {
  262. p.append("/ExtGState " + this.extGState + " \n");
  263. }
  264. if (this.matrix != null) {
  265. vectorSize = this.matrix.size();
  266. p.append("/Matrix [ ");
  267. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  268. p.append(PDFNumber.doubleOut(
  269. (Double) this.matrix.get(tempInt), 8));
  270. p.append(" ");
  271. }
  272. p.append("] \n");
  273. }
  274. } // end of if patterntype =1...else 2.
  275. p.append(">> \n");
  276. buffer = encode(p.toString());
  277. int length = buffer.length;
  278. stream.write(buffer);
  279. // stream representing the function
  280. if (pdfStream != null) {
  281. length += pdfStream.outputStreamData(encodedStream, stream);
  282. }
  283. patternDataStream = null;
  284. return length;
  285. }
  286. /**
  287. * Output PDF bytes, not used.
  288. * @return returns null
  289. */
  290. public byte[] toPDF() {
  291. return null;
  292. }
  293. /** {@inheritDoc} */
  294. protected boolean contentEquals(PDFObject obj) {
  295. if (obj == null) {
  296. return false;
  297. }
  298. if (obj == this) {
  299. return true;
  300. }
  301. if (!(obj instanceof PDFPattern)) {
  302. return false;
  303. }
  304. PDFPattern patt = (PDFPattern)obj;
  305. if (patternType != patt.patternType) {
  306. return false;
  307. }
  308. if (paintType != patt.paintType) {
  309. return false;
  310. }
  311. if (tilingType != patt.tilingType) {
  312. return false;
  313. }
  314. if (xStep != patt.xStep) {
  315. return false;
  316. }
  317. if (yStep != patt.yStep) {
  318. return false;
  319. }
  320. if (bBox != null) {
  321. if (!bBox.equals(patt.bBox)) {
  322. return false;
  323. }
  324. } else if (patt.bBox != null) {
  325. return false;
  326. }
  327. if (bBox != null) {
  328. if (!bBox.equals(patt.bBox)) {
  329. return false;
  330. }
  331. } else if (patt.bBox != null) {
  332. return false;
  333. }
  334. if (xUID != null) {
  335. if (!xUID.equals(patt.xUID)) {
  336. return false;
  337. }
  338. } else if (patt.xUID != null) {
  339. return false;
  340. }
  341. if (extGState != null) {
  342. if (!extGState.equals(patt.extGState)) {
  343. return false;
  344. }
  345. } else if (patt.extGState != null) {
  346. return false;
  347. }
  348. if (matrix != null) {
  349. if (!matrix.equals(patt.matrix)) {
  350. return false;
  351. }
  352. } else if (patt.matrix != null) {
  353. return false;
  354. }
  355. if (resources != null) {
  356. if (!resources.equals(patt.resources)) {
  357. return false;
  358. }
  359. } else if (patt.resources != null) {
  360. return false;
  361. }
  362. if (shading != null) {
  363. if (!shading.equals(patt.shading)) {
  364. return false;
  365. }
  366. } else if (patt.shading != null) {
  367. return false;
  368. }
  369. if (patternDataStream != null) {
  370. if (!patternDataStream.equals(patt.patternDataStream)) {
  371. return false;
  372. }
  373. } else if (patt.patternDataStream != null) {
  374. return false;
  375. }
  376. return true;
  377. }
  378. }