Merge from mainline.
[official-gcc.git] / libjava / classpath / gnu / java / awt / peer / gtk / GdkGraphics.java
blob50066ff1bd541d834b382c2269bcc2c20c8e0e02
1 /* GdkGraphics.java
2 Copyright (C) 1998, 1999, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 gnu.classpath.Configuration;
43 import java.awt.Color;
44 import java.awt.Dimension;
45 import java.awt.Font;
46 import java.awt.FontMetrics;
47 import java.awt.Graphics;
48 import java.awt.Image;
49 import java.awt.Rectangle;
50 import java.awt.Shape;
51 import java.awt.Toolkit;
52 import java.awt.image.ImageObserver;
53 import java.text.AttributedCharacterIterator;
55 public class GdkGraphics extends Graphics
57 static
59 System.loadLibrary("gtkpeer");
61 initStaticState ();
64 static native void initStaticState();
65 private final int native_state = GtkGenericPeer.getUniqueInteger ();
67 Color color, xorColor;
68 GtkComponentPeer component;
69 Font font = new Font ("Dialog", Font.PLAIN, 12);
70 Rectangle clip;
71 GtkImage image;
73 int xOffset = 0;
74 int yOffset = 0;
76 static final int GDK_COPY = 0, GDK_XOR = 2;
78 native void initState (GtkComponentPeer component);
79 native void initStateUnlocked (GtkComponentPeer component);
80 native void initState (int width, int height);
81 native void initFromImage (GtkImage image);
82 native void nativeCopyState (GdkGraphics g);
84 /**
85 * A cached instance that is used by {@link #create} in order to avoid
86 * massive allocation of graphics contexts.
88 GdkGraphics cached = null;
90 /**
91 * A link to the parent context. This is used in {@link #dispose} to put
92 * this graphics context into the cache.
94 GdkGraphics parent = null;
96 GdkGraphics (GdkGraphics g)
98 parent = g;
99 copyState (g);
102 GdkGraphics (int width, int height)
104 initState (width, height);
105 color = Color.black;
106 clip = new Rectangle (0, 0, width, height);
107 font = new Font ("Dialog", Font.PLAIN, 12);
110 GdkGraphics (GtkImage image)
112 this.image = image;
113 initFromImage (image);
114 color = Color.black;
115 clip = new Rectangle (0, 0,
116 image.getWidth(null), image.getHeight(null));
117 font = new Font ("Dialog", Font.PLAIN, 12);
120 GdkGraphics (GtkComponentPeer component)
122 this.component = component;
123 color = Color.black;
125 if (component.isRealized ())
126 initComponentGraphics ();
127 else
128 connectSignals (component);
131 void initComponentGraphics ()
133 initState (component);
134 color = component.awtComponent.getForeground ();
135 if (color == null)
136 color = Color.BLACK;
137 Dimension d = component.awtComponent.getSize ();
138 clip = new Rectangle (0, 0, d.width, d.height);
141 // called back by native side: realize_cb
142 void initComponentGraphicsUnlocked ()
144 initStateUnlocked (component);
145 color = component.awtComponent.getForeground ();
146 if (color == null)
147 color = Color.BLACK;
148 Dimension d = component.awtComponent.getSize ();
149 clip = new Rectangle (0, 0, d.width, d.height);
152 native void connectSignals (GtkComponentPeer component);
154 public native void clearRect(int x, int y, int width, int height);
156 public void clipRect (int x, int y, int width, int height)
158 if (component != null && ! component.isRealized ())
159 return;
161 clip = clip.intersection (new Rectangle (x, y, width, height));
162 setClipRectangle (clip.x, clip.y, clip.width, clip.height);
165 public native void copyArea(int x, int y, int width, int height,
166 int dx, int dy);
169 * Creates a copy of this GdkGraphics instance. This implementation can
170 * reuse a cached instance to avoid massive instantiation of Graphics objects
171 * during painting.
173 * @return a copy of this graphics context
175 public Graphics create()
177 GdkGraphics copy = cached;
178 if (copy == null)
179 copy = new GdkGraphics(this);
180 else
182 copy.copyState(this);
183 cached = null;
185 return copy;
188 public native void nativeDispose();
191 * Disposes this graphics object. This puts this graphics context into the
192 * cache of its parent graphics if there is one.
194 public void dispose()
196 if (parent != null)
198 parent.cached = this;
199 parent = null;
201 else
202 nativeDispose();
206 * This is called when this object gets finalized by the garbage collector.
207 * In addition to {@link Graphics#finalize()} this calls nativeDispose() to
208 * make sure the native resources are freed before the graphics context is
209 * thrown away.
211 public void finalize()
213 super.finalize();
214 nativeDispose();
217 public boolean drawImage (Image img, int x, int y,
218 Color bgcolor, ImageObserver observer)
220 if (img != null)
221 return drawImage(img, x, y, img.getWidth(null), img.getHeight(null),
222 bgcolor, observer);
223 return false;
226 public boolean drawImage (Image img, int x, int y, ImageObserver observer)
228 return drawImage (img, x, y, null, observer);
231 public boolean drawImage(Image img, int x, int y, int width, int height,
232 Color bgcolor, ImageObserver observer)
234 if (img != null)
236 if (img instanceof GtkImage)
237 return ((GtkImage) img).drawImage(this, x, y, width, height, bgcolor,
238 observer);
239 return (new GtkImage(img.getSource())).drawImage(this, x, y, width,
240 height, bgcolor,
241 observer);
243 return false;
246 public boolean drawImage (Image img, int x, int y, int width, int height,
247 ImageObserver observer)
249 return drawImage (img, x, y, width, height, null, observer);
252 public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
253 int sx1, int sy1, int sx2, int sy2,
254 Color bgcolor, ImageObserver observer)
256 if (img != null)
258 if (img instanceof GtkImage)
259 return ((GtkImage) img).drawImage(this, dx1, dy1, dx2, dy2, sx1, sy1,
260 sx2, sy2, bgcolor, observer);
261 return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1, dx2,
262 dy2, sx1, sy1, sx2,
263 sy2, bgcolor, observer);
265 return false;
268 public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
269 int sx1, int sy1, int sx2, int sy2,
270 ImageObserver observer)
272 return drawImage (img, dx1, dy1, dx2, dy2,
273 sx1, sy1, sx2, sy2,
274 null, observer);
277 public native void drawLine(int x1, int y1, int x2, int y2);
279 public native void drawArc(int x, int y, int width, int height,
280 int startAngle, int arcAngle);
281 public native void fillArc(int x, int y, int width, int height,
282 int startAngle, int arcAngle);
283 public native void drawOval(int x, int y, int width, int height);
284 public native void fillOval(int x, int y, int width, int height);
286 public native void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
287 public native void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
289 public native void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
291 public native void drawRect(int x, int y, int width, int height);
292 public native void fillRect(int x, int y, int width, int height);
294 GdkFontPeer getFontPeer()
296 return (GdkFontPeer) getFont().getPeer();
299 native void drawString (GdkFontPeer f, String str, int x, int y);
300 public void drawString (String str, int x, int y)
302 drawString(getFontPeer(), str, x, y);
305 public void drawString (AttributedCharacterIterator ci, int x, int y)
307 throw new Error ("not implemented");
310 public void drawRoundRect(int x, int y, int width, int height,
311 int arcWidth, int arcHeight)
313 if (arcWidth > width)
314 arcWidth = width;
315 if (arcHeight > height)
316 arcHeight = height;
318 int xx = x + width - arcWidth;
319 int yy = y + height - arcHeight;
321 drawArc (x, y, arcWidth, arcHeight, 90, 90);
322 drawArc (xx, y, arcWidth, arcHeight, 0, 90);
323 drawArc (xx, yy, arcWidth, arcHeight, 270, 90);
324 drawArc (x, yy, arcWidth, arcHeight, 180, 90);
326 int y1 = y + arcHeight / 2;
327 int y2 = y + height - arcHeight / 2;
328 drawLine (x, y1, x, y2);
329 drawLine (x + width, y1, x + width, y2);
331 int x1 = x + arcWidth / 2;
332 int x2 = x + width - arcWidth / 2;
333 drawLine (x1, y, x2, y);
334 drawLine (x1, y + height, x2, y + height);
337 public void fillRoundRect (int x, int y, int width, int height,
338 int arcWidth, int arcHeight)
340 if (arcWidth > width)
341 arcWidth = width;
342 if (arcHeight > height)
343 arcHeight = height;
345 int xx = x + width - arcWidth;
346 int yy = y + height - arcHeight;
348 fillArc (x, y, arcWidth, arcHeight, 90, 90);
349 fillArc (xx, y, arcWidth, arcHeight, 0, 90);
350 fillArc (xx, yy, arcWidth, arcHeight, 270, 90);
351 fillArc (x, yy, arcWidth, arcHeight, 180, 90);
353 fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1);
354 fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height);
357 public Shape getClip ()
359 return getClipBounds ();
362 public Rectangle getClipBounds ()
364 if (clip == null)
365 return null;
366 else
367 return clip.getBounds();
370 public Color getColor ()
372 return color;
375 public Font getFont ()
377 return font;
380 public FontMetrics getFontMetrics (Font font)
382 // Get the font metrics through GtkToolkit to take advantage of
383 // the metrics cache.
384 return Toolkit.getDefaultToolkit().getFontMetrics (font);
387 native void setClipRectangle (int x, int y, int width, int height);
389 public void setClip (int x, int y, int width, int height)
391 if ((component != null && ! component.isRealized ())
392 || clip == null)
393 return;
395 clip.x = x;
396 clip.y = y;
397 clip.width = width;
398 clip.height = height;
400 setClipRectangle (x, y, width, height);
403 public void setClip (Rectangle clip)
405 setClip (clip.x, clip.y, clip.width, clip.height);
408 public void setClip (Shape clip)
410 if (clip == null)
412 // Reset clipping.
413 Dimension d = component.awtComponent.getSize();
414 setClip(new Rectangle (0, 0, d.width, d.height));
416 else
417 setClip(clip.getBounds());
420 private native void setFGColor(int red, int green, int blue);
422 public void setColor (Color c)
424 if (c == null)
425 color = Color.BLACK;
426 else
427 color = c;
429 if (xorColor == null) /* paint mode */
430 setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
431 else /* xor mode */
432 setFGColor (color.getRed () ^ xorColor.getRed (),
433 color.getGreen () ^ xorColor.getGreen (),
434 color.getBlue () ^ xorColor.getBlue ());
437 public void setFont (Font font)
439 if (font != null)
440 this.font = font;
443 native void setFunction (int gdk_func);
445 public void setPaintMode ()
447 xorColor = null;
449 setFunction (GDK_COPY);
450 setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
453 public void setXORMode (Color c)
455 xorColor = c;
457 setFunction (GDK_XOR);
458 setFGColor (color.getRed () ^ xorColor.getRed (),
459 color.getGreen () ^ xorColor.getGreen (),
460 color.getBlue () ^ xorColor.getBlue ());
463 public native void translateNative(int x, int y);
465 public void translate (int x, int y)
467 if (component != null && ! component.isRealized ())
468 return;
470 clip.x -= x;
471 clip.y -= y;
473 translateNative (x, y);
477 * Copies over the state of another GdkGraphics to this instance. This is
478 * used by the {@link #GdkGraphics(GdkGraphics)} constructor and the
479 * {@link #create()} method.
481 * @param g the GdkGraphics object to copy the state from
483 private void copyState(GdkGraphics g)
485 color = g.color;
486 xorColor = g.xorColor;
487 font = g.font;
488 if (font == null)
489 font = new Font ("Dialog", Font.PLAIN, 12);
490 clip = new Rectangle (g.clip);
491 component = g.component;
492 nativeCopyState(g);