KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > LinearGradientPaintContext


1 /*
2  * @(#)LinearGradientPaintContext.java 1.2 06/04/24
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt;
9
10 import java.awt.MultipleGradientPaint.CycleMethod JavaDoc;
11 import java.awt.MultipleGradientPaint.ColorSpaceType JavaDoc;
12 import java.awt.geom.AffineTransform JavaDoc;
13 import java.awt.geom.Point2D JavaDoc;
14 import java.awt.geom.Rectangle2D JavaDoc;
15 import java.awt.image.ColorModel JavaDoc;
16
17 /**
18  * Provides the actual implementation for the LinearGradientPaint.
19  * This is where the pixel processing is done.
20  *
21  * @see java.awt.LinearGradientPaint
22  * @see java.awt.PaintContext
23  * @see java.awt.Paint
24  * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
25  */

26 final class LinearGradientPaintContext extends MultipleGradientPaintContext JavaDoc {
27     
28     /**
29      * The following invariants are used to process the gradient value from
30      * a device space coordinate, (X, Y):
31      * g(X, Y) = dgdX*X + dgdY*Y + gc
32      */

33     private float dgdX, dgdY, gc;
34            
35     /**
36      * Constructor for LinearGradientPaintContext.
37      *
38      * @param paint the {@code LinearGradientPaint} from which this context
39      * is created
40      * @param cm {@code ColorModel} that receives
41      * the <code>Paint</code> data. This is used only as a hint.
42      * @param deviceBounds the device space bounding box of the
43      * graphics primitive being rendered
44      * @param userBounds the user space bounding box of the
45      * graphics primitive being rendered
46      * @param t the {@code AffineTransform} from user
47      * space into device space (gradientTransform should be
48      * concatenated with this)
49      * @param hints the hints that the context object uses to choose
50      * between rendering alternatives
51      * @param dStart gradient start point, in user space
52      * @param dEnd gradient end point, in user space
53      * @param fractions the fractions specifying the gradient distribution
54      * @param colors the gradient colors
55      * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
56      * @param colorSpace which colorspace to use for interpolation,
57      * either SRGB or LINEAR_RGB
58      */

59     LinearGradientPaintContext(LinearGradientPaint JavaDoc paint,
60                                ColorModel JavaDoc cm,
61                                Rectangle JavaDoc deviceBounds,
62                                Rectangle2D JavaDoc userBounds,
63                                AffineTransform JavaDoc t,
64                                RenderingHints JavaDoc hints,
65                                Point2D JavaDoc start,
66                                Point2D JavaDoc end,
67                                float[] fractions,
68                                Color JavaDoc[] colors,
69                                CycleMethod cycleMethod,
70                                ColorSpaceType colorSpace)
71     {
72         super(paint, cm, deviceBounds, userBounds, t, hints, fractions,
73               colors, cycleMethod, colorSpace);
74
75         // A given point in the raster should take on the same color as its
76
// projection onto the gradient vector.
77
// Thus, we want the projection of the current position vector
78
// onto the gradient vector, then normalized with respect to the
79
// length of the gradient vector, giving a value which can be mapped
80
// into the range 0-1.
81
// projection =
82
// currentVector dot gradientVector / length(gradientVector)
83
// normalized = projection / length(gradientVector)
84

85         float startx = (float)start.getX();
86         float starty = (float)start.getY();
87         float endx = (float)end.getX();
88         float endy = (float)end.getY();
89
90         float dx = endx - startx; // change in x from start to end
91
float dy = endy - starty; // change in y from start to end
92
float dSq = dx*dx + dy*dy; // total distance squared
93

94         // avoid repeated calculations by doing these divides once
95
float constX = dx/dSq;
96         float constY = dy/dSq;
97
98         // incremental change along gradient for +x
99
dgdX = a00*constX + a10*constY;
100         // incremental change along gradient for +y
101
dgdY = a01*constX + a11*constY;
102
103         // constant, incorporates the translation components from the matrix
104
gc = (a02-startx)*constX + (a12-starty)*constY;
105     }
106
107     /**
108      * Return a Raster containing the colors generated for the graphics
109      * operation. This is where the area is filled with colors distributed
110      * linearly.
111      *
112      * @param x,y,w,h the area in device space for which colors are
113      * generated.
114      */

115     protected void fillRaster(int[] pixels, int off, int adjust,
116                               int x, int y, int w, int h)
117     {
118         // current value for row gradients
119
float g = 0;
120         
121         // used to end iteration on rows
122
int rowLimit = off + w;
123         
124         // constant which can be pulled out of the inner loop
125
float initConst = (dgdX*x) + gc;
126         
127         for (int i = 0; i < h; i++) { // for every row
128

129             // initialize current value to be start
130
g = initConst + dgdY*(y+i);
131             
132             while (off < rowLimit) { // for every pixel in this row
133
// get the color
134
pixels[off++] = indexIntoGradientsArrays(g);
135
136                 // incremental change in g
137
g += dgdX;
138             }
139
140             // change in off from row to row
141
off += adjust;
142
143             //rowlimit is width + offset
144
rowLimit = off + w;
145         }
146     }
147 }
148
Popular Tags