use of sun.awt.image.PixelConverter in project jdk8u_jdk by JetBrains.
the class BufferedPaints method setGradientPaint.
/************************* GradientPaint support ****************************/
/**
* Note: This code is factored out into a separate static method
* so that it can be shared by both the Gradient and LinearGradient
* implementations. LinearGradient uses this code (for the
* two-color sRGB case only) because it can be much faster than the
* equivalent implementation that uses fragment shaders.
*
* We use OpenGL's texture coordinate generator to automatically
* apply a smooth gradient (either cyclic or acyclic) to the geometry
* being rendered. This technique is almost identical to the one
* described in the comments for BufferedPaints.setTexturePaint(),
* except the calculations take place in one dimension instead of two.
* Instead of an anchor rectangle in the TexturePaint case, we use
* the vector between the two GradientPaint end points in our
* calculations. The generator uses a single plane equation that
* takes the (x,y) location (in device space) of the fragment being
* rendered to calculate a (u) texture coordinate for that fragment:
* u = Ax + By + Cz + Dw
*
* The gradient renderer uses a two-pixel 1D texture where the first
* pixel contains the first GradientPaint color, and the second pixel
* contains the second GradientPaint color. (Note that we use the
* GL_CLAMP_TO_EDGE wrapping mode for acyclic gradients so that we
* clamp the colors properly at the extremes.) The following diagram
* attempts to show the layout of the texture containing the two
* GradientPaint colors (C1 and C2):
*
* +-----------------+
* | C1 | C2 |
* | | |
* +-----------------+
* u=0 .25 .5 .75 1
*
* We calculate our plane equation constants (A,B,D) such that u=0.25
* corresponds to the first GradientPaint end point in user space and
* u=0.75 corresponds to the second end point. This is somewhat
* non-obvious, but since the gradient colors are generated by
* interpolating between C1 and C2, we want the pure color at the
* end points, and we will get the pure color only when u correlates
* to the center of a texel. The following chart shows the expected
* color for some sample values of u (where C' is the color halfway
* between C1 and C2):
*
* u value acyclic (GL_CLAMP) cyclic (GL_REPEAT)
* ------- ------------------ ------------------
* -0.25 C1 C2
* 0.0 C1 C'
* 0.25 C1 C1
* 0.5 C' C'
* 0.75 C2 C2
* 1.0 C2 C'
* 1.25 C2 C1
*
* Original inspiration for this technique came from UMD's Agile2D
* project (GradientManager.java).
*/
private static void setGradientPaint(RenderQueue rq, AffineTransform at, Color c1, Color c2, Point2D pt1, Point2D pt2, boolean isCyclic, boolean useMask) {
// convert gradient colors to IntArgbPre format
PixelConverter pc = PixelConverter.ArgbPre.instance;
int pixel1 = pc.rgbToPixel(c1.getRGB(), null);
int pixel2 = pc.rgbToPixel(c2.getRGB(), null);
// calculate plane equation constants
double x = pt1.getX();
double y = pt1.getY();
at.translate(x, y);
// now gradient point 1 is at the origin
x = pt2.getX() - x;
y = pt2.getY() - y;
double len = Math.sqrt(x * x + y * y);
at.rotate(x, y);
// now gradient point 2 is on the positive x-axis
at.scale(2 * len, 1);
// now gradient point 2 is at (0.5, 0)
at.translate(-0.25, 0);
// now gradient point 1 is at (0.25, 0), point 2 is at (0.75, 0)
double p0, p1, p3;
try {
at.invert();
p0 = at.getScaleX();
p1 = at.getShearX();
p3 = at.getTranslateX();
} catch (java.awt.geom.NoninvertibleTransformException e) {
p0 = p1 = p3 = 0.0;
}
// assert rq.lock.isHeldByCurrentThread();
rq.ensureCapacityAndAlignment(44, 12);
RenderBuffer buf = rq.getBuffer();
buf.putInt(SET_GRADIENT_PAINT);
buf.putInt(useMask ? 1 : 0);
buf.putInt(isCyclic ? 1 : 0);
buf.putDouble(p0).putDouble(p1).putDouble(p3);
buf.putInt(pixel1).putInt(pixel2);
}
Aggregations