OSDN Git Service

Normalise whitespace in GNU Classpath.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / java / awt / peer / qt / QtGraphics.java
1 /* QtGraphics.java --
2    Copyright (C)  2005, 2006  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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.
10
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.
15
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
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.
25
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. */
37
38 package gnu.java.awt.peer.qt;
39
40 import java.awt.AlphaComposite;
41 import java.awt.AWTPermission;
42 import java.awt.BasicStroke;
43 import java.awt.Color;
44 import java.awt.Composite;
45 import java.awt.GradientPaint;
46 import java.awt.GraphicsConfiguration;
47 import java.awt.Font;
48 import java.awt.FontMetrics;
49 import java.awt.Graphics;
50 import java.awt.Graphics2D;
51 import java.awt.Image;
52 import java.awt.RenderingHints;
53 import java.awt.Rectangle;
54 import java.awt.Paint;
55 import java.awt.Polygon;
56 import java.awt.Shape;
57 import java.awt.Stroke;
58 import java.awt.font.FontRenderContext;
59 import java.awt.font.GlyphVector;
60 import java.awt.geom.AffineTransform;
61 import java.awt.geom.Arc2D;
62 import java.awt.geom.Ellipse2D;
63 import java.awt.geom.Line2D;
64 import java.awt.geom.Rectangle2D;
65 import java.awt.geom.RoundRectangle2D;
66 import java.awt.image.BufferedImage;
67 import java.awt.image.BufferedImageOp;
68 import java.awt.image.ImageObserver;
69 import java.awt.image.RenderedImage;
70 import java.awt.image.renderable.RenderableImage;
71
72 import java.text.AttributedCharacterIterator;
73 import java.text.CharacterIterator;
74 import java.util.Map;
75
76 /**
77  * QtGraphics is an abstract implementation of Graphics2D over a QPainter
78  * object. This is to be subclassed for different drawing contexts,
79  * which may have different requirements.
80  */
81 public abstract class QtGraphics extends Graphics2D
82 {
83   /**
84    * Native QPainter pointer.
85    */
86   protected long nativeObject;
87
88   private static final AffineTransform identity = new AffineTransform();
89
90   // Graphics state
91   protected Font font;              // Current font.
92   protected Color color, bgcolor;   // Current color and background color.
93   protected Shape clip;             // Current clipping area.
94   protected Shape initialClip;      // Initial clip bounds
95   protected AffineTransform xform;  // Current transform
96   protected Stroke currentStroke;   // the current stroke
97   protected boolean nativeStroking; // whether we're using Qt's stroking or not
98   protected Composite composite; // current composite operator
99   protected double currentAlpha; // current alpha
100   protected Paint currentPaint;  // current paint
101   protected RenderingHints renderingHints; // the rendering hints.
102
103   /**
104    * Owner Graphics, used by subcontext created by create()
105    * to avoid GC of the original context.
106    */
107   Graphics parent;
108
109   /**
110    * Do-nothing constructor.
111    */
112   QtGraphics()
113   {
114   }
115
116   /**
117    * Copying constructor - used by copy() and subclasses.
118    */
119   QtGraphics(QtGraphics parent)
120   {
121     cloneNativeContext( parent );
122     setFont( parent.getFont() );
123     setAlpha( parent.currentAlpha );
124     setBackground( parent.getBackground() );
125     setColor( parent.getColor() );
126     setClip( (initialClip = parent.getClip()) );
127     setTransform( parent.getTransform() );
128     setStroke( parent.getStroke() );
129     setComposite( parent.getComposite() );
130     setPaint( parent.getPaint() );
131     setRenderingHints( parent.getRenderingHints() );
132   }
133
134   /**
135    * Set up some generic defaults.
136    */
137   protected void setup()
138   {
139     font = new Font ("Dialog", Font.PLAIN, 12);
140     setTransform( identity );
141     setStroke( new BasicStroke() );
142     renderingHints = new RenderingHints( null );
143   }
144
145   public synchronized native void delete();
146
147   public void dispose()
148   {
149   }
150
151   // ********************** etc *******************************
152
153   private void resetClip()
154   {
155     AffineTransform current = getTransform();
156     setTransform( identity );
157     setClip( initialClip );
158     setTransform( current );
159   }
160
161   protected native void initImage(QtImage image);
162   protected native void initVolatileImage(QtVolatileImage image);
163
164   // Creates a new native QPainter object on the same context.
165   private native void cloneNativeContext( QtGraphics parent );
166   private native void setColor(int r, int g, int b, int a);
167   private native void drawNative( QPainterPath p );
168   private native void fillNative( QPainterPath p );
169   private native void setClipNative( QPainterPath p );
170   private native void setClipRectNative( int x, int y, int w, int h );
171   private native void intersectClipNative( QPainterPath p );
172   private native void intersectClipRectNative( int x, int y, int w, int h );
173   private native void setQtTransform(QMatrix m);
174   private native void setNativeStroke(QPen p);
175   private native void setNativeComposite(int alphaMode);
176   private native void drawStringNative(String string, double x, double y);
177   private native void setLinearGradient(int r1, int g1, int b1,
178                                         int r2, int g2, int b2,
179                                         double x1, double y1,
180                                         double x2, double y2, boolean cyclic);
181   private native void setAlphaNative(double alpha);
182   private native void setFontNative(QtFontPeer font);
183   private native QPainterPath getClipNative();
184
185   void setAlpha(double alpha)
186   {
187     currentAlpha = alpha;
188     setAlphaNative(currentAlpha);
189   }
190
191   // ************ Public methods *********************
192
193   /**
194    * Context-sensitive methods are declared abstract.
195    */
196   public abstract Graphics create();
197
198   public abstract void copyArea(int x, int y, int width, int height,
199                                 int dx, int dy);
200
201   public abstract GraphicsConfiguration getDeviceConfiguration();
202
203
204   public Color getColor()
205   {
206     return new Color(color.getRed(), color.getGreen(), color.getBlue());
207   }
208
209   public void setColor(Color c)
210   {
211     if( c == null )
212       c = Color.white;
213     this.color = c;
214     int alpha = (int)(c.getAlpha() * currentAlpha);
215     setColor(c.getRed(), c.getGreen(), c.getBlue(), alpha);
216   }
217
218   public void setBackground(Color color)
219   {
220     bgcolor = new Color(color.getRed(), color.getGreen(), color.getBlue());
221   }
222
223   public Color getBackground()
224   {
225     return new Color(bgcolor.getRed(), bgcolor.getGreen(), bgcolor.getBlue());
226   }
227
228   public void setPaintMode()
229   {
230   }
231
232   public void setXORMode(Color color)
233   {
234     // FIXME
235   }
236
237   public boolean hit(Rectangle rect, Shape s, boolean onStroke)
238   {
239     if( onStroke )
240       {
241         Shape stroked = currentStroke.createStrokedShape( s );
242         return stroked.intersects( (double)rect.x, (double)rect.y,
243                                    (double)rect.width, (double)rect.height );
244       }
245     return s.intersects( (double)rect.x, (double)rect.y,
246                          (double)rect.width, (double)rect.height );
247   }
248
249   // ******************* Font ***********************
250   public Font getFont()
251   {
252     return font;
253   }
254
255   public void setFont(Font font)
256   {
257     if( font == null )
258       return;
259     this.font = font;
260     if(font.getPeer() != null && font.getPeer() instanceof QtFontPeer)
261       setFontNative( (QtFontPeer)font.getPeer() );
262   }
263
264   public FontMetrics getFontMetrics(Font font)
265   {
266     return new QtFontMetrics(font, this);
267   }
268
269   // ***************** Clipping *********************
270
271   /**
272    * Intersects the current clip with the shape
273    */
274   public void clip(Shape s)
275   {
276     intersectClipNative( new QPainterPath( s ) );
277   }
278
279   public void clipRect(int x, int y, int width, int height)
280   {
281     intersectClipRectNative( x, y, width, height );
282   }
283
284   public void setClip(int x, int y, int width, int height)
285   {
286     setClipRectNative( x, y, width, height );
287   }
288
289   public Shape getClip()
290   {
291     return getClipNative().getPath();
292   }
293
294   public native Rectangle getClipBounds();
295
296   /**
297    * Sets the clip
298    */
299   public void setClip(Shape clip)
300   {
301     if (clip == null)
302       resetClip();
303     else
304       setClipNative(new QPainterPath( clip ));
305   }
306
307   // ***************** Drawing primitives *********************
308
309   public void draw(Shape s)
310   {
311     if( nativeStroking )
312       drawNative( new QPainterPath(s) );
313     else
314       fillNative( new QPainterPath( currentStroke.createStrokedShape( s ) ) );
315   }
316
317   public void fill(Shape s)
318   {
319     fillNative( new QPainterPath(s) );
320   }
321
322   public void drawLine(int x1, int y1, int x2, int y2)
323   {
324     if( nativeStroking )
325       drawNative( new QPainterPath((double)x1, (double)y1, (double)x2, (double)y2, true) );
326     else
327       draw( new Line2D.Double((double)x1, (double)y1, (double)x2, (double)y2) );
328   }
329
330   public void drawRect(int x, int y, int width, int height)
331   {
332     if( nativeStroking )
333       drawNative( new QPainterPath((double)x, (double)y,
334                                    (double)width, (double)height) );
335     else
336       fillNative( new QPainterPath
337                   ( currentStroke.createStrokedShape
338                     (new Rectangle2D.Double
339                      ((double)x, (double)y,
340                       (double)width, (double)height) ) ) );
341   }
342
343   public void fillRect(int x, int y, int width, int height)
344   {
345     fillNative( new QPainterPath( x, y, width, height ) );
346   }
347
348   public void clearRect(int x, int y, int width, int height)
349   {
350     Color c = color;
351     setColor( bgcolor ); // FIXME
352     fillRect( x, y, width, height );
353     setColor( c );
354   }
355
356   public void drawRoundRect(int x, int y, int width, int height,
357                             int arcWidth, int arcHeight)
358   {
359     draw( new RoundRectangle2D.Double(x, y, width, height,
360                                       arcWidth, arcHeight) );
361   }
362
363   public void fillRoundRect(int x, int y, int width, int height,
364                             int arcWidth, int arcHeight)
365   {
366     fill( new RoundRectangle2D.Double(x, y, width, height,
367                                       arcWidth, arcHeight) );
368   }
369
370   public void drawOval(int x, int y, int width, int height)
371   {
372     draw( new Ellipse2D.Double((double)x, (double)y,
373                                (double)width, (double)height) );
374   }
375
376   public void fillOval(int x, int y, int width, int height)
377   {
378     fill( new Ellipse2D.Double(x, y, width, height) );
379   }
380
381   public void drawArc(int x, int y, int width, int height,
382                       int arcStart, int arcAngle)
383   {
384     draw( new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
385                            Arc2D.OPEN) );
386   }
387
388   public void fillArc(int x, int y, int width, int height,
389                       int arcStart, int arcAngle)
390   {
391     fill( new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
392                            Arc2D.CHORD) );
393   }
394
395   public void drawPolyline(int xPoints[], int yPoints[], int npoints)
396   {
397     for( int i = 0; i < npoints - 1; i++)
398       drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]);
399   }
400
401   public void drawPolygon(int xPoints[], int yPoints[], int npoints)
402   {
403     draw( new Polygon(xPoints, yPoints, npoints) );
404   }
405
406   public void fillPolygon(int xPoints[], int yPoints[], int npoints)
407   {
408     fill( new Polygon(xPoints, yPoints, npoints) );
409   }
410
411   public native void fill3DRect(int x, int y, int width, int height, boolean raised);
412
413   public native void draw3DRect(int x, int y, int width, int height, boolean raised);
414
415   // *********************** Text rendering *************************
416
417   public void drawString(String string, int x, int y)
418   {
419     drawStringNative(string, (double)x, (double)y);
420   }
421
422   public void drawString(String string, float x, float y)
423   {
424     drawStringNative(string, (double)x, (double)y);
425   }
426
427   public void drawString (AttributedCharacterIterator ci, int x, int y)
428   {
429     // FIXME - to something more correct ?
430     String s = "";
431     for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
432       s += c;
433     drawString(s, x, y);
434   }
435
436   public void drawString(AttributedCharacterIterator ci,
437                          float x, float y)
438   {
439     // FIXME - to something more correct ?
440     String s = "";
441     for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
442       s += c;
443     drawString(s, x, y);
444   }
445
446   public void drawGlyphVector(GlyphVector v, float x, float y)
447   {
448     throw new RuntimeException("Not implemented");
449   }
450
451   // ******************* Image drawing ******************************
452   public boolean drawImage(Image image,
453                            AffineTransform Tx,
454                            ImageObserver obs)
455   {
456     if (image instanceof QtImage)
457       return ((QtImage)image).drawImage(this, new QMatrix( Tx ), obs);
458
459     return (new QtImage(image.getSource())).drawImage(this,
460                                                       new QMatrix( Tx ),
461                                                       obs);
462   }
463
464   public boolean drawImage(Image image, int x, int y, Color bgcolor,
465                            ImageObserver observer)
466   {
467     if (image instanceof QtImage)
468       return ((QtImage)image).drawImage (this, x, y, bgcolor, observer);
469     return (new QtImage(image.getSource())).drawImage (this, x, y,
470                                                        bgcolor, observer);
471   }
472
473   public boolean drawImage(Image image,
474                            int dx1, int dy1, int dx2, int dy2,
475                            int sx1, int sy1, int sx2, int sy2,
476                            Color bgcolor, ImageObserver observer)
477   {
478     if (image instanceof QtImage)
479       return ((QtImage)image).drawImage(this, dx1, dy1, dx2, dy2,
480                                         sx1, sy1, sx2, sy2, bgcolor, observer);
481
482     return (new QtImage(image.getSource())).drawImage(this, dx1, dy1,
483                                                       dx2, dy2,
484                                                       sx1, sy1, sx2, sy2,
485                                                       bgcolor, observer);
486   }
487
488   public boolean drawImage(Image image, int x, int y,
489                            int width, int height, Color bgcolor,
490                            ImageObserver observer)
491   {
492     if (image instanceof QtImage)
493       return ((QtImage)image).drawImage (this, x, y, width, height,
494                                          bgcolor, observer);
495     return (new QtImage(image.getSource())).drawImage (this, x, y,
496                                                        width, height,
497                                                        bgcolor, observer);
498   }
499
500   public boolean drawImage(Image image, int x, int y, int width, int height,
501                            ImageObserver observer)
502   {
503     return drawImage(image, x, y, width, height, null, observer);
504   }
505
506   public boolean drawImage(Image image, int x, int y, ImageObserver observer)
507   {
508     return drawImage(image, x, y, null, observer);
509   }
510
511   public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
512   {
513     return drawImage(image, dx1, dy1, dx2, dy2,
514                      sx1, sy1, sx2, sy2, null, observer);
515   }
516
517   // *********************** Transform methods *************************
518   public AffineTransform getTransform()
519   {
520     return new AffineTransform( xform );
521   }
522
523   public void setTransform(AffineTransform Tx)
524   {
525     xform = new AffineTransform( Tx );
526     setQtTransform( new QMatrix( xform ) );
527   }
528
529   public void rotate(double theta)
530   {
531     xform.rotate( theta );
532     setQtTransform( new QMatrix( xform ) );
533   }
534
535   public void rotate(double theta, double x, double y)
536   {
537     xform.rotate(theta, x, y);
538     setQtTransform( new QMatrix( xform ) );
539   }
540
541   public void scale(double sx, double sy)
542   {
543     xform.scale(sx, sy);
544     setQtTransform( new QMatrix( xform ) );
545   }
546
547   public void shear(double shx, double shy)
548   {
549     xform.shear(shx, shy);
550     setQtTransform( new QMatrix( xform ) );
551   }
552
553   public void transform(AffineTransform Tx)
554   {
555     xform.concatenate( Tx );
556     setQtTransform( new QMatrix( xform ) );
557   }
558
559   public void translate(double tx, double ty)
560   {
561     xform.translate( tx, ty );
562     setQtTransform( new QMatrix( xform ) );
563   }
564
565   public void translate(int x, int y)
566   {
567     translate((double)x, (double)y);
568   }
569
570   // *************** Stroking, Filling, Compositing *****************
571   public void setStroke(Stroke s)
572   {
573     try  // ..to convert the stroke into a native one.
574       {
575         QPen pen = new QPen( s );
576         nativeStroking = true;
577         setNativeStroke( pen );
578         setColor( color );
579       }
580     catch (IllegalArgumentException e)
581       {
582         nativeStroking = false;
583       }
584     currentStroke = s;
585   }
586
587   public Stroke getStroke()
588   { // FIXME: return copy?
589     return currentStroke;
590   }
591
592   public void setComposite(Composite comp)
593   {
594     if( comp == null)
595       {
596         setNativeComposite( AlphaComposite.SRC_OVER );
597         return;
598       }
599
600     if( comp instanceof AlphaComposite )
601       {
602         if( ((AlphaComposite)comp).getRule() != AlphaComposite.XOR )
603           setAlpha( ((AlphaComposite)comp).getAlpha() );
604         setNativeComposite( ((AlphaComposite)comp).getRule() );
605         composite = comp;
606       }
607     else
608       {
609         // FIXME: this check is only required "if this Graphics2D
610         // context is drawing to a Component on the display screen".
611         SecurityManager sm = System.getSecurityManager();
612         if (sm != null)
613           sm.checkPermission(new AWTPermission("readDisplayPixels"));
614
615         throw new UnsupportedOperationException("We don't support custom"+
616                                                 " composites yet.");
617       }
618   }
619
620   public Composite getComposite()
621   {
622     return composite;
623   }
624
625   public void setPaint(Paint p)
626   {
627     if( p == null )
628       return;
629
630     // FIXME
631     currentPaint = p;
632     if( p instanceof GradientPaint )
633       {
634         GradientPaint lg = (GradientPaint)p;
635         setLinearGradient(lg.getColor1().getRed(), lg.getColor1().getGreen(),
636                           lg.getColor1().getBlue(), lg.getColor2().getRed(),
637                           lg.getColor2().getGreen(), lg.getColor2().getBlue(),
638                           lg.getPoint1().getX(), lg.getPoint1().getY(),
639                           lg.getPoint2().getX(), lg.getPoint2().getY(),
640                           lg.isCyclic() );
641         return;
642       }
643     if( p instanceof Color )
644       {
645         setColor((Color) p);
646         return;
647       }
648     throw new UnsupportedOperationException("We don't support custom"+
649                                             " paints yet.");
650   }
651
652   public Paint getPaint()
653   {
654     // FIXME
655     return currentPaint;
656   }
657
658   // ********************** Rendering Hints *************************
659
660   public void addRenderingHints(Map hints)
661   {
662     renderingHints.putAll( hints );
663   }
664
665   public Object getRenderingHint(RenderingHints.Key hintKey)
666   {
667     return renderingHints.get( hintKey );
668   }
669
670   public RenderingHints getRenderingHints()
671   {
672     return (RenderingHints) renderingHints.clone();
673   }
674
675   public void setRenderingHints(Map<?,?> hints)
676   {
677     renderingHints = new RenderingHints( null );
678     renderingHints.putAll(hints);
679     updateRenderingHints();
680   }
681
682   public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
683   {
684     renderingHints.put( hintKey, hintValue );
685     updateRenderingHints();
686   }
687
688   private void updateRenderingHints()
689   {
690     // FIXME - update native settings.
691   }
692
693   ////////////////////////////// unimplemented /////////////////////
694
695   public FontRenderContext getFontRenderContext()
696   {
697     throw new UnsupportedOperationException("Not implemented yet");
698   }
699
700   public void drawRenderableImage(RenderableImage image, AffineTransform xform)
701   {
702     throw new UnsupportedOperationException("Not implemented yet");
703   }
704
705   public void drawRenderedImage(RenderedImage image, AffineTransform xform)
706   {
707     throw new UnsupportedOperationException("Not implemented yet");
708   }
709
710   public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
711   {
712     throw new UnsupportedOperationException("Not implemented yet");
713   }
714 }