1 /*
2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
153
154 // calculate the solution to be used in the case where X == focusX
155 // in cyclicCircularGradientFillRaster()
156 trivial = (float)Math.sqrt(radiusSq - (dX * dX));
157
158 // constant parts of X, Y user space coordinates
159 constA = a02 - centerX;
160 constB = a12 - centerY;
161
162 // constant second order delta for simple loop
163 gDeltaDelta = 2 * ( a00 * a00 + a10 * a10) / radiusSq;
164 }
165
166 /**
167 * Return a Raster containing the colors generated for the graphics
168 * operation.
169 *
170 * @param x,y,w,h the area in device space for which colors are
171 * generated.
172 */
173 protected void fillRaster(int pixels[], int off, int adjust,
174 int x, int y, int w, int h)
175 {
176 if (isSimpleFocus && isNonCyclic && isSimpleLookup) {
177 simpleNonCyclicFillRaster(pixels, off, adjust, x, y, w, h);
178 } else {
179 cyclicCircularGradientFillRaster(pixels, off, adjust, x, y, w, h);
180 }
181 }
182
183 /**
184 * This code works in the simplest of cases, where the focus == center
185 * point, the gradient is noncyclic, and the gradient lookup method is
186 * fast (single array index, no conversion necessary).
187 */
188 private void simpleNonCyclicFillRaster(int pixels[], int off, int adjust,
189 int x, int y, int w, int h)
190 {
191 /* We calculate sqrt(X^2 + Y^2) relative to the radius
192 * size to get the fraction for the color to use.
193 *
194 * Each step along the scanline adds (a00, a10) to (X, Y).
195 * If we precalculate:
196 * gRel = X^2+Y^2
197 * for the start of the row, then for each step we need to
198 * calculate:
199 * gRel' = (X+a00)^2 + (Y+a10)^2
200 * = X^2 + 2*X*a00 + a00^2 + Y^2 + 2*Y*a10 + a10^2
201 * = (X^2+Y^2) + 2*(X*a00+Y*a10) + (a00^2+a10^2)
202 * = gRel + 2*(X*a00+Y*a10) + (a00^2+a10^2)
203 * = gRel + 2*DP + SD
204 * (where DP = dot product between X,Y and a00,a10
205 * and SD = dot product square of the delta vector)
206 * For the step after that we get:
207 * gRel'' = (X+2*a00)^2 + (Y+2*a10)^2
208 * = X^2 + 4*X*a00 + 4*a00^2 + Y^2 + 4*Y*a10 + 4*a10^2
284
285 // incremental calculation
286 gRel += gDelta;
287 gDelta += gDeltaDelta;
288 i++;
289 }
290 // Quick fill to end of line for "out to the right"
291 while (i < w) {
292 pixels[off + i] = rgbclip;
293 i++;
294 }
295
296 off += adjust;
297 rowX += a01;
298 rowY += a11;
299 }
300 }
301
302 // SQRT_LUT_SIZE must be a power of 2 for the test above to work.
303 private static final int SQRT_LUT_SIZE = (1 << 11);
304 private static float sqrtLut[] = new float[SQRT_LUT_SIZE+1];
305 static {
306 for (int i = 0; i < sqrtLut.length; i++) {
307 sqrtLut[i] = (float) Math.sqrt(i / ((float) SQRT_LUT_SIZE));
308 }
309 }
310
311 /**
312 * Fill the raster, cycling the gradient colors when a point falls outside
313 * of the perimeter of the 100% stop circle.
314 *
315 * This calculation first computes the intersection point of the line
316 * from the focus through the current point in the raster, and the
317 * perimeter of the gradient circle.
318 *
319 * Then it determines the percentage distance of the current point along
320 * that line (focus is 0%, perimeter is 100%).
321 *
322 * Equation of a circle centered at (a,b) with radius r:
323 * (x-a)^2 + (y-b)^2 = r^2
324 * Equation of a line with slope m and y-intercept b:
325 * y = mx + b
326 * Replacing y in the circle equation and solving using the quadratic
327 * formula produces the following set of equations. Constant factors have
328 * been extracted out of the inner loop.
329 */
330 private void cyclicCircularGradientFillRaster(int pixels[], int off,
331 int adjust,
332 int x, int y,
333 int w, int h)
334 {
335 // constant part of the C factor of the quadratic equation
336 final double constC =
337 -radiusSq + (centerX * centerX) + (centerY * centerY);
338
339 // coefficients of the quadratic equation (Ax^2 + Bx + C = 0)
340 double A, B, C;
341
342 // slope and y-intercept of the focus-perimeter line
343 double slope, yintcpt;
344
345 // intersection with circle X,Y coordinate
346 double solutionX, solutionY;
347
348 // constant parts of X, Y coordinates
349 final float constX = (a00*x) + (a01*y) + a02;
350 final float constY = (a10*x) + (a11*y) + a12;
|
1 /*
2 * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
153
154 // calculate the solution to be used in the case where X == focusX
155 // in cyclicCircularGradientFillRaster()
156 trivial = (float)Math.sqrt(radiusSq - (dX * dX));
157
158 // constant parts of X, Y user space coordinates
159 constA = a02 - centerX;
160 constB = a12 - centerY;
161
162 // constant second order delta for simple loop
163 gDeltaDelta = 2 * ( a00 * a00 + a10 * a10) / radiusSq;
164 }
165
166 /**
167 * Return a Raster containing the colors generated for the graphics
168 * operation.
169 *
170 * @param x,y,w,h the area in device space for which colors are
171 * generated.
172 */
173 protected void fillRaster(int[] pixels, int off, int adjust,
174 int x, int y, int w, int h)
175 {
176 if (isSimpleFocus && isNonCyclic && isSimpleLookup) {
177 simpleNonCyclicFillRaster(pixels, off, adjust, x, y, w, h);
178 } else {
179 cyclicCircularGradientFillRaster(pixels, off, adjust, x, y, w, h);
180 }
181 }
182
183 /**
184 * This code works in the simplest of cases, where the focus == center
185 * point, the gradient is noncyclic, and the gradient lookup method is
186 * fast (single array index, no conversion necessary).
187 */
188 private void simpleNonCyclicFillRaster(int[] pixels, int off, int adjust,
189 int x, int y, int w, int h)
190 {
191 /* We calculate sqrt(X^2 + Y^2) relative to the radius
192 * size to get the fraction for the color to use.
193 *
194 * Each step along the scanline adds (a00, a10) to (X, Y).
195 * If we precalculate:
196 * gRel = X^2+Y^2
197 * for the start of the row, then for each step we need to
198 * calculate:
199 * gRel' = (X+a00)^2 + (Y+a10)^2
200 * = X^2 + 2*X*a00 + a00^2 + Y^2 + 2*Y*a10 + a10^2
201 * = (X^2+Y^2) + 2*(X*a00+Y*a10) + (a00^2+a10^2)
202 * = gRel + 2*(X*a00+Y*a10) + (a00^2+a10^2)
203 * = gRel + 2*DP + SD
204 * (where DP = dot product between X,Y and a00,a10
205 * and SD = dot product square of the delta vector)
206 * For the step after that we get:
207 * gRel'' = (X+2*a00)^2 + (Y+2*a10)^2
208 * = X^2 + 4*X*a00 + 4*a00^2 + Y^2 + 4*Y*a10 + 4*a10^2
284
285 // incremental calculation
286 gRel += gDelta;
287 gDelta += gDeltaDelta;
288 i++;
289 }
290 // Quick fill to end of line for "out to the right"
291 while (i < w) {
292 pixels[off + i] = rgbclip;
293 i++;
294 }
295
296 off += adjust;
297 rowX += a01;
298 rowY += a11;
299 }
300 }
301
302 // SQRT_LUT_SIZE must be a power of 2 for the test above to work.
303 private static final int SQRT_LUT_SIZE = (1 << 11);
304 private static float[] sqrtLut = new float[SQRT_LUT_SIZE+1];
305 static {
306 for (int i = 0; i < sqrtLut.length; i++) {
307 sqrtLut[i] = (float) Math.sqrt(i / ((float) SQRT_LUT_SIZE));
308 }
309 }
310
311 /**
312 * Fill the raster, cycling the gradient colors when a point falls outside
313 * of the perimeter of the 100% stop circle.
314 *
315 * This calculation first computes the intersection point of the line
316 * from the focus through the current point in the raster, and the
317 * perimeter of the gradient circle.
318 *
319 * Then it determines the percentage distance of the current point along
320 * that line (focus is 0%, perimeter is 100%).
321 *
322 * Equation of a circle centered at (a,b) with radius r:
323 * (x-a)^2 + (y-b)^2 = r^2
324 * Equation of a line with slope m and y-intercept b:
325 * y = mx + b
326 * Replacing y in the circle equation and solving using the quadratic
327 * formula produces the following set of equations. Constant factors have
328 * been extracted out of the inner loop.
329 */
330 private void cyclicCircularGradientFillRaster(int[] pixels, int off,
331 int adjust,
332 int x, int y,
333 int w, int h)
334 {
335 // constant part of the C factor of the quadratic equation
336 final double constC =
337 -radiusSq + (centerX * centerX) + (centerY * centerY);
338
339 // coefficients of the quadratic equation (Ax^2 + Bx + C = 0)
340 double A, B, C;
341
342 // slope and y-intercept of the focus-perimeter line
343 double slope, yintcpt;
344
345 // intersection with circle X,Y coordinate
346 double solutionX, solutionY;
347
348 // constant parts of X, Y coordinates
349 final float constX = (a00*x) + (a01*y) + a02;
350 final float constY = (a10*x) + (a11*y) + a12;
|