KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > pdf > PDFFunction


1 /*
2  * $Id: PDFFunction.java,v 1.7.2.4 2003/02/25 14:29:37 jeremias Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.pdf;
52
53 // Java...
54
import java.util.List JavaDoc;
55 import java.io.UnsupportedEncodingException JavaDoc;
56
57 /**
58  * class representing a PDF Function.
59  *
60  * PDF Functions represent parameterized mathematical formulas and sampled representations with
61  * arbitrary resolution. Functions are used in two areas: device-dependent
62  * rasterization information for halftoning and transfer
63  * functions, and color specification for smooth shading (a PDF 1.3 feature).
64  *
65  * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range.
66  */

67 public class PDFFunction extends PDFObject {
68     // Guts common to all function types
69

70     /**
71      * Required: The Type of function (0,2,3,4) default is 0.
72      */

73     protected int functionType = 0; // Default
74

75     /**
76      * Required: 2 * m Array of Double numbers which are possible inputs to the function
77      */

78     protected List JavaDoc domain = null;
79
80     /**
81      * Required: 2 * n Array of Double numbers which are possible outputs to the function
82      */

83     protected List JavaDoc range = null;
84
85     /* ********************TYPE 0***************************** */
86     // FunctionType 0 specific function guts
87

88     /**
89      * Required: Array containing the Integer size of the Domain and Range, respectively.
90      * Note: This is really more like two seperate integers, sizeDomain, and sizeRange,
91      * but since they're expressed as an array in PDF, my implementation reflects that.
92      */

93     protected List JavaDoc size = null;
94
95     /**
96      * Required for Type 0: Number of Bits used to represent each sample value. Limited to 1,2,4,8,12,16,24, or 32
97      */

98     protected int bitsPerSample = 1;
99
100     /**
101      * Optional for Type 0: order of interpolation between samples. Limited to linear (1) or cubic (3). Default is 1
102      */

103     protected int order = 1;
104
105     /**
106      * Optional for Type 0: A 2 * m array of Doubles which provides a linear mapping of input values to the domain.
107      *
108      * Required for Type 3: A 2 * k array of Doubles that, taken in pairs, map each subset of the domain defined by Domain and the Bounds array to the domain of the corresponding function.
109      * Should be two values per function, usually (0,1), as in [0 1 0 1] for 2 functions.
110      */

111     protected List JavaDoc encode = null;
112
113     /**
114      * Optinoal for Type 0: A 2 * n array of Doubles which provides a linear mapping of sample values to the range. Defaults to Range.
115      */

116     protected List JavaDoc decode = null;
117
118     /**
119      * Optional For Type 0: A stream of sample values
120      */

121
122     /**
123      * Required For Type 4: Postscript Calculator function composed of arithmetic, boolean, and stack operators + boolean constants
124      */

125     protected StringBuffer JavaDoc functionDataStream = null;
126
127     /**
128      * Required (?) For Type 0: A List of Strings for the various filters to be used to decode the stream.
129      * These are how the string is compressed. Flate, LZW, etc.
130      */

131     protected List JavaDoc filter = null;
132     /* *************************TYPE 2************************** */
133
134     /**
135      * Required For Type 2: An Array of n Doubles defining the function result when x=0. Default is [0].
136      */

137     protected List JavaDoc cZero = null;
138
139     /**
140      * Required For Type 2: An Array of n Doubles defining the function result when x=1. Default is [1].
141      */

142     protected List JavaDoc cOne = null;
143
144     /**
145      * Required for Type 2: The interpolation exponent.
146      * Each value x will return n results.
147      * Must be greater than 0.
148      */

149     protected double interpolationExponentN = 1;
150
151     /* *************************TYPE 3************************** */
152
153     /**
154      * Required for Type 3: A List of PDFFunctions which form an array of k single input functions making up the stitching function.
155      */

156     protected List JavaDoc functions = null;
157
158     /**
159      * Optional for Type 3: An array of (k-1) Doubles that, in combination with Domain, define the intervals to which each function from the Functions array apply. Bounds elements must be in order of increasing magnitude, and each value must be within the value of Domain.
160      * k is the number of functions.
161      * If you pass null, it will output (1/k) in an array of k-1 elements.
162      * This makes each function responsible for an equal amount of the stitching function.
163      * It makes the gradient even.
164      */

165     protected List JavaDoc bounds = null;
166     // See encode above, as it's also part of Type 3 Functions.
167

168     /* *************************TYPE 4************************** */
169     // See 'data' above.
170

171     /**
172      * create an complete Function object of Type 0, A Sampled function.
173      *
174      * Use null for an optional object parameter if you choose not to use it.
175      * For optional int parameters, pass the default.
176      *
177      * @param theDomain List objects of Double objects.
178      * This is the domain of the function.
179      * See page 264 of the PDF 1.3 Spec.
180      * @param theRange List objects of Double objects.
181      * This is the Range of the function.
182      * See page 264 of the PDF 1.3 Spec.
183      * @param theSize A List object of Integer objects.
184      * This is the number of samples in each input dimension.
185      * I can't imagine there being more or less than two input dimensions,
186      * so maybe this should be an array of length 2.
187      *
188      * See page 265 of the PDF 1.3 Spec.
189      * @param theBitsPerSample An int specifying the number of bits user to represent each sample value.
190      * Limited to 1,2,4,8,12,16,24 or 32.
191      * See page 265 of the 1.3 PDF Spec.
192      * @param theOrder The order of interpolation between samples. Default is 1 (one). Limited
193      * to 1 (one) or 3, which means linear or cubic-spline interpolation.
194      *
195      * This attribute is optional.
196      *
197      * See page 265 in the PDF 1.3 spec.
198      * @param theEncode List objects of Double objects.
199      * This is the linear mapping of input values intop the domain
200      * of the function's sample table. Default is hard to represent in
201      * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
202      * This attribute is optional.
203      *
204      * See page 265 in the PDF 1.3 spec.
205      * @param theDecode List objects of Double objects.
206      * This is a linear mapping of sample values into the range.
207      * The default is just the range.
208      *
209      * This attribute is optional.
210      * Read about it on page 265 of the PDF 1.3 spec.
211      * @param theFunctionDataStream The sample values that specify the function are provided in a stream.
212      *
213      * This is optional, but is almost always used.
214      *
215      * Page 265 of the PDF 1.3 spec has more.
216      * @param theFilter This is a List of String objects which are the various filters that
217      * have are to be applied to the stream to make sense of it. Order matters,
218      * so watch out.
219      *
220      * This is not documented in the Function section of the PDF 1.3 spec,
221      * it was deduced from samples that this is sometimes used, even if we may never
222      * use it in FOP. It is added for completeness sake.
223      * @param theNumber The object number of this PDF object.
224      * @param theFunctionType This is the type of function (0,2,3, or 4).
225      * It should be 0 as this is the constructor for sampled functions.
226      */

227     public PDFFunction(int theNumber, int theFunctionType, List JavaDoc theDomain,
228                        List JavaDoc theRange, List JavaDoc theSize, int theBitsPerSample,
229                        int theOrder, List JavaDoc theEncode, List JavaDoc theDecode,
230                        StringBuffer JavaDoc theFunctionDataStream, List JavaDoc theFilter) {
231         super(theNumber);
232
233         this.functionType = 0; // dang well better be 0;
234
this.size = theSize;
235         this.bitsPerSample = theBitsPerSample;
236         this.order = theOrder; // int
237
this.encode = theEncode; // List of int
238
this.decode = theDecode; // List of int
239
this.functionDataStream = theFunctionDataStream;
240         this.filter = theFilter; // List of Strings
241

242         // the domain and range are actually two dimensional arrays.
243
// so if there's not an even number of items, bad stuff
244
// happens.
245
this.domain = theDomain;
246         this.range = theRange;
247     }
248
249     /**
250      * create an complete Function object of Type 2, an Exponential Interpolation function.
251      *
252      * Use null for an optional object parameter if you choose not to use it.
253      * For optional int parameters, pass the default.
254      *
255      * @param theNumber the object's number
256      * @param theDomain List objects of Double objects.
257      * This is the domain of the function.
258      * See page 264 of the PDF 1.3 Spec.
259      * @param theRange List of Doubles that is the Range of the function.
260      * See page 264 of the PDF 1.3 Spec.
261      * @param theCZero This is a List of Double objects which defines the function result
262      * when x=0.
263      *
264      * This attribute is optional.
265      * It's described on page 268 of the PDF 1.3 spec.
266      * @param theCOne This is a List of Double objects which defines the function result
267      * when x=1.
268      *
269      * This attribute is optional.
270      * It's described on page 268 of the PDF 1.3 spec.
271      * @param theInterpolationExponentN This is the inerpolation exponent.
272      *
273      * This attribute is required.
274      * PDF Spec page 268
275      * @param theFunctionType The type of the function, which should be 2.
276      */

277     public PDFFunction(int theNumber, int theFunctionType, List JavaDoc theDomain,
278                        List JavaDoc theRange, List JavaDoc theCZero, List JavaDoc theCOne,
279                        double theInterpolationExponentN) {
280         super(theNumber);
281
282         this.functionType = 2; // dang well better be 2;
283

284         this.cZero = theCZero;
285         this.cOne = theCOne;
286         this.interpolationExponentN = theInterpolationExponentN;
287
288
289         this.domain = theDomain;
290         this.range = theRange;
291
292     }
293
294     /**
295      * create an complete Function object of Type 3, a Stitching 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 theNumber the object's number
301      * @param theDomain List objects of Double objects.
302      * This is the domain of the function.
303      * See page 264 of the PDF 1.3 Spec.
304      * @param theRange List objects of Double objects.
305      * This is the Range of the function.
306      * See page 264 of the PDF 1.3 Spec.
307      * @param theFunctions A List of the PDFFunction objects that the stitching function stitches.
308      *
309      * This attributed is required.
310      * It is described on page 269 of the PDF spec.
311      * @param theBounds This is a List of Doubles representing the numbers that,
312      * in conjunction with Domain define the intervals to which each function from
313      * the 'functions' object applies. It must be in order of increasing magnitude,
314      * and each must be within Domain.
315      *
316      * It basically sets how much of the gradient each function handles.
317      *
318      * This attributed is required.
319      * It's described on page 269 of the PDF 1.3 spec.
320      * @param theEncode List objects of Double objects.
321      * This is the linear mapping of input values intop the domain
322      * of the function's sample table. Default is hard to represent in
323      * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
324      * This attribute is required.
325      *
326      * See page 270 in the PDF 1.3 spec.
327      * @param theFunctionType This is the function type. It should be 3,
328      * for a stitching function.
329      */

330     public PDFFunction(int theNumber, int theFunctionType, List JavaDoc theDomain,
331                        List JavaDoc theRange, List JavaDoc theFunctions,
332                        List JavaDoc theBounds, List JavaDoc theEncode) {
333         super(theNumber);
334
335         this.functionType = 3; // dang well better be 3;
336

337         this.functions = theFunctions;
338         this.bounds = theBounds;
339         this.encode = theEncode;
340         this.domain = theDomain;
341         this.range = theRange;
342
343     }
344
345     /**
346      * create an complete Function object of Type 4, a postscript calculator function.
347      *
348      * Use null for an optional object parameter if you choose not to use it.
349      * For optional int parameters, pass the default.
350      *
351      * @param theDomain List object of Double objects.
352      * This is the domain of the function.
353      * See page 264 of the PDF 1.3 Spec.
354      * @param theRange List object of Double objects.
355      * This is the Range of the function.
356      * See page 264 of the PDF 1.3 Spec.
357      * @param theFunctionDataStream This is a stream of arithmetic, boolean, and stack operators and boolean constants.
358      * I end up enclosing it in the '{' and '}' braces for you, so don't do it
359      * yourself.
360      *
361      * This attribute is required.
362      * It's described on page 269 of the PDF 1.3 spec.
363      * @param theNumber The object number of this PDF object.
364      * @param theFunctionType The type of function which should be 4, as this is
365      * a Postscript calculator function
366      */

367     public PDFFunction(int theNumber, int theFunctionType, List JavaDoc theDomain,
368                        List JavaDoc theRange, StringBuffer JavaDoc theFunctionDataStream) {
369         super(theNumber);
370
371         this.functionType = 4; // dang well better be 4;
372
this.functionDataStream = theFunctionDataStream;
373
374         this.domain = theDomain;
375
376         this.range = theRange;
377
378     }
379
380
381     /**
382      * represent as PDF. Whatever the FunctionType is, the correct
383      * representation spits out. The sets of required and optional
384      * attributes are different for each type, but if a required
385      * attribute's object was constructed as null, then no error
386      * is raised. Instead, the malformed PDF that was requested
387      * by the construction is dutifully output.
388      * This policy should be reviewed.
389      *
390      * @return the PDF string.
391      */

392     public byte[] toPDF() {
393         int vectorSize = 0;
394         int numberOfFunctions = 0;
395         int tempInt = 0;
396         StringBuffer JavaDoc p = new StringBuffer JavaDoc();
397         p.append(this.number + " " + this.generation
398                  + " obj\n<< \n/FunctionType " + this.functionType + " \n");
399
400         // FunctionType 0
401
if (this.functionType == 0) {
402             if (this.domain != null) {
403                 // DOMAIN
404
p.append("/Domain [ ");
405                 vectorSize = this.domain.size();
406                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
407                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.domain.get(tempInt))
408                              + " ");
409                 }
410
411                 p.append("] \n");
412             } else {
413                 p.append("/Domain [ 0 1 ] \n");
414             }
415
416             // SIZE
417
if (this.size != null) {
418                 p.append("/Size [ ");
419                 vectorSize = this.size.size();
420                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
421                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.size.get(tempInt))
422                              + " ");
423                 }
424                 p.append("] \n");
425             }
426             // ENCODE
427
if (this.encode != null) {
428                 p.append("/Encode [ ");
429                 vectorSize = this.encode.size();
430                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
431                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.encode.get(tempInt))
432                              + " ");
433                 }
434                 p.append("] \n");
435             } else {
436                 p.append("/Encode [ ");
437                 vectorSize = this.functions.size();
438                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
439                     p.append("0 1 ");
440                 }
441                 p.append("] \n");
442
443             }
444
445             // BITSPERSAMPLE
446
p.append("/BitsPerSample " + this.bitsPerSample);
447
448             // ORDER (optional)
449
if (this.order == 1 || this.order == 3) {
450                 p.append(" \n/Order " + this.order + " \n");
451             }
452
453             // RANGE
454
if (this.range != null) {
455                 p.append("/Range [ ");
456                 vectorSize = this.range.size();
457                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
458                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.range.get(tempInt))
459                              + " ");
460                 }
461
462                 p.append("] \n");
463             }
464
465             // DECODE
466
if (this.decode != null) {
467                 p.append("/Decode [ ");
468                 vectorSize = this.decode.size();
469                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
470                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.decode.get(tempInt))
471                              + " ");
472                 }
473
474                 p.append("] \n");
475             }
476
477             // LENGTH
478
if (this.functionDataStream != null) {
479                 p.append("/Length " + (this.functionDataStream.length() + 1)
480                          + " \n");
481             }
482
483             // FILTER?
484
if (this.filter != null) { // if there's a filter
485
vectorSize = this.filter.size();
486                 p.append("/Filter ");
487                 if (vectorSize == 1) {
488                     p.append("/" + ((String JavaDoc)this.filter.get(0))
489                              + " \n");
490                 } else {
491                     p.append("[ ");
492                     for (tempInt = 0; tempInt < vectorSize; tempInt++) {
493                         p.append("/" + ((String JavaDoc)this.filter.get(0))
494                                  + " ");
495                     }
496                     p.append("] \n");
497                 }
498             }
499             p.append(">> \n");
500
501             // stream representing the function
502
if (this.functionDataStream != null) {
503                 p.append("stream\n" + this.functionDataStream
504                          + "\nendstream\n");
505             }
506
507             p.append("endobj\n");
508
509         } // end of if FunctionType 0
510
else if (this.functionType == 2) {
511             // DOMAIN
512
if (this.domain != null) {
513                 p.append("/Domain [ ");
514                 vectorSize = this.domain.size();
515                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
516                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.domain.get(tempInt))
517                              + " ");
518                 }
519
520                 p.append("] \n");
521             } else {
522                 p.append("/Domain [ 0 1 ] \n");
523             }
524
525
526             // RANGE
527
if (this.range != null) {
528                 p.append("/Range [ ");
529                 vectorSize = this.range.size();
530                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
531                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.range.get(tempInt))
532                              + " ");
533                 }
534
535                 p.append("] \n");
536             }
537
538             // FunctionType, C0, C1, N are required in PDF
539

