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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [peer/] [x/] [XFontPeer.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* XFontPeer.java -- The font peer for X
2
   Copyright (C) 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
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.
10
 
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.
15
 
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.
20
 
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.
25
 
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. */
37
 
38
 
39
package gnu.java.awt.peer.x;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import java.awt.AWTError;
44
import java.awt.Font;
45
import java.awt.FontMetrics;
46
import java.awt.GraphicsDevice;
47
import java.awt.GraphicsEnvironment;
48
import java.awt.font.FontRenderContext;
49
import java.awt.font.GlyphVector;
50
import java.awt.font.LineMetrics;
51
import java.awt.font.TextAttribute;
52
import java.awt.geom.Rectangle2D;
53
import java.io.IOException;
54
import java.io.InputStream;
55
import java.text.CharacterIterator;
56
import java.util.HashMap;
57
import java.util.Iterator;
58
import java.util.Locale;
59
import java.util.Map;
60
import java.util.Properties;
61
 
62
import gnu.java.awt.peer.ClasspathFontPeer;
63
import gnu.x11.Display;
64
import gnu.x11.Fontable;
65
 
66
/**
67
 * The bridge from AWT to X fonts.
68
 *
69
 * @author Roman Kennke (kennke@aicas.com)
70
 */
71
public class XFontPeer
72
  extends ClasspathFontPeer
73
{
74
 
75
  /**
76
   * The font mapping as specified in the file fonts.properties.
77
   */
78
  private static Properties fontProperties;
79
  static
80
  {
81
    fontProperties = new Properties();
82
    InputStream in = XFontPeer.class.getResourceAsStream("xfonts.properties");
83
    try
84
      {
85
        fontProperties.load(in);
86
      }
87
    catch (IOException e)
88
      {
89
        e.printStackTrace();
90
      }
91
  }
92
 
93
  /**
94
   * The FontMetrics implementation for XFontPeer.
95
   */
96
  private class XFontMetrics
97
    extends FontMetrics
98
  {
99
    /**
100
     * The ascent of the font.
101
     */
102
    int ascent;
103
 
104
    /**
105
     * The descent of the font.
106
     */
107
    int descent;
108
 
109
    /**
110
     * The maximum of the character advances.
111
     */
112
    private int maxAdvance;
113
 
114
    /**
115
     * The internal leading.
116
     */
117
    int leading;
118
 
119
    /**
120
     * Cached string metrics. This caches string metrics locally so that the
121
     * server doesn't have to be asked each time.
122
     */
123
    private HashMap metricsCache;
124
 
125
    /**
126
     * The widths of the characters indexed by the characters themselves.
127
     */
128
    private int[] charWidths;
129
 
130
    /**
131
     * Creates a new XFontMetrics for the specified font.
132
     *
133
     * @param font the font
134
     */
135
    protected XFontMetrics(Font font)
136
    {
137
      super(font);
138
      metricsCache = new HashMap();
139
      Fontable.FontInfo info = getXFont().info();
140
      ascent = info.font_ascent();
141
      descent = info.font_descent();
142
      maxAdvance = info.max_bounds().character_width();
143
      leading = 0; // TODO: Not provided by X. Possible not needed.
144
 
145
      if (info.min_byte1() == 0 && info.max_byte1() == 0)
146
        readCharWidthsLinear(info);
147
      else
148
        readCharWidthsNonLinear(info);
149
    }
150
 
151
    /**
152
     * Reads the character widths when specified in a linear fashion. That is
153
     * when the min-byte1 and max-byte2 fields are both zero in the X protocol.
154
     *
155
     * @param info the font info reply
156
     */
157
    private void readCharWidthsLinear(Fontable.FontInfo info)
158
    {
159
      int startIndex = info.min_char_or_byte2();
160
      int endIndex = info.max_char_or_byte2();
161
      charWidths = new int[endIndex + 1];
162
      // All the characters before startIndex are zero width.
163
      for (int i = 0; i < startIndex; i++)
164
        {
165
          charWidths[i] = 0;
166
        }
167
      // All the other character info is fetched from the font info.
168
      int index = startIndex;
169
      Fontable.FontInfo.CharInfo[] charInfos = info.char_infos();
170
      for (Fontable.FontInfo.CharInfo charInfo : charInfos)
171
        {
172
          charWidths[index] = charInfo.character_width();
173
          index++;
174
        }
175
    }
176
 
177
    private void readCharWidthsNonLinear(Fontable.FontInfo info)
178
    {
179
      // TODO: Implement.
180
      throw new UnsupportedOperationException("Not yet implemented");
181
    }
182
 
183
    /**
184
     * Returns the ascent of the font.
185
     *
186
     * @return the ascent of the font
187
     */
188
    public int getAscent()
189
    {
190
      return ascent;
191
    }
192
 
193
    /**
194
     * Returns the descent of the font.
195
     *
196
     * @return the descent of the font
197
     */
198
    public int getDescent()
199
    {
200
      return descent;
201
    }
202
 
203
    /**
204
     * Returns the overall height of the font. This is the distance from
205
     * baseline to baseline (usually ascent + descent + leading).
206
     *
207
     * @return the overall height of the font
208
     */
209
    public int getHeight()
210
    {
211
      return ascent + descent;
212
    }
213
 
214
    /**
215
     * Returns the leading of the font.
216
     *
217
     * @return the leading of the font
218
     */
219
    public int getLeading()
220
    {
221
      return leading;
222
    }
223
 
224
    /**
225
     * Returns the maximum advance for this font.
226
     *
227
     * @return the maximum advance for this font
228
     */
229
    public int getMaxAdvance()
230
    {
231
      return maxAdvance;
232
    }
233
 
234
    /**
235
     * Determines the width of the specified character <code>c</code>.
236
     *
237
     * @param c the character
238
     *
239
     * @return the width of the character
240
     */
241
    public int charWidth(char c)
242
    {
243
      int width;
244
      if (c > charWidths.length)
245
        width = charWidths['?'];
246
      else
247
        width = charWidths[c];
248
      return width;
249
    }
250
 
251
    /**
252
     * Determines the overall width of the specified string.
253
     *
254
     * @param c the char buffer holding the string
255
     * @param offset the starting offset of the string in the buffer
256
     * @param length the number of characters in the string buffer
257
     *
258
     * @return the overall width of the specified string
259
     */
260
    public int charsWidth(char[] c, int offset, int length)
261
    {
262
      int width = 0;
263
      if (c.length > 0 && length > 0)
264
        {
265
          String s = new String(c, offset, length);
266
          width = stringWidth(s);
267
        }
268
      return width;
269
    }
270
 
271
    /**
272
     * Determines the overall width of the specified string.
273
     *
274
     * @param s the string
275
     *
276
     * @return the overall width of the specified string
277
     */
278
    public int stringWidth(String s)
279
    {
280
      int width = 0;
281
      if (s.length() > 0)
282
        {
283
          if (metricsCache.containsKey(s))
284
            {
285
              width = ((Integer) metricsCache.get(s)).intValue();
286
            }
287
          else
288
            {
289
              Fontable.TextExtentInfo extents = getXFont().text_extent(s);
290
              /*
291
               System.err.println("string: '" + s + "' : ");
292
               System.err.println("ascent: " + extents.getAscent());
293
               System.err.println("descent: " + extents.getDescent());
294
               System.err.println("overall ascent: " + extents.getOverallAscent());
295
               System.err.println("overall descent: " + extents.getOverallDescent());
296
               System.err.println("overall width: " + extents.getOverallWidth());
297
               System.err.println("overall left: " + extents.getOverallLeft());
298
               System.err.println("overall right: " + extents.getOverallRight());
299
               */
300
              width = extents.overall_width(); // + extents.overall_left();
301
              //System.err.println("String: " + s + ", width: " + width);
302
              metricsCache.put(s, new Integer(width));
303
            }
304
        }
305
      //System.err.print("stringWidth: '" + s + "': ");
306
      //System.err.println(width);
307
      return width;
308
    }
309
  }
310
 
311
  /**
312
   * The LineMetrics implementation for the XFontPeer.
313
   */
314
  private class XLineMetrics
315
    extends LineMetrics
316
  {
317
 
318
    /**
319
     * Returns the ascent of the font.
320
     *
321
     * @return the ascent of the font
322
     */
323
    public float getAscent()
324
    {
325
      return fontMetrics.ascent;
326
    }
327
 
328
    public int getBaselineIndex()
329
    {
330
      // FIXME: Implement this.
331
      throw new UnsupportedOperationException();
332
    }
333
 
334
    public float[] getBaselineOffsets()
335
    {
336
      // FIXME: Implement this.
337
      throw new UnsupportedOperationException();
338
    }
339
 
340
    /**
341
     * Returns the descent of the font.
342
     *
343
     * @return the descent of the font
344
     */
345
    public float getDescent()
346
    {
347
      return fontMetrics.descent;
348
    }
349
 
350
    /**
351
     * Returns the overall height of the font. This is the distance from
352
     * baseline to baseline (usually ascent + descent + leading).
353
     *
354
     * @return the overall height of the font
355
     */
356
    public float getHeight()
357
    {
358
      return fontMetrics.ascent + fontMetrics.descent;
359
    }
360
 
361
    /**
362
     * Returns the leading of the font.
363
     *
364
     * @return the leading of the font
365
     */
366
    public float getLeading()
367
    {
368
      return fontMetrics.leading;
369
    }
370
 
371
    public int getNumChars()
372
    {
373
      // FIXME: Implement this.
374
      throw new UnsupportedOperationException();
375
    }
376
 
377
    public float getStrikethroughOffset()
378
    {
379
      return 0.F; // TODO: Provided by X??
380
    }
381
 
382
    public float getStrikethroughThickness()
383
    {
384
      return 1.F; // TODO: Provided by X??
385
    }
386
 
387
    public float getUnderlineOffset()
388
    {
389
      return 0.F; // TODO: Provided by X??
390
    }
391
 
392
    public float getUnderlineThickness()
393
    {
394
      return 1.F; // TODO: Provided by X??
395
    }
396
 
397
  }
398
 
399
  /**
400
   * The X font.
401
   */
402
  private gnu.x11.Font xfont;
403
 
404
  private String name;
405
 
406
  private int style;
407
 
408
  private int size;
409
 
410
  /**
411
   * The font metrics for this font.
412
   */
413
  XFontMetrics fontMetrics;
414
 
415
  /**
416
   * Creates a new XFontPeer for the specified font name, style and size.
417
   *
418
   * @param name the font name
419
   * @param style the font style (bold / italic / normal)
420
   * @param size the size of the font
421
   */
422
  public XFontPeer(String name, int style, int size)
423
  {
424
    super(name, style, size);
425
    this.name = name;
426
    this.style = style;
427
    this.size = size;
428
  }
429
 
430
  /**
431
   * Creates a new XFontPeer for the specified font name and style
432
   * attributes.
433
   *
434
   * @param name the font name
435
   * @param atts the font attributes
436
   */
437
  public XFontPeer(String name, Map atts)
438
  {
439
    super(name, atts);
440
    String family = name;
441
    if (family == null || family.equals(""))
442
      family = (String) atts.get(TextAttribute.FAMILY);
443
    if (family == null)
444
      family = "SansSerif";
445
 
446
    int size = 12;
447
    Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
448
    if (sizeFl != null)
449
      size = sizeFl.intValue();
450
 
451
    int style = 0;
452
    // Detect italic attribute.
453
    Float posture = (Float) atts.get(TextAttribute.POSTURE);
454
    if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
455
      style |= Font.ITALIC;
456
 
457
    // Detect bold attribute.
458
    Float weight = (Float) atts.get(TextAttribute.WEIGHT);
459
    if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
460
      style |= Font.BOLD;
461
 
462
    this.name = name;
463
    this.style = style;
464
    this.size = size;
465
  }
466
 
467
  /**
468
   * Initializes the font peer with the specified attributes. This method is
469
   * called from both constructors.
470
   *
471
   * @param name the font name
472
   * @param style the font style
473
   * @param size the font size
474
   */
475
  private void init(String name, int style, int size)
476
  {
477
    if (name == null)
478
      {
479
        name = "SansSerif";
480
      }
481
    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
482
    GraphicsDevice dev = env.getDefaultScreenDevice();
483
    if (dev instanceof XGraphicsDevice)
484
      {
485
        Display display = ((XGraphicsDevice) dev).getDisplay();
486
        String fontDescr = encodeFont(name, style, size);
487
        if (XToolkit.DEBUG)
488
          System.err.println("XLFD font description: " + fontDescr);
489
        xfont = new gnu.x11.Font(display, fontDescr);
490
      }
491
    else
492
      {
493
        throw new AWTError("Local GraphicsEnvironment is not XWindowGraphicsEnvironment");
494
      }
495
  }
496
 
497
  public boolean canDisplay(Font font, int c)
498
  {
499
    // TODO: Implement this.
500
    throw new UnsupportedOperationException("Not yet implemented.");
501
  }
502
 
503
  public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit)
504
  {
505
    // TODO: Implement this.
506
    throw new UnsupportedOperationException("Not yet implemented.");
507
  }
508
 
509
  public String getSubFamilyName(Font font, Locale locale)
510
  {
511
    // TODO: Implement this.
512
    throw new UnsupportedOperationException("Not yet implemented.");
513
  }
514
 
515
  public String getPostScriptName(Font font)
516
  {
517
    // TODO: Implement this.
518
    throw new UnsupportedOperationException("Not yet implemented.");
519
  }
520
 
521
  public int getNumGlyphs(Font font)
522
  {
523
    // TODO: Implement this.
524
    throw new UnsupportedOperationException("Not yet implemented.");
525
  }
526
 
527
  public int getMissingGlyphCode(Font font)
528
  {
529
    // TODO: Implement this.
530
    throw new UnsupportedOperationException("Not yet implemented.");
531
  }
532
 
533
  public byte getBaselineFor(Font font, char c)
534
  {
535
    // TODO: Implement this.
536
    throw new UnsupportedOperationException("Not yet implemented.");
537
  }
538
 
539
  public String getGlyphName(Font font, int glyphIndex)
540
  {
541
    // TODO: Implement this.
542
    throw new UnsupportedOperationException("Not yet implemented.");
543
  }
544
 
545
  public GlyphVector createGlyphVector(Font font, FontRenderContext frc,
546
                                       CharacterIterator ci)
547
  {
548
    // TODO: Implement this.
549
    throw new UnsupportedOperationException("Not yet implemented.");
550
  }
551
 
552
  public GlyphVector createGlyphVector(Font font, FontRenderContext ctx,
553
                                       int[] glyphCodes)
554
  {
555
    // TODO: Implement this.
556
    throw new UnsupportedOperationException("Not yet implemented.");
557
  }
558
 
559
  public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc,
560
                                       char[] chars, int start, int limit,
561
                                       int flags)
