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