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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* XFontPeer2.java -- A Java based TTF 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
package gnu.java.awt.font;
39
 
40
 
41
import gnu.java.awt.peer.ClasspathFontPeer;
42
import gnu.java.lang.CPStringBuilder;
43
 
44
import java.awt.Font;
45
import java.awt.FontMetrics;
46
import java.awt.font.FontRenderContext;
47
import java.awt.font.GlyphVector;
48
import java.awt.font.LineMetrics;
49
import java.awt.font.TextAttribute;
50
import java.awt.geom.AffineTransform;
51
import java.awt.geom.Point2D;
52
import java.awt.geom.Rectangle2D;
53
import java.io.File;
54
import java.io.FileInputStream;
55
import java.io.IOException;
56
import java.io.InputStream;
57
import java.nio.ByteBuffer;
58
import java.nio.channels.FileChannel;
59
import java.text.CharacterIterator;
60
import java.text.StringCharacterIterator;
61
import java.util.HashMap;
62
import java.util.HashSet;
63
import java.util.Locale;
64
import java.util.Map;
65
import java.util.Properties;
66
import java.util.Set;
67
 
68
public class OpenTypeFontPeer
69
  extends ClasspathFontPeer
70
{
71
 
72
  /**
73
   * The font mapping as specified in the file fonts.properties.
74
   */
75
  private static Properties fontProperties;
76
 
77
  /**
78
   * The available font family names.
79
   */
80
  private static Set<String> availableFontNames;
81
 
82
  /**
83
   * Font spec to file mapping.
84
   */
85
  private static Map<String,Map<String,String>> fontToFileMap;
86
 
87
  static
88
  {
89
    fontProperties = new Properties();
90
    InputStream in = OpenTypeFontPeer.class.getResourceAsStream("fonts.properties");
91
    try
92
      {
93
        fontProperties.load(in);
94
      }
95
    catch (IOException e)
96
      {
97
        e.printStackTrace();
98
      }
99
  }
100
 
101
  private class XLineMetrics
102
    extends LineMetrics
103
  {
104
 
105
    private Font font;
106
    private GlyphVector glyphVector;
107
//    private CharacterIterator characterIterator;
108
//    private int begin;
109
//    private int limit;
110
    private FontRenderContext fontRenderContext;
111
    XLineMetrics(Font f, CharacterIterator ci, int b, int l,
112
                 FontRenderContext rc)
113
    {
114
      font = f;
115
//      characterIterator = ci;
116
//      begin = b;
117
//      limit = l;
118
      fontRenderContext = rc;
119
      glyphVector = fontDelegate.createGlyphVector(font, fontRenderContext,
120
                                                   ci);
121
    }
122
 
123
    public float getAscent()
124
    {
125
      return fontDelegate.getAscent(font.getSize(), fontRenderContext.getTransform(),
126
                             fontRenderContext.isAntiAliased(),
127
                             fontRenderContext.usesFractionalMetrics(), true);
128
    }
129
 
130
    public int getBaselineIndex()
131
    {
132
      // FIXME: Implement this.
133
      throw new UnsupportedOperationException("Not yet implemented");
134
    }
135
 
136
    public float[] getBaselineOffsets()
137
    {
138
      // FIXME: Implement this.
139
      throw new UnsupportedOperationException("Not yet implemented");
140
    }
141
 
142
    public float getDescent()
143
    {
144
      return (int) fontDelegate.getDescent(font.getSize(), IDENDITY, false,
145
                                           false, false);
146
    }
147
 
148
    public float getHeight()
149
    {
150
      return (float) glyphVector.getLogicalBounds().getHeight();
151
    }
152
 
153
    public float getLeading()
154
    {
155
      return getHeight() - getAscent() - getDescent();
156
    }
157
 
158
    public int getNumChars()
159
    {
160
      // FIXME: Implement this.
161
      throw new UnsupportedOperationException("Not yet implemented");
162
    }
163
 
164
    public float getStrikethroughOffset()
165
    {
166
      return 0.F;
167
    }
168
 
169
    public float getStrikethroughThickness()
170
    {
171
      return 0.F;
172
    }
173
 
174
    public float getUnderlineOffset()
175
    {
176
      return 0.F;
177
    }
178
 
179
    public float getUnderlineThickness()
180
    {
181
      return 0.F;
182
    }
183
 
184
  }
185
 
186
  private class XFontMetrics
187
    extends FontMetrics
188
  {
189
    /**
190
     * A cached point instance, to be used in #charWidth().
191
     */
192
    private Point2D cachedPoint = new Point2D.Double();
193
 
194
    XFontMetrics(Font f)
195
    {
196
      super(f);
197
    }
198
 
199
    public int getAscent()
200
    {
201
      return (int) fontDelegate.getAscent(getFont().getSize(), IDENDITY,
202
                                          false, false, false);
203
    }
204
 
205
    public int getDescent()
206
    {
207
      return (int) fontDelegate.getDescent(getFont().getSize(), IDENDITY,
208
                                           false, false, false);
209
    }
210
 
211
    public int getHeight()
212
    {
213
      GlyphVector gv = fontDelegate.createGlyphVector(getFont(),
214
                    new FontRenderContext(IDENDITY, false, false),
215
                    new StringCharacterIterator("m"));
216
      Rectangle2D b = gv.getVisualBounds();
217
      return (int) b.getHeight();
218
    }
219
 
220
    public int charWidth(char c)
221
    {
222
      int code = fontDelegate.getGlyphIndex(c);
223
      Point2D advance = cachedPoint;
224
      fontDelegate.getAdvance(code, font.getSize2D(), IDENDITY,
225
                              false, false, true, advance);
226
      return (int) advance.getX();
227
    }
228
 
229
    public int charsWidth(char[] chars, int offs, int len)
230
    {
231
      return stringWidth(new String(chars, offs, len));
232
    }
233
 
234
    public int stringWidth(String s)
235
    {
236
      GlyphVector gv = fontDelegate.createGlyphVector(getFont(),
237
                    new FontRenderContext(IDENDITY, false, false),
238
                    new StringCharacterIterator(s));
239
      Rectangle2D b = gv.getVisualBounds();
240
      return (int) b.getWidth();
241
    }
242
  }
243
 
244
  /**
245
   * The indendity transform, to be used in several methods.
246
   */
247
  private static final AffineTransform IDENDITY = new AffineTransform();
248
 
249
  private FontDelegate fontDelegate;
250
 
251
  public OpenTypeFontPeer(String name, int style, int size)
252
  {
253
    super(name, style, size);
254
    try
255
      {
256
        String fontSpec = encodeFont(name, style);
257
        String filename = mapFontToFilename(fontSpec);
258
        File fontfile = new File(filename);
259
        FileInputStream in = new FileInputStream(fontfile);
260
        FileChannel ch = in.getChannel();
261
        ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
262
                                   fontfile.length());
263
        fontDelegate = FontFactory.createFonts(buffer)[0];
264
      }
265
    catch (Exception ex)
266
      {
267
        ex.printStackTrace();
268
      }
269
  }