540             // C0
541
if (this.cZero != null) {
542                 p.append("/C0 [ ");
543                 vectorSize = this.cZero.size();
544                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
545                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.cZero.get(tempInt))
546                              + " ");
547                 }
548                 p.append("] \n");
549             }
550
551             // C1
552
if (this.cOne != null) {
553                 p.append("/C1 [ ");
554                 vectorSize = this.cOne.size();
555                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
556                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.cOne.get(tempInt))
557                              + " ");
558                 }
559                 p.append("] \n");
560             }
561
562             // N: The interpolation Exponent
563
p.append("/N "
564                      + PDFNumber.doubleOut(new Double JavaDoc(this.interpolationExponentN))
565                      + " \n");
566
567             p.append(">> \nendobj\n");
568
569         } else if (this.functionType
570                    == 3) { // fix this up when my eyes uncross
571
// DOMAIN
572
if (this.domain != null) {
573                 p.append("/Domain [ ");
574                 vectorSize = this.domain.size();
575                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
576                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.domain.get(tempInt))
577                              + " ");
578                 }
579                 p.append("] \n");
580             } else {
581                 p.append("/Domain [ 0 1 ] \n");
582             }
583
584             // RANGE
585
if (this.range != null) {
586                 p.append("/Range [ ");
587                 vectorSize = this.range.size();
588                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
589                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.range.get(tempInt))
590                              + " ");
591                 }
592
593                 p.append("] \n");
594             }
595
596             // FUNCTIONS
597
if (this.functions != null) {
598                 p.append("/Functions [ ");
599                 numberOfFunctions = this.functions.size();
600                 for (tempInt = 0; tempInt < numberOfFunctions; tempInt++) {
601                     p.append(((PDFFunction)this.functions.get(tempInt)).referencePDF()
602                              + " ");
603
604                 }
605                 p.append("] \n");
606             }
607
608
609             // ENCODE
610
if (this.encode != null) {
611                 p.append("/Encode [ ");
612                 vectorSize = this.encode.size();
613                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
614                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.encode.get(tempInt))
615                              + " ");
616                 }
617
618                 p.append("] \n");
619             } else {
620                 p.append("/Encode [ ");
621                 vectorSize = this.functions.size();
622                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
623                     p.append("0 1 ");
624                 }
625                 p.append("] \n");
626
627             }
628
629
630             // BOUNDS, required, but can be empty
631
p.append("/Bounds [ ");
632             if (this.bounds != null) {
633
634                 vectorSize = this.bounds.size();
635                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
636                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.bounds.get(tempInt))
637                              + " ");
638                 }
639
640             } else {
641                 if (this.functions != null) {
642                     // if there are n functions,
643
// there must be n-1 bounds.
644
// so let each function handle an equal portion
645
// of the whole. e.g. if there are 4, then [ 0.25 0.25 0.25 ]
646

647                     String JavaDoc functionsFraction = PDFNumber.doubleOut(new Double JavaDoc(1.0
648                             / ((double)numberOfFunctions)));
649
650                     for (tempInt = 0; tempInt + 1 < numberOfFunctions;
651                             tempInt++) {
652
653                         p.append(functionsFraction + " ");
654                     }
655                     functionsFraction = null; // clean reference.
656

657                 }
658
659             }
660             p.append("] \n");
661
662
663             p.append(">> \nendobj\n");
664         } else if (this.functionType
665                    == 4) { // fix this up when my eyes uncross
666
// DOMAIN
667
if (this.domain != null) {
668                 p.append("/Domain [ ");
669                 vectorSize = this.domain.size();
670                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
671                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.domain.get(tempInt))
672                              + " ");
673                 }
674
675                 p.append("] \n");
676             } else {
677                 p.append("/Domain [ 0 1 ] \n");
678             }
679
680             // RANGE
681
if (this.range != null) {
682                 p.append("/Range [ ");
683                 vectorSize = this.range.size();
684                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
685                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.range.get(tempInt))
686                              + " ");
687                 }
688
689                 p.append("] \n");
690             }
691
692             // LENGTH
693
if (this.functionDataStream != null) {
694                 p.append("/Length " + (this.functionDataStream.length() + 1)
695                          + " \n");
696             }
697
698             p.append(">> \n");
699
700             // stream representing the function
701
if (this.functionDataStream != null) {
702                 p.append("stream\n{ " + this.functionDataStream
703                          + " } \nendstream\n");
704             }
705
706             p.append("endobj\n");
707
708         }
709
710         try {
711             return p.toString().getBytes(PDFDocument.ENCODING);
712         } catch (UnsupportedEncodingException JavaDoc ue) {
713             return p.toString().getBytes();
714         }
715     }
716
717 }
718
Popular Tags