001: /*
002: *
003: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License version
008: * 2 only, as published by the Free Software Foundation.
009: *
010: * This program is distributed in the hope that it will be useful, but
011: * WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * General Public License version 2 for more details (a copy is
014: * included at /legal/license.txt).
015: *
016: * You should have received a copy of the GNU General Public License
017: * version 2 along with this work; if not, write to the Free Software
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022: * Clara, CA 95054 or visit www.sun.com if you need additional
023: * information or have any questions.
024: */
025:
026: package com.sun.pisces;
027:
028: public class RadialGradient extends Gradient {
029:
030: float cx, cy, rsq;
031: float fx, fy;
032:
033: public RadialGradient(int cx, int cy, int fx, int fy, int radius,
034: Transform6 gradientTransform, GradientColorMap colorMap) {
035: super (gradientTransform, colorMap);
036:
037: this .cx = cx / 65536.0f;
038: this .cy = cy / 65536.0f;
039: float r = radius / 65536.0f;
040: this .rsq = r * r;
041: this .fx = fx / 65536.0f;
042: this .fy = fy / 65536.0f;
043:
044: float fcx = this .fx - this .cx;
045: float fcy = this .fy - this .cy;
046: float d = (float) Math.sqrt(fcx * fcx + fcy * fcy);
047: if (d > r * 0.97f) {
048: float f = (r * 0.97f) / d;
049: this .fx = this .cx + f * fcx;
050: this .fy = this .cy + f * fcy;
051: }
052: }
053:
054: public void paint(int x, int y, int width, int height,
055: int[] minTouched, int[] maxTouched, int[] dst,
056: int dstOffset, int dstScanlineStride) {
057: float a00 = inverse.m00 / 65536.0f;
058: float a01 = inverse.m01 / 65536.0f;
059: float a02 = inverse.m02 / 65536.0f;
060: float a10 = inverse.m10 / 65536.0f;
061: float a11 = inverse.m11 / 65536.0f;
062: float a12 = inverse.m12 / 65536.0f;
063:
064: int sx = x;
065:
066: for (int j = 0; j < height; j++, y++) {
067: int minX = minTouched[j];
068: int maxX = maxTouched[j];
069: int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
070: if (w + minX > width) {
071: w = width - minX;
072: }
073:
074: int didx = dstOffset + minX;
075: x = sx + minX;
076:
077: double txx = x * a00 + y * a01 + a02;
078: double tyy = x * a10 + y * a11 + a12;
079:
080: double fxx = fx - txx;
081: double fyy = fy - tyy;
082: double A = fxx * fxx + fyy * fyy;
083: double cfx = cx - fx;
084: double cfy = cy - fy;
085: double B = 2.0f * (cfx * fxx + cfy * fyy);
086: double C = cfx * cfx + cfy * cfy - rsq;
087: double Csq = C * C;
088: double U = -B / (2.0f * C);
089: double dU = (a00 * cfx + a10 * cfy) / C;
090: double V = (B * B - 4.0f * A * C) / (4.0f * Csq);
091: double dV = (2.0f
092: * a00
093: * a10
094: * cfx
095: * cfy
096: + a00
097: * (a00 * (cfx * cfx - C) - B * cfx + 2.0f * C * fxx) + a10
098: * (a10 * (cfy * cfy - C) - B * cfy + 2.0f * C * fyy))
099: / Csq;
100: double tmp = a10 * cfx - a00 * cfy;
101: double ddV = 2.0f
102: * ((a00 * a00 + a10 * a10) * rsq - tmp * tmp) / Csq;
103:
104: for (int i = 0; i < w; i++, didx++, x++) {
105: double g = U + Math.sqrt(V);
106: U += dU;
107: V += dV;
108: dV += ddV;
109:
110: dst[didx] = colorMap.getColor((int) (g * 65536.0));
111: }
112:
113: dstOffset += dstScanlineStride;
114: }
115: }
116: }
|