001: /*
002: * Copyright 2002 Paulo Soares
003: *
004: * The contents of this file are subject to the Mozilla Public License Version 1.1
005: * (the "License"); you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the License.
011: *
012: * The Original Code is 'iText, a free JAVA-PDF library'.
013: *
014: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
015: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
016: * All Rights Reserved.
017: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
018: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
019: *
020: * Contributor(s): all the names of the contributors are added in the source code
021: * where applicable.
022: *
023: * Alternatively, the contents of this file may be used under the terms of the
024: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
025: * provisions of LGPL are applicable instead of those above. If you wish to
026: * allow use of your version of this file only under the terms of the LGPL
027: * License and not to allow others to use your version of this file under
028: * the MPL, indicate your decision by deleting the provisions above and
029: * replace them with the notice and other provisions required by the LGPL.
030: * If you do not delete the provisions above, a recipient may use your version
031: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
032: *
033: * This library is free software; you can redistribute it and/or modify it
034: * under the terms of the MPL as stated above or under the terms of the GNU
035: * Library General Public License as published by the Free Software Foundation;
036: * either version 2 of the License, or any later version.
037: *
038: * This library is distributed in the hope that it will be useful, but WITHOUT
039: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
040: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
041: * details.
042: *
043: * If you didn't download this code from the following link, you should check if
044: * you aren't using an obsolete version:
045: * http://www.lowagie.com/iText/
046: */
047: package com.lowagie.text.pdf;
048:
049: import java.awt.Color;
050: import java.io.IOException;
051:
052: /** Implements the shading dictionary (or stream).
053: *
054: * @author Paulo Soares (psoares@consiste.pt)
055: */
056: public class PdfShading {
057:
058: protected PdfDictionary shading;
059:
060: protected PdfWriter writer;
061:
062: protected int shadingType;
063:
064: protected ColorDetails colorDetails;
065:
066: protected PdfName shadingName;
067:
068: protected PdfIndirectReference shadingReference;
069:
070: private Color cspace;
071:
072: /** Holds value of property bBox. */
073: protected float[] bBox;
074:
075: /** Holds value of property antiAlias. */
076: protected boolean antiAlias = false;
077:
078: /** Creates new PdfShading */
079: protected PdfShading(PdfWriter writer) {
080: this .writer = writer;
081: }
082:
083: protected void setColorSpace(Color color) {
084: cspace = color;
085: int type = ExtendedColor.getType(color);
086: PdfObject colorSpace = null;
087: switch (type) {
088: case ExtendedColor.TYPE_GRAY: {
089: colorSpace = PdfName.DEVICEGRAY;
090: break;
091: }
092: case ExtendedColor.TYPE_CMYK: {
093: colorSpace = PdfName.DEVICECMYK;
094: break;
095: }
096: case ExtendedColor.TYPE_SEPARATION: {
097: SpotColor spot = (SpotColor) color;
098: colorDetails = writer.addSimple(spot.getPdfSpotColor());
099: colorSpace = colorDetails.getIndirectReference();
100: break;
101: }
102: case ExtendedColor.TYPE_PATTERN:
103: case ExtendedColor.TYPE_SHADING: {
104: throwColorSpaceError();
105: }
106: default:
107: colorSpace = PdfName.DEVICERGB;
108: break;
109: }
110: shading.put(PdfName.COLORSPACE, colorSpace);
111: }
112:
113: public Color getColorSpace() {
114: return cspace;
115: }
116:
117: public static void throwColorSpaceError() {
118: throw new IllegalArgumentException(
119: "A tiling or shading pattern cannot be used as a color space in a shading pattern");
120: }
121:
122: public static void checkCompatibleColors(Color c1, Color c2) {
123: int type1 = ExtendedColor.getType(c1);
124: int type2 = ExtendedColor.getType(c2);
125: if (type1 != type2)
126: throw new IllegalArgumentException(
127: "Both colors must be of the same type.");
128: if (type1 == ExtendedColor.TYPE_SEPARATION
129: && ((SpotColor) c1).getPdfSpotColor() != ((SpotColor) c2)
130: .getPdfSpotColor())
131: throw new IllegalArgumentException(
132: "The spot color must be the same, only the tint can vary.");
133: if (type1 == ExtendedColor.TYPE_PATTERN
134: || type1 == ExtendedColor.TYPE_SHADING)
135: throwColorSpaceError();
136: }
137:
138: public static float[] getColorArray(Color color) {
139: int type = ExtendedColor.getType(color);
140: switch (type) {
141: case ExtendedColor.TYPE_GRAY: {
142: return new float[] { ((GrayColor) color).getGray() };
143: }
144: case ExtendedColor.TYPE_CMYK: {
145: CMYKColor cmyk = (CMYKColor) color;
146: return new float[] { cmyk.getCyan(), cmyk.getMagenta(),
147: cmyk.getYellow(), cmyk.getBlack() };
148: }
149: case ExtendedColor.TYPE_SEPARATION: {
150: return new float[] { ((SpotColor) color).getTint() };
151: }
152: case ExtendedColor.TYPE_RGB: {
153: return new float[] { color.getRed() / 255f,
154: color.getGreen() / 255f, color.getBlue() / 255f };
155: }
156: }
157: throwColorSpaceError();
158: return null;
159: }
160:
161: public static PdfShading type1(PdfWriter writer, Color colorSpace,
162: float domain[], float tMatrix[], PdfFunction function) {
163: PdfShading sp = new PdfShading(writer);
164: sp.shading = new PdfDictionary();
165: sp.shadingType = 1;
166: sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(
167: sp.shadingType));
168: sp.setColorSpace(colorSpace);
169: if (domain != null)
170: sp.shading.put(PdfName.DOMAIN, new PdfArray(domain));
171: if (tMatrix != null)
172: sp.shading.put(PdfName.MATRIX, new PdfArray(tMatrix));
173: sp.shading.put(PdfName.FUNCTION, function.getReference());
174: return sp;
175: }
176:
177: public static PdfShading type2(PdfWriter writer, Color colorSpace,
178: float coords[], float domain[], PdfFunction function,
179: boolean extend[]) {
180: PdfShading sp = new PdfShading(writer);
181: sp.shading = new PdfDictionary();
182: sp.shadingType = 2;
183: sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(
184: sp.shadingType));
185: sp.setColorSpace(colorSpace);
186: sp.shading.put(PdfName.COORDS, new PdfArray(coords));
187: if (domain != null)
188: sp.shading.put(PdfName.DOMAIN, new PdfArray(domain));
189: sp.shading.put(PdfName.FUNCTION, function.getReference());
190: if (extend != null && (extend[0] || extend[1])) {
191: PdfArray array = new PdfArray(
192: extend[0] ? PdfBoolean.PDFTRUE
193: : PdfBoolean.PDFFALSE);
194: array.add(extend[1] ? PdfBoolean.PDFTRUE
195: : PdfBoolean.PDFFALSE);
196: sp.shading.put(PdfName.EXTEND, array);
197: }
198: return sp;
199: }
200:
201: public static PdfShading type3(PdfWriter writer, Color colorSpace,
202: float coords[], float domain[], PdfFunction function,
203: boolean extend[]) {
204: PdfShading sp = type2(writer, colorSpace, coords, domain,
205: function, extend);
206: sp.shadingType = 3;
207: sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(
208: sp.shadingType));
209: return sp;
210: }
211:
212: public static PdfShading simpleAxial(PdfWriter writer, float x0,
213: float y0, float x1, float y1, Color startColor,
214: Color endColor, boolean extendStart, boolean extendEnd) {
215: checkCompatibleColors(startColor, endColor);
216: PdfFunction function = PdfFunction.type2(writer, new float[] {
217: 0, 1 }, null, getColorArray(startColor),
218: getColorArray(endColor), 1);
219: return type2(writer, startColor,
220: new float[] { x0, y0, x1, y1 }, null, function,
221: new boolean[] { extendStart, extendEnd });
222: }
223:
224: public static PdfShading simpleAxial(PdfWriter writer, float x0,
225: float y0, float x1, float y1, Color startColor,
226: Color endColor) {
227: return simpleAxial(writer, x0, y0, x1, y1, startColor,
228: endColor, true, true);
229: }
230:
231: public static PdfShading simpleRadial(PdfWriter writer, float x0,
232: float y0, float r0, float x1, float y1, float r1,
233: Color startColor, Color endColor, boolean extendStart,
234: boolean extendEnd) {
235: checkCompatibleColors(startColor, endColor);
236: PdfFunction function = PdfFunction.type2(writer, new float[] {
237: 0, 1 }, null, getColorArray(startColor),
238: getColorArray(endColor), 1);
239: return type3(writer, startColor, new float[] { x0, y0, r0, x1,
240: y1, r1 }, null, function, new boolean[] { extendStart,
241: extendEnd });
242: }
243:
244: public static PdfShading simpleRadial(PdfWriter writer, float x0,
245: float y0, float r0, float x1, float y1, float r1,
246: Color startColor, Color endColor) {
247: return simpleRadial(writer, x0, y0, r0, x1, y1, r1, startColor,
248: endColor, true, true);
249: }
250:
251: PdfName getShadingName() {
252: return shadingName;
253: }
254:
255: PdfIndirectReference getShadingReference() {
256: if (shadingReference == null)
257: shadingReference = writer.getPdfIndirectReference();
258: return shadingReference;
259: }
260:
261: void setName(int number) {
262: shadingName = new PdfName("Sh" + number);
263: }
264:
265: void addToBody() throws IOException {
266: if (bBox != null)
267: shading.put(PdfName.BBOX, new PdfArray(bBox));
268: if (antiAlias)
269: shading.put(PdfName.ANTIALIAS, PdfBoolean.PDFTRUE);
270: writer.addToBody(shading, getShadingReference());
271: }
272:
273: PdfWriter getWriter() {
274: return writer;
275: }
276:
277: ColorDetails getColorDetails() {
278: return colorDetails;
279: }
280:
281: public float[] getBBox() {
282: return bBox;
283: }
284:
285: public void setBBox(float[] bBox) {
286: if (bBox.length != 4)
287: throw new IllegalArgumentException(
288: "BBox must be a 4 element array.");
289: this .bBox = bBox;
290: }
291:
292: public boolean isAntiAlias() {
293: return antiAlias;
294: }
295:
296: public void setAntiAlias(boolean antiAlias) {
297: this.antiAlias = antiAlias;
298: }
299:
300: }
|