2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / gnu / java / awt / peer / gtk / GdkGraphics2D.java
blob036e40f972d85a2651e2756327a0433e7a84ebbb
1 /* GdkGraphics2D.java
2 Copyright (C) 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.awt.peer.gtk;
41 import java.awt.*;
42 import java.awt.geom.*;
43 import java.awt.font.*;
44 import java.awt.color.*;
45 import java.awt.image.*;
46 import java.awt.image.renderable.*;
48 import java.text.AttributedCharacterIterator;
49 import java.util.Map;
50 import java.util.Stack;
51 import java.lang.Integer;
52 import gnu.java.awt.ClasspathToolkit;
53 import gnu.java.awt.peer.ClasspathFontPeer;
54 import gnu.classpath.Configuration;
56 public class GdkGraphics2D extends Graphics2D
59 //////////////////////////////////////
60 ////// State Management Methods //////
61 //////////////////////////////////////
63 static
65 if (Configuration.INIT_LOAD_LIBRARY)
67 System.loadLibrary("gtkpeer");
69 initStaticState ();
71 native static void initStaticState ();
72 private final int native_state = GtkGenericPeer.getUniqueInteger();
74 private Paint paint;
75 private Stroke stroke;
76 private Color fg;
77 private Color bg;
78 private Shape clip;
79 private AffineTransform transform;
80 private GtkComponentPeer component;
81 private Font font;
83 private Stack stateStack;
85 native private int[] initState (GtkComponentPeer component);
86 native private void initState (int width, int height);
87 native private void copyState (GdkGraphics2D g);
88 native public void dispose ();
90 public void finalize ()
92 dispose();
95 public Graphics create ()
97 return new GdkGraphics2D (this);
100 public Graphics create (int x, int y, int width, int height)
102 return new GdkGraphics2D (width, height);
105 GdkGraphics2D (GdkGraphics2D g)
107 paint = g.paint;
108 stroke = g.stroke;
110 if (g.fg.getAlpha() != -1)
111 fg = new Color (g.fg.getRed (), g.fg.getGreen (),
112 g.fg.getBlue (), g.fg.getAlpha ());
113 else
114 fg = new Color (g.fg.getRGB ());
116 if (g.bg.getAlpha() != -1)
117 bg = new Color(g.bg.getRed (), g.bg.getGreen (),
118 g.bg.getBlue (), g.bg.getAlpha ());
119 else
120 bg = new Color (g.bg.getRGB ());
122 if (g.clip == null)
123 clip = null;
124 else
125 clip = new Rectangle (g.getClipBounds ());
127 if (g.transform == null)
128 transform = AffineTransform.getTranslateInstance (0.5, 0.5);
129 else
130 transform = new AffineTransform (g.transform);
132 font = g.font;
133 component = g.component;
134 copyState (g);
136 setColor (fg);
137 setBackground (bg);
138 setPaint (paint);
139 setStroke (stroke);
140 setClip (clip);
141 setTransform (transform);
142 stateStack = new Stack();
145 GdkGraphics2D (int width, int height)
147 initState (width, height);
149 setColor(Color.black);
150 setBackground (Color.black);
151 setPaint (getColor());
152 setFont (new Font("SansSerif", Font.PLAIN, 12));
153 setTransform (AffineTransform.getTranslateInstance (0.5, 0.5));
154 setStroke (new BasicStroke ());
156 stateStack = new Stack();
159 GdkGraphics2D (GtkComponentPeer component)
161 this.component = component;
162 int rgb[] = initState (component);
164 setColor (new Color (rgb[0], rgb[1], rgb[2]));
165 setBackground (new Color (rgb[3], rgb[4], rgb[5]));
166 setPaint (getColor());
167 setFont (new Font("SansSerif", Font.PLAIN, 12));
168 setTransform (AffineTransform.getTranslateInstance (0.5, 0.5));
169 setStroke (new BasicStroke ());
171 stateStack = new Stack ();
175 ////////////////////////////////////
176 ////// Native Drawing Methods //////
177 ////////////////////////////////////
179 // GDK drawing methods
180 private native void gdkDrawDrawable (GdkGraphics2D other, int x, int y);
182 // drawing utility methods
183 private native void drawPixels (int pixels[], int w, int h, int stride, double i2u[]);
184 private native void setTexturePixels (int pixels[], int w, int h, int stride);
185 private native void setGradient (double x1, double y1,
186 double x2, double y2,
187 int r1, int g1, int b1, int a1,
188 int r2, int g2, int b2, int a2,
189 boolean cyclic);
191 // simple passthroughs to cairo
192 private native void cairoSave ();
193 private native void cairoRestore ();
194 private native void cairoSetMatrix (double m[]);
195 private native void cairoSetFont (GdkClasspathFontPeer peer);
196 private native void cairoShowGlyphs (int codes[],
197 float positions[]);
198 private native void cairoSetOperator (int cairoOperator);
199 private native void cairoSetRGBColor (double red, double green, double blue);
200 private native void cairoSetAlpha (double alpha);
201 private native void cairoSetFillRule (int cairoFillRule);
202 private native void cairoSetLineWidth (double width);
203 private native void cairoSetLineCap (int cairoLineCap);
204 private native void cairoSetLineJoin (int cairoLineJoin);
205 private native void cairoSetDash (double dashes[], int ndash, double offset);
206 private native void cairoSetMiterLimit (double limit);
207 private native void cairoNewPath ();
208 private native void cairoMoveTo (double x, double y);
209 private native void cairoLineTo (double x, double y);
210 private native void cairoCurveTo (double x1, double y1,
211 double x2, double y2,
212 double x3, double y3);
213 private native void cairoRelMoveTo (double dx, double dy);
214 private native void cairoRelLineTo (double dx, double dy);
215 private native void cairoRelCurveTo (double dx1, double dy1,
216 double dx2, double dy2,
217 double dx3, double dy3);
218 private native void cairoRectangle (double x, double y,
219 double width, double height);
220 private native void cairoClosePath ();
221 private native void cairoStroke ();
222 private native void cairoFill ();
223 private native void cairoClip ();
226 /////////////////////////////////////////////
227 ////// General Drawing Support Methods //////
228 /////////////////////////////////////////////
230 private class DrawState
232 private Paint paint;
233 private Stroke stroke;
234 private Color fg;
235 private Color bg;
236 private Shape clip;
237 private AffineTransform transform;
238 private Font font;
239 DrawState (GdkGraphics2D g)
241 this.paint = g.paint;
242 this.stroke = g.stroke;
243 this.fg = g.fg;
244 this.bg = g.bg;
245 this.clip = g.clip;
246 if (g.transform != null)
247 this.transform = (AffineTransform) g.transform.clone();
248 this.font = g.font;
250 public void restore(GdkGraphics2D g)
252 g.paint = this.paint;
253 g.stroke = this.stroke;
254 g.fg = this.fg;
255 g.bg = this.bg;
256 g.clip = this.clip;
257 g.transform = this.transform;
258 g.font = this.font;
262 private void stateSave ()
264 stateStack.push (new DrawState (this));
265 cairoSave ();
268 private void stateRestore ()
270 ((DrawState)(stateStack.pop ())).restore (this);
271 cairoRestore ();
275 double x;
276 double y;
277 private void setPos (double nx, double ny)
279 x = nx;
280 y = ny;
283 private void walkPath(PathIterator p)
285 double coords[] = new double[6];
287 cairoSetFillRule (p.getWindingRule ());
288 for ( ; ! p.isDone (); p.next())
290 int seg = p.currentSegment (coords);
291 switch(seg)
294 case PathIterator.SEG_MOVETO:
295 setPos(coords[0], coords[1]);
296 cairoMoveTo (coords[0], coords[1]);
297 break;
299 case PathIterator.SEG_LINETO:
300 setPos(coords[0], coords[1]);
301 cairoLineTo (coords[0], coords[1]);
302 break;
304 case PathIterator.SEG_QUADTO:
306 // splitting a quadratic bezier into a cubic:
307 // see: http://pfaedit.sourceforge.net/bezier.html
309 double x1 = x + (2.0/3.0) * (coords[0] - x);
310 double y1 = y + (2.0/3.0) * (coords[1] - y);
312 double x2 = x1 + (1.0/3.0) * (coords[2] - x);
313 double y2 = y1 + (1.0/3.0) * (coords[3] - y);
315 setPos(coords[2], coords[3]);
316 cairoCurveTo (x1, y1,
317 x2, y2,
318 coords[2], coords[3]);
319 break;
321 case PathIterator.SEG_CUBICTO:
322 setPos(coords[4], coords[5]);
323 cairoCurveTo (coords[0], coords[1],
324 coords[2], coords[3],
325 coords[4], coords[5]);
326 break;
328 case PathIterator.SEG_CLOSE:
329 cairoClosePath ();
330 break;
336 //////////////////////////////////////////////////
337 ////// Implementation of Graphics2D Methods //////
338 //////////////////////////////////////////////////
340 public void draw (Shape s)
343 if (stroke != null &&
344 !(stroke instanceof BasicStroke))
346 fill (stroke.createStrokedShape (s));
347 return;
350 stateSave ();
351 cairoNewPath ();
352 if (s instanceof Rectangle2D)
354 Rectangle2D r = (Rectangle2D)s;
355 cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
357 else
358 walkPath (s.getPathIterator (null));
359 cairoStroke ();
360 stateRestore ();
363 public void fill (Shape s)
365 stateSave();
366 cairoNewPath ();
367 if (s instanceof Rectangle2D)
369 Rectangle2D r = (Rectangle2D)s;
370 cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
372 else
373 walkPath (s.getPathIterator (null));
374 cairoFill ();
375 stateRestore ();
378 public void clip (Shape s)
380 // update it
382 if (clip == null || s == null)
383 clip = s;
384 else if (s instanceof Rectangle2D
385 && clip instanceof Rectangle2D)
387 Rectangle2D r = (Rectangle2D)s;
388 Rectangle2D curr = (Rectangle2D)clip;
389 clip = curr.createIntersection (r);
391 else
392 throw new UnsupportedOperationException ();
394 // draw it
395 if (clip != null)
397 cairoNewPath ();
398 if (clip instanceof Rectangle2D)
400 Rectangle2D r = (Rectangle2D)clip;
401 cairoRectangle (r.getX (), r.getY (),
402 r.getWidth (), r.getHeight ());
404 else
405 walkPath (clip.getPathIterator (null));
406 cairoClosePath ();
407 cairoClip ();
411 public Paint getPaint ()
413 return paint;
416 public AffineTransform getTransform ()
418 return (AffineTransform) transform.clone ();
421 public void setPaint (Paint p)
423 if (paint == null)
424 return;
426 paint = p;
427 if (paint instanceof Color)
429 setColor ((Color) paint);
431 else if (paint instanceof TexturePaint)
433 TexturePaint tp = (TexturePaint) paint;
434 BufferedImage img = tp.getImage ();
435 int pixels[] = img.getRGB(0, 0, img.getWidth (),
436 img.getHeight (), null,
437 0, img.getWidth ());
438 setTexturePixels (pixels, img.getWidth (),
439 img.getHeight (), img.getWidth ());
441 else if (paint instanceof GradientPaint)
443 GradientPaint gp = (GradientPaint) paint;
444 Point2D p1 = gp.getPoint1 ();
445 Point2D p2 = gp.getPoint2 ();
446 Color c1 = gp.getColor1 ();
447 Color c2 = gp.getColor2 ();
448 setGradient (p1.getX (), p1.getY (),
449 p2.getX (), p2.getY (),
450 c1.getRed (), c1.getGreen (),
451 c1.getBlue (), c1.getAlpha (),
452 c2.getRed (), c2.getGreen (),
453 c2.getBlue (), c2.getAlpha (),
454 gp.isCyclic ());
456 else
457 throw new java.lang.UnsupportedOperationException ();
460 public void setTransform (AffineTransform tx)
462 transform = tx;
463 if (transform != null)
465 double m[] = new double[6];
466 transform.getMatrix (m);
467 cairoSetMatrix (m);
471 public void transform (AffineTransform tx)
473 if (transform == null)
474 transform = new AffineTransform (tx);
475 else
476 transform.concatenate (tx);
477 setTransform (transform);
480 public void rotate(double theta)
482 transform (AffineTransform.getRotateInstance (theta));
485 public void rotate(double theta, double x, double y)
487 transform (AffineTransform.getRotateInstance (theta, x, y));
490 public void scale(double sx, double sy)
492 transform (AffineTransform.getScaleInstance (sx, sy));
495 public void translate (double tx, double ty)
497 transform (AffineTransform.getTranslateInstance (tx, ty));
500 public void translate (int x, int y)
502 translate ((double) x, (double) y);
505 public void shear(double shearX, double shearY)
507 transform (AffineTransform.getShearInstance (shearX, shearY));
510 public Stroke getStroke()
512 return stroke;
515 public void setStroke (Stroke st)
517 stroke = st;
518 if (stroke instanceof BasicStroke)
520 BasicStroke bs = (BasicStroke) stroke;
521 cairoSetLineCap (bs.getEndCap());
522 cairoSetLineWidth (bs.getLineWidth() / 2.0);
523 cairoSetLineJoin (bs.getLineJoin());
524 cairoSetMiterLimit (bs.getMiterLimit());
525 float dashes[] = bs.getDashArray();
526 if (dashes != null)
528 double double_dashes[] = new double[dashes.length];
529 for (int i = 0; i < dashes.length; i++)
530 double_dashes[i] = dashes[i];
531 cairoSetDash (double_dashes, double_dashes.length,
532 (double) bs.getDashPhase ());
538 ////////////////////////////////////////////////
539 ////// Implementation of Graphics Methods //////
540 ////////////////////////////////////////////////
542 public void setPaintMode ()
544 setComposite (java.awt.AlphaComposite.SrcOver);
547 public void setXORMode (Color c)
549 setComposite (new BitwiseXorComposite (c));
552 public void setColor (Color c)
554 fg = c;
555 paint = c;
556 cairoSetRGBColor (fg.getRed() / 255.0,
557 fg.getGreen() / 255.0,
558 fg.getBlue() / 255.0);
559 cairoSetAlpha ((fg.getAlpha() & 255) / 255.0);
562 public Color getColor ()
564 return fg;
567 public void clipRect (int x, int y, int width, int height)
569 clip (new Rectangle (x, y, width, height));
572 public Shape getClip ()
574 return getClipInDevSpace ();
577 public Rectangle getClipBounds ()
579 if (clip == null)
580 return null;
581 else
582 return clip.getBounds ();
585 protected Rectangle2D getClipInDevSpace ()
587 Rectangle2D uclip = clip.getBounds2D ();
588 if (transform == null)
589 return uclip;
590 else
592 Point2D pos = transform.transform (new Point2D.Double(uclip.getX (),
593 uclip.getY ()),
594 (Point2D)null);
595 Point2D extent = transform.deltaTransform (new Point2D.Double(uclip.getWidth (),
596 uclip.getHeight ()),
597 (Point2D)null);
598 return new Rectangle2D.Double (pos.getX (), pos.getY (),
599 extent.getX (), extent.getY ());
603 public void setClip (int x, int y, int width, int height)
605 cairoNewPath ();
606 cairoRectangle (x, y, width, height);
607 cairoClosePath ();
608 cairoClip ();
609 clip = new Rectangle2D.Double ((double)x, (double)y,
610 (double)width, (double)height);
613 public void setClip (Shape s)
615 clip (s);
618 public void draw3DRect(int x, int y, int width,
619 int height, boolean raised)
621 Color std = fg;
622 Color light = std.brighter();
623 Color dark = std.darker();
625 if (!raised)
627 Color t = light;
628 light = dark;
629 dark = t;
632 double x1 = (double) x;
633 double x2 = (double) x + width;
635 double y1 = (double) y;
636 double y2 = (double) y + height;
638 stateSave ();
640 cairoNewPath ();
641 setColor (light);
642 cairoMoveTo (x1, y1);
643 cairoLineTo (x2, y1);
644 cairoLineTo (x2, y2);
645 cairoStroke ();
647 cairoNewPath ();
648 setColor (dark);
649 cairoMoveTo (x1, y1);
650 cairoLineTo (x1, y2);
651 cairoLineTo (x2, y2);
652 cairoStroke ();
654 stateRestore ();
657 public void fill3DRect(int x, int y, int width,
658 int height, boolean raised)
660 double step = 1.0;
661 if (stroke != null && stroke instanceof BasicStroke)
663 BasicStroke bs = (BasicStroke) stroke;
664 step = bs.getLineWidth();
667 Color bright = fg.brighter ();
668 Color dark = fg.darker ();
670 draw3DRect (x, y, width, height, raised);
672 stateSave ();
673 translate (step/2.0, step/2.0);
674 cairoNewPath ();
675 cairoRectangle ((double) x, (double) y,
676 ((double) width) - step,
677 ((double) height) - step );
678 cairoClosePath ();
679 cairoFill ();
680 stateRestore ();
684 public void drawRect (int x, int y, int width, int height)
686 draw(new Rectangle (x, y, width, height));
689 public void fillRect (int x, int y, int width, int height)
691 fill(new Rectangle (x, y, width, height));
694 public void clearRect (int x, int y, int width, int height)
696 stateSave ();
697 cairoSetRGBColor (bg.getRed() / 255.0,
698 bg.getGreen() / 255.0,
699 bg.getBlue() / 255.0);
700 cairoSetAlpha (1.0);
701 cairoNewPath ();
702 cairoRectangle (x, y, width, height);
703 cairoClosePath ();
704 cairoFill ();
705 stateRestore ();
708 public void setBackground(Color c)
710 bg = c;
713 public Color getBackground()
715 return bg;
718 private void doPolygon(int[] xPoints, int[] yPoints, int nPoints,
719 boolean close, boolean fill)
721 if (nPoints < 1)
722 return;
723 GeneralPath gp = new GeneralPath ();
724 gp.moveTo ((float)xPoints[0], (float)yPoints[0]);
725 for (int i = 1; i < nPoints; i++)
726 gp.lineTo ((float)xPoints[i], (float)yPoints[i]);
728 if (close)
729 gp.closePath ();
731 Shape sh = gp;
732 if (fill == false &&
733 stroke != null &&
734 !(stroke instanceof BasicStroke))
736 sh = stroke.createStrokedShape (gp);
737 fill = true;
740 if (fill)
741 fill (sh);
742 else
743 draw (sh);
746 public void drawLine (int x1, int y1, int x2, int y2)
748 int xp[] = new int[2];
749 int yp[] = new int[2];
751 xp[0] = x1;
752 xp[1] = x2;
753 yp[0] = y1;
754 yp[1] = y2;
756 doPolygon (xp, yp, 2, false, false);
759 public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
761 doPolygon (xPoints, yPoints, nPoints, true, true);
764 public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
766 doPolygon (xPoints, yPoints, nPoints, true, false);
769 public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
771 doPolygon (xPoints, yPoints, nPoints, false, false);
774 private boolean drawRaster (ColorModel cm, Raster r,
775 AffineTransform imageToUser)
777 if (r == null)
778 return false;
780 SampleModel sm = r.getSampleModel ();
781 DataBuffer db = r.getDataBuffer ();
783 if (db == null || sm == null)
784 return false;
786 if (cm == null)
787 cm = ColorModel.getRGBdefault ();
789 double[] i2u = new double[6];
790 if (imageToUser != null)
791 imageToUser.getMatrix(i2u);
792 else
794 i2u[0] = 1; i2u[1] = 0;
795 i2u[2] = 0; i2u[3] = 1;
796 i2u[2] = 0; i2u[3] = 0;
799 int pixels[] = null;
801 if (sm.getDataType () == DataBuffer.TYPE_INT &&
802 db instanceof DataBufferInt &&
803 db.getNumBanks () == 1)
805 // single bank, ARGB-ints buffer in sRGB space
806 DataBufferInt dbi = (DataBufferInt)db;
807 pixels = dbi.getData ();
809 else
810 pixels = r.getPixels (0, 0, r.getWidth (), r.getHeight (), pixels);
812 ColorSpace cs = cm.getColorSpace ();
813 if (cs != null &&
814 cs.getType () != ColorSpace.CS_sRGB)
816 int pixels2[] = new int[pixels.length];
817 for (int i = 0; i < pixels2.length; i++)
818 pixels2[i] = cm.getRGB (pixels[i]);
819 pixels = pixels2;
822 stateSave ();
823 translate (x, y);
824 drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u);
825 stateRestore ();
826 return true;
829 public void drawRenderedImage(RenderedImage image,
830 AffineTransform xform)
832 drawRaster (image.getColorModel(), image.getData(), xform);
835 public void drawRenderableImage(RenderableImage image,
836 AffineTransform xform)
838 drawRenderedImage (image.createRendering (new RenderContext (xform)), xform);
841 public boolean drawImage(Image img,
842 AffineTransform xform,
843 ImageObserver obs)
845 if (img instanceof GtkOffScreenImage &&
846 img.getGraphics () instanceof GdkGraphics2D &&
847 (xform == null
848 || xform.getType () == AffineTransform.TYPE_IDENTITY
849 || xform.getType () == AffineTransform.TYPE_TRANSLATION)
852 // we are being asked to flush a double buffer from Gdk
853 GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
854 gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
855 return true;
857 else
859 if (img instanceof BufferedImage)
861 // draw an image which has actually been loaded into memory fully
862 BufferedImage b = (BufferedImage) img;
863 return drawRaster (b.getColorModel (), b.getData (), xform);
865 else
867 // begin progressive loading in a separate thread
868 new PainterThread (this, img, xform);
869 return false;
874 public void drawImage(BufferedImage image,
875 BufferedImageOp op,
876 int x,
877 int y)
879 Image filtered = op.filter(image, null);
880 drawImage(filtered, new AffineTransform(1f,0f,0f,1f,x,y), null);
883 public boolean drawImage (Image img, int x, int y,
884 ImageObserver observer)
886 return drawImage(img, new AffineTransform(1f,0f,0f,1f,x,y), observer);
890 ////////////////////////////////////////
891 ////// Supporting Private Classes //////
892 ////////////////////////////////////////
894 private class PainterThread implements Runnable, ImageConsumer
897 // this is a helper which is spun off when someone tries to do
898 // Graphics2D.drawImage on an image we cannot determine to be either
899 // one of our own offscreen images or a BufferedImage; that is, when
900 // someone wants to draw an image which is possibly still loading over
901 // a network or something. you run it in a separate thread and it
902 // writes through to the underlying Graphics2D as pixels becomg
903 // available.
905 GdkGraphics2D gr;
906 Image image;
907 ColorModel defaultModel;
908 AffineTransform xform;
910 public PainterThread (GdkGraphics2D g, Image im, AffineTransform xf)
912 image = im;
913 xform = xf;
914 this.gr = (GdkGraphics2D) g.create ();
915 new Thread (this).start ();
918 public void imageComplete (int status)
922 public void setColorModel (ColorModel model)
924 defaultModel = model;
927 public void setDimensions (int width, int height)
931 public void setHints (int hintflags)
935 public void setPixels (int x, int y, int w, int h, ColorModel model,
936 byte[] pixels, int off, int scansize)
940 public void setPixels (int x, int y, int w, int h, ColorModel model,
941 int[] pixels, int off, int scansize)
943 gr.stateSave ();
944 gr.translate (x, y);
946 if (model == null)
947 model = defaultModel;
949 int pixels2[];
950 if (model != null)
952 pixels2 = new int[pixels.length];
953 for (int yy = 0; yy < h; yy++)
954 for (int xx = 0; xx < w; xx++)
956 int i = yy * scansize + xx;
957 pixels2[i] = model.getRGB (pixels[i]);
960 else
961 pixels2 = pixels;
963 double[] xf = new double[6];
964 xform.getMatrix(xf);
965 gr.drawPixels (pixels2, w, h, scansize, xf);
966 gr.stateRestore ();
969 public void setProperties (java.util.Hashtable props)
973 public void run ()
975 image.getSource ().startProduction (this);
976 gr.dispose ();
981 private class BitwiseXorComposite implements Composite
983 // this is a special class which does a bitwise XOR composite, for
984 // backwards compatibility sake. it does *not* implement the
985 // porter-duff XOR operator. the porter-duff XOR is unrelated to
986 // bitwise XOR; it just happens to have a similar name but it
987 // represents a desire to composite the exclusive or of overlapping
988 // subpixel regions. bitwise XOR is for drawing "highlights" such as
989 // cursors (in a cheap oldskool bitblit fashion) by inverting colors
990 // temporarily and then inverting them back.
992 Color xorColor;
994 class BitwiseXorCompositeContext implements CompositeContext
996 ColorModel srcColorModel;
997 ColorModel dstColorModel;
999 public BitwiseXorCompositeContext (ColorModel s,
1000 ColorModel d)
1002 srcColorModel = s;
1003 dstColorModel = d;
1006 public void dispose ()
1010 public void compose (Raster src,
1011 Raster dstIn,
1012 WritableRaster dstOut)
1014 Rectangle srcRect = src.getBounds ();
1015 Rectangle dstInRect = dstIn.getBounds ();
1016 Rectangle dstOutRect = dstOut.getBounds ();
1018 int xp = xorColor.getRGB ();
1019 int x = 0, y = 0;
1020 int w = Math.min (Math.min (srcRect.width, dstOutRect.width), dstInRect.width);
1021 int h = Math.min (Math.min (srcRect.height, dstOutRect.height), dstInRect.height);
1022 Object srcPix = null, dstPix = null;
1024 for (y = 0; y < h; y++)
1025 for (x = 0; x < w; x++)
1027 srcPix = src.getDataElements (x + srcRect.x, y + srcRect.y, srcPix);
1028 dstPix = dstIn.getDataElements (x + dstInRect.x, y + dstInRect.y, dstPix);
1029 int sp = srcColorModel.getRGB (srcPix);
1030 int dp = dstColorModel.getRGB (dstPix);
1031 int rp = sp ^ xp ^ dp;
1032 dstOut.setDataElements (x + dstOutRect.x, y + dstOutRect.y,
1033 dstColorModel.getDataElements (rp, null));
1038 public BitwiseXorComposite (Color c)
1040 xorColor = c;
1043 public CompositeContext createContext (ColorModel srcColorModel,
1044 ColorModel dstColorModel,
1045 RenderingHints hints)
1047 return new BitwiseXorCompositeContext (srcColorModel, dstColorModel);
1052 ///////////////////////////////////////////////
1053 ////// Unimplemented Stubs and Overloads //////
1054 ///////////////////////////////////////////////
1058 public boolean hit(Rectangle rect, Shape text,
1059 boolean onStroke)
1061 throw new java.lang.UnsupportedOperationException ();
1064 public GraphicsConfiguration getDeviceConfiguration()
1066 throw new java.lang.UnsupportedOperationException ();
1069 public void setComposite(Composite comp)
1071 throw new java.lang.UnsupportedOperationException ();
1074 public void setRenderingHint(RenderingHints.Key hintKey,
1075 Object hintValue)
1077 throw new java.lang.UnsupportedOperationException ();
1080 public Object getRenderingHint(RenderingHints.Key hintKey)
1082 throw new java.lang.UnsupportedOperationException ();
1085 public void setRenderingHints(Map hints)
1087 throw new java.lang.UnsupportedOperationException ();
1090 public void addRenderingHints(Map hints)
1092 throw new java.lang.UnsupportedOperationException ();
1095 public RenderingHints getRenderingHints()
1097 throw new java.lang.UnsupportedOperationException ();
1100 public Composite getComposite()
1102 throw new java.lang.UnsupportedOperationException ();
1105 public FontRenderContext getFontRenderContext ()
1107 return new FontRenderContext (transform, true, true);
1110 public void drawGlyphVector (GlyphVector g, float x, float y)
1112 stateSave ();
1113 setFont (g.getFont ());
1114 translate ((double)x, (double)y);
1115 cairoMoveTo (0, 0);
1116 int nglyphs = g.getNumGlyphs ();
1117 int codes[] = g.getGlyphCodes (0, nglyphs, (int []) null);
1118 float posns[] = g.getGlyphPositions (0, nglyphs, (float []) null);
1119 cairoShowGlyphs (codes, posns);
1120 stateRestore ();
1123 public void copyArea (int x, int y, int width, int height, int dx, int dy)
1125 throw new java.lang.UnsupportedOperationException ();
1128 public void drawArc (int x, int y, int width, int height,
1129 int startAngle, int arcAngle)
1131 draw (new Arc2D.Double((double)x, (double)y,
1132 (double)width, (double)height,
1133 (double)startAngle, (double)arcAngle,
1134 Arc2D.OPEN));
1137 public boolean drawImage (Image img, int x, int y, Color bgcolor,
1138 ImageObserver observer)
1140 throw new java.lang.UnsupportedOperationException ();
1143 public boolean drawImage (Image img, int x, int y, int width, int height,
1144 Color bgcolor, ImageObserver observer)
1146 throw new java.lang.UnsupportedOperationException ();
1149 public boolean drawImage (Image img, int x, int y, int width, int height,
1150 ImageObserver observer)
1152 throw new java.lang.UnsupportedOperationException ();
1155 public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
1156 int sx1, int sy1, int sx2, int sy2,
1157 Color bgcolor, ImageObserver observer)
1159 throw new java.lang.UnsupportedOperationException ();
1162 public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
1163 int sx1, int sy1, int sx2, int sy2,
1164 ImageObserver observer)
1166 throw new java.lang.UnsupportedOperationException ();
1169 public void drawOval(int x, int y, int width, int height)
1171 drawArc (x, y, width, height, 0, 360);
1174 public void drawRoundRect(int x, int y, int width, int height,
1175 int arcWidth, int arcHeight)
1177 int x1 = x + arcWidth, x2 = x + width - arcWidth;
1178 int y1 = y + arcHeight, y2 = y + height - arcHeight;
1179 fillRect (x1, y, x2 - x1, height);
1180 fillRect (x, y1, width, y2 - y1);
1181 fillArc (x, y, arcWidth, arcHeight, 90, 90);
1182 fillArc (x1, y, arcWidth, arcHeight, 0, 90);
1183 fillArc (x2, y2, arcWidth, arcHeight, 270, 90);
1184 fillArc (x, y2, arcWidth, arcHeight, 180, 90);
1187 public void drawString (String str, int x, int y)
1189 drawString (str, (float)x, (float)y);
1192 public void drawString (String str, float x, float y)
1194 GlyphVector gv = font.createGlyphVector (getFontRenderContext(), str);
1195 drawGlyphVector (gv, x, y);
1198 public void drawString (AttributedCharacterIterator ci, int x, int y)
1200 drawString (ci, (float)x, (float)y);
1203 public void drawString (AttributedCharacterIterator ci, float x, float y)
1205 GlyphVector gv = font.createGlyphVector (getFontRenderContext(), ci);
1206 drawGlyphVector (gv, x, y);
1209 public void fillArc (int x, int y, int width, int height,
1210 int startAngle, int arcAngle)
1212 fill (new Arc2D.Double((double)x, (double)y,
1213 (double)width, (double)height,
1214 (double)startAngle, (double)arcAngle,
1215 Arc2D.OPEN));
1218 public void fillOval(int x, int y, int width, int height)
1220 fillArc (x, y, width, height, 0, 360);
1223 public void fillRoundRect (int x, int y, int width, int height,
1224 int arcWidth, int arcHeight)
1226 int x1 = x + arcWidth, x2 = x + width - arcWidth;
1227 int y1 = y + arcHeight, y2 = y + height - arcHeight;
1228 fillRect (x1, y, x2 - x1, height);
1229 fillRect (x, y1, width, y2 - y1);
1230 fillArc (x, y, arcWidth, arcHeight, 90, 90);
1231 fillArc (x1, y, arcWidth, arcHeight, 0, 90);
1232 fillArc (x2, y2, arcWidth, arcHeight, 270, 90);
1233 fillArc (x, y2, arcWidth, arcHeight, 180, 90);
1236 public Font getFont ()
1238 return font;
1241 public FontMetrics getFontMetrics ()
1243 return Toolkit.getDefaultToolkit ().getFontMetrics (font);
1246 public FontMetrics getFontMetrics (Font f)
1248 return Toolkit.getDefaultToolkit ().getFontMetrics (f);
1251 public void setFont (Font f)
1253 if (f.getPeer() instanceof GdkClasspathFontPeer)
1254 font = f;
1255 else
1256 font =
1257 ((ClasspathToolkit)(Toolkit.getDefaultToolkit ()))
1258 .getFont (f.getName(), f.getAttributes ());
1260 if (f != null &&
1261 f.getPeer() instanceof GdkClasspathFontPeer)
1262 cairoSetFont ((GdkClasspathFontPeer) f.getPeer());
1265 public String toString()
1267 throw new java.lang.UnsupportedOperationException ();