aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/xlib/GC.java
blob: da427c9ab9dd73cb4e01d4699e87b98559a30cc7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* Copyright (C) 2000, 2003  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package gnu.gcj.xlib;

import gnu.gcj.RawData;
import java.awt.Rectangle;

/**
 * An X11 graphics context.  Unlike a traditional X11 graphics
 * context, the target drawable is part of the GC state.
 *
 * Implementation notes: There is no need to do coalescing of changes
 * since Xlib will do this for us.  The implementation relies on the
 * Xlib GC cache and will not try to be clever.
 *
 * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
 */
public class GC implements Cloneable
{
  /** Protected constructor, because GC.create(target) should be used instead.
   */
  protected GC(Drawable target)
  {
    this.target = target;
    initStructure(null);
  }

  /** Try to get a suitable GC from the drawable's cache.
   * If there isn't one, create one.
   */
  public Object clone()
  {
    try
      {
	GC gcClone = target.getGCFromCache ();
	if (gcClone==null)
	  {
	    gcClone = (GC) super.clone();
	    gcClone.structure = null;
	  }
	gcClone.initStructure(this);
	gcClone.updateClip(clipRectangles);
	return gcClone;
      } 
    catch (CloneNotSupportedException ex)
      {
	// This should never happen.
	throw new InternalError ();
      }
  }

  private native void initStructure(GC copyFrom);

  public GC create()
  {
    return (GC) clone();
  }
  
  /** Create a GC, or if one is already cached for target, return that.
   * @param target The Drawable for which a GC is needed
   * @return The new or retrieved GC
   */
  static public GC create (Drawable target)
  {
    GC returnValue = target.getGCFromCache ();
    if (returnValue == null)
      returnValue = new GC (target);
    return returnValue;
  }

  public void finalize()
  {
    disposeImpl();
  }

  /** Save this GC in the drawable's cache.
   *  The "real" dispose (disposeImpl) is called when the
   *  drawable is finialized, to free X server resources.
   */
  public void dispose()
  {
    target.putGCInCache (this);
  }

  public synchronized native void disposeImpl();

  public native void setForeground(long pixel);
  public native void setFont(gnu.gcj.xlib.Font font);

  /**
   * Set the clip region for the graphics operations performed by the
   * GC.
   *
   * This is one of the few costly operations of this class.  It is
   * suggested that the clip is only set or changed if really
   * necessary.  Higher level APIs can make such optimizations
   * transparent.
   *
   * @param rectangles the union of these rectangles describe the clip
   * region.
   */
  public void setClipRectangles(Rectangle[] rectangles)
  {
    clipRectangles = rectangles;
    updateClip(clipRectangles);
  }

  public native void drawString(String text, int x, int y);
  public native void drawLine(int x1, int y1, int x2, int y2);
  public native void drawRectangle(int x, int y, int w, int h);

  public native void fillRectangle(int x, int y, int w, int h);
  public native void fillPolygon(int[] xPoints, int[] yPoints, int nPoints,
				 int translateX, int translateY);
  
  public native void drawArc(int x, int y, int w, int h,
			     int startAngle, int arcAngle);
  public native void fillArc(int x, int y, int w, int h,
			     int startAngle, int arcAngle);

  /** 
   * 
   * Clear area using the background pixel or pixmap of the drawable.
   * Note that this operation does not adhere to the current clip.
   */
  public native void clearArea(int x, int y, int w, int h,
			       boolean exposures);


  public native void putImage(XImage image,
			      int srcX, int srcY,
			      int destX, int destY,
			      int width, int height);

  public native void copyArea (Drawable source,
                               int srcX, int srcY,
                               int destX, int destY,
                               int width, int height);
  
  public Drawable getDrawable()
  {
    return target;
  }

  private native void updateClip(Rectangle[] rectangles);

  private Drawable target;
  private RawData structure;
  private Rectangle[] clipRectangles;
}