1 /*
   2  * Copyright (c) 2010, 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
  23  * questions.
  24  */
  25 
  26 package sun.java2d.xr;
  27 
  28 import java.awt.geom.*;
  29 import java.util.*;
  30 
  31 import sun.font.*;
  32 import sun.java2d.jules.*;
  33 import sun.java2d.pipe.*;
  34 
  35 import static sun.java2d.xr.XRUtils.XDoubleToFixed;
  36 
  37 /**
  38  * Native implementation of XRBackend.
  39  * Almost direct 1:1 binding to libX11.
  40  *
  41  * @author Clemens Eisserer
  42  */
  43 
  44 public class XRBackendNative implements XRBackend {
  45 
  46     static {
  47         initIDs();
  48     }
  49 
  50     private static long FMTPTR_A8;
  51     private static long FMTPTR_ARGB32;
  52     private static long MASK_XIMG;
  53 
  54     private static native void initIDs();
  55 
  56     public native long createGC(int drawable);
  57 
  58     public native void freeGC(long gc);
  59 
  60     public native int createPixmap(int drawable, int depth,
  61                                    int width, int height);
  62 
  63     private native int createPictureNative(int drawable, long formatID);
  64 
  65     public native void freePicture(int picture);
  66 
  67     public native void freePixmap(int pixmap);
  68 
  69     public native void setGCExposures(long gc, boolean exposure);
  70 
  71     public native void setGCForeground(long gc, int pixel);
  72 
  73     public native void setPictureRepeat(int picture, int repeat);
  74 
  75     public native void copyArea(int src, int dst, long gc,
  76                                 int srcx, int srcy, int width, int height,
  77                                  int dstx, int dsty);
  78 
  79     public native void setGCMode(long gc, boolean copy);
  80 
  81     private static native void GCRectanglesNative(int drawable, long gc,
  82                                                   int[] rectArray, int rectCnt);
  83 
  84     public native void renderComposite(byte op, int src, int mask,
  85                                        int dst, int srcX, int srcY,
  86                                        int maskX, int maskY, int dstX, int dstY,
  87                                        int width, int height);
  88 
  89     private native void renderRectangle(int dst, byte op,
  90                                         short red, short green,
  91                                         short blue, short alpha,
  92                                         int x, int y, int width, int height);
  93 
  94     private static native void
  95          XRenderRectanglesNative(int dst, byte op,
  96                                  short red, short green,
  97                                  short blue, short alpha,
  98                                  int[] rects, int rectCnt);
  99 
 100     private native void XRSetTransformNative(int pic,
 101                                              int m00, int m01, int m02,
 102                                              int m10, int m11, int m12);
 103 
 104     private static native int
 105         XRCreateLinearGradientPaintNative(float[] fractionsArray,
 106                                           short[] pixelsArray,
 107                                           int x1, int y1, int x2, int y2,
 108                                           int numStops, int repeat,
 109                                           int m00, int m01, int m02,
 110                                            int m10, int m11, int m12);
 111 
 112     private native static int
 113         XRCreateRadialGradientPaintNative(float[] fractionsArray,
 114                                           short[] pixelsArray, int numStops,
 115                                           int centerX, int centerY,
 116                                           int innerRadius, int outerRadius,
 117                                           int repeat,
 118                                           int m00, int m01, int m02,
 119                                           int m10, int m11, int m12);
 120 
 121     public native void setFilter(int picture, int filter);
 122 
 123     private static native void XRSetClipNative(long dst,
 124                                                int x1, int y1, int x2, int y2,
 125                                                Region clip, boolean isGC);
 126 
 127     public void GCRectangles(int drawable, long gc, GrowableRectArray rects) {
 128         GCRectanglesNative(drawable, gc, rects.getArray(), rects.getSize());
 129     }
 130 
 131     public int createPicture(int drawable, int formatID) {
 132         return createPictureNative(drawable, getFormatPtr(formatID));
 133     }
 134 
 135     public void setPictureTransform(int picture, AffineTransform transform) {
 136         XRSetTransformNative(picture,
 137                              XDoubleToFixed(transform.getScaleX()),
 138                              XDoubleToFixed(transform.getShearX()),
 139                              XDoubleToFixed(transform.getTranslateX()),
 140                              XDoubleToFixed(transform.getShearY()),
 141                              XDoubleToFixed(transform.getScaleY()),
 142                              XDoubleToFixed(transform.getTranslateY()));
 143     }
 144 
 145     public void renderRectangle(int dst, byte op, XRColor color,
 146                                 int x, int y, int width, int height) {
 147         renderRectangle(dst, op, (short)color.red, (short)color.green,
 148                        (short)color.blue, (short)color.alpha,
 149                         x, y, width, height);
 150     }
 151 
 152     private short[] getRenderColors(int[] pixels) {
 153         short[] renderColors = new short[pixels.length * 4];
 154 
 155         XRColor c = new XRColor();
 156         for (int i = 0; i < pixels.length; i++) {
 157             c.setColorValues(pixels[i], true);
 158             renderColors[i * 4 + 0] = (short) c.alpha;
 159             renderColors[i * 4 + 1] = (short) c.red;
 160             renderColors[i * 4 + 2] = (short) c.green;
 161             renderColors[i * 4 + 3] = (short) c.blue;
 162         }
 163 
 164         return renderColors;
 165     }
 166 
 167     private static long getFormatPtr(int formatID) {
 168         switch (formatID) {
 169         case XRUtils.PictStandardA8:
 170             return FMTPTR_A8;
 171         case XRUtils.PictStandardARGB32:
 172             return FMTPTR_ARGB32;
 173         }
 174 
 175         return 0L;
 176     }
 177 
 178     public int createLinearGradient(Point2D p1, Point2D p2, float[] fractions,
 179                               int[] pixels,  int repeat, AffineTransform trx) {
 180 
 181         short[] colorValues = getRenderColors(pixels);
 182         int gradient =
 183            XRCreateLinearGradientPaintNative(fractions, colorValues,
 184                 XDoubleToFixed(p1.getX()), XDoubleToFixed(p1.getY()),
 185                 XDoubleToFixed(p2.getX()), XDoubleToFixed(p2.getY()),
 186                 fractions.length, repeat,
 187                 XDoubleToFixed(trx.getScaleX()),
 188                 XDoubleToFixed(trx.getShearX()),
 189                 XDoubleToFixed(trx.getTranslateX()),
 190                 XDoubleToFixed(trx.getShearY()),
 191                 XDoubleToFixed(trx.getScaleY()),
 192                 XDoubleToFixed(trx.getTranslateY()));
 193         return gradient;
 194     }
 195 
 196     public int createRadialGradient(float centerX, float centerY,
 197                                    float innerRadius, float outerRadius,
 198                                    float[] fractions, int[] pixels, int repeat,
 199                                    AffineTransform trx) {
 200 
 201         short[] colorValues = getRenderColors(pixels);
 202         return XRCreateRadialGradientPaintNative
 203              (fractions, colorValues, fractions.length,
 204               XDoubleToFixed(centerX),
 205               XDoubleToFixed(centerY),
 206               XDoubleToFixed(innerRadius),
 207               XDoubleToFixed(outerRadius),
 208               repeat,
 209               XDoubleToFixed(trx.getScaleX()),
 210               XDoubleToFixed(trx.getShearX()),
 211               XDoubleToFixed(trx.getTranslateX()),
 212               XDoubleToFixed(trx.getShearY()),
 213               XDoubleToFixed(trx.getScaleY()),
 214               XDoubleToFixed(trx.getTranslateY()));
 215     }
 216 
 217     public void setGCClipRectangles(long gc, Region clip) {
 218         XRSetClipNative(gc, clip.getLoX(), clip.getLoY(),
 219                         clip.getHiX(), clip.getHiY(),
 220                         clip.isRectangular() ? null : clip, true);
 221     }
 222 
 223     public void setClipRectangles(int picture, Region clip) {
 224         if (clip != null) {
 225             XRSetClipNative(picture, clip.getLoX(), clip.getLoY(),
 226                             clip.getHiX(), clip.getHiY(),
 227                             clip.isRectangular() ? null : clip, false);
 228         } else {
 229             XRSetClipNative(picture, 0, 0, 32767, 32767, null, false);
 230         }
 231     }
 232 
 233     public void renderRectangles(int dst, byte op, XRColor color,
 234                                  GrowableRectArray rects) {
 235         XRenderRectanglesNative(dst, op,
 236                                 (short) color.red, (short) color.green,
 237                                 (short) color.blue, (short) color.alpha,
 238                                 rects.getArray(), rects
 239                 .getSize());
 240     }
 241 
 242     private static long[] getGlyphInfoPtrs(List<XRGlyphCacheEntry> cacheEntries) {
 243         long[] glyphInfoPtrs = new long[cacheEntries.size()];
 244         for (int i = 0; i < cacheEntries.size(); i++) {
 245             glyphInfoPtrs[i] = cacheEntries.get(i).getGlyphInfoPtr();
 246         }
 247         return glyphInfoPtrs;
 248     }
 249 
 250     public void XRenderAddGlyphs(int glyphSet, GlyphList gl,
 251                                  List<XRGlyphCacheEntry> cacheEntries,
 252                                  byte[] pixelData) {
 253         long[] glyphInfoPtrs = getGlyphInfoPtrs(cacheEntries);
 254         XRAddGlyphsNative(glyphSet, glyphInfoPtrs,
 255                           glyphInfoPtrs.length, pixelData, pixelData.length);
 256     }
 257 
 258     public void XRenderFreeGlyphs(int glyphSet, int[] gids) {
 259         XRFreeGlyphsNative(glyphSet, gids, gids.length);
 260     }
 261 
 262     private static native void XRAddGlyphsNative(int glyphSet,
 263                                                  long[] glyphInfoPtrs,
 264                                                  int glyphCnt,
 265                                                  byte[] pixelData,
 266                                                  int pixelDataLength);
 267 
 268     private static native void XRFreeGlyphsNative(int glyphSet,
 269                                                   int[] gids, int idCnt);
 270 
 271     private static native void
 272         XRenderCompositeTextNative(int op, int src, int dst,
 273                                    int srcX, int srcY, long maskFormat,
 274                                    int[] eltArray, int[] glyphIDs, int eltCnt,
 275                                    int glyphCnt);
 276 
 277     public int XRenderCreateGlyphSet(int formatID) {
 278         return XRenderCreateGlyphSetNative(getFormatPtr(formatID));
 279     }
 280 
 281     private static native int XRenderCreateGlyphSetNative(long format);
 282 
 283     public void XRenderCompositeText(byte op, int src, int dst,
 284                                      int maskFormatID,
 285                                      int sx, int sy, int dx, int dy,
 286                                      int glyphset, GrowableEltArray elts) {
 287 
 288         GrowableIntArray glyphs = elts.getGlyphs();
 289         XRenderCompositeTextNative(op, src, dst, sx, sy, 0, elts.getArray(),
 290                                    glyphs.getArray(), elts.getSize(),
 291                                    glyphs.getSize());
 292     }
 293 
 294     public void putMaskImage(int drawable, long gc, byte[] imageData,
 295                              int sx, int sy, int dx, int dy,
 296                              int width, int height, int maskOff,
 297                              int maskScan, float ea) {
 298         putMaskNative(drawable, gc, imageData, sx, sy, dx, dy,
 299                       width, height, maskOff, maskScan, ea, MASK_XIMG);
 300     }
 301 
 302     private static native void putMaskNative(int drawable, long gc,
 303                                              byte[] imageData,
 304                                              int sx, int sy, int dx, int dy,
 305                                              int width, int height,
 306                                              int maskOff, int maskScan,
 307                                              float ea, long xImg);
 308 
 309     public void padBlit(byte op, int srcPict, int maskPict, int dstPict,
 310                         AffineTransform maskTrx, int maskWidth, int maskHeight,
 311                         int lastMaskWidth, int lastMaskHeight,
 312                         int sx, int sy, int dx, int dy, int w, int h) {
 313 
 314         padBlitNative(op, srcPict, maskPict, dstPict,
 315                       XDoubleToFixed(maskTrx.getScaleX()),
 316                       XDoubleToFixed(maskTrx.getShearX()),
 317                       XDoubleToFixed(maskTrx.getTranslateX()),
 318                       XDoubleToFixed(maskTrx.getShearY()),
 319                       XDoubleToFixed(maskTrx.getScaleY()),
 320                       XDoubleToFixed(maskTrx.getTranslateY()),
 321                       maskWidth, maskHeight, lastMaskWidth, lastMaskHeight,
 322                       sx, sy, dx, dy, w, h);
 323     }
 324 
 325     private static native void padBlitNative(byte op, int srcPict,
 326                                              int maskPict, int dstPict,
 327                                              int m00, int m01, int m02,
 328                                              int m10, int m11, int m12,
 329                                              int maskWidth, int maskHeight,
 330                                              int lastMaskWidth,
 331                                              int lastMaskHeight,
 332                                              int sx, int sy, int dx, int dy,
 333                                              int w, int h);
 334 
 335     public void renderCompositeTrapezoids(byte op, int src, int maskFormat,
 336                                           int dst, int srcX, int srcY,
 337                                           TrapezoidList trapList) {
 338         renderCompositeTrapezoidsNative(op, src, getFormatPtr(maskFormat),
 339                                         dst, srcX, srcY,
 340                                         trapList.getTrapArray());
 341     }
 342 
 343     private static native void
 344         renderCompositeTrapezoidsNative(byte op, int src, long maskFormat,
 345                                         int dst, int srcX, int srcY,
 346                                         int[] trapezoids);
 347 }