2 Copyright (C) 2005, 2006 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)
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., 51 Franklin Street, Fifth Floor, Boston, MA
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
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. */
38 package gnu.java.awt.peer.qt;
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;
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;
72 import java.text.AttributedCharacterIterator;
73 import java.text.CharacterIterator;
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.
81 public abstract class QtGraphics extends Graphics2D
84 * Native QPainter pointer.
86 protected long nativeObject;
88 private static final AffineTransform identity = new AffineTransform();
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.
104 * Owner Graphics, used by subcontext created by create()
105 * to avoid GC of the original context.
110 * Do-nothing constructor.
117 * Copying constructor - used by copy() and subclasses.
119 QtGraphics(QtGraphics parent)
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() );
135 * Set up some generic defaults.
137 protected void setup()
139 font = new Font ("Dialog", Font.PLAIN, 12);
140 setTransform( identity );
141 setStroke( new BasicStroke() );
142 renderingHints = new RenderingHints( null );
145 public synchronized native void delete();
147 public void dispose()
151 // ********************** etc *******************************
153 private void resetClip()
155 AffineTransform current = getTransform();
156 setTransform( identity );
157 setClip( initialClip );
158 setTransform( current );
161 protected native void initImage(QtImage image);
162 protected native void initVolatileImage(QtVolatileImage image);
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();
185 void setAlpha(double alpha)
187 currentAlpha = alpha;
188 setAlphaNative(currentAlpha);
191 // ************ Public methods *********************
194 * Context-sensitive methods are declared abstract.
196 public abstract Graphics create();
198 public abstract void copyArea(int x, int y, int width, int height,
201 public abstract GraphicsConfiguration getDeviceConfiguration();
204 public Color getColor()
206 return new Color(color.getRed(), color.getGreen(), color.getBlue());
209 public void setColor(Color c)
214 int alpha = (int)(c.getAlpha() * currentAlpha);
215 setColor(c.getRed(), c.getGreen(), c.getBlue(), alpha);
218 public void setBackground(Color color)
220 bgcolor = new Color(color.getRed(), color.getGreen(), color.getBlue());
223 public Color getBackground()
225 return new Color(bgcolor.getRed(), bgcolor.getGreen(), bgcolor.getBlue());
228 public void setPaintMode()
232 public void setXORMode(Color color)
237 public boolean hit(Rectangle rect, Shape s, boolean onStroke)
241 Shape stroked = currentStroke.createStrokedShape( s );
242 return stroked.intersects( (double)rect.x, (double)rect.y,
243 (double)rect.width, (double)rect.height );
245 return s.intersects( (double)rect.x, (double)rect.y,
246 (double)rect.width, (double)rect.height );
249 // ******************* Font ***********************
250 public Font getFont()
255 public void setFont(Font font)
260 if(font.getPeer() != null && font.getPeer() instanceof QtFontPeer)
261 setFontNative( (QtFontPeer)font.getPeer() );
264 public FontMetrics getFontMetrics(Font font)
266 return new QtFontMetrics(font, this);
269 // ***************** Clipping *********************
272 * Intersects the current clip with the shape
274 public void clip(Shape s)
276 intersectClipNative( new QPainterPath( s ) );
279 public void clipRect(int x, int y, int width, int height)
281 intersectClipRectNative( x, y, width, height );
284 public void setClip(int x, int y, int width, int height)
286 setClipRectNative( x, y, width, height );
289 public Shape getClip()
291 return getClipNative().getPath();
294 public native Rectangle getClipBounds();
299 public void setClip(Shape clip)
304 setClipNative(new QPainterPath( clip ));
307 // ***************** Drawing primitives *********************
309 public void draw(Shape s)
312 drawNative( new QPainterPath(s) );
314 fillNative( new QPainterPath( currentStroke.createStrokedShape( s ) ) );
317 public void fill(Shape s)
319 fillNative( new QPainterPath(s) );
322 public void drawLine(int x1, int y1, int x2, int y2)
325 drawNative( new QPainterPath((double)x1, (double)y1, (double)x2, (double)y2, true) );
327 draw( new Line2D.Double((double)x1, (double)y1, (double)x2, (double)y2) );
330 public void drawRect(int x, int y, int width, int height)
333 drawNative( new QPainterPath((double)x, (double)y,
334 (double)width, (double)height) );
336 fillNative( new QPainterPath
337 ( currentStroke.createStrokedShape
338 (new Rectangle2D.Double
339 ((double)x, (double)y,
340 (double)width, (double)height) ) ) );
343 public void fillRect(int x, int y, int width, int height)
345 fillNative( new QPainterPath( x, y, width, height ) );
348 public void clearRect(int x, int y, int width, int height)
351 setColor( bgcolor ); // FIXME
352 fillRect( x, y, width, height );
356 public void drawRoundRect(int x, int y, int width, int height,
357 int arcWidth, int arcHeight)
359 draw( new RoundRectangle2D.Double(x, y, width, height,
360 arcWidth, arcHeight) );
363 public void fillRoundRect(int x, int y, int width, int height,
364 int arcWidth, int arcHeight)
366 fill( new RoundRectangle2D.Double(x, y, width, height,
367 arcWidth, arcHeight) );
370 public void drawOval(int x, int y, int width, int height)
372 draw( new Ellipse2D.Double((double)x, (double)y,
373 (double)width, (double)height) );
376 public void fillOval(int x, int y, int width, int height)
378 fill( new Ellipse2D.Double(x, y, width, height) );
381 public void drawArc(int x, int y, int width, int height,
382 int arcStart, int arcAngle)
384 draw( new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
388 public void fillArc(int x, int y, int width, int height,
389 int arcStart, int arcAngle)
391 fill( new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
395 public void drawPolyline(int xPoints[], int yPoints[], int npoints)
397 for( int i = 0; i < npoints - 1; i++)
398 drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]);
401 public void drawPolygon(int xPoints[], int yPoints[], int npoints)
403 draw( new Polygon(xPoints, yPoints, npoints) );
406 public void fillPolygon(int xPoints[], int yPoints[], int npoints)
408 fill( new Polygon(xPoints, yPoints, npoints) );
411 public native void fill3DRect(int x, int y, int width, int height, boolean raised);
413 public native void draw3DRect(int x, int y, int width, int height, boolean raised);
415 // *********************** Text rendering *************************
417 public void drawString(String string, int x, int y)
419 drawStringNative(string, (double)x, (double)y);
422 public void drawString(String string, float x, float y)
424 drawStringNative(string, (double)x, (double)y);
427 public void drawString (AttributedCharacterIterator ci, int x, int y)
429 // FIXME - to something more correct ?
431 for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
436 public void drawString(AttributedCharacterIterator ci,
439 // FIXME - to something more correct ?
441 for(char c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
446 public void drawGlyphVector(GlyphVector v, float x, float y)
448 throw new RuntimeException("Not implemented");
451 // ******************* Image drawing ******************************
452 public boolean drawImage(Image image,
456 if (image instanceof QtImage)
457 return ((QtImage)image).drawImage(this, new QMatrix( Tx ), obs);
459 return (new QtImage(image.getSource())).drawImage(this,
464 public boolean drawImage(Image image, int x, int y, Color bgcolor,
465 ImageObserver observer)
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,
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)
478 if (image instanceof QtImage)
479 return ((QtImage)image).drawImage(this, dx1, dy1, dx2, dy2,
480 sx1, sy1, sx2, sy2, bgcolor, observer);
482 return (new QtImage(image.getSource())).drawImage(this, dx1, dy1,
488 public boolean drawImage(Image image, int x, int y,
489 int width, int height, Color bgcolor,
490 ImageObserver observer)
492 if (image instanceof QtImage)
493 return ((QtImage)image).drawImage (this, x, y, width, height,
495 return (new QtImage(image.getSource())).drawImage (this, x, y,
500 public boolean drawImage(Image image, int x, int y, int width, int height,
501 ImageObserver observer)
503 return drawImage(image, x, y, width, height, null, observer);
506 public boolean drawImage(Image image, int x, int y, ImageObserver observer)
508 return drawImage(image, x, y, null, observer);
511 public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
513 return drawImage(image, dx1, dy1, dx2, dy2,
514 sx1, sy1, sx2, sy2, null, observer);
517 // *********************** Transform methods *************************
518 public AffineTransform getTransform()
520 return new AffineTransform( xform );
523 public void setTransform(AffineTransform Tx)
525 xform = new AffineTransform( Tx );
526 setQtTransform( new QMatrix( xform ) );
529 public void rotate(double theta)
531 xform.rotate( theta );
532 setQtTransform( new QMatrix( xform ) );
535 public void rotate(double theta, double x, double y)
537 xform.rotate(theta, x, y);
538 setQtTransform( new QMatrix( xform ) );
541 public void scale(double sx, double sy)
544 setQtTransform( new QMatrix( xform ) );
547 public void shear(double shx, double shy)
549 xform.shear(shx, shy);
550 setQtTransform( new QMatrix( xform ) );
553 public void transform(AffineTransform Tx)
555 xform.concatenate( Tx );
556 setQtTransform( new QMatrix( xform ) );
559 public void translate(double tx, double ty)
561 xform.translate( tx, ty );
562 setQtTransform( new QMatrix( xform ) );
565 public void translate(int x, int y)
567 translate((double)x, (double)y);
570 // *************** Stroking, Filling, Compositing *****************
571 public void setStroke(Stroke s)
573 try // ..to convert the stroke into a native one.
575 QPen pen = new QPen( s );
576 nativeStroking = true;
577 setNativeStroke( pen );
580 catch (IllegalArgumentException e)
582 nativeStroking = false;
587 public Stroke getStroke()
588 { // FIXME: return copy?
589 return currentStroke;
592 public void setComposite(Composite comp)
596 setNativeComposite( AlphaComposite.SRC_OVER );
600 if( comp instanceof AlphaComposite )
602 if( ((AlphaComposite)comp).getRule() != AlphaComposite.XOR )
603 setAlpha( ((AlphaComposite)comp).getAlpha() );
604 setNativeComposite( ((AlphaComposite)comp).getRule() );
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();
613 sm.checkPermission(new AWTPermission("readDisplayPixels"));
615 throw new UnsupportedOperationException("We don't support custom"+
620 public Composite getComposite()
625 public void setPaint(Paint p)
632 if( p instanceof GradientPaint )
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(),
643 if( p instanceof Color )
648 throw new UnsupportedOperationException("We don't support custom"+
652 public Paint getPaint()
658 // ********************** Rendering Hints *************************
660 public void addRenderingHints(Map hints)
662 renderingHints.putAll( hints );
665 public Object getRenderingHint(RenderingHints.Key hintKey)
667 return renderingHints.get( hintKey );
670 public RenderingHints getRenderingHints()
672 return (RenderingHints) renderingHints.clone();
675 public void setRenderingHints(Map<?,?> hints)
677 renderingHints = new RenderingHints( null );
678 renderingHints.putAll(hints);
679 updateRenderingHints();
682 public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
684 renderingHints.put( hintKey, hintValue );
685 updateRenderingHints();
688 private void updateRenderingHints()
690 // FIXME - update native settings.
693 ////////////////////////////// unimplemented /////////////////////
695 public FontRenderContext getFontRenderContext()
697 throw new UnsupportedOperationException("Not implemented yet");
700 public void drawRenderableImage(RenderableImage image, AffineTransform xform)
702 throw new UnsupportedOperationException("Not implemented yet");
705 public void drawRenderedImage(RenderedImage image, AffineTransform xform)
707 throw new UnsupportedOperationException("Not implemented yet");
710 public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
712 throw new UnsupportedOperationException("Not implemented yet");