1 | /* Copyright (C) 2000, 2003 Free Software Foundation
|
---|
2 |
|
---|
3 | This file is part of libgcj.
|
---|
4 |
|
---|
5 | This software is copyrighted work licensed under the terms of the
|
---|
6 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
---|
7 | details. */
|
---|
8 |
|
---|
9 | package gnu.awt.xlib;
|
---|
10 |
|
---|
11 | import java.awt.*;
|
---|
12 | import java.awt.image.WritableRaster;
|
---|
13 | import java.awt.image.Raster;
|
---|
14 | import java.awt.image.DataBuffer;
|
---|
15 | import java.awt.image.ColorModel;
|
---|
16 | import java.awt.image.ImageObserver;
|
---|
17 | import java.awt.image.BufferedImage;
|
---|
18 | import gnu.gcj.xlib.GC;
|
---|
19 | import gnu.gcj.xlib.XImage;
|
---|
20 | import gnu.gcj.xlib.Drawable;
|
---|
21 | import gnu.gcj.xlib.Window;
|
---|
22 | import gnu.gcj.xlib.Drawable;
|
---|
23 | import gnu.gcj.xlib.Visual;
|
---|
24 | import gnu.awt.j2d.DirectRasterGraphics;
|
---|
25 | import gnu.awt.j2d.MappedRaster;
|
---|
26 |
|
---|
27 | public class XGraphics implements Cloneable, DirectRasterGraphics
|
---|
28 | {
|
---|
29 | static class XRaster extends MappedRaster
|
---|
30 | {
|
---|
31 | XImage ximage;
|
---|
32 |
|
---|
33 | public XRaster(WritableRaster raster, XImage ximage, ColorModel cm)
|
---|
34 | {
|
---|
35 | super(raster, cm);
|
---|
36 | this.ximage = ximage;
|
---|
37 | }
|
---|
38 | }
|
---|
39 |
|
---|
40 | GC context;
|
---|
41 | XGraphicsConfiguration config;
|
---|
42 | Rectangle clipBounds;
|
---|
43 |
|
---|
44 | XFontMetrics metrics;
|
---|
45 |
|
---|
46 |
|
---|
47 | public Object clone()
|
---|
48 | {
|
---|
49 | XGraphics gfxCopy = (XGraphics) super.clone();
|
---|
50 | gfxCopy.context = context.create();
|
---|
51 |
|
---|
52 | return gfxCopy;
|
---|
53 | }
|
---|
54 |
|
---|
55 | public void dispose()
|
---|
56 | {
|
---|
57 | GC lContext = context;
|
---|
58 | context = null;
|
---|
59 | config = null;
|
---|
60 | clipBounds = null;
|
---|
61 |
|
---|
62 | if (lContext != null)
|
---|
63 | {
|
---|
64 | lContext.dispose();
|
---|
65 | }
|
---|
66 | }
|
---|
67 |
|
---|
68 | public XGraphics(Drawable drawable, XGraphicsConfiguration config)
|
---|
69 | {
|
---|
70 | context = new GC(drawable);
|
---|
71 | this.config = config;
|
---|
72 | }
|
---|
73 |
|
---|
74 | public void setColor(Color color)
|
---|
75 | {
|
---|
76 | context.setForeground(config.getPixel(color));
|
---|
77 | }
|
---|
78 |
|
---|
79 | public void setPaintMode()
|
---|
80 | {
|
---|
81 | throw new UnsupportedOperationException("not implemented");
|
---|
82 | }
|
---|
83 |
|
---|
84 | public void setXORMode(Color c1)
|
---|
85 | {
|
---|
86 | throw new UnsupportedOperationException("not implemented");
|
---|
87 | }
|
---|
88 |
|
---|
89 | public void setFont(Font font)
|
---|
90 | {
|
---|
91 | if ((metrics != null) && font.equals(metrics.getFont())) return;
|
---|
92 |
|
---|
93 | metrics = config.getXFontMetrics(font);
|
---|
94 | context.setFont(metrics.xfont);
|
---|
95 | }
|
---|
96 |
|
---|
97 | public FontMetrics getFontMetrics(Font font)
|
---|
98 | {
|
---|
99 | if ((metrics != null) && font.equals(metrics.getFont()))
|
---|
100 | return metrics;
|
---|
101 |
|
---|
102 | return config.getXFontMetrics(font);
|
---|
103 | }
|
---|
104 |
|
---|
105 | public void setClip(int x, int y, int width, int height)
|
---|
106 | {
|
---|
107 | Rectangle[] rects = { new Rectangle(x, y, width, height) };
|
---|
108 | context.setClipRectangles(rects);
|
---|
109 | }
|
---|
110 |
|
---|
111 | public void setClip(Shape clip)
|
---|
112 | {
|
---|
113 | /* TODO: create a special RectangleUnion shape that can be
|
---|
114 | used to draw advantage of the GCs ability to set multiple
|
---|
115 | rectangles.
|
---|
116 | */
|
---|
117 |
|
---|
118 | /* FIXME: creating all these objects is wasteful and can be
|
---|
119 | costly in the long run, since this code is run at every
|
---|
120 | expose. */
|
---|
121 | Rectangle newClipBounds = clip.getBounds();
|
---|
122 |
|
---|
123 | if ((clipBounds != null) && !clipBounds.contains(newClipBounds))
|
---|
124 | {
|
---|
125 | System.err.println("warning: old clip ("+ clipBounds +") does " +
|
---|
126 | "not fully contain new clip (" +
|
---|
127 | newClipBounds + ")");
|
---|
128 | }
|
---|
129 | clipBounds = newClipBounds;
|
---|
130 | Rectangle[] rects = { clipBounds };
|
---|
131 | context.setClipRectangles(rects);
|
---|
132 | }
|
---|
133 |
|
---|
134 | public void copyArea(int x, int y, int width, int height, int
|
---|
135 | dx, int dy)
|
---|
136 | {
|
---|
137 | throw new UnsupportedOperationException("not implemented");
|
---|
138 | }
|
---|
139 |
|
---|
140 | public void drawLine(int x1, int y1, int x2, int y2)
|
---|
141 | {
|
---|
142 | context.drawLine(x1, y1, x2, y2);
|
---|
143 | }
|
---|
144 |
|
---|
145 | public void drawRect(int x, int y, int width, int height)
|
---|
146 | {
|
---|
147 | throw new UnsupportedOperationException("not implemented yet");
|
---|
148 | }
|
---|
149 |
|
---|
150 | public void fillRect(int x, int y, int width, int height)
|
---|
151 | {
|
---|
152 | context.fillRectangle(x, y, width, height);
|
---|
153 | }
|
---|
154 |
|
---|
155 | public void drawArc(int x, int y, int width, int height, int
|
---|
156 | startAngle, int arcAngle)
|
---|
157 | {
|
---|
158 | throw new UnsupportedOperationException("not implemented");
|
---|
159 | }
|
---|
160 |
|
---|
161 | public void fillArc(int x, int y, int width, int height, int
|
---|
162 | startAngle, int arcAngle)
|
---|
163 | {
|
---|
164 | throw new UnsupportedOperationException("not implemented");
|
---|
165 | }
|
---|
166 |
|
---|
167 | public void drawPolyline(int[] xPoints, int[] yPoints, int
|
---|
168 | nPoints)
|
---|
169 | {
|
---|
170 | throw new UnsupportedOperationException("not implemented");
|
---|
171 | }
|
---|
172 |
|
---|
173 | public void drawPolygon(int[] xPoints, int[] yPoints, int
|
---|
174 | nPoints)
|
---|
175 | {
|
---|
176 | throw new UnsupportedOperationException("not implemented");
|
---|
177 | }
|
---|
178 |
|
---|
179 | public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints,
|
---|
180 | int translateX, int translateY)
|
---|
181 | {
|
---|
182 | context.fillPolygon(xPoints, yPoints, nPoints, translateX, translateY);
|
---|
183 | }
|
---|
184 |
|
---|
185 | public void drawString(String str, int x, int y)
|
---|
186 | {
|
---|
187 | context.drawString(str, x, y);
|
---|
188 | }
|
---|
189 |
|
---|
190 | public boolean drawImage(Image img, int x, int y,
|
---|
191 | ImageObserver observer)
|
---|
192 | {
|
---|
193 | if (clipBounds == null)
|
---|
194 | return false; // ***FIXME***
|
---|
195 |
|
---|
196 | if (!(img instanceof BufferedImage))
|
---|
197 | {
|
---|
198 | throw new AWTError("unknown image class");
|
---|
199 | }
|
---|
200 |
|
---|
201 | BufferedImage bimg = (BufferedImage) img;
|
---|
202 |
|
---|
203 | XImage ximg = (XImage) bimg.getProperty("gnu.gcj.xlib.XImage");
|
---|
204 | if (ximg == null)
|
---|
205 | {
|
---|
206 | System.err.println("FIXME: skipping null XImage, should " +
|
---|
207 | "really do on the spot conversion");
|
---|
208 | return false;
|
---|
209 | }
|
---|
210 |
|
---|
211 | /*
|
---|
212 | +------------------
|
---|
213 | | clip
|
---|
214 | | +---------+
|
---|
215 | | img | |
|
---|
216 | | +--+-------+ |
|
---|
217 | | | | | |
|
---|
218 | | | | | |
|
---|
219 | | | +-------+-+
|
---|
220 | | | |
|
---|
221 | | +----------+
|
---|
222 | */
|
---|
223 |
|
---|
224 | int iLeft = Math.max(x, clipBounds.x);
|
---|
225 | int iTop = Math.max(y, clipBounds.y);
|
---|
226 | int iRight = Math.min(x + bimg.getWidth(),
|
---|
227 | clipBounds.x + clipBounds.width);
|
---|
228 | int iBottom = Math.min(y + bimg.getHeight(),
|
---|
229 | clipBounds.y + clipBounds.height);
|
---|
230 |
|
---|
231 | int srcX = iLeft - x;
|
---|
232 | int srcY = iTop - y;
|
---|
233 |
|
---|
234 | int width = iRight - iLeft;
|
---|
235 | int height = iBottom - iTop;
|
---|
236 |
|
---|
237 | if ((width > 0) && (height > 0))
|
---|
238 | context.putImage(ximg, srcX, srcY, iLeft, iTop, width, height);
|
---|
239 |
|
---|
240 | return true;
|
---|
241 | }
|
---|
242 |
|
---|
243 | public MappedRaster mapRaster(Rectangle bounds)
|
---|
244 | {
|
---|
245 | Visual visual = config.getVisual();
|
---|
246 | XImage ximage = new XImage(visual, bounds.width, bounds.height,
|
---|
247 | false // do not auto allocate memory
|
---|
248 | );
|
---|
249 |
|
---|
250 | WritableRaster raster =
|
---|
251 | config.createRasterForXImage(ximage,
|
---|
252 | new Point(bounds.x, bounds.y));
|
---|
253 |
|
---|
254 | DataBuffer dataB = raster.getDataBuffer();
|
---|
255 | XGraphicsConfiguration.attachData(ximage, dataB, 0);
|
---|
256 |
|
---|
257 | Drawable drawable = context.getDrawable();
|
---|
258 |
|
---|
259 | // TODO: restrict to clipping
|
---|
260 |
|
---|
261 | Rectangle mBounds = drawable.copyIntoXImage(ximage, bounds, 0, 0);
|
---|
262 |
|
---|
263 | return new XRaster(raster, ximage, config.imageCM);
|
---|
264 | }
|
---|
265 |
|
---|
266 |
|
---|
267 | public void unmapRaster(MappedRaster mappedRaster)
|
---|
268 | {
|
---|
269 | XRaster xraster = (XRaster) mappedRaster;
|
---|
270 | XImage ximage = xraster.ximage;
|
---|
271 | Raster raster = xraster.getRaster();
|
---|
272 | int x = raster.getMinX();
|
---|
273 | int y = raster.getMinY();
|
---|
274 | int width = raster.getWidth();
|
---|
275 | int height = raster.getHeight();
|
---|
276 |
|
---|
277 | context.putImage(ximage, 0, 0, x, y, width, height);
|
---|
278 | }
|
---|
279 | }
|
---|