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