562
  {
563
    // TODO: Implement this.
564
    throw new UnsupportedOperationException("Not yet implemented.");
565
  }
566
 
567
  /**
568
   * Returns the font metrics for the specified font.
569
   *
570
   * @param font the font for which to fetch the font metrics
571
   *
572
   * @return the font metrics for the specified font
573
   */
574
  public FontMetrics getFontMetrics(Font font)
575
  {
576
    if (font.getPeer() != this)
577
      throw new AWTError("The specified font has a different peer than this");
578
 
579
    if (fontMetrics == null)
580
      fontMetrics = new XFontMetrics(font);
581
    return fontMetrics;
582
  }
583
 
584
  /**
585
   * Frees the font in the X server.
586
   */
587
  protected void finalize()
588
  {
589
    if (xfont != null)
590
      xfont.close();
591
  }
592
 
593
  public boolean hasUniformLineMetrics(Font font)
594
  {
595
    // TODO: Implement this.
596
    throw new UnsupportedOperationException("Not yet implemented.");
597
  }
598
 
599
  /**
600
   * Returns the line metrics for this font and the specified string and
601
   * font render context.
602
   */
603
  public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin,
604
                                    int limit, FontRenderContext rc)
605
  {
606
    return new XLineMetrics();
607
  }
608
 
