1:
8:
9: package ;
10:
11: import ;
12: import ;
13: import ;
14: import ;
15: import ;
16: import ;
17: import ;
18: import ;
19: import ;
20: import ;
21: import ;
22: import ;
23: import ;
24: import ;
25: import ;
26: import ;
27: import ;
28: import ;
29: import ;
30: import ;
31: import ;
32: import ;
33: import ;
34: import ;
35:
36: public class XGraphicsConfiguration extends GraphicsConfiguration
37: {
38:
39:
40: Visual visual;
41: int format;
42: Colormap colormap;
43: ColorModel imageCM;
44: ColorModel pixelCM;
45: private static final int CACHE_SIZE_PER_DISPLAY = 10;
46: static FontMetricsCache fontMetricsCache = new FontMetricsCache ();
47:
48:
54: static class FontMetricsCache
55: {
56: private java.util.Hashtable displays = new java.util.Hashtable ();
57:
58:
60: class PerDisplayCache
61: {
62: private int lruCount = 0;
63: private java.util.Hashtable entries = new java.util.Hashtable ();
64:
65: class CacheEntry
66: {
67: int lruOrder;
68: XFontMetrics fm;
69: Font font;
70: }
71:
72:
74: XFontMetrics get (Font font)
75: {
76: CacheEntry entry = (CacheEntry)entries.get (font);
77: if (entry != null)
78: {
79: entry.lruOrder = lruCount++;
80: }
81: return (entry==null) ? null : entry.fm;
82: }
83:
84:
87: void put (Font font, XFontMetrics fontMetrics)
88: {
89: if (entries.size () >= CACHE_SIZE_PER_DISPLAY)
90: {
91:
92:
93: int maxAge = 0;
94: CacheEntry oldestEntry = null;
95: int referenceCount = lruCount;
96: for (Enumeration e = entries.elements (); e.hasMoreElements ();)
97: {
98: CacheEntry entry = (CacheEntry)e.nextElement ();
99: if ((referenceCount-entry.lruOrder) > maxAge)
100: {
101: maxAge = referenceCount-entry.lruOrder;
102: oldestEntry = entry;
103: }
104: }
105: if (oldestEntry != null)
106: entries.remove (oldestEntry.font);
107: }
108: CacheEntry newEntry = new CacheEntry ();
109: newEntry.lruOrder = lruCount++;
110: newEntry.fm = fontMetrics;
111: newEntry.font = font;
112: entries.put (font,newEntry);
113: }
114: }
115:
116:
121: XFontMetrics get (Font font, Display display)
122: {
123: PerDisplayCache cache = (PerDisplayCache)displays.get (display);
124: return (cache==null) ? null : cache.get (font);
125: }
126:
127:
132: void put (Font font, Display display, XFontMetrics fontMetrics)
133: {
134: PerDisplayCache cache = (PerDisplayCache)displays.get (display);
135: if (cache == null)
136: {
137: cache = new PerDisplayCache ();
138: displays.put (display,cache);
139: }
140: cache.put (font,fontMetrics);
141: }
142: }
143:
144: public XGraphicsConfiguration(Visual visual)
145: {
146: this.visual = visual;
147: }
148:
149: public BufferedImage createCompatibleImage(int width, int height)
150: {
151: XImage ximg = new XImage(visual, width, height,
152: false
153: );
154:
155: Point origin = new Point(0, 0);
156: WritableRaster raster = createRasterForXImage(ximg, origin);
157:
158:
160: Hashtable props = new Hashtable();
161: props.put("gnu.gcj.xlib.XImage", ximg);
162: props.put("java.awt.GraphicsConfiguration", this);
163:
164: BufferedImage bimg = new BufferedImage(imageCM,raster, false, props);
165:
166: DataBuffer dataB = raster.getDataBuffer();
167: attachData(ximg, dataB, 0);
168: return bimg;
169: }
170:
171: WritableRaster createRasterForXImage(XImage ximage, Point origin)
172: {
173: if (imageCM == null) prepareColorModel(ximage);
174:
175:
181:
182:
183:
184: SampleModel imageSM = null;
185:
186: int width = ximage.getWidth();
187: int height = ximage.getHeight();
188: int bitsPerPixel = ximage.getBitsPerPixel();
189: int dataType =
190: Buffers.smallestAppropriateTransferType(bitsPerPixel);
191: int bitsPerDataElement = DataBuffer.getDataTypeSize(dataType);
192: int scanlineStride = ximage.getBytesPerLine()*8/bitsPerDataElement;
193:
194: if (imageCM instanceof IndexColorModel)
195: {
196: int[] bandOffsets = {0};
197: imageSM = new ComponentSampleModel(dataType,
198: width, height,
199: 1,
200: scanlineStride,
201: bandOffsets);
202: }
203: else if (imageCM instanceof PackedColorModel)
204: {
205: PackedColorModel pcm = (PackedColorModel) imageCM;
206: int[] masks = pcm.getMasks();
207:
208: imageSM = new SinglePixelPackedSampleModel(dataType,
209: width, height,
210: scanlineStride,
211: masks);
212: }
213:
214: if (imageSM == null)
215: {
216: throw new UnsupportedOperationException("creating sample model " +
217: "for " + imageCM +
218: " not implemented");
219: }
220:
221: WritableRaster raster = Raster.createWritableRaster(imageSM, origin);
222: return raster;
223: }
224:
225:
226:
227:
235: static void attachData(XImage ximage, DataBuffer dataB, int offset)
236: {
237: offset += dataB.getOffset();
238: switch (dataB.getDataType())
239: {
240: case DataBuffer.TYPE_BYTE:
241: ximage.setData(((DataBufferByte) dataB).getData(), offset);
242: break;
243: case DataBuffer.TYPE_USHORT:
244: ximage.setData(((DataBufferUShort) dataB).getData(), offset);
245: break;
246: case DataBuffer.TYPE_INT:
247: ximage.setData(((DataBufferInt) dataB).getData(), offset);
248: break;
249: default:
250: throw
251: new UnsupportedOperationException("Do not know how to " +
252: "set data for data " +
253: "type " +
254: dataB.getDataType());
255: }
256: }
257:
258: void prepareColorModel(XImage ximage)
259: {
260: format = ximage.getFormat();
261: int bitsPerPixel = ximage.getBitsPerPixel();
262: switch (format) {
263: case XImage.ZPIXMAP_FORMAT:
264: calcZPixmapModels(bitsPerPixel);
265: break;
266:
267: default:
268: throw new UnsupportedOperationException("unimplemented format");
269: }
270: }
271:
272: void calcZPixmapModels(int bitsPerPixel)
273: {
274: switch (visual.getVisualClass())
275: {
276: case Visual.VC_TRUE_COLOR:
277: calcDecomposedRGBModels(bitsPerPixel);
278: break;
279: case Visual.VC_PSEUDO_COLOR:
280: calcPseudoColorModels(bitsPerPixel);
281: break;
282: default:
283: String msg = "unimplemented visual class";
284: throw new UnsupportedOperationException(msg);
285: }
286: }
287:
288: void calcDecomposedRGBModels(int bitsPerPixel)
289: {
290: int dataType = Buffers.smallestAppropriateTransferType(bitsPerPixel);
291:
292:
293: if (DataBuffer.getDataTypeSize(dataType) == bitsPerPixel)
294: {
295: ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
296:
297: imageCM = new DirectColorModel(cs,
298: visual.getDepth(),
299: visual.getRedMask(),
300: visual.getGreenMask(),
301: visual.getBlueMask(),
302: 0,
303: false,
304: dataType);
305: }
306: else
307: {
308: throw new
309: UnsupportedOperationException("unimplemented bits per pixel");
310: }
311: }
312:
313: void calcPseudoColorModels(int bitsPerPixel)
314: {
315: if (colormap == null)
316: colormap = visual.getScreen().getDefaultColormap();
317:
318: XColor[] colArray = colormap.getXColors();
319:
320: int numCol = colArray.length;
321: byte[] rmap = new byte[numCol];
322: byte[] gmap = new byte[numCol];
323: byte[] bmap = new byte[numCol];
324: byte[] amap = new byte[numCol];
325:
326: for (int i=0; i < numCol; i++)
327: {
328: XColor color = colArray[i];
329: if (color.getFlags() == Colormap.FLAG_SHARED)
330: {
331: rmap[i] = (byte) (color.getRed() >> 8);
332: gmap[i] = (byte) (color.getGreen() >> 8);
333: bmap[i] = (byte) (color.getBlue() >> 8);
334: amap[i] = (byte) 0xff;
335: }
336: }
337:
338: imageCM = new IndexColorModel(visual.getDepth(), numCol,
339: rmap, gmap, bmap, amap);
340: }
341:
342:
347: public GraphicsDevice getDevice()
348: {
349: throw new UnsupportedOperationException("not implemented");
350: }
351:
352:
360: public BufferedImage createCompatibleImage(int width,
361: int height,
362: int transparency)
363: {
364: throw new UnsupportedOperationException("not implemented");
365: }
366:
367:
378: public VolatileImage createCompatibleVolatileImage(int w, int h)
379: {
380: throw new UnsupportedOperationException("not implemented");
381: }
382:
383:
386: public ColorModel getColorModel()
387: {
388: if (pixelCM == null)
389: preparePixelCM();
390: return pixelCM;
391: }
392:
393: void preparePixelCM()
394: {
395: switch (visual.getVisualClass())
396: {
397: case Visual.VC_TRUE_COLOR:
398: pixelCM = new DirectColorModel(visual.getDepth(),
399: visual.getRedMask(),
400: visual.getGreenMask(),
401: visual.getBlueMask());
402: break;
403: case Visual.VC_PSEUDO_COLOR:
404:
405: if (colormap == null)
406: colormap = visual.getScreen().getDefaultColormap();
407:
408: XColor[] colArray = colormap.getXColors();
409:
410: int numCol = colArray.length;
411: byte[] rmap = new byte[numCol];
412: byte[] gmap = new byte[numCol];
413: byte[] bmap = new byte[numCol];
414: byte[] amap = new byte[numCol];
415:
416: for (int i=0; i < numCol; i++)
417: {
418: XColor color = colArray[i];
419: if (color.getFlags() == Colormap.FLAG_SHARED) {
420: rmap[i] = (byte) (color.getRed() >> 8);
421: gmap[i] = (byte) (color.getGreen() >> 8);
422: bmap[i] = (byte) (color.getBlue() >> 8);
423: amap[i] = (byte) 0xff;
424: }
425:
426: }
427:
428: pixelCM = new IndexColorModel(visual.getDepth(), numCol,
429: rmap, gmap, bmap, amap);
430: break;
431: default:
432: throw new UnsupportedOperationException("not implemented");
433: }
434: }
435:
436: public ColorModel getColorModel(int transparency)
437: {
438: throw new UnsupportedOperationException("not implemented");
439: }
440:
441: public AffineTransform getDefaultTransform()
442: {
443: throw new UnsupportedOperationException("not implemented");
444: }
445:
446: public AffineTransform getNormalizingTransform()
447: {
448: throw new UnsupportedOperationException("not implemented");
449: }
450:
451: public Rectangle getBounds()
452: {
453: throw new UnsupportedOperationException("not implemented");
454: }
455:
456: Visual getVisual()
457: {
458: return visual;
459: }
460:
461:
462: XFontMetrics getXFontMetrics (java.awt.Font awtFont)
463: {
464:
465:
466: Display display = visual.getScreen ().getDisplay ();
467: XFontMetrics fm = fontMetricsCache.get (awtFont,display);
468: if (fm == null)
469: {
470: String foundry = "*";
471: String family = awtFont.getName ();
472: String weight = awtFont.isBold () ? "bold" : "medium";
473: String slant = awtFont.isItalic () ? "i" : "r";
474: String sWidth = "*";
475: String addStyle = "";
476: String pixelSize = "*";
477: String pointSize = awtFont.getSize () + "0";
478: String xres = "*";
479: String yres = "*";
480: String spacing = "*";
481: String averageWidth = "*";
482: String charset = "iso10646-1";
483:
484: String logicalFontDescription =
485: "-" +
486: foundry + "-" + family + "-" + weight + "-" +
487: slant + "-" + sWidth + "-" + addStyle + "-" +
488: pixelSize + "-" + pointSize + "-" + xres + "-" +
489: yres + "-" + spacing + "-" + averageWidth + "-";
490:
491:
492:
493: try
494: {
495: gnu.gcj.xlib.Font xfont = new gnu.gcj.xlib.Font (display, logicalFontDescription + charset);
496: fm = new XFontMetrics (xfont, awtFont);
497: }
498: catch (XException e)
499: {
500: gnu.gcj.xlib.Font xfont = new gnu.gcj.xlib.Font (display, logicalFontDescription + "*-*");
501: fm = new XFontMetrics (xfont, awtFont);
502: }
503: fontMetricsCache.put (awtFont,display,fm);
504: }
505: return fm;
506: }
507:
508: int getPixel(Color color)
509: {
510:
524:
525: int[] unnormalizedComponents = { 0, 0, 0, 0xff };
526: ColorModel cm = getColorModel ();
527: if (color != null)
528: {
529: float[] normalizedComponents =
530: {
531: ((float)color.getRed ()) / 255F,
532: ((float)color.getGreen ()) / 255F,
533: ((float)color.getBlue ()) / 255F,
534: 1
535: };
536: cm.getUnnormalizedComponents(normalizedComponents, 0,
537: unnormalizedComponents, 0);
538: }
539: return cm.getDataElement (unnormalizedComponents, 0);
540: }
541:
542:
545: public VolatileImage createCompatibleVolatileImage (int width, int height,
546: int transparency)
547: {
548: return null;
549: }
550: }