0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: /**
0018: * @author Oleg V. Khaschansky
0019: * @version $Revision$
0020: *
0021: * @date: Nov 22, 2005
0022: */package org.apache.harmony.awt.gl.linux;
0023:
0024: import java.awt.*;
0025: import java.awt.font.GlyphVector;
0026: import java.awt.image.IndexColorModel;
0027: import java.awt.geom.AffineTransform;
0028: import java.awt.geom.Point2D;
0029:
0030: import org.apache.harmony.awt.gl.CommonGraphics2D;
0031: import org.apache.harmony.awt.gl.MultiRectArea;
0032: import org.apache.harmony.awt.gl.Surface;
0033: import org.apache.harmony.awt.gl.Utils;
0034: import org.apache.harmony.awt.gl.XORComposite;
0035: import org.apache.harmony.awt.gl.font.FontManager;
0036: import org.apache.harmony.awt.gl.font.LinuxNativeFont;
0037: import org.apache.harmony.awt.wtk.NativeWindow;
0038: import org.apache.harmony.awt.nativebridge.Int8Pointer;
0039: import org.apache.harmony.awt.nativebridge.NativeBridge;
0040: import org.apache.harmony.awt.nativebridge.linux.X11;
0041: import org.apache.harmony.awt.nativebridge.linux.Xft;
0042: import org.apache.harmony.awt.nativebridge.linux.X11Defs;
0043:
0044: public class XGraphics2D extends CommonGraphics2D {
0045: private static final X11 x11 = X11.getInstance();
0046: private static final Xft xft = Xft.getInstance();
0047:
0048: long drawable; // X11 window or pixmap
0049: long display;
0050:
0051: long xftDraw;
0052:
0053: // Context related
0054: long gc; // X11 GC for basic drawing
0055: long imageGC; // X11 GC for image operations
0056: int argb;
0057:
0058: XGraphicsConfiguration xConfig;
0059:
0060: boolean nativeLines = true;
0061: boolean nativePaint = true;
0062: boolean transparentColor = false;
0063: boolean simpleComposite = true;
0064: boolean xor_mode = false;
0065:
0066: boolean indexModel = false;
0067:
0068: public XGraphics2D(long drawable, int tx, int ty, MultiRectArea clip) {
0069: super (tx, ty, clip);
0070: this .drawable = drawable;
0071: xConfig = (XGraphicsConfiguration) getDeviceConfiguration();
0072: display = xConfig.dev.display;
0073: gc = createGC(display, drawable);
0074:
0075: X11.Visual visual = xConfig.info.get_visual();
0076: xftDraw = createXftDraw(display, drawable, visual.lock());
0077: visual.unlock();
0078:
0079: imageGC = createGC(display, drawable);
0080:
0081: //xSetForeground(argb); // Set default foregroung to black
0082:
0083: blitter = XBlitter.getInstance();
0084: Rectangle bounds = clip.getBounds();
0085: dstSurf = new XSurface(this , bounds.width, bounds.height);
0086: if (!FontManager.IS_FONTLIB) {
0087: jtr = DrawableTextRenderer.inst;
0088: }
0089:
0090: //setTransformedClip(clip);
0091: setClip(clip);
0092:
0093: if (xConfig.getColorModel() instanceof IndexColorModel) {
0094: indexModel = true;
0095: }
0096: }
0097:
0098: public XGraphics2D(XVolatileImage image, int tx, int ty, int width,
0099: int height) {
0100: this (image, tx, ty, new MultiRectArea(new Rectangle(width,
0101: height)));
0102: }
0103:
0104: public XGraphics2D(XVolatileImage image, int tx, int ty,
0105: MultiRectArea clip) {
0106: super (tx, ty, clip);
0107: drawable = image.getPixmap();
0108: xConfig = (XGraphicsConfiguration) getDeviceConfiguration();
0109: display = xConfig.dev.display;
0110: gc = createGC(display, drawable);
0111:
0112: X11.Visual visual = xConfig.info.get_visual();
0113: xftDraw = createXftDraw(display, drawable, visual.lock());
0114: visual.unlock();
0115:
0116: imageGC = createGC(display, drawable);
0117:
0118: //xSetForeground(argb); // Set default foregroung to black
0119:
0120: blitter = XBlitter.getInstance();
0121: Rectangle bounds = clip.getBounds();
0122: dstSurf = image.getImageSurface();
0123:
0124: if (!FontManager.IS_FONTLIB) {
0125: jtr = DrawableTextRenderer.inst;
0126: }
0127:
0128: //setTransformedClip(clip);
0129: setClip(clip);
0130:
0131: if (xConfig.getColorModel() instanceof IndexColorModel) {
0132: indexModel = true;
0133: }
0134: }
0135:
0136: public XGraphics2D(long drawable, int tx, int ty, int width,
0137: int height) {
0138: this (drawable, tx, ty, new MultiRectArea(new Rectangle(width,
0139: height)));
0140: }
0141:
0142: public XGraphics2D(NativeWindow nwin, int tx, int ty,
0143: MultiRectArea clip) {
0144: this (nwin.getId(), tx, ty, clip);
0145: }
0146:
0147: public XGraphics2D(NativeWindow nwin, int tx, int ty, int width,
0148: int height) {
0149: this (nwin.getId(), tx, ty, new MultiRectArea(new Rectangle(
0150: width, height)));
0151: }
0152:
0153: public Graphics create() {
0154: XGraphics2D res = new XGraphics2D(drawable, origPoint.x,
0155: origPoint.y, dstSurf.getWidth(), dstSurf.getHeight());
0156: copyInternalFields(res);
0157: return res;
0158: }
0159:
0160: public long createXftDraw(long display, long drawable, long visual) {
0161: long draw = LinuxNativeFont.createXftDrawNative(display,
0162: drawable, visual);
0163: LinuxNativeFont.xftDrawSetSubwindowModeNative(draw,
0164: X11Defs.IncludeInferiors);
0165: return draw;
0166: }
0167:
0168: private final long createGC(long display, long win) {
0169: return createGC(display, win, 0L, 0L);
0170: }
0171:
0172: public GraphicsConfiguration getDeviceConfiguration() {
0173: GraphicsEnvironment env = GraphicsEnvironment
0174: .getLocalGraphicsEnvironment();
0175: return env.getDefaultScreenDevice().getDefaultConfiguration();
0176: }
0177:
0178: public void copyArea(int x, int y, int width, int height, int dx,
0179: int dy) {
0180: x += transform.getTranslateX();
0181: y += transform.getTranslateY();
0182:
0183: copyArea(display, drawable, drawable, gc, x, y, width, height,
0184: dx + x, dy + y);
0185: }
0186:
0187: // Caller should free native pointer to rects after using it
0188: private static final X11.XRectangle createXRects(int[] vertices) {
0189: int rectsSize = (vertices[0] - 1) << 1; // sizeof(XRectangle) = 8
0190:
0191: Int8Pointer rects = NativeBridge.getInstance()
0192: .createInt8Pointer(rectsSize, true);
0193: int idx = 0;
0194: for (int i = 1; i < vertices[0]; i += 4) {
0195: X11.XRectangle r = x11.createXRectangle(rects
0196: .getElementPointer(idx));
0197: r.set_x((short) vertices[i]);
0198: r.set_y((short) vertices[i + 1]);
0199: r.set_width((short) (vertices[i + 2] - vertices[i] + 1));
0200: r
0201: .set_height((short) (vertices[i + 3]
0202: - vertices[i + 1] + 1));
0203: idx += r.size();
0204: }
0205:
0206: return x11.createXRectangle(rects);
0207: }
0208:
0209: public void setPaint(Paint paint) {
0210: if (paint == null)
0211: return;
0212:
0213: if (paint instanceof Color) {
0214: setColor((Color) paint);
0215: nativePaint = true;
0216: } else {
0217: super .setPaint(paint);
0218: nativePaint = false;
0219: }
0220: }
0221:
0222: public void setColor(Color color) {
0223: if (color == null)
0224: return;
0225: super .setColor(color);
0226:
0227: // Get values for XColor
0228: int argb_val = color.getRGB();
0229: if (argb_val != argb) {
0230: // Check if it is a transparent color
0231: if ((argb_val & 0xFF000000) != 0xFF000000)
0232: transparentColor = true;
0233: else
0234: transparentColor = false;
0235:
0236: xSetForeground(argb_val);
0237: }
0238: }
0239:
0240: private void xSetForeground(int argb_val) {
0241: // XAllocColor doesn't match closest color,
0242: // get the exact value from ColorModel
0243: if (indexModel) {
0244: IndexColorModel icm = (IndexColorModel) xConfig
0245: .getColorModel();
0246: int pixel = ((int[]) icm.getDataElements(argb_val,
0247: new int[] { 0 }))[0];
0248: argb_val = icm.getRGB(pixel);
0249: }
0250:
0251: setForeground(display, gc, xConfig.xcolormap, argb_val);
0252:
0253: }
0254:
0255: public void dispose() {
0256: super .dispose();
0257:
0258: if (xftDraw != 0) {
0259: LinuxNativeFont.freeXftDrawNative(this .xftDraw);
0260: xftDraw = 0;
0261: }
0262:
0263: if (dstSurf instanceof XSurface)
0264: dstSurf.dispose();
0265:
0266: if (gc != 0) {
0267: freeGC(display, gc);
0268: gc = 0;
0269: }
0270: if (imageGC != 0) {
0271: freeGC(display, imageGC);
0272: imageGC = 0;
0273: }
0274: }
0275:
0276: void setXClip(MultiRectArea mra, long gc) {
0277: if (mra == null) {
0278: resetXClip(gc);
0279: } else {
0280: int vertices[] = mra.rect;
0281: int numVert = vertices[0] - 1;
0282: setClipRectangles(display, gc, 0, 0, vertices, numVert);
0283: }
0284: }
0285:
0286: void resetXClip(long gc) {
0287: setClipMask(display, gc, X11Defs.None);
0288: }
0289:
0290: void setXftClip(MultiRectArea mra) {
0291: if (mra == null) {
0292: resetXftClip();
0293: } else {
0294:
0295: X11.XRectangle clipXRects = createXRects(mra.rect);
0296: xft.XftDrawSetClipRectangles(xftDraw, 0, 0, clipXRects, mra
0297: .getRectCount());
0298: clipXRects.free();
0299: }
0300: }
0301:
0302: void resetXftClip() {
0303: xft.XftDrawSetClip(xftDraw, 0);
0304: }
0305:
0306: protected void setTransformedClip(MultiRectArea clip) {
0307: super .setTransformedClip(clip);
0308: if (xftDraw != 0) {
0309: setXftClip(clip);
0310: }
0311: if (gc != 0) {
0312: setXClip(clip, gc);
0313: }
0314: }
0315:
0316: void setGCFunction(int func) {
0317: setFunction(display, gc, func);
0318: }
0319:
0320: void setImageGCFunction(int func) { // Note: works with imageGC
0321: setFunction(display, imageGC, func);
0322: }
0323:
0324: Surface getSurface() {
0325: return dstSurf;
0326: }
0327:
0328: public void setStroke(Stroke s) {
0329: super .setStroke(s);
0330: if (s instanceof BasicStroke) {
0331: BasicStroke bs = (BasicStroke) s;
0332: if (bs.getMiterLimit() != 10.f) { // Check if it is same as in xlib
0333: nativeLines = false;
0334: return;
0335: }
0336:
0337: int line_width = (int) (bs.getLineWidth() + 0.5f);
0338: int join_style = bs.getLineJoin();
0339: int cap_style = bs.getEndCap() + 1;
0340: int dash_offset = (int) (bs.getDashPhase() + 0.5f);
0341:
0342: float fdashes[] = bs.getDashArray();
0343:
0344: int len = 0;
0345: byte bdashes[] = null;
0346:
0347: if (fdashes != null) {
0348: len = fdashes.length;
0349: bdashes = new byte[len];
0350:
0351: for (int i = 0; i < len; i++) {
0352: bdashes[i] = (byte) (fdashes[i] + 0.5f);
0353: }
0354: }
0355:
0356: setStroke(display, gc, line_width, join_style, cap_style,
0357: dash_offset, bdashes, len);
0358:
0359: nativeLines = true;
0360: } else {
0361: nativeLines = false;
0362: }
0363: }
0364:
0365: public void setTransform(AffineTransform transform) {
0366: super .setTransform(transform);
0367: }
0368:
0369: public void drawLine(int x1, int y1, int x2, int y2) {
0370: if (nativeLines && nativePaint && !transparentColor
0371: && simpleComposite) {
0372: int type = transform.getType();
0373: if (type < 2) {
0374:
0375: int tx = (int) transform.getTranslateX();
0376: int ty = (int) transform.getTranslateY();
0377:
0378: x1 += tx;
0379: y1 += ty;
0380: x2 += tx;
0381: y2 += ty;
0382:
0383: drawLine(display, drawable, gc, x1, y1, x2, y2);
0384:
0385: if (xor_mode) {
0386: XORComposite xor = (XORComposite) composite;
0387: Color xorcolor = xor.getXORColor();
0388: xSetForeground(xorcolor.getRGB());
0389: drawLine(display, drawable, gc, x1, y1, x2, y2);
0390: xSetForeground(fgColor.getRGB());
0391: }
0392: } else {
0393:
0394: float points[] = new float[] { x1, y1, x2, y2 };
0395: transform.transform(points, 0, points, 0, 2);
0396:
0397: x1 = (int) points[0];
0398: y1 = (int) points[1];
0399: x2 = (int) points[2];
0400: y2 = (int) points[3];
0401:
0402: drawLine(display, drawable, gc, x1, y1, x2, y2);
0403:
0404: if (xor_mode) {
0405: XORComposite xor = (XORComposite) composite;
0406: Color xorcolor = xor.getXORColor();
0407: xSetForeground(xorcolor.getRGB());
0408: drawLine(display, drawable, gc, x1, y1, x2, y2);
0409: xSetForeground(fgColor.getRGB());
0410: }
0411: }
0412: } else {
0413: super .drawLine(x1, y1, x2, y2);
0414: }
0415: }
0416:
0417: @Override
0418: public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
0419: if (nativeLines && nativePaint && !transparentColor
0420: && simpleComposite) {
0421:
0422: short points[] = new short[npoints << 1];
0423:
0424: int type = transform.getType();
0425: if (type < 2) {
0426:
0427: int tx = (int) transform.getTranslateX();
0428: int ty = (int) transform.getTranslateY();
0429:
0430: for (int idx = 0, i = 0; i < npoints; i++) {
0431: points[idx++] = (short) (xpoints[i] + tx);
0432: points[idx++] = (short) (ypoints[i] + ty);
0433: }
0434:
0435: drawLines(display, drawable, gc, points, points.length);
0436: } else {
0437:
0438: float fpoints[] = new float[npoints << 1];
0439:
0440: for (int idx = 0, i = 0; i < npoints; i++) {
0441: fpoints[idx++] = xpoints[i];
0442: fpoints[idx++] = ypoints[i];
0443: }
0444:
0445: transform.transform(fpoints, 0, fpoints, 0, npoints);
0446: for (int i = 0; i < fpoints.length; i++)
0447: points[i] = (short) (fpoints[i] + 0.5f);
0448:
0449: drawLines(display, drawable, gc, points, points.length);
0450: }
0451:
0452: if (xor_mode) {
0453: XORComposite xor = (XORComposite) composite;
0454: Color xorcolor = xor.getXORColor();
0455: xSetForeground(xorcolor.getRGB());
0456: drawLines(display, drawable, gc, points, points.length);
0457: xSetForeground(fgColor.getRGB());
0458: }
0459: } else {
0460: super .drawPolyline(xpoints, ypoints, npoints);
0461: }
0462: }
0463:
0464: @Override
0465: public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
0466: if (nativeLines && nativePaint && !transparentColor
0467: && simpleComposite) {
0468:
0469: short points[] = new short[(npoints << 1) + 2];
0470:
0471: int type = transform.getType();
0472: if (type < 2) {
0473:
0474: int tx = (int) transform.getTranslateX();
0475: int ty = (int) transform.getTranslateY();
0476:
0477: int idx = 0;
0478: for (int i = 0; i < npoints; i++) {
0479: points[idx++] = (short) (xpoints[i] + tx);
0480: points[idx++] = (short) (ypoints[i] + ty);
0481: }
0482: points[idx++] = (short) (xpoints[0] + tx);
0483: points[idx++] = (short) (ypoints[0] + ty);
0484:
0485: drawLines(display, drawable, gc, points, points.length);
0486: } else {
0487:
0488: float fpoints[] = new float[npoints << 1];
0489:
0490: for (int idx = 0, i = 0; i < npoints; i++) {
0491: fpoints[idx++] = xpoints[i];
0492: fpoints[idx++] = ypoints[i];
0493: }
0494:
0495: transform.transform(fpoints, 0, fpoints, 0, npoints);
0496: int i = 0;
0497: for (; i < fpoints.length; i++)
0498: points[i] = (short) (fpoints[i] + 0.5f);
0499: points[i++] = (short) (fpoints[0] + 0.5f);
0500: points[i++] = (short) (fpoints[1] + 0.5f);
0501:
0502: drawLines(display, drawable, gc, points, points.length);
0503: }
0504:
0505: if (xor_mode) {
0506: XORComposite xor = (XORComposite) composite;
0507: Color xorcolor = xor.getXORColor();
0508: xSetForeground(xorcolor.getRGB());
0509: drawLines(display, drawable, gc, points, points.length);
0510: xSetForeground(fgColor.getRGB());
0511: }
0512: } else {
0513: super .drawPolygon(xpoints, ypoints, npoints);
0514: }
0515: }
0516:
0517: @Override
0518: public void drawPolygon(Polygon polygon) {
0519: drawPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
0520: }
0521:
0522: @Override
0523: public void drawRect(int x, int y, int width, int height) {
0524: if (nativeLines && nativePaint && !transparentColor
0525: && simpleComposite) {
0526: int type = transform.getType();
0527: if (type < 2) {
0528: x += (int) transform.getTranslateX();
0529: y += (int) transform.getTranslateY();
0530: drawRectangle(display, drawable, gc, x, y, width,
0531: height);
0532:
0533: if (xor_mode) {
0534: XORComposite xor = (XORComposite) composite;
0535: Color xorcolor = xor.getXORColor();
0536: xSetForeground(xorcolor.getRGB());
0537: drawRectangle(display, drawable, gc, x, y, width,
0538: height);
0539: xSetForeground(fgColor.getRGB());
0540: }
0541:
0542: } else if (type < 7) {
0543: float points[] = new float[] { x, y, x + width - 1,
0544: y + height - 1 };
0545: transform.transform(points, 0, points, 0, 2);
0546:
0547: if (points[0] < points[2]) {
0548: x = (int) points[0];
0549: width = (int) (points[2] - points[0]) + 1;
0550: } else {
0551: x = (int) points[2];
0552: width = (int) (points[0] - points[2]) + 1;
0553: }
0554:
0555: if (points[1] < points[3]) {
0556: y = (int) points[1];
0557: height = (int) (points[3] - points[1]) + 1;
0558: } else {
0559: y = (int) points[3];
0560: height = (int) (points[1] - points[3]) + 1;
0561: }
0562:
0563: drawRectangle(display, drawable, gc, x, y, width,
0564: height);
0565:
0566: if (xor_mode) {
0567: XORComposite xor = (XORComposite) composite;
0568: Color xorcolor = xor.getXORColor();
0569: xSetForeground(xorcolor.getRGB());
0570: drawRectangle(display, drawable, gc, x, y, width,
0571: height);
0572: xSetForeground(fgColor.getRGB());
0573: }
0574: } else {
0575: float fpoints[] = new float[] { x, y, x + width - 1, y,
0576: x + width - 1, y + height - 1, x,
0577: y + height - 1 };
0578: transform.transform(fpoints, 0, fpoints, 0, 4);
0579:
0580: short points[] = new short[fpoints.length + 2];
0581:
0582: int i = 0;
0583: for (; i < fpoints.length; i++)
0584: points[i] = (short) (fpoints[i] + 0.5f);
0585: points[i++] = (short) (fpoints[0] + 0.5f);
0586: points[i++] = (short) (fpoints[1] + 0.5f);
0587:
0588: drawLines(display, drawable, gc, points, points.length);
0589:
0590: if (xor_mode) {
0591: XORComposite xor = (XORComposite) composite;
0592: Color xorcolor = xor.getXORColor();
0593: xSetForeground(xorcolor.getRGB());
0594: drawLines(display, drawable, gc, points,
0595: points.length);
0596: xSetForeground(fgColor.getRGB());
0597: }
0598: }
0599: } else {
0600: super .drawRect(x, y, width, height);
0601: }
0602: }
0603:
0604: @Override
0605: public void drawArc(int x, int y, int width, int height, int sa,
0606: int ea) {
0607: if (nativeLines && nativePaint && !transparentColor
0608: && simpleComposite && transform.getType() < 2) {
0609: x += (int) transform.getTranslateX();
0610: y += (int) transform.getTranslateY();
0611: drawArc(display, drawable, gc, x, y, width, height,
0612: sa << 6, ea << 6);
0613:
0614: if (xor_mode) {
0615: XORComposite xor = (XORComposite) composite;
0616: Color xorcolor = xor.getXORColor();
0617: xSetForeground(xorcolor.getRGB());
0618: drawArc(display, drawable, gc, x, y, width, height,
0619: sa << 6, ea << 6);
0620: xSetForeground(fgColor.getRGB());
0621: }
0622: } else {
0623: super .drawArc(x, y, width, height, sa, ea);
0624: }
0625: }
0626:
0627: @Override
0628: public void drawOval(int x, int y, int width, int height) {
0629: drawArc(x, y, width, height, 0, 360);
0630: }
0631:
0632: @Override
0633: public void fillRect(int x, int y, int width, int height) {
0634: if (nativeLines && nativePaint && !transparentColor
0635: && simpleComposite) {
0636: int type = transform.getType();
0637: if (type < 2) {
0638:
0639: x += (int) transform.getTranslateX();
0640: y += (int) transform.getTranslateY();
0641: fillRectangle(display, drawable, gc, x, y, width,
0642: height);
0643:
0644: if (xor_mode) {
0645: XORComposite xor = (XORComposite) composite;
0646: Color xorcolor = xor.getXORColor();
0647: xSetForeground(xorcolor.getRGB());
0648: fillRectangle(display, drawable, gc, x, y, width,
0649: height);
0650: xSetForeground(fgColor.getRGB());
0651: }
0652:
0653: } else if (type < 7) {
0654: float points[] = new float[] { x, y, x + width - 1,
0655: y + height - 1 };
0656: transform.transform(points, 0, points, 0, 2);
0657:
0658: if (points[0] < points[2]) {
0659: x = (int) points[0];
0660: width = (int) (points[2] - points[0]) + 1;
0661: } else {
0662: x = (int) points[2];
0663: width = (int) (points[0] - points[2]) + 1;
0664: }
0665:
0666: if (points[1] < points[3]) {
0667: y = (int) points[1];
0668: height = (int) (points[3] - points[1]) + 1;
0669: } else {
0670: y = (int) points[3];
0671: height = (int) (points[1] - points[3]) + 1;
0672: }
0673:
0674: fillRectangle(display, drawable, gc, x, y, width,
0675: height);
0676:
0677: if (xor_mode) {
0678: XORComposite xor = (XORComposite) composite;
0679: Color xorcolor = xor.getXORColor();
0680: xSetForeground(xorcolor.getRGB());
0681: fillRectangle(display, drawable, gc, x, y, width,
0682: height);
0683: xSetForeground(fgColor.getRGB());
0684: }
0685: } else {
0686: float points[] = new float[] { x, y, x + width - 1, y,
0687: x + width - 1, y + height - 1, x,
0688: y + height - 1 };
0689: transform.transform(points, 0, points, 0, 4);
0690:
0691: short spoints[] = new short[points.length];
0692: for (int i = 0; i < points.length; i++)
0693: spoints[i] = (short) (points[i] + 0.5f);
0694: fillPolygon(display, drawable, gc, spoints,
0695: spoints.length);
0696:
0697: if (xor_mode) {
0698: XORComposite xor = (XORComposite) composite;
0699: Color xorcolor = xor.getXORColor();
0700: xSetForeground(xorcolor.getRGB());
0701: fillPolygon(display, drawable, gc, spoints,
0702: spoints.length);
0703: xSetForeground(fgColor.getRGB());
0704: }
0705: }
0706: } else {
0707: super .fill(new Rectangle(x, y, width, height));
0708: }
0709: }
0710:
0711: protected void fillMultiRectAreaColor(MultiRectArea mra) {
0712: if (nativeLines && nativePaint && !transparentColor
0713: && simpleComposite) {
0714: int vertices[] = mra.rect;
0715: int numVert = vertices[0] - 1;
0716: fillRectangles(display, drawable, gc, vertices, numVert);
0717:
0718: if (xor_mode) {
0719: XORComposite xor = (XORComposite) composite;
0720: Color xorcolor = xor.getXORColor();
0721: xSetForeground(xorcolor.getRGB());
0722: fillRectangles(display, drawable, gc, vertices, numVert);
0723: xSetForeground(fgColor.getRGB());
0724: }
0725: } else {
0726: super .fillMultiRectAreaColor(mra);
0727: }
0728: }
0729:
0730: @Override
0731: public void fillPolygon(Polygon p) {
0732: fillPolygon(p.xpoints, p.ypoints, p.npoints);
0733: }
0734:
0735: @Override
0736: public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) {
0737: if (nativeLines && nativePaint && !transparentColor
0738: && simpleComposite) {
0739:
0740: short points[] = new short[npoints << 1];
0741:
0742: int type = transform.getType();
0743: if (type < 2) {
0744:
0745: int tx = (int) transform.getTranslateX();
0746: int ty = (int) transform.getTranslateY();
0747:
0748: for (int idx = 0, i = 0; i < npoints; i++) {
0749: points[idx++] = (short) (xpoints[i] + tx);
0750: points[idx++] = (short) (ypoints[i] + ty);
0751: }
0752:
0753: fillPolygon(display, drawable, gc, points,
0754: points.length);
0755: } else {
0756:
0757: float fpoints[] = new float[npoints << 1];
0758:
0759: for (int idx = 0, i = 0; i < npoints; i++) {
0760: fpoints[idx++] = xpoints[i];
0761: fpoints[idx++] = ypoints[i];
0762:
0763: }
0764: transform.transform(fpoints, 0, fpoints, 0, npoints);
0765:
0766: for (int i = 0; i < fpoints.length; i++)
0767: points[i] = (short) (fpoints[i] + 0.5f);
0768:
0769: fillPolygon(display, drawable, gc, points,
0770: points.length);
0771: }
0772:
0773: if (xor_mode) {
0774: XORComposite xor = (XORComposite) composite;
0775: Color xorcolor = xor.getXORColor();
0776: xSetForeground(xorcolor.getRGB());
0777: fillPolygon(display, drawable, gc, points,
0778: points.length);
0779: xSetForeground(fgColor.getRGB());
0780: }
0781: } else {
0782: super .fillPolygon(xpoints, ypoints, npoints);
0783: }
0784: }
0785:
0786: @Override
0787: public void fillArc(int x, int y, int width, int height, int sa,
0788: int ea) {
0789: if (nativeLines && nativePaint && !transparentColor
0790: && simpleComposite && transform.getType() < 2) {
0791: x += (int) transform.getTranslateX();
0792: y += (int) transform.getTranslateY();
0793: fillArc(display, drawable, gc, x, y, width, height,
0794: sa << 6, ea << 6);
0795:
0796: if (xor_mode) {
0797: XORComposite xor = (XORComposite) composite;
0798: Color xorcolor = xor.getXORColor();
0799: xSetForeground(xorcolor.getRGB());
0800: fillArc(display, drawable, gc, x, y, width, height,
0801: sa << 6, ea << 6);
0802: xSetForeground(fgColor.getRGB());
0803: }
0804: } else {
0805: super .fillArc(x, y, width, height, sa, ea);
0806: }
0807: }
0808:
0809: @Override
0810: public void fillOval(int x, int y, int width, int height) {
0811: fillArc(x, y, width, height, 0, 360);
0812: }
0813:
0814: @Override
0815: public void setXORMode(Color color) {
0816: super .setXORMode(color);
0817: setFunction(display, gc, X11Defs.GXxor);
0818: xor_mode = true;
0819: simpleComposite = true;
0820: }
0821:
0822: @Override
0823: public void setPaintMode() {
0824: setComposite(AlphaComposite.SrcOver);
0825: }
0826:
0827: public void setComposite(Composite composite) {
0828: super .setComposite(composite);
0829: xor_mode = false;
0830: if (composite instanceof AlphaComposite) {
0831: AlphaComposite acomp = (AlphaComposite) composite;
0832: int rule = acomp.getRule();
0833: float srca = acomp.getAlpha();
0834:
0835: switch (rule) {
0836: case AlphaComposite.CLEAR:
0837: case AlphaComposite.SRC_OUT:
0838: setFunction(display, gc, X11Defs.GXclear);
0839: simpleComposite = true;
0840: break;
0841:
0842: case AlphaComposite.SRC:
0843: case AlphaComposite.SRC_IN:
0844: if (srca == 0.0f)
0845: setFunction(display, gc, X11Defs.GXclear);
0846: else
0847: setFunction(display, gc, X11Defs.GXcopy);
0848: simpleComposite = true;
0849: break;
0850:
0851: case AlphaComposite.DST:
0852: case AlphaComposite.DST_OVER:
0853: setFunction(display, gc, X11Defs.GXnoop);
0854: simpleComposite = true;
0855: break;
0856:
0857: case AlphaComposite.SRC_ATOP:
0858: case AlphaComposite.SRC_OVER:
0859: setFunction(display, gc, X11Defs.GXcopy);
0860: if (srca == 1.0f) {
0861: simpleComposite = true;
0862: } else {
0863: simpleComposite = false;
0864: }
0865: break;
0866:
0867: case AlphaComposite.DST_IN:
0868: case AlphaComposite.DST_ATOP:
0869: if (srca != 0.0f) {
0870: setFunction(display, gc, X11Defs.GXnoop);
0871: } else {
0872: setFunction(display, gc, X11Defs.GXclear);
0873: }
0874: simpleComposite = true;
0875: break;
0876:
0877: case AlphaComposite.DST_OUT:
0878: case AlphaComposite.XOR:
0879: if (srca != 1.0f) {
0880: setFunction(display, gc, X11Defs.GXnoop);
0881: } else {
0882: setFunction(display, gc, X11Defs.GXclear);
0883: }
0884: simpleComposite = true;
0885: break;
0886: }
0887: } else {
0888: simpleComposite = false;
0889: }
0890: }
0891:
0892: @Override
0893: public void drawString(String str, float x, float y) {
0894: AffineTransform at = (AffineTransform) this .getTransform()
0895: .clone();
0896: AffineTransform fontTransform = font.getTransform();
0897: at.concatenate(fontTransform);
0898:
0899: if (!at.isIdentity()) {
0900: // TYPE_TRANSLATION
0901: if (at.getType() == AffineTransform.TYPE_TRANSLATION) {
0902: jtr.drawString(this , str, (float) (x + fontTransform
0903: .getTranslateX()), (float) (y + fontTransform
0904: .getTranslateY()));
0905: return;
0906: }
0907: // TODO: we use slow type of drawing strings when Font object
0908: // in Graphics has transforms, we just fill outlines. New textrenderer
0909: // is to be implemented.
0910: Shape sh = font.createGlyphVector(
0911: this .getFontRenderContext(), str).getOutline(x, y);
0912: fill(sh);
0913: } else {
0914: jtr.drawString(this , str, x, y);
0915: }
0916: }
0917:
0918: @Override
0919: public void drawGlyphVector(GlyphVector gv, float x, float y) {
0920:
0921: AffineTransform at = gv.getFont().getTransform();
0922:
0923: double[] matrix = new double[6];
0924: if ((at != null) && (!at.isIdentity())) {
0925:
0926: int atType = at.getType();
0927: at.getMatrix(matrix);
0928:
0929: // TYPE_TRANSLATION
0930: if ((atType == AffineTransform.TYPE_TRANSLATION)
0931: && ((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)) {
0932: jtr.drawGlyphVector(this , gv, (int) (x + matrix[4]),
0933: (int) (y + matrix[5]));
0934: return;
0935: }
0936: } else {
0937: if (((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)) {
0938: jtr.drawGlyphVector(this , gv, x, y);
0939: return;
0940: }
0941: }
0942:
0943: // TODO: we use slow type of drawing strings when Font object
0944: // in Graphics has transforms, we just fill outlines. New textrenderer
0945: // is to be implemented.
0946:
0947: Shape sh = gv.getOutline(x, y);
0948: this .fill(sh);
0949:
0950: }
0951:
0952: // Native methods
0953:
0954: // GC methods
0955: // Creating and Releasing
0956: private native long createGC(long display, long drawable,
0957: long valuemask, long values);
0958:
0959: private native int freeGC(long display, long gc);
0960:
0961: // Setting GC function
0962: private native int setFunction(long display, long gc, int func);
0963:
0964: // Stroke (line attributes)
0965: private native int setStroke(long display, long gc, int line_width,
0966: int join_style, int cap_style, int dash_offset,
0967: byte dashes[], int len);
0968:
0969: // Foreground
0970: private native int setForeground(long display, long gc,
0971: long colormap, int argb_val);
0972:
0973: // Clipping
0974: private native int setClipMask(long display, long gc, long pixmap);
0975:
0976: private native int setClipRectangles(long display, long gc,
0977: int clip_x_origin, int clip_y_origin, int clip_rects[],
0978: int num_rects);
0979:
0980: // Drawing methods
0981:
0982: private native int drawArc(long display, long drawable, long gc,
0983: int x, int y, int width, int height, int startAngle,
0984: int angle);
0985:
0986: private native int drawLine(long display, long drawable, long gc,
0987: int x1, int y1, int x2, int y2);
0988:
0989: private native int drawLines(long display, long drawable, long gc,
0990: short points[], int numPoints);
0991:
0992: private native int drawRectangle(long display, long drawable,
0993: long gc, int x, int y, int width, int height);
0994:
0995: // Filling methods
0996:
0997: private native int fillRectangles(long display, long drawable,
0998: long gc, int vertices[], int numVert);
0999:
1000: private native int fillRectangle(long display, long drawable,
1001: long gc, int x, int y, int width, int height);
1002:
1003: private native int fillPolygon(long display, long drawable,
1004: long gc, short points[], int numPoints);
1005:
1006: private native int fillArc(long display, long drawable, long gc,
1007: int x, int y, int width, int height, int startAngle,
1008: int angle);
1009:
1010: private native int copyArea(long display, long src, long dst,
1011: long gc, int src_x, int src_y, int width, int height,
1012: int dst_x, int dst_y);
1013:
1014: }
|