609
  public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
610
  {
611
    // TODO: Implement this.
612
    throw new UnsupportedOperationException("Not yet implemented.");
613
  }
614
 
615
  public Rectangle2D getStringBounds(Font font, CharacterIterator ci,
616
                                     int begin, int limit, FontRenderContext frc)
617
  {
618
    // TODO: Implement this.
619
    throw new UnsupportedOperationException("Not yet implemented.");
620
  }
621
 
622
  /**
623
   * Encodes a font name + style + size specification into a X logical font
624
   * description (XLFD) as described here:
625
   *
626
   * http://www.meretrx.com/e93/docs/xlfd.html
627
   *
628
   * This is implemented to look up the font description in the
629
   * fonts.properties of this package.
630
   *
631
   * @param name the font name
632
   * @param atts the text attributes
633
   *
634
   * @return the encoded font description
635
   */
636
  static String encodeFont(String name, Map atts)
637
  {
638
    String family = name;
639
    if (family == null || family.equals(""))
640
      family = (String) atts.get(TextAttribute.FAMILY);
641
    if (family == null)
642
      family = "SansSerif";
643
 
644
    int size = 12;
645
    Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
646
    if (sizeFl != null)
647
      size = sizeFl.intValue();
648
 
649
    int style = 0;
650
    // Detect italic attribute.
651
    Float posture = (Float) atts.get(TextAttribute.POSTURE);
652
    if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
653
      style |= Font.ITALIC;
654
 
655
    // Detect bold attribute.
656
    Float weight = (Float) atts.get(TextAttribute.WEIGHT);
657
    if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
658
      style |= Font.BOLD;
659
 
660
    return encodeFont(family, style, size);
661
  }
