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
26package sun.java2d.xr;
27
28import java.awt.geom.*;
29import java.util.*;
30
31import sun.font.*;
32import sun.java2d.jules.*;
33import sun.java2d.pipe.*;
34
35import 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
44public 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}
331