Java Code Examples for sun.awt.image.PixelConverter#rgbToPixel()
The following examples show how to use
sun.awt.image.PixelConverter#rgbToPixel() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: BufferedPaints.java From dragonwell8_jdk with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 2
Source File: BufferedPaints.java From TencentKona-8 with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 3
Source File: BufferedPaints.java From jdk8u60 with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 4
Source File: BufferedPaints.java From openjdk-jdk8u with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 5
Source File: BufferedPaints.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 6
Source File: BufferedPaints.java From Bytecoder with Apache License 2.0 | 2 votes |
/** * 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); }
Example 7
Source File: BufferedPaints.java From openjdk-jdk9 with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 8
Source File: BufferedPaints.java From jdk8u-jdk with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 9
Source File: BufferedPaints.java From hottub with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 10
Source File: BufferedPaints.java From openjdk-8-source with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 11
Source File: BufferedPaints.java From openjdk-8 with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 12
Source File: BufferedPaints.java From jdk8u_jdk with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 13
Source File: BufferedPaints.java From jdk8u-jdk with GNU General Public License v2.0 | 2 votes |
/** * 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); }
Example 14
Source File: BufferedPaints.java From jdk8u-dev-jdk with GNU General Public License v2.0 | 2 votes |
/** * 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); }