001: /*
002: * @(#)PPCGraphics.java 1.3 02/12/09
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package sun.awt.pocketpc;
028:
029: /**
030: * PPCGraphics.java
031: *
032: */
033:
034: import java.awt.*;
035: import java.io.*;
036: import java.util.*;
037: import sun.awt.peer.FontPeer;
038: import java.awt.image.ImageObserver;
039: import java.awt.image.BufferedImage;
040: import sun.awt.image.OffScreenImageSource;
041: import sun.awt.image.ImageRepresentation;
042: import sun.awt.AWTFinalizer;
043: import sun.awt.AWTFinalizeable;
044: import sun.awt.ConstrainableGraphics;
045: import sun.awt.FontDescriptor;
046: import sun.awt.PlatformFont;
047: import sun.awt.CharsetString;
048: import java.io.CharConversionException;
049: import sun.io.CharToByteConverter;
050:
051: /**
052: * PPCGraphics is an object that encapsulates a graphics context for a
053: * particular drawing area using the PPC library.
054: *
055: */
056:
057: class PPCGraphics extends Graphics2D implements ConstrainableGraphics {
058: private static native void initIDs();
059:
060: static {
061: initIDs();
062: }
063: int pData;
064: /** The peer that created this graphics. This is needed by clearRect which
065: needs to clear the background with the background color of the
066: heavyweight component that created it. */
067:
068: PPCComponentPeer peer;
069: Color foreground;
070: Font font;
071: int originX; // TODO: change to float
072: int originY; // TODO: change to float
073: private AlphaComposite composite;
074: /** winCE does not support alpha. So alpha is approximated.
075: * The approximation is: if alpha is 0.0 then the colour is transparent,
076: * else the colour is opaque. This flag indicates whether the extra alpha in
077: * the AlphaComposite is not 0.0. The source colour alpha is premultiplied
078: * by the extra alpha, hence an extra alpha of 0.0 will create transparent
079: * pixels.
080: */
081: private static final int DRAW_NONE = 0x00;
082: private static final int DRAW_PRIMATIVE = 0x01;
083: private static final int DRAW_BITMAP = 0x02;
084: private static final int DRAW_NORMAL = DRAW_PRIMATIVE | DRAW_BITMAP;
085: private static final int DRAW_CLEAR = 0x04 | DRAW_PRIMATIVE;
086: private int drawType = DRAW_NORMAL;
087:
088: /** The current user clip rectangle or null if no clip has been set. This
089: is stored in the native coordinate system and not the possibly
090: translated Java coordinate system. */
091: private Rectangle clip;
092:
093: /** The rectangle this graphics object has been constrained too. This is
094: stored in the native coordinate system and not the (possibly) translated
095: Java coordinate system. If it is null then this graphics has not been
096: constrained. The constrained rectangle is another layer of clipping
097: independant of the user clip. The actaul clip used is the
098: intersection */
099:
100: private Rectangle constrainedRect;
101:
102: /** The GraphicsConfiguration that this graphics uses. */
103: private GraphicsConfiguration graphicsConfiguration;
104:
105: private native void createFromComponent(PPCComponentPeer peer);
106:
107: private native void createFromGraphics(PPCGraphics g);
108:
109: private native void createFromImage(ImageRepresentation imageRep);
110:
111: private native void pSetForeground(int value);
112:
113: private native void pSetFont(Font f);
114:
115: sun.awt.image.Image image;
116:
117: PPCGraphics(PPCComponentPeer peer) {
118: createFromComponent(peer);
119: this .peer = peer;
120: composite = AlphaComposite.SrcOver;
121: foreground = ((Component) peer.target).getForeground();
122: if (foreground == null)
123: foreground = SystemColor.windowText;
124: GraphicsEnvironment ge = GraphicsEnvironment
125: .getLocalGraphicsEnvironment();
126: graphicsConfiguration = ge.getDefaultScreenDevice()
127: .getDefaultConfiguration();
128: setFont(((Component) peer.target).getFont());
129: setupApproximatedAlpha();
130: }
131:
132: PPCGraphics(PPCGraphics g) {
133: createFromGraphics(g);
134: graphicsConfiguration = g.graphicsConfiguration;
135: peer = g.peer;
136: originX = g.originX;
137: originY = g.originY;
138: clip = g.clip;
139: image = g.image;
140: composite = g.composite;
141: foreground = g.foreground;
142: setFont(g.font);
143: setupApproximatedAlpha();
144: }
145:
146: public PPCGraphics(PPCImage image) {
147: createFromImage(image.getImageRep());
148: composite = AlphaComposite.SrcOver;
149: foreground = Color.white;
150: graphicsConfiguration = image.gc;
151: this .image = image;
152: setupApproximatedAlpha();
153: }
154:
155: /**
156: * Create a new PPCGraphics Object based on this one.
157: */
158: public Graphics create() {
159: return new PPCGraphics(this );
160: }
161:
162: /**
163: * Translate
164: */
165: public void translate(int x, int y) {
166: originX += x;
167: originY += y;
168: }
169:
170: private boolean disposed = false;
171:
172: /*
173: * Subclasses should override disposeImpl() instead of dispose(). Client
174: * code should always invoke dispose(), never disposeImpl().
175: *
176: * A WGraphics cannot be used after being disposed.
177: */
178: protected native void disposeImpl();
179:
180: public final void dispose() {
181: boolean call_disposeImpl = false;
182:
183: if (!disposed) {
184: synchronized (this ) {
185: if (!disposed) {
186: disposed = call_disposeImpl = true;
187: }
188: }
189: }
190:
191: if (call_disposeImpl) {
192: disposeImpl();
193: }
194: }
195:
196: //AWTFinalizeable finalnext;
197:
198: public void finalize() {
199: /*if (data != 0) {
200: AWTFinalizer.addFinalizeable(this);
201: }*/
202: dispose();
203: super .finalize();
204: }
205:
206: /*public void doFinalization() {
207: dispose();
208: }
209:
210: public void setNextFinalizeable(AWTFinalizeable o) {
211: finalnext = o;
212: }
213:
214: public AWTFinalizeable getNextFinalizeable() {
215: return finalnext;
216: }*/
217:
218: public void setFont(Font font) {
219: if ((font != null) && (this .font != font)) {
220: this .font = font;
221: pSetFont(font);
222: }
223: }
224:
225: public Font getFont() {
226: return font;
227: }
228:
229: /**
230: * Gets font metrics for the given font.
231: */
232: public FontMetrics getFontMetrics(Font font) {
233: return PPCFontMetrics.getFontMetrics(font);
234: }
235:
236: /**
237: * Sets the foreground color.
238: */
239: public void setColor(Color c) {
240: if ((c != null) && (c != foreground)) {
241: if (c instanceof SystemColor) {
242: c = new Color(c.getRGB());
243: }
244: foreground = c;
245: setupApproximatedAlpha();
246: }
247: }
248:
249: public Color getColor() {
250: return foreground;
251: }
252:
253: public Composite getComposite() {
254: return composite;
255: }
256:
257: public void setComposite(Composite comp) {
258: if ((comp != null) && (comp != composite)) {
259: if (!(comp instanceof AlphaComposite))
260: throw new IllegalArgumentException(
261: "Only AlphaComposite is supported");
262: composite = (AlphaComposite) comp;
263: setupApproximatedAlpha();
264: }
265: }
266:
267: private void setupApproximatedAlpha() {
268: int rule = composite.getRule();
269: if (rule == AlphaComposite.CLEAR) {
270: pSetForeground(Color.black.getRGB());
271: drawType = DRAW_CLEAR;
272: } else if (rule == AlphaComposite.SRC_OVER) {
273: if (composite.getAlpha() == 0)
274: drawType = DRAW_NONE;
275: else if (foreground.getAlpha() == 0)
276: drawType = DRAW_BITMAP;
277: else {
278: drawType = DRAW_NORMAL;
279: pSetForeground(foreground.getRGB());
280: }
281: } else {
282: drawType = DRAW_NORMAL;
283: pSetForeground(foreground.getRGB());
284: }
285: }
286:
287: public GraphicsConfiguration getDeviceConfiguration() {
288: return graphicsConfiguration;
289: }
290:
291: /**
292: * Sets the paint mode to overwrite the destination with the
293: * current color. This is the default paint mode.
294: */
295: public native void setPaintMode();
296:
297: /**
298: * Sets the paint mode to alternate between the current color
299: * and the given color.
300: */
301: public native void setXORMode(Color c1);
302:
303: /**
304: * Gets the current clipping area
305: */
306: //public native Rectangle getClipBounds();
307: public Rectangle getClipBounds() {
308: if (clip != null)
309: return new Rectangle(clip.x - originX, clip.y - originY,
310: clip.width, clip.height);
311: return null;
312: }
313:
314: /** Returns a Shape object representing the MicroWindows clip. */
315:
316: public Shape getClip() {
317: return getClipBounds();
318: }
319:
320: public void constrain(int x, int y, int w, int h) {
321: originX += x;
322: originY += y;
323: Rectangle rect = new Rectangle(originX, originY, w, h);
324: if (constrainedRect != null)
325: constrainedRect = constrainedRect.intersection(rect);
326: else
327: constrainedRect = rect;
328: setupClip();
329: }
330:
331: private native void setClipNative(int X, int Y, int W, int H);
332:
333: private native void removeClip();
334:
335: public void clipRect(int x, int y, int w, int h) {
336: Rectangle rect = new Rectangle(x + originX, y + originY, w, h);
337: if (clip != null)
338: clip = clip.intersection(rect);
339: else
340: clip = rect;
341: setupClip();
342: }
343:
344: /** Sets up the clip for this Graphics. The clip is the result of combining
345: the user clip with the constrainedRect. */
346:
347: private void setupClip() {
348: if (constrainedRect != null) {
349: if (clip != null) {
350: Rectangle intersection = constrainedRect
351: .intersection(clip);
352: setClipNative(intersection.x, intersection.y,
353: intersection.width, intersection.height);
354: } else {
355: setClipNative(constrainedRect.x, constrainedRect.y,
356: constrainedRect.width, constrainedRect.height);
357: }
358: } else {
359: if (clip != null) {
360: setClipNative(clip.x, clip.y, clip.width, clip.height);
361: } else {
362: removeClip();
363: }
364: }
365: }
366:
367: /** Sets the clipping rectangle for this X11Graphics context. */
368: public void setClip(int x, int y, int w, int h) {
369: clip = new Rectangle(x + originX, y + originY, w, h);
370: setupClip();
371: }
372:
373: /** Sets the clip to a Shape (only Rectangle allowed). */
374:
375: public void setClip(Shape clip) {
376: if (clip == null) {
377: this .clip = null;
378: setupClip();
379: } else if (clip instanceof Rectangle) {
380: Rectangle rect = (Rectangle) clip;
381: setClip(rect.x, rect.y, rect.width, rect.height);
382: } else
383: throw new IllegalArgumentException(
384: "setClip(Shape) only supports Rectangle objects");
385: }
386:
387: /** Clears the rectangle indicated by x,y,w,h. */
388: public native void clearRect(int x, int y, int w, int h);
389:
390: /** Fills the given rectangle with the foreground color. */
391: public void fillRect(int X, int Y, int W, int H) {
392: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
393: fillRectNative(X, Y, W, H);
394: }
395:
396: /** Draws the given rectangle. */
397: public void drawRect(int X, int Y, int W, int H) {
398: if (W <= 0 || H <= 0)
399: return;
400: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
401: drawRectNative(X, Y, W, H);
402: }
403:
404: private native void drawRectNative(int X, int Y, int W, int H);
405:
406: private native void fillRectNative(int x, int y, int w, int h);
407:
408: /** Draws the given string. */
409: public void drawString(String string, int x, int y) {
410: drawChars(string.toCharArray(), 0, string.length(), x, y);
411: }
412:
413: /** Draws the given character array. */
414: public void drawChars(char chars[], int offset, int length, int x,
415: int y) {
416: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE) {
417: PlatformFont pf = ((PlatformFont) PPCFontPeer
418: .getFontPeer(font));
419: if (pf.mightHaveMultiFontMetrics()) {
420: drawMFChars(chars, offset, length, x, y, font, pf);
421: } else {
422: drawSFChars(chars, offset, length, x, y);
423: }
424: }
425: }
426:
427: private native void drawSFChars(char[] chars, int offset,
428: int length, int x, int y);
429:
430: private void drawMFChars(char chars[], int offset, int length,
431: int x, int y, Font font, PlatformFont pf) {
432: if (length == 0) {
433: return;
434: }
435:
436: sun.awt.CharsetString[] css = pf.makeMultiCharsetString(chars,
437: offset, length);
438:
439: byte[] csb = null;
440: int baLen = 0;
441: int w = 0;
442: for (int i = 0; i < css.length; i++) {
443: CharsetString cs = css[i];
444:
445: if (PPCFontMetrics.needsConversion(font, cs.fontDescriptor)) {
446: try {
447: int l = cs.fontDescriptor.fontCharset
448: .getMaxBytesPerChar()
449: * cs.length;
450: if (l > baLen) {
451: baLen = l;
452: csb = new byte[baLen];
453: }
454: // use a new instance of the fontCharset (bug 4078870)
455: CharToByteConverter cv = (CharToByteConverter) cs.fontDescriptor.fontCharset
456: .getClass().newInstance();
457: int csbLen = cv.convert(cs.charsetChars, cs.offset,
458: cs.offset + cs.length, csb, 0, csb.length);
459: w += drawMFCharsConvertedSegment(font,
460: cs.fontDescriptor, csb, csbLen, x + w, y);
461: } catch (InstantiationException ignored) {
462: } catch (IllegalAccessException ignored) {
463: // CharToByte converters are public and can be instantiated
464: // so no exceptions should be thrown
465: } catch (CharConversionException ignored) {
466: }
467: } else {
468: w += drawMFCharsSegment(font, cs.fontDescriptor,
469: cs.charsetChars, cs.offset, cs.length, x + w, y);
470: }
471: }
472: }
473:
474: private native int drawMFCharsSegment(Font font,
475: FontDescriptor des, char[] chars, int offset,
476: int charLength, int x, int y);
477:
478: private native int drawMFCharsConvertedSegment(Font font,
479: FontDescriptor des, byte[] bytes, int length, int x, int y);
480:
481: private native void drawBytesNative(byte data[], int offset,
482: int length, int x, int y);
483:
484: /** Draws the given byte array. */
485: public void drawBytes(byte data[], int offset, int length, int x,
486: int y) {
487: if (drawType == DRAW_NONE)
488: return;
489: drawBytesNative(data, offset, length, x, y);
490: }
491:
492: private native void drawLineNative(int x1, int y1, int x2, int y2);
493:
494: /** Draws the given line. */
495: public void drawLine(int x1, int y1, int x2, int y2) {
496: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
497: drawLineNative(x1, y1, x2, y2);
498: }
499:
500: /**
501: * Draws an image at x,y in nonblocking mode with a callback object.
502: */
503: public boolean drawImage(Image img, int x, int y,
504: ImageObserver observer) {
505: PPCDrawableImage ppcimage;
506: if (img instanceof BufferedImage)
507: ppcimage = (PPCDrawableImage) PPCToolkit
508: .getBufferedImagePeer((BufferedImage) img);
509: else
510: ppcimage = (PPCDrawableImage) img;
511: switch (drawType) {
512: case DRAW_BITMAP:
513: case DRAW_NORMAL:
514: return ppcimage.draw(this , x, y, observer);
515:
516: case DRAW_CLEAR:
517: fillRectNative(x, y, ppcimage.getWidth(), ppcimage
518: .getHeight());
519:
520: case DRAW_NONE:
521: default:
522: return ppcimage.isComplete();
523: }
524: }
525:
526: /**
527: * Draws an image scaled to x,y,w,h in nonblocking mode with a
528: * callback object.
529: */
530: public boolean drawImage(Image img, int x, int y, int width,
531: int height, ImageObserver observer) {
532: PPCDrawableImage ppcimage;
533: if (img instanceof BufferedImage)
534: ppcimage = (PPCDrawableImage) PPCToolkit
535: .getBufferedImagePeer((BufferedImage) img);
536: else
537: ppcimage = (PPCDrawableImage) img;
538: switch (drawType) {
539: case DRAW_BITMAP:
540: case DRAW_NORMAL:
541: return ppcimage.draw(this , x, y, width, height, observer);
542:
543: case DRAW_CLEAR:
544: fillRectNative(x, y, width, height);
545:
546: case DRAW_NONE:
547: default:
548: return ppcimage.isComplete();
549: }
550: }
551:
552: /**
553: * Draws an image at x,y in nonblocking mode with a solid background
554: * color and a callback object.
555: */
556: public boolean drawImage(Image img, int x, int y, Color bg,
557: ImageObserver observer) {
558: PPCDrawableImage ppcimage;
559: if (img instanceof BufferedImage)
560: ppcimage = (PPCDrawableImage) PPCToolkit
561: .getBufferedImagePeer((BufferedImage) img);
562: else
563: ppcimage = (PPCDrawableImage) img;
564: switch (drawType) {
565: case DRAW_BITMAP:
566: case DRAW_NORMAL:
567: return ppcimage.draw(this , x, y, bg, observer);
568:
569: case DRAW_CLEAR:
570: fillRectNative(x, y, ppcimage.getWidth(), ppcimage
571: .getHeight());
572:
573: case DRAW_NONE:
574: default:
575: return ppcimage.isComplete();
576: }
577: }
578:
579: /**
580: * Draws an image scaled to x,y,w,h in nonblocking mode with a
581: * solid background color and a callback object.
582: */
583: public boolean drawImage(Image img, int x, int y, int width,
584: int height, Color bg, ImageObserver observer) {
585: PPCDrawableImage ppcimage;
586: if (img instanceof BufferedImage)
587: ppcimage = (PPCDrawableImage) PPCToolkit
588: .getBufferedImagePeer((BufferedImage) img);
589: else
590: ppcimage = (PPCDrawableImage) img;
591: switch (drawType) {
592: case DRAW_BITMAP:
593: case DRAW_NORMAL:
594: return ppcimage.draw(this , x, y, width, height, bg,
595: observer);
596:
597: case DRAW_CLEAR:
598: fillRectNative(x, y, width, height);
599:
600: case DRAW_NONE:
601: default:
602: return ppcimage.isComplete();
603: }
604: }
605:
606: /**
607: * Draws a subrectangle of an image scaled to a destination rectangle
608: * in nonblocking mode with a callback object.
609: */
610: public boolean drawImage(Image img, int dx1, int dy1, int dx2,
611: int dy2, int sx1, int sy1, int sx2, int sy2,
612: ImageObserver observer) {
613: PPCDrawableImage ppcimage;
614: if (img instanceof BufferedImage)
615: ppcimage = (PPCDrawableImage) PPCToolkit
616: .getBufferedImagePeer((BufferedImage) img);
617: else
618: ppcimage = (PPCDrawableImage) img;
619: switch (drawType) {
620: case DRAW_BITMAP:
621: case DRAW_NORMAL:
622: return ppcimage.draw(this , dx1, dy1, dx2, dy2, sx1, sy1,
623: sx2, sy2, observer);
624:
625: case DRAW_CLEAR: {
626: int w = dx2 - dx1;
627: int h = dy2 - dy1;
628: int x = dx1, y = dy1;
629: if (w < 0) {
630: x = dx2;
631: w *= -1;
632: }
633: if (h < 0) {
634: y = dy2;
635: h *= -1;
636: }
637: fillRectNative(x, y, w, h);
638: }
639:
640: case DRAW_NONE:
641: default:
642: return ppcimage.isComplete();
643: }
644: }
645:
646: /**
647: * Draws a subrectangle of an image scaled to a destination rectangle in
648: * nonblocking mode with a solid background color and a callback object.
649: */
650: public boolean drawImage(Image img, int dx1, int dy1, int dx2,
651: int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor,
652: ImageObserver observer) {
653: PPCDrawableImage ppcimage;
654: if (img instanceof BufferedImage)
655: ppcimage = (PPCDrawableImage) PPCToolkit
656: .getBufferedImagePeer((BufferedImage) img);
657: else
658: ppcimage = (PPCDrawableImage) img;
659: switch (drawType) {
660: case DRAW_BITMAP:
661: case DRAW_NORMAL:
662: return ppcimage.draw(this , dx1, dy1, dx2, dy2, sx1, sy1,
663: sx2, sy2, bgcolor, observer);
664:
665: case DRAW_CLEAR: {
666: int w = dx2 - dx1;
667: int h = dy2 - dy1;
668: int x = dx1, y = dy1;
669: if (w < 0) {
670: x = dx2;
671: w *= -1;
672: }
673: if (h < 0) {
674: y = dy2;
675: h *= -1;
676: }
677: fillRectNative(x, y, w, h);
678: }
679:
680: case DRAW_NONE:
681: default:
682: return ppcimage.isComplete();
683: }
684: }
685:
686: /**
687: * Copies an area of the canvas that this graphics context paints to.
688: * @param X the x-coordinate of the source.
689: * @param Y the y-coordinate of the source.
690: * @param W the width.
691: * @param H the height.
692: * @param dx the x-coordinate of the destination.
693: * @param dy the y-coordinate of the destination.
694: */
695: public native void copyArea(int X, int Y, int W, int H, int dx,
696: int dy);
697:
698: private native void drawRoundRectNative(int x, int y, int w, int h,
699: int arcWidth, int arcHeight);
700:
701: private native void fillRoundRectNative(int x, int y, int w, int h,
702: int arcWidth, int arcHeight);
703:
704: /** Draws a rounded rectangle. */
705: public void drawRoundRect(int x, int y, int w, int h, int arcWidth,
706: int arcHeight) {
707: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
708: drawRoundRectNative(x, y, w, h, arcWidth, arcHeight);
709: }
710:
711: /** Draws a filled rounded rectangle. */
712: public void fillRoundRect(int x, int y, int w, int h, int arcWidth,
713: int arcHeight) {
714: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
715: fillRoundRectNative(x, y, w, h, arcWidth, arcHeight);
716: }
717:
718: private native void drawPolylineNative(int xPoints[],
719: int yPoints[], int nPoints);
720:
721: /** Draws a bunch of lines defined by an array of x points and y points */
722: public void drawPolyline(int xPoints[], int yPoints[], int nPoints) {
723: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
724: drawPolylineNative(xPoints, yPoints, nPoints);
725: }
726:
727: private native void drawPolygonNative(int xPoints[], int yPoints[],
728: int nPoints);
729:
730: /** Draws a polygon defined by an array of x points and y points */
731: public void drawPolygon(int xPoints[], int yPoints[], int nPoints) {
732: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
733: drawPolygonNative(xPoints, yPoints, nPoints);
734: }
735:
736: private native void fillPolygonNative(int xPoints[], int yPoints[],
737: int nPoints);
738:
739: /** Fills a polygon with the current fill mask */
740: public void fillPolygon(int xPoints[], int yPoints[], int nPoints) {
741: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
742: fillPolygonNative(xPoints, yPoints, nPoints);
743: }
744:
745: private native void drawOvalNative(int x, int y, int w, int h);
746:
747: /** Draws an oval to fit in the given rectangle */
748: public void drawOval(int x, int y, int w, int h) {
749: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
750: drawOvalNative(x, y, w, h);
751: }
752:
753: private native void fillOvalNative(int x, int y, int w, int h);
754:
755: /** Fills an oval to fit in the given rectangle */
756: public void fillOval(int x, int y, int w, int h) {
757: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
758: fillOvalNative(x, y, w, h);
759: }
760:
761: private native void drawArcNative(int x, int y, int w, int h,
762: int startAngle, int endAngle);
763:
764: /**
765: * Draws an arc bounded by the given rectangle from startAngle to
766: * endAngle. 0 degrees is a vertical line straight up from the
767: * center of the rectangle. Positive angles indicate clockwise
768: * rotations, negative angle are counter-clockwise.
769: */
770: public void drawArc(int x, int y, int w, int h, int startAngle,
771: int endAngle) {
772: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
773: drawArcNative(x, y, w, h, startAngle, endAngle);
774: }
775:
776: private native void fillArcNative(int x, int y, int w, int h,
777: int startAngle, int endAngle);
778:
779: /** fills an arc. arguments are the same as drawArc. */
780: public void fillArc(int x, int y, int w, int h, int startAngle,
781: int endAngle) {
782: if ((drawType & DRAW_PRIMATIVE) == DRAW_PRIMATIVE)
783: fillArcNative(x, y, w, h, startAngle, endAngle);
784: }
785:
786: public String toString() {
787: return getClass().getName() + "[" + originX + "," + originY
788: + "]";
789: }
790: /* Outline the given region. */
791: //public native void drawRegion(Region r);
792: /* Fill the given region. */
793: //public native void fillRegion(Region r);
794: }
|