270
 
271
  public OpenTypeFontPeer(String name, Map atts)
272
  {
273
    super(name, atts);
274
    try
275
      {
276
        String fontSpec = encodeFont(name, atts);
277
        String filename = mapFontToFilename(fontSpec);
278
        File fontfile = new File(filename);
279
        FileInputStream in = new FileInputStream(fontfile);
280
        FileChannel ch = in.getChannel();
281
        ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
282
                                   fontfile.length());
283
        fontDelegate = FontFactory.createFonts(buffer)[0];
284
      }
285
    catch (Exception ex)
286
      {
287
        ex.printStackTrace();
288
      }
289
  }
290
 
291
  public boolean canDisplay(Font font, int c)
292
  {
293
    // FIXME: Implement this.
294
    throw new UnsupportedOperationException("Not yet implemented");
295
  }
296
 
297
  public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit)
298
  {
299
    // FIXME: Implement this.
300
    throw new UnsupportedOperationException("Not yet implemented");
301
  }
302
 
303
  public String getSubFamilyName(Font font, Locale locale)
304
  {
305
    // FIXME: Implement this.
306
    throw new UnsupportedOperationException("Not yet implemented");
307
  }
308
 
309
  public String getPostScriptName(Font font)
310
  {
311
    // FIXME: Implement this.
312
    throw new UnsupportedOperationException("Not yet implemented");
313
  }
