/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.prism.impl.paint;
import com.sun.javafx.geom.transform.Affine2D;
import com.sun.javafx.geom.transform.BaseTransform;
import com.sun.prism.paint.Color;
import com.sun.prism.paint.Gradient;
import com.sun.prism.paint.LinearGradient;
import com.sun.prism.paint.Paint;
import com.sun.prism.paint.RadialGradient;
import com.sun.prism.paint.Stop;
public class PaintUtil {
private static final Affine2D gradXform = new Affine2D();
public static void fillImageWithGradient(int[] pixels,
Gradient grad, BaseTransform xform,
int px, int py,
int pw, int ph,
float bx, float by,
float bw, float bh)
{
Gradient mgrad = (Gradient)grad;
int numStops = mgrad.getNumStops();
float[] fractions = new float[numStops];
Color[] colors = new Color[numStops];
for (int i = 0; i < numStops; i++) {
Stop stop = mgrad.getStops().get(i);
fractions[i] = stop.getOffset();
colors[i] = stop.getColor();
}
MultipleGradientContext context;
if (grad.getType() == Paint.Type.LINEAR_GRADIENT) {
LinearGradient lgrad = (LinearGradient)grad;
float x1, y1, x2, y2;
if (lgrad.isProportional()) {
x1 = (lgrad.getX1() * bw) + bx;
y1 = (lgrad.getY1() * bh) + by;
x2 = (lgrad.getX2() * bw) + bx;
y2 = (lgrad.getY2() * bh) + by;
} else {
x1 = lgrad.getX1();
y1 = lgrad.getY1();
x2 = lgrad.getX2();
y2 = lgrad.getY2();
}
if (x1 == x2 && y1 == y2) {
// prevent identical start and end points
x1 -= 0.000001f;
x2 += 0.000001f;
}
context = new LinearGradientContext(lgrad, xform,
x1, y1, x2, y2,
fractions, colors,
lgrad.getSpreadMethod());
} else {
RadialGradient rgrad = (RadialGradient)grad;
gradXform.setTransform(xform);
float radius = rgrad.getRadius();
float cx = rgrad.getCenterX();
float cy = rgrad.getCenterY();
double fa = Math.toRadians(rgrad.getFocusAngle());
float fd = rgrad.getFocusDistance();
if (rgrad.isProportional()) {
float bcx = bx + (bw / 2f);
float bcy = by + (bh / 2f);
float scale = Math.min(bw, bh);
cx = (cx - 0.5f) * scale + bcx;
cy = (cy - 0.5f) * scale + bcy;
if (bw != bh && bw != 0f && bh != 0f) {
gradXform.translate(bcx, bcy);
gradXform.scale(bw / scale, bh / scale);
gradXform.translate(-bcx, -bcy);
}
radius = radius * scale;
}
if (radius <= 0f) {
radius = 0.001f;
}
fd *= radius;
float fx = (float) (cx + fd * Math.cos(fa));
float fy = (float) (cy + fd * Math.sin(fa));
context = new RadialGradientContext(rgrad, gradXform,
cx, cy, radius, fx, fy,
fractions, colors,
rgrad.getSpreadMethod());
}
context.fillRaster(pixels, 0, 0, px, py, pw, ph);
}
}