LinearGradientPaintContext.java revision 0
809N/A/*
809N/A * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
809N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
809N/A *
809N/A * This code is free software; you can redistribute it and/or modify it
809N/A * under the terms of the GNU General Public License version 2 only, as
809N/A * published by the Free Software Foundation. Sun designates this
809N/A * particular file as subject to the "Classpath" exception as provided
809N/A * by Sun in the LICENSE file that accompanied this code.
809N/A *
809N/A * This code is distributed in the hope that it will be useful, but WITHOUT
809N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
809N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
809N/A * version 2 for more details (a copy is included in the LICENSE file that
809N/A * accompanied this code).
809N/A *
809N/A * You should have received a copy of the GNU General Public License version
809N/A * 2 along with this work; if not, write to the Free Software Foundation,
809N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
809N/A *
809N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
809N/A * CA 95054 USA or visit www.sun.com if you need additional information or
809N/A * have any questions.
809N/A */
809N/A
809N/Apackage java.awt;
809N/A
809N/Aimport java.awt.MultipleGradientPaint.CycleMethod;
809N/Aimport java.awt.MultipleGradientPaint.ColorSpaceType;
809N/Aimport java.awt.geom.AffineTransform;
809N/Aimport java.awt.geom.Point2D;
809N/Aimport java.awt.geom.Rectangle2D;
809N/Aimport java.awt.image.ColorModel;
809N/A
809N/A/**
809N/A * Provides the actual implementation for the LinearGradientPaint.
809N/A * This is where the pixel processing is done.
809N/A *
809N/A * @see java.awt.LinearGradientPaint
809N/A * @see java.awt.PaintContext
809N/A * @see java.awt.Paint
809N/A * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
809N/A */
809N/Afinal class LinearGradientPaintContext extends MultipleGradientPaintContext {
809N/A
809N/A /**
809N/A * The following invariants are used to process the gradient value from
809N/A * a device space coordinate, (X, Y):
809N/A * g(X, Y) = dgdX*X + dgdY*Y + gc
809N/A */
809N/A private float dgdX, dgdY, gc;
809N/A
809N/A /**
809N/A * Constructor for LinearGradientPaintContext.
809N/A *
809N/A * @param paint the {@code LinearGradientPaint} from which this context
809N/A * is created
809N/A * @param cm {@code ColorModel} that receives
809N/A * the <code>Paint</code> data. This is used only as a hint.
809N/A * @param deviceBounds the device space bounding box of the
809N/A * graphics primitive being rendered
809N/A * @param userBounds the user space bounding box of the
809N/A * graphics primitive being rendered
809N/A * @param t the {@code AffineTransform} from user
809N/A * space into device space (gradientTransform should be
809N/A * concatenated with this)
809N/A * @param hints the hints that the context object uses to choose
809N/A * between rendering alternatives
809N/A * @param dStart gradient start point, in user space
809N/A * @param dEnd gradient end point, in user space
809N/A * @param fractions the fractions specifying the gradient distribution
809N/A * @param colors the gradient colors
809N/A * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
809N/A * @param colorSpace which colorspace to use for interpolation,
809N/A * either SRGB or LINEAR_RGB
809N/A */
809N/A LinearGradientPaintContext(LinearGradientPaint paint,
809N/A ColorModel cm,
809N/A Rectangle deviceBounds,
809N/A Rectangle2D userBounds,
809N/A AffineTransform t,
809N/A RenderingHints hints,
Point2D start,
Point2D end,
float[] fractions,
Color[] colors,
CycleMethod cycleMethod,
ColorSpaceType colorSpace)
{
super(paint, cm, deviceBounds, userBounds, t, hints, fractions,
colors, cycleMethod, colorSpace);
// A given point in the raster should take on the same color as its
// projection onto the gradient vector.
// Thus, we want the projection of the current position vector
// onto the gradient vector, then normalized with respect to the
// length of the gradient vector, giving a value which can be mapped
// into the range 0-1.
// projection =
// currentVector dot gradientVector / length(gradientVector)
// normalized = projection / length(gradientVector)
float startx = (float)start.getX();
float starty = (float)start.getY();
float endx = (float)end.getX();
float endy = (float)end.getY();
float dx = endx - startx; // change in x from start to end
float dy = endy - starty; // change in y from start to end
float dSq = dx*dx + dy*dy; // total distance squared
// avoid repeated calculations by doing these divides once
float constX = dx/dSq;
float constY = dy/dSq;
// incremental change along gradient for +x
dgdX = a00*constX + a10*constY;
// incremental change along gradient for +y
dgdY = a01*constX + a11*constY;
// constant, incorporates the translation components from the matrix
gc = (a02-startx)*constX + (a12-starty)*constY;
}
/**
* Return a Raster containing the colors generated for the graphics
* operation. This is where the area is filled with colors distributed
* linearly.
*
* @param x,y,w,h the area in device space for which colors are
* generated.
*/
protected void fillRaster(int[] pixels, int off, int adjust,
int x, int y, int w, int h)
{
// current value for row gradients
float g = 0;
// used to end iteration on rows
int rowLimit = off + w;
// constant which can be pulled out of the inner loop
float initConst = (dgdX*x) + gc;
for (int i = 0; i < h; i++) { // for every row
// initialize current value to be start
g = initConst + dgdY*(y+i);
while (off < rowLimit) { // for every pixel in this row
// get the color
pixels[off++] = indexIntoGradientsArrays(g);
// incremental change in g
g += dgdX;
}
// change in off from row to row
off += adjust;
//rowlimit is width + offset
rowLimit = off + w;
}
}
}