314
 
315
  public int getNumGlyphs(Font font)
316
  {
317
    // FIXME: Implement this.
318
    throw new UnsupportedOperationException("Not yet implemented");
319
  }
320
 
321
  public int getMissingGlyphCode(Font font)
322
  {
323
    // FIXME: Implement this.
324
    throw new UnsupportedOperationException("Not yet implemented");
325
  }
326
 
327
  public byte getBaselineFor(Font font, char c)
328
  {
329
    // FIXME: Implement this.
330
    throw new UnsupportedOperationException("Not yet implemented");
331
  }
332
 
333
  public String getGlyphName(Font font, int glyphIndex)
334
  {
335
    // FIXME: Implement this.
336
    throw new UnsupportedOperationException("Not yet implemented");
337
  }
338
 
339
  public GlyphVector createGlyphVector(Font font, FontRenderContext frc, CharacterIterator ci)
340
  {
341
    return fontDelegate.createGlyphVector(font, frc, ci);
342
  }
343
 
344
  public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, int[] glyphCodes)
345
  {
346
    // FIXME: Implement this.
347
    throw new UnsupportedOperationException("Not yet implemented");
348
  }
349
 
350
  public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, int limit, int flags)
351
  {
352
    StringCharacterIterator i = new StringCharacterIterator(new String(chars), start, limit, 0);
353
    return fontDelegate.createGlyphVector(font, frc, i);
354
  }
355
 
356
  public FontMetrics getFontMetrics(Font font)
357
  {
358
    return new XFontMetrics(font);
359
  }
360
 
361
  public boolean hasUniformLineMetrics(Font font)
362
  {
363
    // FIXME: Implement this.
364
    throw new UnsupportedOperationException("Not yet implemented");
365
  }
366
 
367
  public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc)
368
  {
369
    return new XLineMetrics(font, ci, begin, limit, rc);
370
  }
371
 
372
  public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
373
  {
374
    // FIXME: Implement this.
375
    throw new UnsupportedOperationException("Not yet implemented");
376
  }
377
 
378
  /**
379
   * Encodes a font name + style + size specification into a X logical font
380
   * description (XLFD) as described here:
381
   *
382
   * http://www.meretrx.com/e93/docs/xlfd.html
383
   *
384
   * This is implemented to look up the font description in the
385
   * fonts.properties of this package.
386
   *
387
   * @param name the font name
388
   * @param atts the text attributes
389
   *
390
   * @return the encoded font description
391
   */
392
  public static String encodeFont(String name, Map atts)
393
  {
394
    String family = name;
395
    if (family == null || family.equals(""))
396
      family = (String) atts.get(TextAttribute.FAMILY);
397
    if (family == null)
398
      family = "SansSerif";
399
 
400
    int style = 0;
401
    // Detect italic attribute.
402
    Float posture = (Float) atts.get(TextAttribute.POSTURE);
403
    if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
404
      style |= Font.ITALIC;
405
 
406
    // Detect bold attribute.
407
    Float weight = (Float) atts.get(TextAttribute.WEIGHT);
408
    if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
409
      style |= Font.BOLD;
410
 
411
    return encodeFont(name, style);
412
  }
413
 
414
  /**
415
   * Encodes a font name + style into a combined string.
416
   *
417
   * This is implemented to look up the font description in the
418
   * fonts.properties of this package.
419
   *
420
   * @param name the font name
421
   * @param style the font style
422
   *
423
   * @return the encoded font description
424
   */
425
  static String encodeFont(String name, int style)
426
  {
427
    CPStringBuilder key = new CPStringBuilder();
428
    key.append(validName(name));
429
    key.append('/');
430
    switch (style)
431
    {
432
      case Font.BOLD:
433
        key.append("b");
434
        break;
435
      case Font.ITALIC:
436
        key.append("i");
437
        break;
438
      case (Font.BOLD | Font.ITALIC):
439
        key.append("bi");
440
        break;
441
      case Font.PLAIN:
442
      default:
443
        key.append("p");
444
 
445
    }
446
 
447
    return key.toString();
448
  }
