KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Id: PDFShading.java,v 1.7.2.4 2003/02/25 14:29:38 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.io.UnsupportedEncodingException JavaDoc;
55 import java.util.List JavaDoc;
56
57 // FOP
58
import org.apache.fop.datatypes.ColorSpace;
59
60 /**
61  * class representing a PDF Smooth Shading object.
62  *
63  * PDF Functions represent parameterized mathematical formulas and sampled representations with
64  * arbitrary resolution. Functions are used in two areas: device-dependent
65  * rasterization information for halftoning and transfer
66  * functions, and color specification for smooth shading (a PDF 1.3 feature).
67  *
68  * All PDF Functions have a shadingType (0,2,3, or 4), a Domain, and a Range.
69  */

70 public class PDFShading extends PDFObject {
71     // Guts common to all function types
72

73     /**
74      * The name of the Shading e.g. "Shading1"
75      */

76     protected String JavaDoc shadingName = null;
77
78     /**
79      * Required: The Type of shading (1,2,3,4,5,6,7)
80      */

81     protected int shadingType = 3; // Default
82

83     /**
84      * A ColorSpace representing the colorspace. "DeviceRGB" is an example.
85      */

86     // protected StringBuffer colorSpace = null;
87
protected ColorSpace colorSpace = null;
88
89     /**
90      * The background color. Since shading is opaque,
91      * this is very rarely used.
92      */

93     protected List JavaDoc background = null;
94
95     /**
96      * Optional: A List specifying the clipping rectangle
97      */

98     protected List JavaDoc bBox = null;
99
100     /**
101      * Optional: A flag whether or not to filter the shading function
102      * to prevent aliasing artifacts. Default is false.
103      */

104     protected boolean antiAlias = false;
105
106     /**
107      * Optional for Type 1: Array of four numbers, xmin, xmax, ymin, ymax. Default is [0 1 0 1]
108      * Optional for Type 2: An array of two numbers between which the blend varies between start and end points. Default is 0, 1.
109      * Optional for Type 3: An array of two numbers between which the blend varies between start and end points. Default is 0, 1.
110      */

111
112     protected List JavaDoc domain = null;
113
114     /**
115      * Optional for Type 1: A transformation matrix
116      */

117     protected List JavaDoc matrix = null;
118
119     /**
120      * Required for Type 1, 2, and 3:
121      * The object of the color mapping function (usually type 2 or 3).
122      * Optional for Type 4,5,6, and 7: When it's nearly the same thing.
123      */

124     protected PDFFunction function = null;
125
126     /**
127      * Required for Type 2: An Array of four numbers specifying the starting and ending coordinate pairs
128      * Required for Type 3: An Array of six numbers [x0,y0,r0,x1,y1,r1] specifying the centers and radii of
129      * the starting and ending circles.
130      */

131     protected List JavaDoc coords = null;
132
133     /**
134      * Required for Type 2+3: An Array of two boolean values specifying whether to extend the
135      * start and end colors past the start and end points,
136      * respectively. Default is false, false.
137      */

138     protected List JavaDoc extend = null;
139
140     /**
141      * Required for Type 4,5,6, and 7: Specifies the number of bits used to represent each vertex coordinate.
142      * Allowed to be 1,2,4,8,12,16,24, or 32.
143      */

144     protected int bitsPerCoordinate = 0;
145
146     /**
147      * Required for Type 4,5,6, and 7: Specifies the number of bits used to represent the edge flag for each vertex.
148      * Allowed to be 2,4,or 8, while the Edge flag itself is allowed to be 0,1 or 2.
149      */

150     protected int bitsPerFlag = 0;
151
152     /**
153      * Required for Type 4,5,6, and 7: Array of Doubles which specifies how to decode coordinate and color component values.
154      * Each type has a differing number of decode array members, so check the spec.
155      * Page 303 in PDF Spec 1.3
156      */

157     protected List JavaDoc decode = null;
158
159     /**
160      * Required for Type 4,5,6, and 7: Specifies the number of bits used to represent each color coordinate.
161      * Allowed to be 1,2,4,8,12, or 16
162      */

163     protected int bitsPerComponent = 0;
164
165     /**
166      * Required for Type 5:The number of vertices in each "row" of the lattice; it must be greater than or equal to 2.
167      */

168     protected int verticesPerRow = 0;
169
170     /**
171      * Constructor for type function based shading
172      *
173      * @param theNumber The object number of this PDF object
174      * @param theShadingName The name of the shading pattern. Can be anything
175      * without spaces. "Shading1" or "Sh1" are good examples.
176      * @param theShadingType The type of shading object, which should be 1 for function
177      * based shading.
178      * @param theColorSpace The colorspace is 'DeviceRGB' or something similar.
179      * @param theBackground An array of color components appropriate to the
180      * colorspace key specifying a single color value.
181      * This key is used by the f operator buy ignored by the sh operator.
182      * @param theBBox List of double's representing a rectangle
183      * in the coordinate space that is current at the
184      * time of shading is imaged. Temporary clipping
185      * boundary.
186      * @param theAntiAlias Whether or not to anti-alias.
187      * @param theDomain Optional List of Doubles specifying the domain.
188      * @param theMatrix List of Doubles specifying the matrix.
189      * If it's a pattern, then the matrix maps it to pattern space.
190      * If it's a shading, then it maps it to current user space.
191      * It's optional, the default is the identity matrix
192      * @param theFunction The PDF Function that maps an (x,y) location to a color
193      */

194     public PDFShading(int theNumber, String JavaDoc theShadingName,
195                       int theShadingType, ColorSpace theColorSpace,
196                       List JavaDoc theBackground, List JavaDoc theBBox,
197                       boolean theAntiAlias, List JavaDoc theDomain,
198                       List JavaDoc theMatrix, PDFFunction theFunction) {
199         super(theNumber);
200         this.shadingName = theShadingName;
201         this.shadingType = theShadingType; // 1
202
this.colorSpace = theColorSpace;
203         this.background = theBackground;
204         this.bBox = theBBox;
205         this.antiAlias = theAntiAlias;
206
207         this.domain = theDomain;
208         this.matrix = theMatrix;
209         this.function = theFunction;
210
211     }
212
213     /**
214      * Constructor for Type 2 and 3
215      *
216      * @param theNumber The object number of this PDF object.
217      * @param theShadingName The name of the shading pattern. Can be anything
218      * without spaces. "Shading1" or "Sh1" are good examples.
219      * @param theShadingType 2 or 3 for axial or radial shading
220      * @param theColorSpace "DeviceRGB" or similar.
221      * @param theBackground theBackground An array of color components appropriate to the
222      * colorspace key specifying a single color value.
223      * This key is used by the f operator buy ignored by the sh operator.
224      * @param theBBox List of double's representing a rectangle
225      * in the coordinate space that is current at the
226      * time of shading is imaged. Temporary clipping
227      * boundary.
228      * @param theAntiAlias Default is false
229      * @param theCoords List of four (type 2) or 6 (type 3) Double
230      * @param theDomain List of Doubles specifying the domain
231      * @param theFunction the Stitching (PDFfunction type 3) function, even if it's stitching a single function
232      * @param theExtend List of Booleans of whether to extend teh start and end colors past the start and end points
233      * The default is [false, false]
234      */

235     public PDFShading(int theNumber, String JavaDoc theShadingName,
236                       int theShadingType, ColorSpace theColorSpace,
237                       List JavaDoc theBackground, List JavaDoc theBBox,
238                       boolean theAntiAlias, List JavaDoc theCoords,
239                       List JavaDoc theDomain, PDFFunction theFunction,
240                       List JavaDoc theExtend) {
241         super(theNumber);
242         this.shadingName = theShadingName;
243         this.shadingType = theShadingType; // 2 or 3
244
this.colorSpace = theColorSpace;
245         this.background = theBackground;
246         this.bBox = theBBox;
247         this.antiAlias = theAntiAlias;
248
249         this.coords = theCoords;
250         this.domain = theDomain;
251         this.function = theFunction;
252         this.extend = theExtend;
253
254     }
255
256     /**
257      * Constructor for Type 4,6, or 7
258      *
259      * @param theNumber The object number of this PDF object.
260      * @param theShadingType 4, 6, or 7 depending on whether it's
261      * Free-form gouraud-shaded triangle meshes, coons patch meshes,
262      * or tensor product patch meshes, respectively.
263      * @param theShadingName The name of the shading pattern. Can be anything
264      * without spaces. "Shading1" or "Sh1" are good examples.
265      * @param theColorSpace "DeviceRGB" or similar.
266      * @param theBackground theBackground An array of color components appropriate to the
267      * colorspace key specifying a single color value.
268      * This key is used by the f operator buy ignored by the sh operator.
269      * @param theBBox List of double's representing a rectangle
270      * in the coordinate space that is current at the
271      * time of shading is imaged. Temporary clipping
272      * boundary.
273      * @param theAntiAlias Default is false
274      * @param theBitsPerCoordinate 1,2,4,8,12,16,24 or 32.
275      * @param theBitsPerComponent 1,2,4,8,12, and 16
276      * @param theBitsPerFlag 2,4,8.
277      * @param theDecode List of Doubles see PDF 1.3 spec pages 303 to 312.
278      * @param theFunction the PDFFunction
279      */

280     public PDFShading(int theNumber, String JavaDoc theShadingName,
281                       int theShadingType, ColorSpace theColorSpace,
282                       List JavaDoc theBackground, List JavaDoc theBBox,
283                       boolean theAntiAlias, int theBitsPerCoordinate,
284                       int theBitsPerComponent, int theBitsPerFlag,
285                       List JavaDoc theDecode, PDFFunction theFunction) {
286         super(theNumber);
287
288         this.shadingType = theShadingType; // 4,6 or 7
289
this.colorSpace = theColorSpace;
290         this.background = theBackground;
291         this.bBox = theBBox;
292         this.antiAlias = theAntiAlias;
293
294         this.bitsPerCoordinate = theBitsPerCoordinate;
295         this.bitsPerComponent = theBitsPerComponent;
296         this.bitsPerFlag = theBitsPerFlag;
297         this.decode = theDecode;
298         this.function = theFunction;
299     }
300
301     /**
302      * Constructor for type 5
303      *
304      * @param theShadingType 5 for lattice-Form Gouraud shaded-triangle mesh
305      * @param theShadingName The name of the shading pattern. Can be anything
306      * without spaces. "Shading1" or "Sh1" are good examples.
307      * @param theColorSpace "DeviceRGB" or similar.
308      * @param theBackground theBackground An array of color components appropriate to the
309      * colorspace key specifying a single color value.
310      * This key is used by the f operator buy ignored by the sh operator.
311      * @param theBBox List of double's representing a rectangle
312      * in the coordinate space that is current at the
313      * time of shading is imaged. Temporary clipping
314      * boundary.
315      * @param theAntiAlias Default is false
316      * @param theBitsPerCoordinate 1,2,4,8,12,16, 24, or 32
317      * @param theBitsPerComponent 1,2,4,8,12,24,32
318      * @param theDecode List of Doubles. See page 305 in PDF 1.3 spec.
319      * @param theVerticesPerRow number of vertices in each "row" of the lattice.
320      * @param theFunction The PDFFunction that's mapped on to this shape
321      * @param theNumber the object number of this PDF object.
322      */

323     public PDFShading(int theNumber, String JavaDoc theShadingName,
324                       int theShadingType, ColorSpace theColorSpace,
325                       List JavaDoc theBackground, List JavaDoc theBBox,
326                       boolean theAntiAlias, int theBitsPerCoordinate,
327                       int theBitsPerComponent, List JavaDoc theDecode,
328                       int theVerticesPerRow, PDFFunction theFunction) {
329         super(theNumber);
330         this.shadingName = theShadingName;
331         this.shadingType = theShadingType; // 5
332
this.colorSpace = theColorSpace;
333         this.background = theBackground;
334         this.bBox = theBBox;
335         this.antiAlias = theAntiAlias;
336
337         this.bitsPerCoordinate = theBitsPerCoordinate;
338         this.bitsPerComponent = theBitsPerComponent;
339         this.decode = theDecode;
340         this.verticesPerRow = theVerticesPerRow;
341         this.function = theFunction;
342
343     }
344
345     public String JavaDoc getName() {
346         return (this.shadingName);
347     }
348
349     /**
350      * represent as PDF. Whatever the shadingType is, the correct
351      * representation spits out. The sets of required and optional
352      * attributes are different for each type, but if a required
353      * attribute's object was constructed as null, then no error
354      * is raised. Instead, the malformed PDF that was requested
355      * by the construction is dutifully output.
356      * This policy should be reviewed.
357      *
358      * @return the PDF string.
359      */

360     public byte[] toPDF() {
361         int vectorSize;
362         int tempInt;
363         StringBuffer JavaDoc p = new StringBuffer JavaDoc();
364         p.append(this.number + " " + this.generation
365                  + " obj\n<< \n/ShadingType " + this.shadingType + " \n");
366         if (this.colorSpace != null) {
367             p.append("/ColorSpace /"
368                      + this.colorSpace.getColorSpacePDFString() + " \n");
369         }
370
371         if (this.background != null) {
372             p.append("/Background [ ");
373             vectorSize = this.background.size();
374             for (tempInt = 0; tempInt < vectorSize; tempInt++) {
375                 p.append(PDFNumber.doubleOut((Double JavaDoc)this.background.get(tempInt))
376                          + " ");
377             }
378             p.append("] \n");
379         }
380
381         if (this.bBox
382                 != null) { // I've never seen an example, so I guess this is right.
383
p.append("/BBox [ ");
384             vectorSize = this.bBox.size();
385             for (tempInt = 0; tempInt < vectorSize; tempInt++) {
386                 p.append(PDFNumber.doubleOut((Double JavaDoc)this.bBox.get(tempInt))
387                          + " ");
388             }
389             p.append("] \n");
390         }
391
392         if (this.antiAlias) {
393             p.append("/AntiAlias " + this.antiAlias + " \n");
394         }
395
396         // Here's where we differentiate based on what type it is.
397
if (this.shadingType == 1) { // function based shading
398
if (this.domain != null) {
399                 p.append("/Domain [ ");
400                 vectorSize = this.domain.size();
401                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
402                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.domain.get(tempInt))
403                              + " ");
404                 }
405                 p.append("] \n");
406             } else {
407                 p.append("/Domain [ 0 1 ] \n");
408             }
409
410             if (this.matrix != null) {
411                 p.append("/Matrix [ ");
412                 vectorSize = this.matrix.size();
413                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
414                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.matrix.get(tempInt))
415                              + " ");
416                 }
417                 p.append("] \n");
418             }
419
420             if (this.function != null) {
421                 p.append("/Function ");
422                 p.append(this.function.referencePDF() + " \n");
423             }
424         } else if ((this.shadingType == 2)
425                    || (this.shadingType
426                        == 3)) { // 2 is axial shading (linear gradient)
427
// 3 is radial shading (circular gradient)
428
if (this.coords != null) {
429                 p.append("/Coords [ ");
430                 vectorSize = this.coords.size();
431                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
432                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.coords.get(tempInt))
433                              + " ");
434                 }
435                 p.append("] \n");
436             }
437
438             // DOMAIN
439
if (this.domain != null) {
440                 p.append("/Domain [ ");
441                 vectorSize = this.domain.size();
442                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
443                     p.append(PDFNumber.doubleOut((Double JavaDoc)this.domain.get(tempInt))
444                              + " ");
445                 }
446                 p.append("] \n");
447             } else {
448                 p.append("/Domain [ 0 1 ] \n");
449             }
450
451             if (this.extend != null) {
452                 p.append("/Extend [ ");
453                 vectorSize = this.extend.size();
454                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
455                     p.append(((Boolean JavaDoc)this.extend.get(tempInt)) + " ");
456                 }
457
458                 p.append("] \n");
459             } else {
460                 p.append("/Extend [ true true ] \n");
461             }
462
463
464             if (this.function != null) {
465                 p.append("/Function ");
466                 p.append(this.function.referencePDF() + " \n");
467             }
468
469
470         } else if ((this.shadingType == 4) || (this.shadingType == 6)
471                    || (this.shadingType
472                        == 7)) { // 4:Free-form Gouraud-shaded triangle meshes
473
// 6:coons patch meshes
474
// 7://tensor product patch meshes (which no one ever uses)
475
if (this.bitsPerCoordinate > 0) {
476                 p.append("/BitsPerCoordinate " + this.bitsPerCoordinate
477                          + " \n");
478             } else {
479                 p.append("/BitsPerCoordinate 1 \n");
480             }
481
482             if (this.bitsPerComponent > 0) {
483                 p.append("/BitsPerComponent " + this.bitsPerComponent
484                          + " \n");
485             } else {
486                 p.append("/BitsPerComponent 1 \n");
487             }
488
489             if (this.bitsPerFlag > 0) {
490                 p.append("/BitsPerFlag " + this.bitsPerFlag + " \n");
491             } else {
492                 p.append("/BitsPerFlag 2 \n");
493             }
494
495             if (this.decode != null) {
496                 p.append("/Decode [ ");
497                 vectorSize = this.decode.size();
498                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
499                     p.append(((Boolean JavaDoc)this.decode.get(tempInt)) + " ");
500                 }
501
502                 p.append("] \n");
503             }
504
505             if (this.function != null) {
506                 p.append("/Function ");
507                 p.append(this.function.referencePDF() + " \n");
508             }
509
510         } else if (this.shadingType
511                    == 5) { // Lattice Free form gouraud-shaded triangle mesh
512

513             if (this.bitsPerCoordinate > 0) {
514                 p.append("/BitsPerCoordinate " + this.bitsPerCoordinate
515                          + " \n");
516             } else {
517                 p.append("/BitsPerCoordinate 1 \n");
518             }
519
520             if (this.bitsPerComponent > 0) {
521                 p.append("/BitsPerComponent " + this.bitsPerComponent
522                          + " \n");
523             } else {
524                 p.append("/BitsPerComponent 1 \n");
525             }
526
527             if (this.decode != null) {
528                 p.append("/Decode [ ");
529                 vectorSize = this.decode.size();
530                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
531                     p.append(((Boolean JavaDoc)this.decode.get(tempInt)) + " ");
532                 }
533
534                 p.append("] \n");
535             }
536
537             if (this.function != null) {
538                 p.append("/Function ");
539                 p.append(this.function.referencePDF() + " \n");
540             }
541
542             if (this.verticesPerRow > 0) {
543                 p.append("/VerticesPerRow " + this.verticesPerRow + " \n");
544             } else {
545                 p.append("/VerticesPerRow 2 \n");
546             }
547
548         }
549
550         p.append(">> \nendobj\n");
551
552         try {
553             return p.toString().getBytes(PDFDocument.ENCODING);
554         } catch (UnsupportedEncodingException JavaDoc ue) {
555             return p.toString().getBytes();
556         }
557     }
558
559 }
560
Popular Tags