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.

PDFFunction.java 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  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. // Java...
  20. import java.util.List;
  21. /**
  22. * class representing a PDF Function.
  23. *
  24. * PDF Functions represent parameterized mathematical formulas and
  25. * 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 PDFFunction extends PDFObject {
  33. // Guts common to all function types
  34. /**
  35. * Required: The Type of function (0,2,3,4) default is 0.
  36. */
  37. protected int functionType = 0; // Default
  38. /**
  39. * Required: 2 * m Array of Double numbers which are possible inputs to the function
  40. */
  41. protected List domain = null;
  42. /**
  43. * Required: 2 * n Array of Double numbers which are possible outputs to the function
  44. */
  45. protected List range = null;
  46. /* ********************TYPE 0***************************** */
  47. // FunctionType 0 specific function guts
  48. /**
  49. * Required: Array containing the Integer size of the Domain and Range, respectively.
  50. * Note: This is really more like two seperate integers, sizeDomain, and sizeRange,
  51. * but since they're expressed as an array in PDF, my implementation reflects that.
  52. */
  53. protected List size = null;
  54. /**
  55. * Required for Type 0: Number of Bits used to represent each sample value.
  56. * Limited to 1,2,4,8,12,16,24, or 32
  57. */
  58. protected int bitsPerSample = 1;
  59. /**
  60. * Optional for Type 0: order of interpolation between samples.
  61. * Limited to linear (1) or cubic (3). Default is 1
  62. */
  63. protected int order = 1;
  64. /**
  65. * Optional for Type 0: A 2 * m array of Doubles which provides a
  66. * linear mapping of input values to the domain.
  67. *
  68. * Required for Type 3: A 2 * k array of Doubles that, taken
  69. * in pairs, map each subset of the domain defined by Domain
  70. * and the Bounds array to the domain of the corresponding function.
  71. * Should be two values per function, usually (0,1),
  72. * as in [0 1 0 1] for 2 functions.
  73. */
  74. protected List encode = null;
  75. /**
  76. * Optional for Type 0: A 2 * n array of Doubles which provides
  77. * a linear mapping of sample values to the range. Defaults to Range.
  78. */
  79. protected List decode = null;
  80. /**
  81. * Optional For Type 0: A stream of sample values
  82. */
  83. /**
  84. * Required For Type 4: Postscript Calculator function
  85. * composed of arithmetic, boolean, and stack operators + boolean constants
  86. */
  87. protected StringBuffer functionDataStream = null;
  88. /**
  89. * Required (possibly) For Type 0: A vector of Strings for the
  90. * various filters to be used to decode the stream.
  91. * These are how the string is compressed. Flate, LZW, etc.
  92. */
  93. protected List filter = null;
  94. /* *************************TYPE 2************************** */
  95. /**
  96. * Required For Type 2: An Array of n Doubles defining
  97. * the function result when x=0. Default is [0].
  98. */
  99. protected List cZero = null;
  100. /**
  101. * Required For Type 2: An Array of n Doubles defining
  102. * the function result when x=1. Default is [1].
  103. */
  104. protected List cOne = null;
  105. /**
  106. * Required for Type 2: The interpolation exponent.
  107. * Each value x will return n results.
  108. * Must be greater than 0.
  109. */
  110. protected double interpolationExponentN = 1;
  111. /* *************************TYPE 3************************** */
  112. /**
  113. * Required for Type 3: An vector of PDFFunctions which
  114. * form an array of k single input functions making up
  115. * the stitching function.
  116. */
  117. protected List functions = null;
  118. /**
  119. * Optional for Type 3: An array of (k-1) Doubles that,
  120. * in combination with Domain, define the intervals to which
  121. * each function from the Functions array apply. Bounds
  122. * elements must be in order of increasing magnitude,
  123. * and each value must be within the value of Domain.
  124. * k is the number of functions.
  125. * If you pass null, it will output (1/k) in an array of k-1 elements.
  126. * This makes each function responsible for an equal amount of the stitching function.
  127. * It makes the gradient even.
  128. */
  129. protected List bounds = null;
  130. // See encode above, as it's also part of Type 3 Functions.
  131. /* *************************TYPE 4************************** */
  132. // See 'data' above.
  133. /**
  134. * create an complete Function object of Type 0, A Sampled function.
  135. *
  136. * Use null for an optional object parameter if you choose not to use it.
  137. * For optional int parameters, pass the default.
  138. *
  139. * @param theDomain List objects of Double objects.
  140. * This is the domain of the function.
  141. * See page 264 of the PDF 1.3 Spec.
  142. * @param theRange List objects of Double objects.
  143. * This is the Range of the function.
  144. * See page 264 of the PDF 1.3 Spec.
  145. * @param theSize A List object of Integer objects.
  146. * This is the number of samples in each input dimension.
  147. * I can't imagine there being more or less than two input dimensions,
  148. * so maybe this should be an array of length 2.
  149. *
  150. * See page 265 of the PDF 1.3 Spec.
  151. * @param theBitsPerSample An int specifying the number of bits
  152. used to represent each sample value.
  153. * Limited to 1,2,4,8,12,16,24 or 32.
  154. * See page 265 of the 1.3 PDF Spec.
  155. * @param theOrder The order of interpolation between samples. Default is 1 (one). Limited
  156. * to 1 (one) or 3, which means linear or cubic-spline interpolation.
  157. *
  158. * This attribute is optional.
  159. *
  160. * See page 265 in the PDF 1.3 spec.
  161. * @param theEncode List objects of Double objects.
  162. * This is the linear mapping of input values intop the domain
  163. * of the function's sample table. Default is hard to represent in
  164. * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
  165. * This attribute is optional.
  166. *
  167. * See page 265 in the PDF 1.3 spec.
  168. * @param theDecode List objects of Double objects.
  169. * This is a linear mapping of sample values into the range.
  170. * The default is just the range.
  171. *
  172. * This attribute is optional.
  173. * Read about it on page 265 of the PDF 1.3 spec.
  174. * @param theFunctionDataStream The sample values that specify
  175. * the function are provided in a stream.
  176. *
  177. * This is optional, but is almost always used.
  178. *
  179. * Page 265 of the PDF 1.3 spec has more.
  180. * @param theFilter This is a vector of String objects which are the various filters that
  181. * have are to be applied to the stream to make sense of it. Order matters,
  182. * so watch out.
  183. *
  184. * This is not documented in the Function section of the PDF 1.3 spec,
  185. * it was deduced from samples that this is sometimes used, even if we may never
  186. * use it in FOP. It is added for completeness sake.
  187. * @param theFunctionType This is the type of function (0,2,3, or 4).
  188. * It should be 0 as this is the constructor for sampled functions.
  189. */
  190. public PDFFunction( // CSOK: ParameterNumber
  191. int theFunctionType, List theDomain,
  192. List theRange, List theSize, int theBitsPerSample,
  193. int theOrder, List theEncode, List theDecode,
  194. StringBuffer theFunctionDataStream, List theFilter) {
  195. super();
  196. this.functionType = 0; // dang well better be 0;
  197. this.size = theSize;
  198. this.bitsPerSample = theBitsPerSample;
  199. this.order = theOrder; // int
  200. this.encode = theEncode; // vector of int
  201. this.decode = theDecode; // vector of int
  202. this.functionDataStream = theFunctionDataStream;
  203. this.filter = theFilter; // vector of Strings
  204. // the domain and range are actually two dimensional arrays.
  205. // so if there's not an even number of items, bad stuff
  206. // happens.
  207. this.domain = theDomain;
  208. this.range = theRange;
  209. }
  210. /**
  211. * create an complete Function object of Type 2, an Exponential Interpolation function.
  212. *
  213. * Use null for an optional object parameter if you choose not to use it.
  214. * For optional int parameters, pass the default.
  215. *
  216. * @param theDomain List objects of Double objects.
  217. * This is the domain of the function.
  218. * See page 264 of the PDF 1.3 Spec.
  219. * @param theRange List of Doubles that is the Range of the function.
  220. * See page 264 of the PDF 1.3 Spec.
  221. * @param theCZero This is a vector of Double objects which defines the function result
  222. * when x=0.
  223. *
  224. * This attribute is optional.
  225. * It's described on page 268 of the PDF 1.3 spec.
  226. * @param theCOne This is a vector of Double objects which defines the function result
  227. * when x=1.
  228. *
  229. * This attribute is optional.
  230. * It's described on page 268 of the PDF 1.3 spec.
  231. * @param theInterpolationExponentN This is the inerpolation exponent.
  232. *
  233. * This attribute is required.
  234. * PDF Spec page 268
  235. * @param theFunctionType The type of the function, which should be 2.
  236. */
  237. public PDFFunction(int theFunctionType, List theDomain,
  238. List theRange, List theCZero, List theCOne,
  239. double theInterpolationExponentN) {
  240. super();
  241. this.functionType = 2; // dang well better be 2;
  242. this.cZero = theCZero;
  243. this.cOne = theCOne;
  244. this.interpolationExponentN = theInterpolationExponentN;
  245. this.domain = theDomain;
  246. this.range = theRange;
  247. }
  248. /**
  249. * create an complete Function object of Type 3, a Stitching function.
  250. *
  251. * Use null for an optional object parameter if you choose not to use it.
  252. * For optional int parameters, pass the default.
  253. *
  254. * @param theDomain List objects of Double objects.
  255. * This is the domain of the function.
  256. * See page 264 of the PDF 1.3 Spec.
  257. * @param theRange List objects of Double objects.
  258. * This is the Range of the function.
  259. * See page 264 of the PDF 1.3 Spec.
  260. * @param theFunctions A List of the PDFFunction objects that the stitching function stitches.
  261. *
  262. * This attributed is required.
  263. * It is described on page 269 of the PDF spec.
  264. * @param theBounds This is a vector of Doubles representing the numbers that,
  265. * in conjunction with Domain define the intervals to which each function from
  266. * the 'functions' object applies. It must be in order of increasing magnitude,
  267. * and each must be within Domain.
  268. *
  269. * It basically sets how much of the gradient each function handles.
  270. *
  271. * This attributed is required.
  272. * It's described on page 269 of the PDF 1.3 spec.
  273. * @param theEncode List objects of Double objects.
  274. * This is the linear mapping of input values intop the domain
  275. * of the function's sample table. Default is hard to represent in
  276. * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
  277. * This attribute is required.
  278. *
  279. * See page 270 in the PDF 1.3 spec.
  280. * @param theFunctionType This is the function type. It should be 3,
  281. * for a stitching function.
  282. */
  283. public PDFFunction(int theFunctionType, List theDomain,
  284. List theRange, List theFunctions,
  285. List theBounds, List theEncode) {
  286. super();
  287. this.functionType = 3; // dang well better be 3;
  288. this.functions = theFunctions;
  289. this.bounds = theBounds;
  290. this.encode = theEncode;
  291. this.domain = theDomain;
  292. this.range = theRange;
  293. }
  294. /**
  295. * create an complete Function object of Type 4, a postscript calculator function.
  296. *
  297. * Use null for an optional object parameter if you choose not to use it.
  298. * For optional int parameters, pass the default.
  299. *
  300. * @param theDomain List object of Double objects.
  301. * This is the domain of the function.
  302. * See page 264 of the PDF 1.3 Spec.
  303. * @param theRange List object of Double objects.
  304. * This is the Range of the function.
  305. * See page 264 of the PDF 1.3 Spec.
  306. * @param theFunctionDataStream This is a stream of arithmetic,
  307. * boolean, and stack operators and boolean constants.
  308. * I end up enclosing it in the '{' and '}' braces for you, so don't do it
  309. * yourself.
  310. *
  311. * This attribute is required.
  312. * It's described on page 269 of the PDF 1.3 spec.
  313. * @param theFunctionType The type of function which should be 4, as this is
  314. * a Postscript calculator function
  315. */
  316. public PDFFunction(int theFunctionType, List theDomain,
  317. List theRange, StringBuffer theFunctionDataStream) {
  318. super();
  319. this.functionType = 4; // dang well better be 4;
  320. this.functionDataStream = theFunctionDataStream;
  321. this.domain = theDomain;
  322. this.range = theRange;
  323. }
  324. /**
  325. * represent as PDF. Whatever the FunctionType is, the correct
  326. * representation spits out. The sets of required and optional
  327. * attributes are different for each type, but if a required
  328. * attribute's object was constructed as null, then no error
  329. * is raised. Instead, the malformed PDF that was requested
  330. * by the construction is dutifully output.
  331. * This policy should be reviewed.
  332. *
  333. * @return the PDF string.
  334. */
  335. public byte[] toPDF() { // CSOK: MethodLength
  336. int vectorSize = 0;
  337. int numberOfFunctions = 0;
  338. int tempInt = 0;
  339. StringBuffer p = new StringBuffer(256);
  340. p.append("<< \n/FunctionType " + this.functionType + " \n");
  341. // FunctionType 0
  342. if (this.functionType == 0) {
  343. if (this.domain != null) {
  344. // DOMAIN
  345. p.append("/Domain [ ");
  346. vectorSize = this.domain.size();
  347. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  348. p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
  349. + " ");
  350. }
  351. p.append("] \n");
  352. } else {
  353. p.append("/Domain [ 0 1 ] \n");
  354. }
  355. // SIZE
  356. if (this.size != null) {
  357. p.append("/Size [ ");
  358. vectorSize = this.size.size();
  359. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  360. p.append(PDFNumber.doubleOut((Double)this.size.get(tempInt))
  361. + " ");
  362. }
  363. p.append("] \n");
  364. }
  365. // ENCODE
  366. if (this.encode != null) {
  367. p.append("/Encode [ ");
  368. vectorSize = this.encode.size();
  369. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  370. p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt))
  371. + " ");
  372. }
  373. p.append("] \n");
  374. } else {
  375. p.append("/Encode [ ");
  376. vectorSize = this.functions.size();
  377. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  378. p.append("0 1 ");
  379. }
  380. p.append("] \n");
  381. }
  382. // BITSPERSAMPLE
  383. p.append("/BitsPerSample " + this.bitsPerSample);
  384. // ORDER (optional)
  385. if (this.order == 1 || this.order == 3) {
  386. p.append(" \n/Order " + this.order + " \n");
  387. }
  388. // RANGE
  389. if (this.range != null) {
  390. p.append("/Range [ ");
  391. vectorSize = this.range.size();
  392. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  393. p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
  394. + " ");
  395. }
  396. p.append("] \n");
  397. }
  398. // DECODE
  399. if (this.decode != null) {
  400. p.append("/Decode [ ");
  401. vectorSize = this.decode.size();
  402. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  403. p.append(PDFNumber.doubleOut((Double)this.decode.get(tempInt))
  404. + " ");
  405. }
  406. p.append("] \n");
  407. }
  408. // LENGTH
  409. if (this.functionDataStream != null) {
  410. p.append("/Length " + (this.functionDataStream.length() + 1)
  411. + " \n");
  412. }
  413. // FILTER?
  414. if (this.filter != null) { // if there's a filter
  415. vectorSize = this.filter.size();
  416. p.append("/Filter ");
  417. if (vectorSize == 1) {
  418. p.append("/" + ((String)this.filter.get(0))
  419. + " \n");
  420. } else {
  421. p.append("[ ");
  422. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  423. p.append("/" + ((String)this.filter.get(0))
  424. + " ");
  425. }
  426. p.append("] \n");
  427. }
  428. }
  429. p.append(">>");
  430. // stream representing the function
  431. if (this.functionDataStream != null) {
  432. p.append("\nstream\n" + this.functionDataStream
  433. + "\nendstream");
  434. }
  435. // end of if FunctionType 0
  436. } else if (this.functionType == 2) {
  437. // DOMAIN
  438. if (this.domain != null) {
  439. p.append("/Domain [ ");
  440. vectorSize = this.domain.size();
  441. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  442. p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
  443. + " ");
  444. }
  445. p.append("] \n");
  446. } else {
  447. p.append("/Domain [ 0 1 ] \n");
  448. }
  449. // RANGE
  450. if (this.range != null) {
  451. p.append("/Range [ ");
  452. vectorSize = this.range.size();
  453. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  454. p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
  455. + " ");
  456. }
  457. p.append("] \n");
  458. }
  459. // FunctionType, C0, C1, N are required in PDF
  460. // C0
  461. if (this.cZero != null) {
  462. p.append("/C0 [ ");
  463. vectorSize = this.cZero.size();
  464. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  465. p.append(PDFNumber.doubleOut((Double)this.cZero.get(tempInt))
  466. + " ");
  467. }
  468. p.append("] \n");
  469. }
  470. // C1
  471. if (this.cOne != null) {
  472. p.append("/C1 [ ");
  473. vectorSize = this.cOne.size();
  474. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  475. p.append(PDFNumber.doubleOut((Double)this.cOne.get(tempInt))
  476. + " ");
  477. }
  478. p.append("] \n");
  479. }
  480. // N: The interpolation Exponent
  481. p.append("/N "
  482. + PDFNumber.doubleOut(new Double(this.interpolationExponentN))
  483. + " \n");
  484. p.append(">>");
  485. } else if (this.functionType
  486. == 3) { // fix this up when my eyes uncross
  487. // DOMAIN
  488. if (this.domain != null) {
  489. p.append("/Domain [ ");
  490. vectorSize = this.domain.size();
  491. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  492. p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
  493. + " ");
  494. }
  495. p.append("] \n");
  496. } else {
  497. p.append("/Domain [ 0 1 ] \n");
  498. }
  499. // RANGE
  500. if (this.range != null) {
  501. p.append("/Range [ ");
  502. vectorSize = this.range.size();
  503. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  504. p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
  505. + " ");
  506. }
  507. p.append("] \n");
  508. }
  509. // FUNCTIONS
  510. if (this.functions != null) {
  511. p.append("/Functions [ ");
  512. numberOfFunctions = this.functions.size();
  513. for (tempInt = 0; tempInt < numberOfFunctions; tempInt++) {
  514. p.append(((PDFFunction)this.functions.get(tempInt)).referencePDF()
  515. + " ");
  516. }
  517. p.append("] \n");
  518. }
  519. // ENCODE
  520. if (this.encode != null) {
  521. p.append("/Encode [ ");
  522. vectorSize = this.encode.size();
  523. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  524. p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt))
  525. + " ");
  526. }
  527. p.append("] \n");
  528. } else {
  529. p.append("/Encode [ ");
  530. vectorSize = this.functions.size();
  531. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  532. p.append("0 1 ");
  533. }
  534. p.append("] \n");
  535. }
  536. // BOUNDS, required, but can be empty
  537. p.append("/Bounds [ ");
  538. if (this.bounds != null) {
  539. vectorSize = this.bounds.size();
  540. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  541. p.append(PDFNumber.doubleOut((Double)this.bounds.get(tempInt))
  542. + " ");
  543. }
  544. } else {
  545. if (this.functions != null) {
  546. // if there are n functions,
  547. // there must be n-1 bounds.
  548. // so let each function handle an equal portion
  549. // of the whole. e.g. if there are 4, then [ 0.25 0.25 0.25 ]
  550. String functionsFraction = PDFNumber.doubleOut(new Double(1.0
  551. / ((double)numberOfFunctions)));
  552. for (tempInt = 0; tempInt + 1 < numberOfFunctions;
  553. tempInt++) {
  554. p.append(functionsFraction + " ");
  555. }
  556. functionsFraction = null; // clean reference.
  557. }
  558. }
  559. p.append("]\n>>");
  560. } else if (this.functionType
  561. == 4) { // fix this up when my eyes uncross
  562. // DOMAIN
  563. if (this.domain != null) {
  564. p.append("/Domain [ ");
  565. vectorSize = this.domain.size();
  566. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  567. p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
  568. + " ");
  569. }
  570. p.append("] \n");
  571. } else {
  572. p.append("/Domain [ 0 1 ] \n");
  573. }
  574. // RANGE
  575. if (this.range != null) {
  576. p.append("/Range [ ");
  577. vectorSize = this.range.size();
  578. for (tempInt = 0; tempInt < vectorSize; tempInt++) {
  579. p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
  580. + " ");
  581. }
  582. p.append("] \n");
  583. }
  584. // LENGTH
  585. if (this.functionDataStream != null) {
  586. p.append("/Length " + (this.functionDataStream.length() + 1)
  587. + " \n");
  588. }
  589. p.append(">>");
  590. // stream representing the function
  591. if (this.functionDataStream != null) {
  592. p.append("\nstream\n{ " + this.functionDataStream
  593. + " }\nendstream");
  594. }
  595. }
  596. return encode(p.toString());
  597. }
  598. /** {@inheritDoc} */
  599. protected boolean contentEquals(PDFObject obj) {
  600. if (obj == null) {
  601. return false;
  602. }
  603. if (obj == this) {
  604. return true;
  605. }
  606. if (!(obj instanceof PDFFunction)) {
  607. return false;
  608. }
  609. PDFFunction func = (PDFFunction)obj;
  610. if (functionType != func.functionType) {
  611. return false;
  612. }
  613. if (bitsPerSample != func.bitsPerSample) {
  614. return false;
  615. }
  616. if (order != func.order) {
  617. return false;
  618. }
  619. if (interpolationExponentN != func.interpolationExponentN) {
  620. return false;
  621. }
  622. if (domain != null) {
  623. if (!domain.equals(func.domain)) {
  624. return false;
  625. }
  626. } else if (func.domain != null) {
  627. return false;
  628. }
  629. if (range != null) {
  630. if (!range.equals(func.range)) {
  631. return false;
  632. }
  633. } else if (func.range != null) {
  634. return false;
  635. }
  636. if (size != null) {
  637. if (!size.equals(func.size)) {
  638. return false;
  639. }
  640. } else if (func.size != null) {
  641. return false;
  642. }
  643. if (encode != null) {
  644. if (!encode.equals(func.encode)) {
  645. return false;
  646. }
  647. } else if (func.encode != null) {
  648. return false;
  649. }
  650. if (decode != null) {
  651. if (!decode.equals(func.decode)) {
  652. return false;
  653. }
  654. } else if (func.decode != null) {
  655. return false;
  656. }
  657. if (functionDataStream != null) {
  658. if (!functionDataStream.equals(func.functionDataStream)) {
  659. return false;
  660. }
  661. } else if (func.functionDataStream != null) {
  662. return false;
  663. }
  664. if (filter != null) {
  665. if (!filter.equals(func.filter)) {
  666. return false;
  667. }
  668. } else if (func.filter != null) {
  669. return false;
  670. }
  671. if (cZero != null) {
  672. if (!cZero.equals(func.cZero)) {
  673. return false;
  674. }
  675. } else if (func.cZero != null) {
  676. return false;
  677. }
  678. if (cOne != null) {
  679. if (!cOne.equals(func.cOne)) {
  680. return false;
  681. }
  682. } else if (func.cOne != null) {
  683. return false;
  684. }
  685. if (functions != null) {
  686. if (!functions.equals(func.functions)) {
  687. return false;
  688. }
  689. } else if (func.functions != null) {
  690. return false;
  691. }
  692. if (bounds != null) {
  693. if (!bounds.equals(func.bounds)) {
  694. return false;
  695. }
  696. } else if (func.bounds != null) {
  697. return false;
  698. }
  699. return true;
  700. }
  701. }