662
 
663
  /**
664
   * Encodes a font name + style + size specification into a X logical font
665
   * description (XLFD) as described here:
666
   *
667
   * http://www.meretrx.com/e93/docs/xlfd.html
668
   *
669
   * This is implemented to look up the font description in the
670
   * fonts.properties of this package.
671
   *
672
   * @param name the font name
673
   * @param style the font style
674
   * @param size the font size
675
   *
676
   * @return the encoded font description
677
   */
678
  static String encodeFont(String name, int style, int size)
679
  {
680
    CPStringBuilder key = new CPStringBuilder();
681
    key.append(validName(name));
682
    key.append('.');
683
    switch (style)
684
    {
685
      case Font.BOLD:
686
        key.append("bold");
687
        break;
688
      case Font.ITALIC:
689
        key.append("italic");
690
        break;
691
      case (Font.BOLD | Font.ITALIC):
692
        key.append("bolditalic");
693
        break;
694
      case Font.PLAIN:
695
      default:
696
        key.append("plain");
697
 
698
    }
699
 
700
    String protoType = fontProperties.getProperty(key.toString());
701
    int s = validSize(size);
702
    return protoType.replaceFirst("%d", String.valueOf(s));
703
  }
704
 
705
  /**
706
   * Checks the specified font name for a valid font name. If the font name
707
   * is not known, then this returns 'sansserif' as fallback.
708
   *
709
   * @param name the font name to check
710
   *
711
   * @return a valid font name
712
   */
