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 LinearGradient extends Gradient {
029:
030: int x0, y0, x1, y1;
031: long mx, my, b;
032:
033: // Construct a transform (mx, my, b) such that for each point (x,
034: // y) the value mx*x + my*y + b will be the (unpadded) gradient
035: // value. The gradient value is defined by taking the projection
036: // of (x, y) transformed by 'originalTransform' onto the vector
037: // from (x0, y0) to (x1, y1); the gradient value is the length of
038: // the projected vector divided by the length of the vector onto
039: // which it is projected.
040: private void computeTransform() {
041: float fx0 = x0 / 65536.0f;
042: float fx1 = x1 / 65536.0f;
043: float fy0 = y0 / 65536.0f;
044: float fy1 = y1 / 65536.0f;
045: float fdx = fx1 - fx0;
046: float fdy = fy1 - fy0;
047: float flensq = fdx * fdx + fdy * fdy;
048:
049: float a00 = inverse.m00 / 65536.0f;
050: float a01 = inverse.m01 / 65536.0f;
051: float a02 = inverse.m02 / 65536.0f;
052: float a10 = inverse.m10 / 65536.0f;
053: float a11 = inverse.m11 / 65536.0f;
054: float a12 = inverse.m12 / 65536.0f;
055:
056: this .mx = (int) (65536.0f * (a00 * fdx + a10 * fdy) / flensq);
057: this .my = (int) (65536.0f * (a01 * fdx + a11 * fdy) / flensq);
058: float t = fdx * fx0 + fdy * fy0;
059: this .b = (int) (65536.0f * (a02 * fdx + a12 * fdy - t) / flensq);
060: }
061:
062: public LinearGradient(int x0, int y0, int x1, int y1,
063: Transform6 gradientTransform, GradientColorMap colorMap) {
064: super (gradientTransform, colorMap);
065: this .x0 = x0;
066: this .y0 = y0;
067: this .x1 = x1;
068: this .y1 = y1;
069: computeTransform();
070: }
071:
072: public void setTransform(Transform6 transform) {
073: super .setTransform(transform);
074: computeTransform();
075: }
076:
077: public void paint(int x, int y, int width, int height,
078: int[] minTouched, int[] maxTouched, int[] dst,
079: int dstOffset, int dstScanlineStride) {
080: int sx = x;
081:
082: for (int j = 0; j < height; j++, y++) {
083: int minX = minTouched[j];
084: int maxX = maxTouched[j];
085: int w = (maxX >= minX) ? (maxX - minX + 1) : 0;
086: if (w + minX > width) {
087: w = width - minX;
088: }
089:
090: int didx = dstOffset + minX;
091: x = sx + minX;
092:
093: long frac = x * mx + y * my + b;
094: for (int i = 0; i < w; i++, didx++, x++) {
095: dst[didx] = colorMap.getColor((int) frac);
096: frac += mx;
097: }
098:
099: dstOffset += dstScanlineStride;
100: }
101: }
102: }
|