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