449
 
450
  /**
451
   * Checks the specified font name for a valid font name. If the font name
452
   * is not known, then this returns 'sansserif' as fallback.
453
   *
454
   * @param name the font name to check
455
   *
456
   * @return a valid font name
457
   */
458
  static String validName(String name)
459
  {
460
    String retVal;
461
    Set<String> fontNames = getFontNames();
462
    if (fontNames.contains(name))
463
      {
464
        retVal = name;
465
      }
466
    else
467
      {
468
        retVal = "SansSerif";
469
      }
470
    return retVal;
471
  }
472
 
473
  public static String[] getAvailableFontFamilyNames(Locale l)
474
  {
475
    Set<String> fontNames = getFontNames();
476
    int numNames = fontNames.size();
477
    String[] ret = fontNames.toArray(new String[numNames]);
478
    return ret;
479
  }
480
 
481
  private static synchronized Set<String> getFontNames()
482
  {
483
    if (availableFontNames == null)
484
      {
485
        HashSet<String> familyNames = new HashSet<String>();
486
        for (Object o : fontProperties.keySet())
487
          {
488
            if (o instanceof String)
489
              {
490
                String key = (String) o;
491
                int slashIndex = key.indexOf('/');
492
                String name = key.substring(0, slashIndex);
493
                familyNames.add(name);
494
              }
495
          }
496
        availableFontNames = familyNames;
497
      }
498
    return availableFontNames;
499
  }
500
 
501
  /**
502
   * Takes a font spec as returned by {@link #encodeFont(String, int)},
503
   * and returns the corresponding font file, or <code>null</code> if no such
504
   * font mapping exists.
505
   *
506
   * @param fontSpec font name and style as returned by
507
   *        {@link #encodeFont(String, int)}
508
   *
509
   * @return filename of the corresponding font file
510
   */
511
  private synchronized String mapFontToFilename(String fontSpec)
512
  {
513
    if (fontToFileMap == null)
514
      {
515
        fontToFileMap = new HashMap<String,Map<String,String>>();
516
 
517
        // Initialize font spec to file mapping according to the
518
        // font.properties.
519
        for (Object o : fontProperties.keySet())
520
          {
521
            if (o instanceof String)
522
              {
523
                String key = (String) o;
524
                int slashIndex = key.indexOf('/');
525
                String name = key.substring(0, slashIndex);
526
                String spec = key.substring(slashIndex + 1);
527
                // Handle aliases in the 2nd pass below.
528
                if (! spec.equals("a"))
529
                  {
530
                    Map<String,String> specToFileMap = fontToFileMap.get(name);
531
                    if (specToFileMap == null)
532
                      {
533
                        specToFileMap = new HashMap<String,String>();
534
                        fontToFileMap.put(name, specToFileMap);
535
                      }
536
                    specToFileMap.put(spec, fontProperties.getProperty(key));
537
                  }
538
              }
539
          }
540
        // 2nd pass for handling aliases.
541
        for (Object o : fontProperties.keySet())
542
          {
543
            if (o instanceof String)
544
              {
545
                String key = (String) o;
546
                int slashIndex = key.indexOf('/');
547
                String name = key.substring(0, slashIndex);
548
                String spec = key.substring(slashIndex + 1);
549
                // Handle aliases in the 2nd pass below.
550
                if (spec.equals("a"))
551
                  {
552
                    String alias = fontProperties.getProperty(key);
553
                    Map<String,String> specToFileMap = fontToFileMap.get(alias);
554
                    fontToFileMap.put(name, specToFileMap);
555
                  }
556
              }
557
          }
558
      }
559
    // Look up font file.
560
    int slashIndex = fontSpec.indexOf('/');
561
    String name = fontSpec.substring(0, slashIndex);
562
    String spec = fontSpec.substring(slashIndex + 1);
563
    return fontToFileMap.get(name).get(spec);
564
  }
565
}

powered by: WebSVN 2.1.0

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