jdk/src/solaris/classes/sun/java2d/xr/XRPaints.java
changeset 21233 a36ed36d3209
parent 6374 e214162c907e
child 22584 eed64ee05369
equal deleted inserted replaced
21232:049cc21737df 21233:a36ed36d3209
    27 
    27 
    28 import java.awt.*;
    28 import java.awt.*;
    29 import java.awt.MultipleGradientPaint.*;
    29 import java.awt.MultipleGradientPaint.*;
    30 import java.awt.geom.*;
    30 import java.awt.geom.*;
    31 import java.awt.image.*;
    31 import java.awt.image.*;
    32 
       
    33 import sun.java2d.*;
    32 import sun.java2d.*;
    34 import sun.java2d.loops.*;
    33 import sun.java2d.loops.*;
    35 import sun.java2d.pipe.*;
    34 import sun.java2d.xr.XRSurfaceData.XRInternalSurfaceData;
    36 
    35 
    37 abstract class XRPaints {
    36 abstract class XRPaints {
    38     static XRCompositeManager xrCompMan;
    37     static XRCompositeManager xrCompMan;
    39 
    38 
    40     static final XRGradient xrGradient = new XRGradient();
    39     static final XRGradient xrGradient = new XRGradient();
   106         }
   105         }
   107 
   106 
   108         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
   107         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
   109             GradientPaint paint = (GradientPaint) pt;
   108             GradientPaint paint = (GradientPaint) pt;
   110 
   109 
   111             int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }, false);
   110             int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad;
   112 
   111             float fractions[] = {0, 1};
   113             float fractions[] = new float[2];
   112             int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() });
   114             fractions[0] = 0;
       
   115             fractions[1] = 1;
       
   116 
   113 
   117             Point2D pt1 = paint.getPoint1();
   114             Point2D pt1 = paint.getPoint1();
   118             Point2D pt2 = paint.getPoint2();
   115             Point2D pt2 = paint.getPoint2();
   119 
   116 
   120             AffineTransform at = (AffineTransform) sg2d.transform.clone();
   117             XRBackend con = xrCompMan.getBackend();
       
   118             int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat);
       
   119             xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient));
       
   120         }
       
   121     }
       
   122 
       
   123     public int getGradientLength(Point2D pt1, Point2D pt2) {
       
   124            double xDiff = Math.max(pt1.getX(), pt2.getX()) - Math.min(pt1.getX(), pt2.getX());
       
   125            double yDiff = Math.max(pt1.getY(), pt2.getY()) - Math.min(pt1.getY(), pt2.getY());
       
   126            return (int) Math.ceil(Math.sqrt(xDiff*xDiff + yDiff*yDiff));
       
   127     }
       
   128 
       
   129     private static class XRLinearGradient extends XRPaints {
       
   130 
       
   131         @Override
       
   132         boolean isPaintValid(SunGraphics2D sg2d) {
       
   133             return ((LinearGradientPaint) sg2d.getPaint()).getColorSpace() == ColorSpaceType.SRGB;
       
   134         }
       
   135 
       
   136         @Override
       
   137         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
       
   138             LinearGradientPaint paint = (LinearGradientPaint) pt;
       
   139 
       
   140             Color[] colors = paint.getColors();
       
   141             Point2D pt1 = paint.getStartPoint();
       
   142             Point2D pt2 = paint.getEndPoint();
       
   143 
       
   144             int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
       
   145             float[] fractions = paint.getFractions();
       
   146             int[] pixels = convertToIntArgbPixels(colors);
       
   147 
       
   148             AffineTransform at = paint.getTransform();
       
   149             try {
       
   150                 at.invert();
       
   151             } catch (NoninvertibleTransformException ex) {
       
   152                 ex.printStackTrace();
       
   153             }
       
   154 
       
   155             XRBackend con = xrCompMan.getBackend();
       
   156             int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat);
       
   157             XRInternalSurfaceData x11sd = new XRSurfaceData.XRInternalSurfaceData(con, gradient);
       
   158             x11sd.setStaticSrcTx(at);
       
   159             xrCompMan.setGradientPaint(x11sd);
       
   160         }
       
   161     }
       
   162 
       
   163     private static class XRRadialGradient extends XRPaints {
       
   164 
       
   165         @Override
       
   166         boolean isPaintValid(SunGraphics2D sg2d) {
       
   167             RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint;
       
   168             return grad.getFocusPoint().equals(grad.getCenterPoint())
       
   169                    && grad.getColorSpace() == ColorSpaceType.SRGB;
       
   170         }
       
   171 
       
   172         @Override
       
   173         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
       
   174             RadialGradientPaint paint = (RadialGradientPaint) pt;
       
   175             Color[] colors = paint.getColors();
       
   176             Point2D center = paint.getCenterPoint();
       
   177 
       
   178             int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
       
   179             float[] fractions = paint.getFractions();
       
   180             int[] pixels = convertToIntArgbPixels(colors);
       
   181             float radius = paint.getRadius();
       
   182 
       
   183             float cx = (float) center.getX();
       
   184             float cy = (float) center.getY();
       
   185 
       
   186             AffineTransform at = paint.getTransform();
       
   187             try {
       
   188                 at.invert();
       
   189             } catch (NoninvertibleTransformException ex) {
       
   190                 ex.printStackTrace();
       
   191             }
       
   192 
       
   193             XRBackend con = xrCompMan.getBackend();
       
   194             int gradient = con.createRadialGradient(cx, cy, 0, radius, fractions, pixels, repeat);
       
   195             XRInternalSurfaceData x11sd = new XRSurfaceData.XRInternalSurfaceData(con, gradient);
       
   196             x11sd.setStaticSrcTx(at);
       
   197             xrCompMan.setGradientPaint(x11sd);
       
   198         }
       
   199     }
       
   200 
       
   201     private static class XRTexture extends XRPaints {
       
   202 
       
   203         private XRSurfaceData getAccSrcSurface(XRSurfaceData dstData, BufferedImage bi) {
       
   204             // REMIND: this is a hack that attempts to cache the system
       
   205             // memory image from the TexturePaint instance into an
       
   206             // XRender pixmap...
       
   207             SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
       
   208             if (!(srcData instanceof XRSurfaceData)) {
       
   209                 srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
       
   210                 if (!(srcData instanceof XRSurfaceData)) {
       
   211                     throw new InternalError("Surface not cachable");
       
   212                 }
       
   213             }
       
   214 
       
   215             return (XRSurfaceData) srcData;
       
   216         }
       
   217 
       
   218         @Override
       
   219         boolean isPaintValid(SunGraphics2D sg2d) {
       
   220             TexturePaint paint = (TexturePaint) sg2d.paint;
       
   221             BufferedImage bi = paint.getImage();
       
   222             XRSurfaceData dstData = (XRSurfaceData) sg2d.getDestSurface();
       
   223 
       
   224             return getAccSrcSurface(dstData, bi) != null;
       
   225         }
       
   226 
       
   227         @Override
       
   228         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
       
   229             TexturePaint paint = (TexturePaint) pt;
       
   230             BufferedImage bi = paint.getImage();
       
   231             Rectangle2D anchor = paint.getAnchorRect();
       
   232 
       
   233             XRSurfaceData dstData = (XRSurfaceData) sg2d.surfaceData;
       
   234             XRSurfaceData srcData = (XRSurfaceData) getAccSrcSurface(dstData, bi);
       
   235 
       
   236             AffineTransform at = new AffineTransform();
       
   237             at.translate(anchor.getX(), anchor.getY());
       
   238             at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
       
   239 
   121             try {
   240             try {
   122                 at.invert();
   241                 at.invert();
   123             } catch (NoninvertibleTransformException ex) {
   242             } catch (NoninvertibleTransformException ex) {
   124                 at.setToIdentity();
   243                 at.setToIdentity();
   125             }
   244             }
   126 
   245             srcData.setStaticSrcTx(at);
   127             int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad;
   246 
   128 
   247             srcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
   129             XRBackend con = xrCompMan.getBackend();
   248             xrCompMan.setTexturePaint(srcData);
   130             int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat, at);
   249         }
   131             xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at));
   250     }
   132         }
   251 
   133     }
   252     public int[] convertToIntArgbPixels(Color[] colors) {
   134 
       
   135     public int getGradientLength(Point2D pt1, Point2D pt2) {
       
   136            double xDiff = Math.max(pt1.getX(), pt2.getX()) - Math.min(pt1.getX(), pt2.getX());
       
   137            double yDiff = Math.max(pt1.getY(), pt2.getY()) - Math.min(pt1.getY(), pt2.getY());
       
   138            return (int) Math.ceil(Math.sqrt(xDiff*xDiff + yDiff*yDiff));
       
   139     }
       
   140 
       
   141     private static class XRLinearGradient extends XRPaints {
       
   142 
       
   143         @Override
       
   144         boolean isPaintValid(SunGraphics2D sg2d) {
       
   145             return true;
       
   146         }
       
   147 
       
   148         @Override
       
   149         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
       
   150             LinearGradientPaint paint = (LinearGradientPaint) pt;
       
   151             boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
       
   152 
       
   153             Color[] colors = paint.getColors();
       
   154             Point2D pt1 = paint.getStartPoint();
       
   155             Point2D pt2 = paint.getEndPoint();
       
   156 
       
   157 
       
   158             AffineTransform at = paint.getTransform();
       
   159             at.preConcatenate(sg2d.transform);
       
   160 
       
   161             int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
       
   162             float[] fractions = paint.getFractions();
       
   163             int[] pixels = convertToIntArgbPixels(colors, linear);
       
   164 
       
   165             try {
       
   166                 at.invert();
       
   167             } catch (NoninvertibleTransformException ex) {
       
   168                 ex.printStackTrace();
       
   169             }
       
   170 
       
   171             XRBackend con = xrCompMan.getBackend();
       
   172             int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat, at);
       
   173             xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at));
       
   174         }
       
   175     }
       
   176 
       
   177     private static class XRRadialGradient extends XRPaints {
       
   178 
       
   179         @Override
       
   180         boolean isPaintValid(SunGraphics2D sg2d) {
       
   181             RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint;
       
   182             return grad.getFocusPoint().equals(grad.getCenterPoint());
       
   183         }
       
   184 
       
   185         @Override
       
   186         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
       
   187             RadialGradientPaint paint = (RadialGradientPaint) pt;
       
   188             boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
       
   189             Color[] colors = paint.getColors();
       
   190             Point2D center = paint.getCenterPoint();
       
   191             Point2D focus = paint.getFocusPoint();
       
   192 
       
   193             int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
       
   194             float[] fractions = paint.getFractions();
       
   195             int[] pixels = convertToIntArgbPixels(colors, linear);
       
   196             float radius = paint.getRadius();
       
   197 
       
   198             // save original (untransformed) center and focus points
       
   199             double cx = center.getX();
       
   200             double cy = center.getY();
       
   201             double fx = focus.getX();
       
   202             double fy = focus.getY();
       
   203 
       
   204             AffineTransform at = paint.getTransform();
       
   205             at.preConcatenate(sg2d.transform);
       
   206             focus = at.transform(focus, focus);
       
   207 
       
   208             // transform unit circle to gradient coords; we start with the
       
   209             // unit circle (center=(0,0), focus on positive x-axis, radius=1)
       
   210             // and then transform into gradient space
       
   211             at.translate(cx, cy);
       
   212             at.rotate(fx - cx, fy - cy);
       
   213             // at.scale(radius, radius);
       
   214 
       
   215             // invert to get mapping from device coords to unit circle
       
   216             try {
       
   217                 at.invert();
       
   218             } catch (Exception e) {
       
   219                 at.setToScale(0.0, 0.0);
       
   220             }
       
   221             focus = at.transform(focus, focus);
       
   222 
       
   223             // clamp the focus point so that it does not rest on, or outside
       
   224             // of, the circumference of the gradient circle
       
   225             fx = Math.min(focus.getX(), 0.99);
       
   226 
       
   227             XRBackend con = xrCompMan.getBackend();
       
   228             int gradient = con.createRadialGradient(new Point2D.Float(0, 0), new Point2D.Float(0, 0), 0, radius, fractions, pixels, repeat, at);
       
   229             xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at));
       
   230         }
       
   231     }
       
   232 
       
   233     private static class XRTexture extends XRPaints {
       
   234 
       
   235         @Override
       
   236         boolean isPaintValid(SunGraphics2D sg2d) {
       
   237             TexturePaint paint = (TexturePaint) sg2d.paint;
       
   238             BufferedImage bi = paint.getImage();
       
   239             XRSurfaceData dstData = (XRSurfaceData) sg2d.getDestSurface();
       
   240 
       
   241             SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
       
   242             if (!(srcData instanceof XRSurfaceData)) {
       
   243                 // REMIND: this is a hack that attempts to cache the system
       
   244                 // memory image from the TexturePaint instance into an
       
   245                 // OpenGL texture...
       
   246                 srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
       
   247                 if (!(srcData instanceof XRSurfaceData)) {
       
   248                     return false;
       
   249                 }
       
   250             }
       
   251 
       
   252             return true;
       
   253         }
       
   254 
       
   255         @Override
       
   256         void setXRPaint(SunGraphics2D sg2d, Paint pt) {
       
   257             TexturePaint paint = (TexturePaint) pt;
       
   258 
       
   259             BufferedImage bi = paint.getImage();
       
   260             SurfaceData dstData = sg2d.surfaceData;
       
   261             SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
       
   262 
       
   263             // REMIND: this hack tries to ensure that we have a cached texture
       
   264             if (!(srcData instanceof XRSurfaceData)) {
       
   265                 srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
       
   266                 if (!(srcData instanceof XRSurfaceData)) {
       
   267                     throw new InternalError("Surface not cachable");
       
   268                 }
       
   269             }
       
   270 
       
   271             XRSurfaceData x11SrcData = (XRSurfaceData) srcData;
       
   272 
       
   273             AffineTransform at = (AffineTransform) sg2d.transform.clone();
       
   274             Rectangle2D anchor = paint.getAnchorRect();
       
   275             at.translate(anchor.getX(), anchor.getY());
       
   276             at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
       
   277 
       
   278             try {
       
   279                 at.invert();
       
   280             } catch (NoninvertibleTransformException ex) {
       
   281                 at.setToIdentity(); /* TODO: Right thing to do in this case? */
       
   282             }
       
   283 
       
   284             x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
       
   285             xrCompMan.setTexturePaint(((XRSurfaceData) srcData));
       
   286         }
       
   287     }
       
   288 
       
   289     public int[] convertToIntArgbPixels(Color[] colors, boolean linear) {
       
   290         int[] pixels = new int[colors.length];
   253         int[] pixels = new int[colors.length];
   291         for (int i = 0; i < colors.length; i++) {
   254         for (int i = 0; i < colors.length; i++) {
   292             pixels[i] = colorToIntArgbPixel(colors[i], linear);
   255             pixels[i] = colorToIntArgbPixel(colors[i]);
   293         }
   256         }
   294         return pixels;
   257         return pixels;
   295     }
   258     }
   296 
   259 
   297     public int colorToIntArgbPixel(Color c, boolean linear) {
   260     public int colorToIntArgbPixel(Color c) {
   298         int rgb = c.getRGB();
   261         int rgb = c.getRGB();
   299 
   262         int a = (int) Math.round(xrCompMan.getExtraAlpha() * (rgb >>> 24));
   300         int a = rgb >>> 24;
   263         return ((a << 24) | (rgb & 0x00FFFFFF));
   301         int r = (rgb >> 16) & 0xff;
       
   302         int g = (rgb >> 8) & 0xff;
       
   303         int b = (rgb) & 0xff;
       
   304         if (linear) {
       
   305             r = BufferedPaints.convertSRGBtoLinearRGB(r);
       
   306             g = BufferedPaints.convertSRGBtoLinearRGB(g);
       
   307             b = BufferedPaints.convertSRGBtoLinearRGB(b);
       
   308         }
       
   309 
       
   310         a *= xrCompMan.getExtraAlpha();
       
   311 
       
   312         return ((a << 24) | (r << 16) | (g << 8) | (b));
       
   313     }
   264     }
   314 }
   265 }