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.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 110 private static native int 111 XRCreateRadialGradientPaintNative(float[] fractionsArray, 112 short[] pixelsArray, int numStops, 113 int centerX, int centerY, 114 int innerRadius, int outerRadius, 115 int repeat); 116 117 public native void setFilter(int picture, int filter); 118 119 private static native void XRSetClipNative(long dst, 120 int x1, int y1, int x2, int y2, 121 Region clip, boolean isGC); 122 123 public void GCRectangles(int drawable, long gc, GrowableRectArray rects) { 124 GCRectanglesNative(drawable, gc, rects.getArray(), rects.getSize()); 125 } 126 127 public int createPicture(int drawable, int formatID) { 128 return createPictureNative(drawable, getFormatPtr(formatID)); 129 } 130 131 public void setPictureTransform(int picture, AffineTransform transform) { 132 XRSetTransformNative(picture, 133 XDoubleToFixed(transform.getScaleX()), 134 XDoubleToFixed(transform.getShearX()), 135 XDoubleToFixed(transform.getTranslateX()), 136 XDoubleToFixed(transform.getShearY()), 137 XDoubleToFixed(transform.getScaleY()), 138 XDoubleToFixed(transform.getTranslateY())); 139 } 140 141 public void renderRectangle(int dst, byte op, XRColor color, 142 int x, int y, int width, int height) { 143 renderRectangle(dst, op, (short)color.red, (short)color.green, 144 (short)color.blue, (short)color.alpha, 145 x, y, width, height); 146 } 147 148 private short[] getRenderColors(int[] pixels) { 149 short[] renderColors = new short[pixels.length * 4]; 150 151 XRColor c = new XRColor(); 152 for (int i = 0; i < pixels.length; i++) { 153 c.setColorValues(pixels[i], true); 154 renderColors[i * 4 + 0] = (short) c.alpha; 155 renderColors[i * 4 + 1] = (short) c.red; 156 renderColors[i * 4 + 2] = (short) c.green; 157 renderColors[i * 4 + 3] = (short) c.blue; 158 } 159 160 return renderColors; 161 } 162 163 private static long getFormatPtr(int formatID) { 164 switch (formatID) { 165 case XRUtils.PictStandardA8: 166 return FMTPTR_A8; 167 case XRUtils.PictStandardARGB32: 168 return FMTPTR_ARGB32; 169 } 170 171 return 0L; 172 } 173 174 public int createLinearGradient(Point2D p1, Point2D p2, float[] fractions, 175 int[] pixels, int repeat) { 176 177 short[] colorValues = getRenderColors(pixels); 178 int gradient = 179 XRCreateLinearGradientPaintNative(fractions, colorValues, 180 XDoubleToFixed(p1.getX()), XDoubleToFixed(p1.getY()), 181 XDoubleToFixed(p2.getX()), XDoubleToFixed(p2.getY()), 182 fractions.length, repeat); 183 return gradient; 184 } 185 186 public int createRadialGradient(float centerX, float centerY, 187 float innerRadius, float outerRadius, 188 float[] fractions, int[] pixels, int repeat) { 189 190 short[] colorValues = getRenderColors(pixels); 191 return XRCreateRadialGradientPaintNative 192 (fractions, colorValues, fractions.length, 193 XDoubleToFixed(centerX), 194 XDoubleToFixed(centerY), 195 XDoubleToFixed(innerRadius), 196 XDoubleToFixed(outerRadius), 197 repeat); 198 } 199 200 public void setGCClipRectangles(long gc, Region clip) { 201 XRSetClipNative(gc, clip.getLoX(), clip.getLoY(), 202 clip.getHiX(), clip.getHiY(), 203 clip.isRectangular() ? null : clip, true); 204 } 205 206 public void setClipRectangles(int picture, Region clip) { 207 if (clip != null) { 208 XRSetClipNative(picture, clip.getLoX(), clip.getLoY(), 209 clip.getHiX(), clip.getHiY(), 210 clip.isRectangular() ? null : clip, false); 211 } else { 212 XRSetClipNative(picture, 0, 0, 32767, 32767, null, false); 213 } 214 } 215 216 public void renderRectangles(int dst, byte op, XRColor color, 217 GrowableRectArray rects) { 218 XRenderRectanglesNative(dst, op, 219 (short) color.red, (short) color.green, 220 (short) color.blue, (short) color.alpha, 221 rects.getArray(), rects 222 .getSize()); 223 } 224 225 private static long[] getGlyphInfoPtrs(List<XRGlyphCacheEntry> cacheEntries) { 226 long[] glyphInfoPtrs = new long[cacheEntries.size()]; 227 for (int i = 0; i < cacheEntries.size(); i++) { 228 glyphInfoPtrs[i] = cacheEntries.get(i).getGlyphInfoPtr(); 229 } 230 return glyphInfoPtrs; 231 } 232 233 public void XRenderAddGlyphs(int glyphSet, GlyphList gl, 234 List<XRGlyphCacheEntry> cacheEntries, 235 byte[] pixelData) { 236 long[] glyphInfoPtrs = getGlyphInfoPtrs(cacheEntries); 237 XRAddGlyphsNative(glyphSet, glyphInfoPtrs, 238 glyphInfoPtrs.length, pixelData, pixelData.length); 239 } 240 241 public void XRenderFreeGlyphs(int glyphSet, int[] gids) { 242 XRFreeGlyphsNative(glyphSet, gids, gids.length); 243 } 244 245 private static native void XRAddGlyphsNative(int glyphSet, 246 long[] glyphInfoPtrs, 247 int glyphCnt, 248 byte[] pixelData, 249 int pixelDataLength); 250 251 private static native void XRFreeGlyphsNative(int glyphSet, 252 int[] gids, int idCnt); 253 254 private static native void 255 XRenderCompositeTextNative(int op, int src, int dst, 256 int srcX, int srcY, long maskFormat, 257 int[] eltArray, int[] glyphIDs, int eltCnt, 258 int glyphCnt); 259 260 public int XRenderCreateGlyphSet(int formatID) { 261 return XRenderCreateGlyphSetNative(getFormatPtr(formatID)); 262 } 263 264 private static native int XRenderCreateGlyphSetNative(long format); 265 266 public void XRenderCompositeText(byte op, int src, int dst, 267 int maskFormatID, 268 int sx, int sy, int dx, int dy, 269 int glyphset, GrowableEltArray elts) { 270 271 GrowableIntArray glyphs = elts.getGlyphs(); 272 XRenderCompositeTextNative(op, src, dst, sx, sy, 0, elts.getArray(), 273 glyphs.getArray(), elts.getSize(), 274 glyphs.getSize()); 275 } 276 277 public void putMaskImage(int drawable, long gc, byte[] imageData, 278 int sx, int sy, int dx, int dy, 279 int width, int height, int maskOff, 280 int maskScan, float ea) { 281 putMaskNative(drawable, gc, imageData, sx, sy, dx, dy, 282 width, height, maskOff, maskScan, ea, MASK_XIMG); 283 } 284 285 private static native void putMaskNative(int drawable, long gc, 286 byte[] imageData, 287 int sx, int sy, int dx, int dy, 288 int width, int height, 289 int maskOff, int maskScan, 290 float ea, long xImg); 291 292 public void padBlit(byte op, int srcPict, int maskPict, int dstPict, 293 AffineTransform maskTrx, int maskWidth, int maskHeight, 294 int lastMaskWidth, int lastMaskHeight, 295 int sx, int sy, int dx, int dy, int w, int h) { 296 297 padBlitNative(op, srcPict, maskPict, dstPict, 298 XDoubleToFixed(maskTrx.getScaleX()), 299 XDoubleToFixed(maskTrx.getShearX()), 300 XDoubleToFixed(maskTrx.getTranslateX()), 301 XDoubleToFixed(maskTrx.getShearY()), 302 XDoubleToFixed(maskTrx.getScaleY()), 303 XDoubleToFixed(maskTrx.getTranslateY()), 304 maskWidth, maskHeight, lastMaskWidth, lastMaskHeight, 305 sx, sy, dx, dy, w, h); 306 } 307 308 private static native void padBlitNative(byte op, int srcPict, 309 int maskPict, int dstPict, 310 int m00, int m01, int m02, 311 int m10, int m11, int m12, 312 int maskWidth, int maskHeight, 313 int lastMaskWidth, 314 int lastMaskHeight, 315 int sx, int sy, int dx, int dy, 316 int w, int h); 317 318 public void renderCompositeTrapezoids(byte op, int src, int maskFormat, 319 int dst, int srcX, int srcY, 320 TrapezoidList trapList) { 321 renderCompositeTrapezoidsNative(op, src, getFormatPtr(maskFormat), 322 dst, srcX, srcY, 323 trapList.getTrapArray()); 324 } 325 326 private static native void 327 renderCompositeTrapezoidsNative(byte op, int src, long maskFormat, 328 int dst, int srcX, int srcY, 329 int[] trapezoids); 330 }