OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [gnu/] [awt/] [xlib/] [XGraphicsConfiguration.java] - Blame information for rev 756

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 756 jeremybenn
/* 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.GraphicsConfiguration;
12
import java.awt.Rectangle;
13
import java.awt.Graphics2D;
14
import java.awt.Graphics;
15
import java.awt.GraphicsDevice;
16
import java.awt.Point;
17
import java.awt.Color;
18
import java.awt.color.ColorSpace;
19
import java.awt.Font;
20
import java.awt.image.*;
21
import java.awt.geom.AffineTransform;
22
import gnu.gcj.xlib.GC;
23
import gnu.gcj.xlib.Drawable;
24
import gnu.gcj.xlib.Window;
25
import gnu.gcj.xlib.XImage;
26
import gnu.gcj.xlib.Visual;
27
import gnu.gcj.xlib.Colormap;
28
import gnu.gcj.xlib.XColor;
29
import gnu.gcj.xlib.Screen;
30
import gnu.gcj.xlib.Display;
31
import gnu.gcj.xlib.XException;
32
import gnu.java.awt.Buffers;
33
import java.util.Enumeration;
34
import java.util.Hashtable;
35
 
36
public class XGraphicsConfiguration extends GraphicsConfiguration
37
{
38
  //public abstract GraphicsDevice getDevice();
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
  /** Font metrics cache class.  Caches at most CACHE_SIZE_PER_DISPLAY
49
   * XFontMetrics objects for each display device.  When a display's cache
50
   * gets full, the least-recently used entry is overwritten.
51
   * XXX: lruOrder rolls over after a few billion operations, so it might
52
   * on very rare occasions misinterpret which is the oldest entry
53
   */
54
  static class FontMetricsCache
55
  {
56
    private java.util.Hashtable displays = new java.util.Hashtable ();
57
 
58
    /** Font metrics cache for a display device
59
     */
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
      /** Get an entry (null if not there) and update LRU ordering
73
       */
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
      /** Put an entry in the cache, eliminating the oldest entry if
85
       * the cache is at capacity.
86
       */
87
      void put (Font font, XFontMetrics fontMetrics)
88
      {
89
        if (entries.size () >= CACHE_SIZE_PER_DISPLAY)
90
        {
91
          // cache is full -- eliminate the oldest entry
92
          // slow operation, but shouldn't happen very often
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
    /** Get the font metrics for a font, if it is present in the cache.
117
     * @param font The AWT font for which to find the font metrics
118
     * @param display The display, to select the cached entries for that display
119
     * @return The font metrics, or null if not cached
120
     */
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
    /** Put a font in the cache
128
     * @param font The font
129
     * @param display The display
130
     * @param fontMetrics The font metrics
131
     */
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 // do not auto allocate memory
153
                             );
154
 
155
    Point origin = new Point(0, 0);
156
    WritableRaster raster = createRasterForXImage(ximg, origin);
157
 
158
    /* This is not a good way of doing this. Multiple toolkits may
159
       want to share the BufferedImage. */
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
    /*
176
      This will not work, since it creates a sample model that
177
      does not necessarily match the format of the XImage.
178
 
179
      WritableRaster raster =
180
      imageCM.createCompatibleWritableRaster(width, height); */
181
 
182
    // Create a sample model matching the XImage:
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, // pixel stride
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
  /**
228
   * Attach a the memory of a data buffer to an XImage
229
   * structure. [This method is not gnu.awt.xlib specific, and should
230
   * maybe be moved to a different location.]
231
   *
232
   * @param offset Offset to data. The given offset does not include
233
   * data buffer offset, which will also be added.
234
   */
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, // no alpha
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
          } // else, leave default zero values...
336
      }
337
 
338
    imageCM = new IndexColorModel(visual.getDepth(), numCol,
339
                                  rmap, gmap, bmap, amap);
340
  }
341
 
342
  /**
343
   * Gets the associated device that this configuration describes.
344
   *
345
   * @return the device
346
   */
347
  public GraphicsDevice getDevice()
348
  {
349
    throw new UnsupportedOperationException("not implemented");
350
  }
351
 
352
  /**
353
   * Returns a buffered image optimized to this device, so that blitting can
354
   * be supported in the buffered image.
355
   *
356
   * @param w the width of the buffer
357
   * @param h the height of the buffer
358
   * @return the buffered image, or null if none is supported
359
   */
360
  public BufferedImage createCompatibleImage(int width,
361
                                             int height,
362
                                             int transparency)
363
  {
364
    throw new UnsupportedOperationException("not implemented");
365
  }
366
 
367
  /**
368
   * Returns a buffered volatile image optimized to this device, so that
369
   * blitting can be supported in the buffered image. Because the buffer is
370
   * volatile, it can be optimized by native graphics accelerators.
371
   *
372
   * @param w the width of the buffer
373
   * @param h the height of the buffer
374
   * @return the buffered image, or null if none is supported
375
   * @see Component#createVolatileImage(int, int)
376
   * @since 1.4
377
   */
378
  public VolatileImage createCompatibleVolatileImage(int w, int h)
379
  {
380
    throw new UnsupportedOperationException("not implemented");
381
  }
382
 
383
  /**
384
   * FIXME: I'm not sure which color model that should be returned here.
385
   */
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
            } // else, leave default zero values...
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
  /* FIXME: This should be moved to XGraphicsDevice... */
462
  XFontMetrics getXFontMetrics (java.awt.Font awtFont)
463
  {
464
    // If the metrics object for this font is already cached, use it.
465
    // Otherwise create and cache it.
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"; // because we use functions like XDrawString16
483
 
484
      String logicalFontDescription =
485
        "-" + // FontNameRegistry prefix
486
        foundry   + "-" + family    + "-" + weight       + "-" +
487
        slant     + "-" + sWidth    + "-" + addStyle     + "-" +
488
        pixelSize + "-" + pointSize + "-" + xres         + "-" +
489
        yres      + "-" + spacing   + "-" + averageWidth + "-";
490
 
491
      // Try to load a Unicode font.  If that doesn't work, try again, without
492
      // specifying the character set.
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
    /* FIXME: consider an integer technique whenever
511
     * the ColorModel is 8 bits per color.
512
     * The problem with using integers is that it doesn't work unless
513
     * the colors are 8 bits each (as in the array), since ColorModel.getDataElement(int[],int)
514
     * expects non-normalized values.  For example, in a 16-bit display mode, you
515
     * would typically have 5 bits each for red and blue, and 6 bits for green.
516
    int[] components =
517
    {
518
      color.getRed (),
519
      color.getGreen (),
520
      color.getBlue (),
521
      0xff
522
    };
523
     */
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
  /**
543
   * @since 1.5
544
   */
545
  public VolatileImage createCompatibleVolatileImage (int width, int height,
546
                                                      int transparency)
547
  {
548
    return null;
549
  }
550
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.