713
  static String validName(String name)
714
  {
715
    String retVal;
716
    if (name.equalsIgnoreCase("sansserif")
717
        || name.equalsIgnoreCase("serif")
718
        || name.equalsIgnoreCase("monospaced")
719
        || name.equalsIgnoreCase("dialog")
720
        || name.equalsIgnoreCase("dialoginput"))
721
      {
722
        retVal = name.toLowerCase();
723
      }
724
    else
725
      {
726
        retVal = "sansserif";
727
      }
728
    return retVal;
729
  }
730
 
731
  /**
732
   * Translates an arbitrary point size to a size that is typically available
733
   * on an X server. These are the sizes 8, 10, 12, 14, 18 and 24.
734
   *
735
   * @param size the queried size
736
   * @return the real available size
737
   */
738
  private static final int validSize(int size)
739
  {
740
    int val;
741
    if (size <= 9)
742
      val = 8;
743
    else if (size <= 11)
744
      val = 10;
745
    else if (size <= 13)
746
      val = 12;
747
    else if (size <= 17)
748
      val = 14;
749
    else if (size <= 23)
750
      val = 18;
751
    else
752
      val = 24;
753
    return val;
754
  }
755
 
756
  /**
757
   * Returns the X Font reference. This lazily loads the font when first
758
   * requested.
759
   *
760
   * @return the X Font reference
761
   */
762
  gnu.x11.Font getXFont()
763
  {
764
    if (xfont == null)
765
      {
766
        init(name, style, size);
767
      }
768
    return xfont;
769
  }
770
}

powered by: WebSVN 2.1.0

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