1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91: import ;
92: import ;
93: import ;
94:
95: public class GdkGraphics2D extends Graphics2D
96: {
97:
98:
99:
100:
101: static
102: {
103: if (! Configuration.GTK_CAIRO_ENABLED)
104: throw new Error("Graphics2D not implemented. "
105: + "Cairo was not found or disabled at configure time");
106:
107: if (Configuration.INIT_LOAD_LIBRARY)
108: System.loadLibrary("gtkpeer");
109:
110: initStaticState();
111: }
112:
113: static native void initStaticState();
114:
115: private final int native_state = GtkGenericPeer.getUniqueInteger();
116:
117:
118: Paint paint;
119: Stroke stroke;
120: Color fg;
121: Color bg;
122: Shape clip;
123: AffineTransform transform;
124: private GtkComponentPeer component;
125:
126: Font font;
127: private RenderingHints hints;
128: private BufferedImage bimage;
129: private boolean pixelConversionRequired;
130: private int[] pixelBuffer;
131:
132: Composite comp;
133: private Stack stateStack;
134:
135: private native void initStateUnlocked(GtkComponentPeer component);
136: private native void initState(GtkComponentPeer component);
137: private native void initState(int width, int height);
138: private native void initState(int[] pixes, int width, int height);
139: private native void copyState(GdkGraphics2D g);
140: public native void dispose();
141: private native void cairoSurfaceSetFilter(int filter);
142: private native void cairoSurfaceSetFilterUnlocked(int filter);
143: native void connectSignals(GtkComponentPeer component);
144:
145: public void finalize()
146: {
147: dispose();
148: }
149:
150: public Graphics create()
151: {
152: return new GdkGraphics2D(this);
153: }
154:
155: public Graphics create(int x, int y, int width, int height)
156: {
157: return new GdkGraphics2D(this, x, y, width, height);
158: }
159:
160: private void fail_g2d ()
161: {
162: System.err.println ("Attempted to instantiate GdkGraphics2D"
163: + " but Graphics2D not enabled. Try again with"
164: + " -Dgnu.java.awt.peer.gtk.Graphics=Graphics2D");
165: System.exit (1);
166: }
167:
168: GdkGraphics2D(GdkGraphics2D g)
169: {
170: if (!GtkToolkit.useGraphics2D ())
171: fail_g2d ();
172:
173: paint = g.paint;
174: stroke = g.stroke;
175: setRenderingHints(g.hints);
176:
177: if (g.fg.getAlpha() != -1)
178: fg = new Color(g.fg.getRed(), g.fg.getGreen(), g.fg.getBlue(),
179: g.fg.getAlpha());
180: else
181: fg = new Color(g.fg.getRGB());
182:
183: if (g.bg != null)
184: {
185: if (g.bg.getAlpha() != -1)
186: bg = new Color(g.bg.getRed(), g.bg.getGreen(), g.bg.getBlue(),
187: g.bg.getAlpha());
188: else
189: bg = new Color(g.bg.getRGB());
190: }
191:
192: if (g.clip == null)
193: clip = null;
194: else
195: clip = new Rectangle(g.getClipBounds());
196:
197: if (g.transform == null)
198: transform = new AffineTransform();
199: else
200: transform = new AffineTransform(g.transform);
201:
202: font = g.font;
203: component = g.component;
204: copyState(g);
205:
206: setColor(fg);
207: setBackground(bg);
208: setPaint(paint);
209: setStroke(stroke);
210: setTransform(transform);
211: setClip(clip);
212: stateStack = new Stack();
213: }
214:
215: GdkGraphics2D(GdkGraphics2D g, int x, int y, int widht, int height)
216: {
217: this(g);
218: translate(x, y);
219: clipRect(0, 0, widht, height);
220: }
221:
222: GdkGraphics2D(int width, int height)
223: {
224: if (!GtkToolkit.useGraphics2D ())
225: fail_g2d ();
226:
227: initState(width, height);
228:
229: setColor(Color.black);
230: setBackground(new Color(0, 0, 0, 0));
231: setPaint(getColor());
232: setFont(new Font("SansSerif", Font.PLAIN, 12));
233: setTransform(new AffineTransform());
234: setStroke(new BasicStroke());
235: setRenderingHints(getDefaultHints());
236:
237: stateStack = new Stack();
238: }
239:
240: GdkGraphics2D(GtkComponentPeer component)
241: {
242: if (!GtkToolkit.useGraphics2D ())
243: fail_g2d ();
244:
245: this.component = component;
246:
247: if (component.isRealized())
248: initComponentGraphics2D();
249: else
250: connectSignals(component);
251: }
252:
253: void initComponentGraphics2D()
254: {
255: initState(component);
256:
257: setColor(component.awtComponent.getForeground());
258: setBackground(component.awtComponent.getBackground());
259: setPaint(getColor());
260: setTransform(new AffineTransform());
261: setStroke(new BasicStroke());
262: setRenderingHints(getDefaultHints());
263: setFont(new Font("SansSerif", Font.PLAIN, 12));
264:
265: stateStack = new Stack();
266: }
267:
268: void initComponentGraphics2DUnlocked()
269: {
270: initStateUnlocked(component);
271:
272: setColorUnlocked(component.awtComponent.getForeground());
273: setBackgroundUnlocked(component.awtComponent.getBackground());
274: setPaintUnlocked(getColorUnlocked());
275: setTransformUnlocked(new AffineTransform());
276: setStrokeUnlocked(new BasicStroke());
277: setRenderingHintsUnlocked(getDefaultHints());
278: setFontUnlocked(new Font("SansSerif", Font.PLAIN, 12));
279:
280: stateStack = new Stack();
281: }
282:
283: GdkGraphics2D(BufferedImage bimage)
284: {
285: this.bimage = bimage;
286: this.pixelBuffer = findSimpleIntegerArray(bimage.getColorModel(),
287: bimage.getRaster());
288: if (this.pixelBuffer == null)
289: {
290: this.pixelBuffer = new int[bimage.getRaster().getWidth() * bimage.getRaster()
291: .getHeight()];
292: this.pixelConversionRequired = true;
293: }
294: else
295: {
296: this.pixelConversionRequired = false;
297: }
298:
299: initState(this.pixelBuffer, bimage.getWidth(), bimage.getHeight());
300:
301: setColor(Color.black);
302: setBackground(new Color(0, 0, 0, 0));
303: setPaint(getColor());
304: setFont(new Font("SansSerif", Font.PLAIN, 12));
305: setTransform(new AffineTransform());
306: setStroke(new BasicStroke());
307: setRenderingHints(getDefaultHints());
308:
309: stateStack = new Stack();
310:
311:
312:
313: if (pixelConversionRequired)
314: drawImage(bimage, new AffineTransform(1, 0, 0, 1, 0, 0), bg, null);
315: }
316:
317:
318:
319:
320:
321:
322: private native void gdkDrawDrawable(GdkGraphics2D other, int x, int y);
323:
324:
325: private native void drawPixels(int[] pixels, int w, int h, int stride,
326: double[] i2u);
327: private native void setTexturePixelsUnlocked(int[] pixels, int w, int h, int stride);
328: private native void setTexturePixels(int[] pixels, int w, int h, int stride);
329: private native void setGradient(double x1, double y1, double x2, double y2,
330: int r1, int g1, int b1, int a1, int r2,
331: int g2, int b2, int a2, boolean cyclic);
332: private native void setGradientUnlocked(double x1, double y1, double x2, double y2,
333: int r1, int g1, int b1, int a1, int r2,
334: int g2, int b2, int a2, boolean cyclic);
335:
336:
337: private native void cairoSave();
338: private native void cairoRestore();
339: private native void cairoSetMatrix(double[] m);
340: private native void cairoSetMatrixUnlocked(double[] m);
341: private native void cairoSetOperator(int cairoOperator);
342: private native void cairoSetRGBAColor(double red, double green,
343: double blue, double alpha);
344: private native void cairoSetRGBAColorUnlocked(double red, double green,
345: double blue, double alpha);
346: private native void cairoSetFillRule(int cairoFillRule);
347: private native void cairoSetLineWidth(double width);
348: private native void cairoSetLineWidthUnlocked(double width);
349: private native void cairoSetLineCap(int cairoLineCap);
350: private native void cairoSetLineCapUnlocked(int cairoLineCap);
351: private native void cairoSetLineJoin(int cairoLineJoin);
352: private native void cairoSetLineJoinUnlocked(int cairoLineJoin);
353: private native void cairoSetDash(double[] dashes, int ndash, double offset);
354: private native void cairoSetDashUnlocked(double[] dashes, int ndash, double offset);
355:
356: private native void cairoSetMiterLimit(double limit);
357: private native void cairoSetMiterLimitUnlocked(double limit);
358: private native void cairoNewPath();
359: private native void cairoMoveTo(double x, double y);
360: private native void cairoLineTo(double x, double y);
361: private native void cairoCurveTo(double x1, double y1, double x2, double y2,
362: double x3, double y3);
363: private native void cairoRelMoveTo(double dx, double dy);
364: private native void cairoRelLineTo(double dx, double dy);
365: private native void cairoRelCurveTo(double dx1, double dy1, double dx2,
366: double dy2, double dx3, double dy3);
367: private native void cairoRectangle(double x, double y, double width,
368: double height);
369: private native void cairoClosePath();
370: private native void cairoStroke();
371: private native void cairoFill();
372: private native void cairoClip();
373:
374:
375:
376:
377:
378: private class DrawState
379: {
380: private Paint paint;
381: private Stroke stroke;
382: private Color fg;
383: private Color bg;
384: private Shape clip;
385: private AffineTransform transform;
386: private Font font;
387: private Composite comp;
388:
389: DrawState(GdkGraphics2D g)
390: {
391: this.paint = g.paint;
392: this.stroke = g.stroke;
393: this.fg = g.fg;
394: this.bg = g.bg;
395: this.clip = g.clip;
396: if (g.transform != null)
397: this.transform = (AffineTransform) g.transform.clone();
398: this.font = g.font;
399: this.comp = g.comp;
400: }
401:
402: public void restore(GdkGraphics2D g)
403: {
404: g.paint = this.paint;
405: g.stroke = this.stroke;
406: g.fg = this.fg;
407: g.bg = this.bg;
408: g.clip = this.clip;
409: g.transform = this.transform;
410: g.font = this.font;
411: g.comp = this.comp;
412: }
413: }
414:
415: private void stateSave()
416: {
417: stateStack.push(new DrawState(this));
418: cairoSave();
419: }
420:
421: private void stateRestore()
422: {
423: ((DrawState) (stateStack.pop())).restore(this);
424: cairoRestore();
425: }
426:
427:
428:
429:
430: private boolean shiftDrawCalls = false;
431:
432: private double shifted(double coord, boolean doShift)
433: {
434: if (doShift)
435: return Math.floor(coord) + 0.5;
436: else
437: return coord;
438: }
439:
440: private void walkPath(PathIterator p, boolean doShift)
441: {
442: double x = 0;
443: double y = 0;
444: double[] coords = new double[6];
445:
446: cairoSetFillRule(p.getWindingRule());
447: for (; ! p.isDone(); p.next())
448: {
449: int seg = p.currentSegment(coords);
450: switch (seg)
451: {
452: case PathIterator.SEG_MOVETO:
453: x = shifted(coords[0], doShift);
454: y = shifted(coords[1], doShift);
455: cairoMoveTo(x, y);
456: break;
457: case PathIterator.SEG_LINETO:
458: x = shifted(coords[0], doShift);
459: y = shifted(coords[1], doShift);
460: cairoLineTo(x, y);
461: break;
462: case PathIterator.SEG_QUADTO:
463:
464:
465: double x1 = x + (2.0 / 3.0) * (shifted(coords[0], doShift) - x);
466: double y1 = y + (2.0 / 3.0) * (shifted(coords[1], doShift) - y);
467:
468: double x2 = x1 + (1.0 / 3.0) * (shifted(coords[2], doShift) - x);
469: double y2 = y1 + (1.0 / 3.0) * (shifted(coords[3], doShift) - y);
470:
471: x = shifted(coords[2], doShift);
472: y = shifted(coords[3], doShift);
473: cairoCurveTo(x1, y1, x2, y2, x, y);
474: break;
475: case PathIterator.SEG_CUBICTO:
476: x = shifted(coords[4], doShift);
477: y = shifted(coords[5], doShift);
478: cairoCurveTo(shifted(coords[0], doShift),
479: shifted(coords[1], doShift),
480: shifted(coords[2], doShift),
481: shifted(coords[3], doShift), x, y);
482: break;
483: case PathIterator.SEG_CLOSE:
484: cairoClosePath();
485: break;
486: }
487: }
488: }
489:
490: private Map getDefaultHints()
491: {
492: HashMap defaultHints = new HashMap();
493:
494: defaultHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
495: RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
496:
497: defaultHints.put(RenderingHints.KEY_STROKE_CONTROL,
498: RenderingHints.VALUE_STROKE_DEFAULT);
499:
500: defaultHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
501: RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
502:
503: defaultHints.put(RenderingHints.KEY_ANTIALIASING,
504: RenderingHints.VALUE_ANTIALIAS_OFF);
505:
506: defaultHints.put(RenderingHints.KEY_RENDERING,
507: RenderingHints.VALUE_RENDER_DEFAULT);
508:
509: return defaultHints;
510: }
511:
512: public static int[] findSimpleIntegerArray (ColorModel cm, Raster raster)
513: {
514: if (cm == null || raster == null)
515: return null;
516:
517: if (! cm.getColorSpace().isCS_sRGB())
518: return null;
519:
520: if (! (cm instanceof DirectColorModel))
521: return null;
522:
523: DirectColorModel dcm = (DirectColorModel) cm;
524:
525: if (dcm.getRedMask() != 0x00FF0000 || dcm.getGreenMask() != 0x0000FF00
526: || dcm.getBlueMask() != 0x000000FF)
527: return null;
528:
529: if (! (raster instanceof WritableRaster))
530: return null;
531:
532: if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT)
533: return null;
534:
535: if (! (raster.getDataBuffer() instanceof DataBufferInt))
536: return null;
537:
538: DataBufferInt db = (DataBufferInt) raster.getDataBuffer();
539:
540: if (db.getNumBanks() != 1)
541: return null;
542:
543:
544:
545:
546:
547:
548: return db.getData();
549: }
550:
551: private void updateBufferedImage()
552: {
553: if (bimage != null && pixelConversionRequired)
554: {
555: int height = bimage.getHeight();
556: int width = bimage.getWidth();
557: int index = 0;
558: for (int y = 0; y < height; ++y)
559: for (int x = 0; x < width; ++x)
560: bimage.setRGB(x, y, pixelBuffer[index++]);
561: }
562: }
563:
564: private boolean drawImage(Image img, AffineTransform xform,
565: Color bgcolor, ImageObserver obs)
566: {
567: if (img == null)
568: return false;
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586: {
587:
588:
589:
590:
591:
592:
593:
594: AffineTransform invertedXform = new AffineTransform();
595:
596: try
597: {
598: invertedXform = xform.createInverse();
599: if (img instanceof BufferedImage)
600: {
601:
602:
603: BufferedImage b = (BufferedImage) img;
604: return drawRaster(b.getColorModel(), b.getTile(0, 0),
605: invertedXform, bgcolor);
606: }
607: else
608: return this.drawImage(GdkPixbufDecoder.createBufferedImage(img
609: .getSource()),
610: xform, bgcolor, obs);
611: }
612: catch (NoninvertibleTransformException e)
613: {
614: throw new ImagingOpException("Unable to invert transform "
615: + xform.toString());
616: }
617: }
618: }
619:
620:
621:
622:
623:
624: public void draw(Shape s)
625: {
626: if (stroke != null && ! (stroke instanceof BasicStroke))
627: {
628: fill(stroke.createStrokedShape(s));
629: return;
630: }
631:
632: cairoNewPath();
633:
634: if (s instanceof Rectangle2D)
635: {
636: Rectangle2D r = (Rectangle2D) s;
637: cairoRectangle(shifted(r.getX(), shiftDrawCalls),
638: shifted(r.getY(), shiftDrawCalls), r.getWidth(),
639: r.getHeight());
640: }
641: else
642: walkPath(s.getPathIterator(null), shiftDrawCalls);
643: cairoStroke();
644:
645: updateBufferedImage();
646: }
647:
648: public void fill(Shape s)
649: {
650: cairoNewPath();
651: if (s instanceof Rectangle2D)
652: {
653: Rectangle2D r = (Rectangle2D) s;
654: cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
655: }
656: else
657: walkPath(s.getPathIterator(null), false);
658:
659: cairoFill();
660:
661: updateBufferedImage();
662: }
663:
664: public void clip(Shape s)
665: {
666:
667: if (clip == null || s == null)
668: clip = s;
669: else if (s instanceof Rectangle2D && clip instanceof Rectangle2D)
670: {
671: Rectangle2D r = (Rectangle2D) s;
672: Rectangle2D curr = (Rectangle2D) clip;
673: clip = curr.createIntersection(r);
674: }
675: else
676: throw new UnsupportedOperationException();
677:
678:
679: if (clip != null)
680: {
681: cairoNewPath();
682: if (clip instanceof Rectangle2D)
683: {
684: Rectangle2D r = (Rectangle2D) clip;
685: cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
686: }
687: else
688: walkPath(clip.getPathIterator(null), false);
689:
690:
691: cairoClip();
692: }
693: }
694:
695: public Paint getPaint()
696: {
697: return paint;
698: }
699:
700: public AffineTransform getTransform()
701: {
702: return (AffineTransform) transform.clone();
703: }
704:
705: public void setPaint(Paint p)
706: {
707: if (paint == null)
708: return;
709:
710: paint = p;
711: if (paint instanceof Color)
712: {
713: setColor((Color) paint);
714: }
715: else if (paint instanceof TexturePaint)
716: {
717: TexturePaint tp = (TexturePaint) paint;
718: BufferedImage img = tp.getImage();
719:
720:
721: int width = (int) tp.getAnchorRect().getWidth();
722: int height = (int) tp.getAnchorRect().getHeight();
723:
724: double scaleX = width / (double) img.getWidth();
725: double scaleY = width / (double) img.getHeight();
726:
727: AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0);
728: AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
729: BufferedImage texture = op.filter(img, null);
730: int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width);
731: setTexturePixels(pixels, width, height, width);
732: }
733: else if (paint instanceof GradientPaint)
734: {
735: GradientPaint gp = (GradientPaint) paint;
736: Point2D p1 = gp.getPoint1();
737: Point2D p2 = gp.getPoint2();
738: Color c1 = gp.getColor1();
739: Color c2 = gp.getColor2();
740: setGradient(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(),
741: c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(),
742: c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic());
743: }
744: else
745: throw new java.lang.UnsupportedOperationException();
746: }
747:
748: public void setPaintUnlocked(Paint p)
749: {
750: if (paint == null)
751: return;
752:
753: paint = p;
754: if (paint instanceof Color)
755: {
756: setColorUnlocked((Color) paint);
757: }
758: else if (paint instanceof TexturePaint)
759: {
760: TexturePaint tp = (TexturePaint) paint;
761: BufferedImage img = tp.getImage();
762:
763:
764: int width = (int) tp.getAnchorRect().getWidth();
765: int height = (int) tp.getAnchorRect().getHeight();
766:
767: double scaleX = width / (double) img.getWidth();
768: double scaleY = width / (double) img.getHeight();
769:
770: AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0);
771: AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
772: BufferedImage texture = op.filter(img, null);
773: int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width);
774: setTexturePixelsUnlocked(pixels, width, height, width);
775: }
776: else if (paint instanceof GradientPaint)
777: {
778: GradientPaint gp = (GradientPaint) paint;
779: Point2D p1 = gp.getPoint1();
780: Point2D p2 = gp.getPoint2();
781: Color c1 = gp.getColor1();
782: Color c2 = gp.getColor2();
783: setGradientUnlocked(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(),
784: c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(),
785: c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic());
786: }
787: else
788: throw new java.lang.UnsupportedOperationException();
789: }
790:
791: public void setTransform(AffineTransform tx)
792: {
793: transform = tx;
794: if (transform != null)
795: {
796: double[] m = new double[6];
797: transform.getMatrix(m);
798: cairoSetMatrix(m);
799: }
800: }
801:
802: public void setTransformUnlocked(AffineTransform tx)
803: {
804: transform = tx;
805: if (transform != null)
806: {
807: double[] m = new double[6];
808: transform.getMatrix(m);
809: cairoSetMatrixUnlocked(m);
810: }
811: }
812:
813: public void transform(AffineTransform tx)
814: {
815: if (transform == null)
816: transform = new AffineTransform(tx);
817: else
818: transform.concatenate(tx);
819: setTransform(transform);
820: if (clip != null)
821: {
822:
823:
824: Rectangle2D r = clip.getBounds2D();
825: double[] coords = new double[]
826: {
827: r.getX(), r.getY(), r.getX() + r.getWidth(),
828: r.getY() + r.getHeight()
829: };
830: try
831: {
832: tx.createInverse().transform(coords, 0, coords, 0, 2);
833: r.setRect(coords[0], coords[1], coords[2] - coords[0],
834: coords[3] - coords[1]);
835: clip = r;
836: }
837: catch (java.awt.geom.NoninvertibleTransformException e)
838: {
839: }
840: }
841: }
842:
843: public void rotate(double theta)
844: {
845: transform(AffineTransform.getRotateInstance(theta));
846: }
847:
848: public void rotate(double theta, double x, double y)
849: {
850: transform(AffineTransform.getRotateInstance(theta, x, y));
851: }
852:
853: public void scale(double sx, double sy)
854: {
855: transform(AffineTransform.getScaleInstance(sx, sy));
856: }
857:
858: public void translate(double tx, double ty)
859: {
860: transform(AffineTransform.getTranslateInstance(tx, ty));
861: }
862:
863: public void translate(int x, int y)
864: {
865: translate((double) x, (double) y);
866: }
867:
868: public void shear(double shearX, double shearY)
869: {
870: transform(AffineTransform.getShearInstance(shearX, shearY));
871: }
872:
873: public Stroke getStroke()
874: {
875: return stroke;
876: }
877:
878: public void setStroke(Stroke st)
879: {
880: stroke = st;
881: if (stroke instanceof BasicStroke)
882: {
883: BasicStroke bs = (BasicStroke) stroke;
884: cairoSetLineCap(bs.getEndCap());
885: cairoSetLineWidth(bs.getLineWidth());
886: cairoSetLineJoin(bs.getLineJoin());
887: cairoSetMiterLimit(bs.getMiterLimit());
888: float[] dashes = bs.getDashArray();
889: if (dashes != null)
890: {
891: double[] double_dashes = new double[dashes.length];
892: for (int i = 0; i < dashes.length; i++)
893: double_dashes[i] = dashes[i];
894: cairoSetDash(double_dashes, double_dashes.length,
895: (double) bs.getDashPhase());
896: }
897: else
898: cairoSetDash(new double[0], 0, 0.0);
899: }
900: }
901:
902: public void setStrokeUnlocked(Stroke st)
903: {
904: stroke = st;
905: if (stroke instanceof BasicStroke)
906: {
907: BasicStroke bs = (BasicStroke) stroke;
908: cairoSetLineCapUnlocked(bs.getEndCap());
909: cairoSetLineWidthUnlocked(bs.getLineWidth());
910: cairoSetLineJoinUnlocked(bs.getLineJoin());
911: cairoSetMiterLimitUnlocked(bs.getMiterLimit());
912: float[] dashes = bs.getDashArray();
913: if (dashes != null)
914: {
915: double[] double_dashes = new double[dashes.length];
916: for (int i = 0; i < dashes.length; i++)
917: double_dashes[i] = dashes[i];
918: cairoSetDashUnlocked(double_dashes, double_dashes.length,
919: (double) bs.getDashPhase());
920: }
921: else
922: cairoSetDashUnlocked(new double[0], 0, 0.0);
923: }
924: }
925:
926:
927:
928:
929:
930: public void setPaintMode()
931: {
932: setComposite(java.awt.AlphaComposite.SrcOver);
933: }
934:
935: public void setXORMode(Color c)
936: {
937: setComposite(new gnu.java.awt.BitwiseXORComposite(c));
938: }
939:
940: public void setColor(Color c)
941: {
942: if (c == null)
943: c = Color.BLACK;
944:
945: fg = c;
946: paint = c;
947: cairoSetRGBAColor(fg.getRed() / 255.0, fg.getGreen() / 255.0,
948: fg.getBlue() / 255.0, fg.getAlpha() / 255.0);
949: }
950:
951: public void setColorUnlocked(Color c)
952: {
953: if (c == null)
954: c = Color.BLACK;
955:
956: fg = c;
957: paint = c;
958: cairoSetRGBAColorUnlocked(fg.getRed() / 255.0, fg.getGreen() / 255.0,
959: fg.getBlue() / 255.0, fg.getAlpha() / 255.0);
960: }
961:
962: public Color getColor()
963: {
964: return fg;
965: }
966:
967: public Color getColorUnlocked()
968: {
969: return getColor();
970: }
971:
972: public void clipRect(int x, int y, int width, int height)
973: {
974: clip(new Rectangle(x, y, width, height));
975: }
976:
977: public Shape getClip()
978: {
979: if (clip == null)
980: return null;
981: else
982: return clip.getBounds2D();
983: }
984:
985: public Rectangle getClipBounds()
986: {
987: if (clip == null)
988: return null;
989: else
990: return clip.getBounds();
991: }
992:
993: protected Rectangle2D getClipInDevSpace()
994: {
995: Rectangle2D uclip = clip.getBounds2D();
996: if (transform == null)
997: return uclip;
998: else
999: {
1000: Point2D pos = transform.transform(new Point2D.Double(uclip.getX(),
1001: uclip.getY()),
1002: (Point2D) null);
1003: Point2D extent = transform.deltaTransform(new Point2D.Double(uclip
1004: .getWidth(),
1005: uclip
1006: .getHeight()),
1007: (Point2D) null);
1008: return new Rectangle2D.Double(pos.getX(), pos.getY(), extent.getX(),
1009: extent.getY());
1010: }
1011: }
1012:
1013: public void setClip(int x, int y, int width, int height)
1014: {
1015: setClip(new Rectangle2D.Double((double) x, (double) y, (double) width,
1016: (double) height));
1017: }
1018:
1019: public void setClip(Shape s)
1020: {
1021: clip = s;
1022: if (clip == null)
1023: {
1024:
1025: if (component != null)
1026: {
1027: Dimension d = component.awtComponent.getSize();
1028: setClip(0, 0, d.width, d.height);
1029: }
1030: }
1031: else
1032: {
1033: cairoNewPath();
1034: if (s instanceof Rectangle2D)
1035: {
1036: Rectangle2D r = (Rectangle2D) s;
1037: cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
1038: }
1039: else
1040: walkPath(s.getPathIterator(null), false);
1041:
1042:
1043: cairoClip();
1044: }
1045: }
1046:
1047: private static BasicStroke draw3DRectStroke = new BasicStroke();
1048:
1049: public void draw3DRect(int x, int y, int width, int height, boolean raised)
1050: {
1051: Stroke tmp = stroke;
1052: setStroke(draw3DRectStroke);
1053: super.draw3DRect(x, y, width, height, raised);
1054: setStroke(tmp);
1055: updateBufferedImage();
1056: }
1057:
1058: public void fill3DRect(int x, int y, int width, int height, boolean raised)
1059: {
1060: Stroke tmp = stroke;
1061: setStroke(draw3DRectStroke);
1062: super.fill3DRect(x, y, width, height, raised);
1063: setStroke(tmp);
1064: updateBufferedImage();
1065: }
1066:
1067: public void drawRect(int x, int y, int width, int height)
1068: {
1069: draw(new Rectangle(x, y, width, height));
1070: }
1071:
1072: public void fillRect(int x, int y, int width, int height)
1073: {
1074: cairoNewPath();
1075: cairoRectangle(x, y, width, height);
1076: cairoFill();
1077: }
1078:
1079: public void clearRect(int x, int y, int width, int height)
1080: {
1081: if (bg != null)
1082: cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0,
1083: bg.getBlue() / 255.0, 1.0);
1084: cairoNewPath();
1085: cairoRectangle(x, y, width, height);
1086: cairoFill();
1087: setColor(fg);
1088:
1089: updateBufferedImage();
1090: }
1091:
1092: public void setBackground(Color c)
1093: {
1094: if (c == null)
1095: c = Color.WHITE;
1096: bg = c;
1097: }
1098:
1099: public void setBackgroundUnlocked(Color c)
1100: {
1101: setBackground(c);
1102: }
1103:
1104: public Color getBackground()
1105: {
1106: return bg;
1107: }
1108:
1109: private void doPolygon(int[] xPoints, int[] yPoints, int nPoints,
1110: boolean close, boolean fill)
1111: {
1112: if (nPoints < 1)
1113: return;
1114: GeneralPath gp = new GeneralPath(PathIterator.WIND_EVEN_ODD);
1115: gp.moveTo((float) xPoints[0], (float) yPoints[0]);
1116: for (int i = 1; i < nPoints; i++)
1117: gp.lineTo((float) xPoints[i], (float) yPoints[i]);
1118:
1119: if (close)
1120: gp.closePath();
1121:
1122: Shape sh = gp;
1123: if (fill == false && stroke != null && ! (stroke instanceof BasicStroke))
1124: {
1125: sh = stroke.createStrokedShape(gp);
1126: fill = true;
1127: }
1128:
1129: if (fill)
1130: fill(sh);
1131: else
1132: draw(sh);
1133: }
1134:
1135: public void drawLine(int x1, int y1, int x2, int y2)
1136: {
1137: int[] xp = new int[2];
1138: int[] yp = new int[2];
1139:
1140: xp[0] = x1;
1141: xp[1] = x2;
1142: yp[0] = y1;
1143: yp[1] = y2;
1144:
1145: doPolygon(xp, yp, 2, false, false);
1146: }
1147:
1148: public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
1149: {
1150: doPolygon(xPoints, yPoints, nPoints, true, true);
1151: }
1152:
1153: public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
1154: {
1155: doPolygon(xPoints, yPoints, nPoints, true, false);
1156: }
1157:
1158: public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
1159: {
1160: doPolygon(xPoints, yPoints, nPoints, false, false);
1161: }
1162:
1163: private boolean drawRaster(ColorModel cm, Raster r,
1164: AffineTransform imageToUser, Color bgcolor)
1165: {
1166: if (r == null)
1167: return false;
1168:
1169: SampleModel sm = r.getSampleModel();
1170: DataBuffer db = r.getDataBuffer();
1171:
1172: if (db == null || sm == null)
1173: return false;
1174:
1175: if (cm == null)
1176: cm = ColorModel.getRGBdefault();
1177:
1178: double[] i2u = new double[6];
1179: if (imageToUser != null)
1180: imageToUser.getMatrix(i2u);
1181: else
1182: {
1183: i2u[0] = 1;
1184: i2u[1] = 0;
1185: i2u[2] = 0;
1186: i2u[3] = 1;
1187: i2u[4] = 0;
1188: i2u[5] = 0;
1189: }
1190:
1191: int[] pixels = findSimpleIntegerArray(cm, r);
1192:
1193: if (pixels == null)
1194: {
1195:
1196:
1197:
1198:
1199: if (sm instanceof MultiPixelPackedSampleModel)
1200: {
1201: pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels);
1202: for (int i = 0; i < pixels.length; i++)
1203: pixels[i] = cm.getRGB(pixels[i]);
1204: }
1205: else
1206: {
1207: pixels = new int[r.getWidth() * r.getHeight()];
1208: for (int i = 0; i < pixels.length; i++)
1209: pixels[i] = cm.getRGB(db.getElem(i));
1210: }
1211: }
1212:
1213:
1214:
1215:
1216: if (cm.hasAlpha())
1217: {
1218: if (bgcolor != null && cm.hasAlpha())
1219: for (int i = 0; i < pixels.length; i++)
1220: {
1221: if (cm.getAlpha(pixels[i]) == 0)
1222: pixels[i] = bgcolor.getRGB();
1223: }
1224: }
1225: else
1226: for (int i = 0; i < pixels.length; i++)
1227: pixels[i] |= 0xFF000000;
1228:
1229: drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u);
1230:
1231: updateBufferedImage();
1232:
1233: return true;
1234: }
1235:
1236: public void drawRenderedImage(RenderedImage image, AffineTransform xform)
1237: {
1238: drawRaster(image.getColorModel(), image.getData(), xform, bg);
1239: }
1240:
1241: public void drawRenderableImage(RenderableImage image, AffineTransform xform)
1242: {
1243: drawRenderedImage(image.createRendering(new RenderContext(xform)), xform);
1244: }
1245:
1246: public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
1247: {
1248: return drawImage(img, xform, bg, obs);
1249: }
1250:
1251: public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
1252: {
1253: Image filtered = op.filter(image, null);
1254: drawImage(filtered, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg, null);
1255: }
1256:
1257: public boolean drawImage(Image img, int x, int y, ImageObserver observer)
1258: {
1259: return drawImage(img, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg,
1260: observer);
1261: }
1262:
1263:
1264:
1265:
1266:
1267: public boolean hit(Rectangle rect, Shape text, boolean onStroke)
1268: {
1269: throw new java.lang.UnsupportedOperationException();
1270: }
1271:
1272: public GraphicsConfiguration getDeviceConfiguration()
1273: {
1274: throw new java.lang.UnsupportedOperationException();
1275: }
1276:
1277: public void setComposite(Composite comp)
1278: {
1279: this.comp = comp;
1280:
1281: if (comp instanceof AlphaComposite)
1282: {
1283: AlphaComposite a = (AlphaComposite) comp;
1284: cairoSetOperator(a.getRule());
1285: Color c = getColor();
1286: setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(),
1287: (int) (a.getAlpha() * ((float) c.getAlpha()))));
1288: }
1289: else
1290: throw new java.lang.UnsupportedOperationException();
1291: }
1292:
1293: public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
1294: {
1295: hints.put(hintKey, hintValue);
1296:
1297: if (hintKey.equals(RenderingHints.KEY_INTERPOLATION)
1298: || hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION))
1299: {
1300: if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
1301: cairoSurfaceSetFilter(0);
1302:
1303: else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
1304: cairoSurfaceSetFilter(1);
1305:
1306: else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
1307: cairoSurfaceSetFilter(2);
1308:
1309: else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
1310: cairoSurfaceSetFilter(3);
1311:
1312: else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
1313: cairoSurfaceSetFilter(4);
1314: }
1315:
1316: shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
1317: || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
1318: }
1319:
1320: public Object getRenderingHint(RenderingHints.Key hintKey)
1321: {
1322: return hints.get(hintKey);
1323: }
1324:
1325: public void setRenderingHints(Map hints)
1326: {
1327: this.hints = new RenderingHints(getDefaultHints());
1328: this.hints.add(new RenderingHints(hints));
1329:
1330: if (hints.containsKey(RenderingHints.KEY_INTERPOLATION))
1331: {
1332: if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
1333: cairoSurfaceSetFilter(0);
1334:
1335: else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
1336: cairoSurfaceSetFilter(1);
1337: }
1338:
1339: if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION))
1340: {
1341: if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
1342: cairoSurfaceSetFilter(2);
1343:
1344: else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
1345: cairoSurfaceSetFilter(3);
1346:
1347: else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
1348: cairoSurfaceSetFilter(4);
1349: }
1350:
1351: shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
1352: || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
1353: }
1354:
1355: public void setRenderingHintsUnlocked(Map hints)
1356: {
1357: this.hints = new RenderingHints(getDefaultHints());
1358: this.hints.add(new RenderingHints(hints));
1359:
1360: if (hints.containsKey(RenderingHints.KEY_INTERPOLATION))
1361: {
1362: if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
1363: cairoSurfaceSetFilterUnlocked(0);
1364:
1365: else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
1366: cairoSurfaceSetFilterUnlocked(1);
1367: }
1368:
1369: if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION))
1370: {
1371: if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
1372: cairoSurfaceSetFilterUnlocked(2);
1373:
1374: else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
1375: cairoSurfaceSetFilterUnlocked(3);
1376:
1377: else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
1378: cairoSurfaceSetFilterUnlocked(4);
1379: }
1380:
1381: shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
1382: || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
1383: }
1384:
1385: public void addRenderingHints(Map hints)
1386: {
1387: this.hints.add(new RenderingHints(hints));
1388: }
1389:
1390: public RenderingHints getRenderingHints()
1391: {
1392: return hints;
1393: }
1394:
1395: public Composite getComposite()
1396: {
1397: if (comp == null)
1398: return AlphaComposite.SrcOver;
1399: else
1400: return comp;
1401: }
1402:
1403: public FontRenderContext getFontRenderContext()
1404: {
1405: return new FontRenderContext(transform, true, true);
1406: }
1407:
1408: public void copyArea(int x, int y, int width, int height, int dx, int dy)
1409: {
1410: GdkGraphics2D g = (GdkGraphics2D) create(x, y, width, height);
1411: gdkDrawDrawable(g, x + dx, y + dy);
1412: }
1413:
1414: public void drawArc(int x, int y, int width, int height, int startAngle,
1415: int arcAngle)
1416: {
1417: draw(new Arc2D.Double((double) x, (double) y, (double) width,
1418: (double) height, (double) startAngle,
1419: (double) arcAngle, Arc2D.OPEN));
1420: }
1421:
1422: public boolean drawImage(Image img, int x, int y, Color bgcolor,
1423: ImageObserver observer)
1424: {
1425: return drawImage(img, x, y, img.getWidth(observer),
1426: img.getHeight(observer), bgcolor, observer);
1427: }
1428:
1429: public boolean drawImage(Image img, int x, int y, int width, int height,
1430: Color bgcolor, ImageObserver observer)
1431: {
1432: double scaleX = width / (double) img.getWidth(observer);
1433: double scaleY = height / (double) img.getHeight(observer);
1434:
1435: return drawImage(img, new AffineTransform(scaleX, 0f, 0f, scaleY, x, y),
1436: bgcolor, observer);
1437: }
1438:
1439: public boolean drawImage(Image img, int x, int y, int width, int height,
1440: ImageObserver observer)
1441: {
1442: return drawImage(img, x, y, width, height, bg, observer);
1443: }
1444:
1445: public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
1446: int sx1, int sy1, int sx2, int sy2, Color bgcolor,
1447: ImageObserver observer)
1448: {
1449: if (img == null)
1450: return false;
1451:
1452: Image subImage;
1453:
1454: int sourceWidth = sx2 - sx1;
1455: int sourceHeight = sy2 - sy1;
1456:
1457: int destWidth = dx2 - dx1;
1458: int destHeight = dy2 - dy1;
1459:
1460: double scaleX = destWidth / (double) sourceWidth;
1461: double scaleY = destHeight / (double) sourceHeight;
1462:
1463:
1464:
1465:
1466: if (img instanceof BufferedImage)
1467: {
1468: BufferedImage b = (BufferedImage) img;
1469: subImage = b.getSubimage(sx1, sy1, sx2, sy2);
1470: }
1471: else
1472: {
1473:
1474:
1475:
1476:
1477:
1478: CropImageFilter filter = new CropImageFilter(sx1, sx2, sx2, sy2);
1479: FilteredImageSource src = new FilteredImageSource(img.getSource(),
1480: filter);
1481:
1482: subImage = Toolkit.getDefaultToolkit().createImage(src);
1483: }
1484:
1485: return drawImage(subImage,
1486: new AffineTransform(scaleX, 0, 0, scaleY, dx1, dy1),
1487: bgcolor, observer);
1488: }
1489:
1490: public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
1491: int sx1, int sy1, int sx2, int sy2,
1492: ImageObserver observer)
1493: {
1494: return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bg, observer);
1495: }
1496:
1497: public void drawOval(int x, int y, int width, int height)
1498: {
1499: drawArc(x, y, width, height, 0, 360);
1500: }
1501:
1502: public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
1503: int arcHeight)
1504: {
1505: if (arcWidth > width)
1506: arcWidth = width;
1507: if (arcHeight > height)
1508: arcHeight = height;
1509:
1510: int xx = x + width - arcWidth;
1511: int yy = y + height - arcHeight;
1512:
1513: drawArc(x, y, arcWidth, arcHeight, 90, 90);
1514: drawArc(xx, y, arcWidth, arcHeight, 0, 90);
1515: drawArc(xx, yy, arcWidth, arcHeight, 270, 90);
1516: drawArc(x, yy, arcWidth, arcHeight, 180, 90);
1517:
1518: int y1 = y + arcHeight / 2;
1519: int y2 = y + height - arcHeight / 2;
1520: drawLine(x, y1, x, y2);
1521: drawLine(x + width, y1, x + width, y2);
1522:
1523: int x1 = x + arcWidth / 2;
1524: int x2 = x + width - arcWidth / 2;
1525: drawLine(x1, y, x2, y);
1526: drawLine(x1, y + height, x2, y + height);
1527: }
1528:
1529:
1530: native void cairoDrawGlyphVector(GdkFontPeer font,
1531: float x, float y, int n,
1532: int[] codes, float[] positions);
1533:
1534: native void cairoDrawGdkTextLayout(GdkTextLayout gl,
1535: float x, float y);
1536:
1537: GdkFontPeer getFontPeer()
1538: {
1539: return (GdkFontPeer) getFont().getPeer();
1540: }
1541:
1542: public void drawGdkTextLayout(GdkTextLayout gl, float x, float y)
1543: {
1544: cairoDrawGdkTextLayout (gl, x, y);
1545: updateBufferedImage ();
1546: }
1547:
1548: public void drawString(String str, float x, float y)
1549: {
1550: if (str == null || str.length() == 0)
1551: return;
1552:
1553: drawGlyphVector(getFont().createGlyphVector(null, str), x, y);
1554: updateBufferedImage ();
1555: }
1556:
1557: public void drawString(String str, int x, int y)
1558: {
1559: drawString (str, (float) x, (float) y);
1560: }
1561:
1562: public void drawString(AttributedCharacterIterator ci, int x, int y)
1563: {
1564: drawString (ci, (float) x, (float) y);
1565: }
1566:
1567: public void drawGlyphVector(GlyphVector gv, float x, float y)
1568: {
1569: int n = gv.getNumGlyphs ();
1570: int[] codes = gv.getGlyphCodes (0, n, null);
1571: float[] positions = gv.getGlyphPositions (0, n, null);
1572:
1573: setFont (gv.getFont ());
1574: cairoDrawGlyphVector (getFontPeer(), x, y, n, codes, positions);
1575: updateBufferedImage ();
1576: }
1577:
1578: public void drawString(AttributedCharacterIterator ci, float x, float y)
1579: {
1580: GlyphVector gv = getFont().createGlyphVector(getFontRenderContext(), ci);
1581: drawGlyphVector(gv, x, y);
1582: }
1583:
1584: public void fillArc(int x, int y, int width, int height, int startAngle,
1585: int arcAngle)
1586: {
1587: fill(new Arc2D.Double((double) x, (double) y, (double) width,
1588: (double) height, (double) startAngle,
1589: (double) arcAngle, Arc2D.OPEN));
1590: }
1591:
1592: public void fillOval(int x, int y, int width, int height)
1593: {
1594: fillArc(x, y, width, height, 0, 360);
1595: }
1596:
1597: public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
1598: int arcHeight)
1599: {
1600: if (arcWidth > width)
1601: arcWidth = width;
1602: if (arcHeight > height)
1603: arcHeight = height;
1604:
1605: int xx = x + width - arcWidth;
1606: int yy = y + height - arcHeight;
1607:
1608: fillArc(x, y, arcWidth, arcHeight, 90, 90);
1609: fillArc(xx, y, arcWidth, arcHeight, 0, 90);
1610: fillArc(xx, yy, arcWidth, arcHeight, 270, 90);
1611: fillArc(x, yy, arcWidth, arcHeight, 180, 90);
1612:
1613: fillRect(x, y + arcHeight / 2, width, height - arcHeight + 1);
1614: fillRect(x + arcWidth / 2, y, width - arcWidth + 1, height);
1615: }
1616:
1617: public Font getFont()
1618: {
1619: if (font == null)
1620: return new Font("SansSerif", Font.PLAIN, 12);
1621: return font;
1622: }
1623:
1624:
1625:
1626:
1627:
1628: static native void releasePeerGraphicsResource(GdkFontPeer f);
1629:
1630: public FontMetrics getFontMetrics()
1631: {
1632: return getFontMetrics(getFont());
1633: }
1634:
1635: public FontMetrics getFontMetrics(Font f)
1636: {
1637:
1638:
1639: return Toolkit.getDefaultToolkit().getFontMetrics(f);
1640: }
1641:
1642: public void setFont(Font f)
1643: {
1644:
1645:
1646: if (f == null)
1647: return;
1648:
1649: if (f.getPeer() instanceof GdkFontPeer)
1650: font = f;
1651: else
1652: font =
1653: ((ClasspathToolkit)(Toolkit.getDefaultToolkit()))
1654: .getFont(f.getName(), f.getAttributes());
1655: }
1656:
1657: public void setFontUnlocked(Font f)
1658: {
1659: setFont (f);
1660: }
1661:
1662: public String toString()
1663: {
1664: return (getClass().getName()
1665: + "[font=" + getFont().toString()
1666: + ",color=" + fg.toString()
1667: + "]");
1668: }
1669: }