001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package com.sun.perseus.j2d;
027:
028: import com.sun.pisces.PiscesRenderer;
029: import com.sun.pisces.Transform6;
030:
031: import org.w3c.dom.svg.SVGRect;
032:
033: /**
034: * LinearGradientPaint support.
035: *
036: * @version $Id: LinearGradientPaintDef.java,v 1.4 2006/04/21 06:35:26 st125089 Exp $
037: */
038: public class LinearGradientPaintDef implements PaintDef {
039: public static final int CYCLE_NONE = 0;
040: public static final int CYCLE_REPEAT = 1;
041: public static final int CYCLE_REFLECT = 2;
042:
043: private Transform6 IDENTITY = new Transform6();
044:
045: /**
046: * The gradient starting point along the x-axis
047: */
048: float x0;
049:
050: /**
051: * The gradient starting point along the y-axis
052: */
053: float y0;
054:
055: /**
056: * The gradient end point along the x-axis
057: */
058: float x1;
059:
060: /**
061: * The gradient end point along the y-axis.
062: */
063: float y1;
064:
065: /**
066: * The array of stop values.
067: */
068: float[] fractions;
069:
070: /**
071: * The array of stop values, as fixed point values.
072: */
073: int[] frac;
074:
075: /**
076: * The array of ARGB color values.
077: */
078: int[] rgba;
079:
080: /**
081: * The last used rgba array, accounting for operation opacity.
082: */
083: int[] lrgba;
084:
085: /**
086: * The last paintOpacity.
087: */
088: int lastPaintOpacity = 255;
089:
090: /**
091: * One of the cycle methods (CYCLE_NONE,
092: * CYCLE_REPEAT, CYCLE_REFLECT
093: */
094: int cycleMethod;
095:
096: /**
097: * Set to true if this gradient is in objectBoundingBox space.
098: */
099: protected boolean isObjectBBox = false;
100:
101: /**
102: * An additional transform from the gradient space. This corresponds to a
103: * SVG gradientTransform attribute.
104: */
105: protected Transform gradientTransform;
106:
107: /**
108: * Constructs an <code>LinearGradientPaint</code>.
109: *
110: * @param x0 the gradient starting point along the x-axis
111: * @param y0 the gradient starting point along the y-axis
112: * @param x1 the gradient end point along the x-axis
113: * @param y1 the gradient end point along the y-axis.
114: * @param fractions the array of stop values.
115: * @param rgba the array of ARGB color values
116: * @param cycleMethod one of the cycle methods (CYCLE_NONE,
117: * CYCLE_REPEAT, CYCLE_REFLECT
118: * @param isObjectBBox if set to true, the RenderGraphic's current
119: * paintTarget object bounding box should be used to append
120: * and additional transform to the gradientTransform. The objectBoundingBox
121: * transform is appended to the right of the gradientTransform.
122: * @param gradientTransform an additional transform to add between the
123: * device coordinate space and the gradient's coordinate space.
124: */
125: public LinearGradientPaintDef(final float x0, final float y0,
126: final float x1, final float y1, final float[] fractions,
127: final int[] rgba, final int cycleMethod,
128: final boolean isObjectBBox,
129: final Transform gradientTransform) {
130: this .x0 = x0;
131: this .y0 = y0;
132: this .x1 = x1;
133: this .y1 = y1;
134: this .fractions = fractions;
135: this .rgba = rgba;
136: this .cycleMethod = cycleMethod;
137: this .isObjectBBox = isObjectBBox;
138: this .gradientTransform = gradientTransform;
139: }
140:
141: /**
142: * Sets the paint on a PiscesRender.
143: *
144: * @param rg the RenderGraphics on requesting the paint to be set.
145: * @param renderer the PiscesRender on which to set the paint.
146: * @param paintOpacity additional paint opacity.
147: */
148: public void setPaint(final PiscesRenderGraphics rg,
149: final PiscesRenderer pr, final int paintOpacity) {
150: // First, lazilly compute the fractions in fixed point.
151: if (frac == null) {
152: frac = new int[fractions.length];
153: for (int i = 0; i < fractions.length; i++) {
154: frac[i] = (int) (fractions[i] * 65536);
155: }
156: }
157:
158: // Now, lazilly compute the offset colors accounting for the current
159: // paint opacity.
160: int[] c = rgba;
161: if (paintOpacity != 255) {
162: c = lrgba;
163: if (paintOpacity != lastPaintOpacity) {
164: if (lrgba == null) {
165: lrgba = new int[rgba.length];
166: }
167: int a = 0;
168: for (int i = 0; i < rgba.length; i++) {
169: lrgba[i] = (rgba[i] & 0x00ffffff);
170: a = (paintOpacity * (0xff & (rgba[i] >> 24)) / 255);
171: lrgba[i] |= (a << 24);
172: }
173: lastPaintOpacity = paintOpacity;
174: }
175: }
176:
177: // Finally, compute the paint transform.
178:
179: // Start with the paintTarget's user space coordinate system.
180: Transform txf = null;
181: if (rg.paintTransform != null) {
182: txf = new Transform(rg.paintTransform);
183: } else {
184: txf = new Transform(rg.transform.m00 / 65536f,
185: rg.transform.m10 / 65536f,
186: rg.transform.m01 / 65536f,
187: rg.transform.m11 / 65536f,
188: rg.transform.m02 / 65536f,
189: rg.transform.m12 / 65536f);
190: }
191:
192: // Append the objectBoundingBox space to user space transform.
193: if (isObjectBBox) {
194: SVGRect bbox = rg.paintTarget.getBBox();
195: txf.mTranslate(bbox.getX(), bbox.getY());
196: txf.mScale(bbox.getWidth(), bbox.getHeight());
197: }
198:
199: // Now, append the gradient transform.
200: if (gradientTransform != null) {
201: txf.mMultiply(gradientTransform);
202: }
203:
204: Transform6 t = new Transform6();
205: t.m00 = (int) (txf.m0 * 65536);
206: t.m10 = (int) (txf.m1 * 65536);
207: t.m01 = (int) (txf.m2 * 65536);
208: t.m11 = (int) (txf.m3 * 65536);
209: t.m02 = (int) (txf.m4 * 65536);
210: t.m12 = (int) (txf.m5 * 65536);
211:
212: pr.setLinearGradient((int) (x0 * 65536), (int) (y0 * 65536),
213: (int) (x1 * 65536), (int) (y1 * 65536), frac, c,
214: cycleMethod, t);
215: }
216: }
|