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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* OpenTypeFont.java -- Manages OpenType and TrueType fonts.
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.opentype;
39
 
40
import java.awt.Font;
41
import java.awt.FontFormatException;
42
import java.awt.font.FontRenderContext;
43
import java.awt.font.GlyphVector;
44
import java.awt.font.OpenType;
45
import java.awt.geom.AffineTransform;
46
import java.awt.geom.GeneralPath;
47
import java.awt.geom.Point2D;
48
import java.nio.ByteBuffer;
49
import java.text.CharacterIterator;
50
import java.util.Locale;
51
 
52
import gnu.java.awt.font.FontDelegate;
53
import gnu.java.awt.font.GNUGlyphVector;
54
import gnu.java.awt.font.autofit.AutoHinter;
55
import gnu.java.awt.font.opentype.truetype.TrueTypeScaler;
56
import gnu.java.awt.font.opentype.truetype.Zone;
57
 
58
 
59
/**
60
 * A font that takes its data from OpenType or TrueType font tables.
61
 *
62
 * <p>OpenType is an extension of the TrueType font format. In addition
63
 * to tables for names, kerning or layout, it also stores the shapes
64
 * of individual glyphs. Three formats are recognized for glyphs:
65
 * Quadratic splines (classic TrueType), cubic splines (PostScript),
66
 * and bitmaps.
67
 *
68
 * @see <a
69
 * href="http://partners.adobe.com/asn/tech/type/opentype/">Adobe&#x2019;s
70
 * OpenType specification</a>
71
 *
72
 * @see <a
73
 * href="http://developer.apple.com/fonts/TTRefMan/">Apple&#x2019;s</code>
74
 * TrueType specification</a>
75
 *
76
 * @author Sascha Brawer (brawer@dandelis.ch)
77
 */
78
public final class OpenTypeFont
79
  implements FontDelegate
80
{
81
  static final int TAG_OTTO = 0x4f54544f; // 'OTTO'
82
  static final int TAG_SFNT = 0x73666e74; // 'sfnt'
83
  static final int TAG_TRUE = 0x74727565; // 'true'
84
  static final int TAG_TTCF = 0x74746366; // 'ttcf'
85
  static final int TAG_ZAPF = 0x5a617066; // 'Zapf'
86
 
87
 
88
  /**
89
   * A buffer containing the font data. Note that this may well be an
90
   * instance of the subclass MappedByteBuffer, in which case the
91
   * virtual memory subsystem can more efficiently handle requests for
92
   * font data. This is especially recommended for large font files
93
   * that contain many glyphs that are rarely accessed.
94
   */
95
  ByteBuffer buf;
96
 
97
 
98
  /**
99
   * The number of glyphs in this font.
100
   */
101
  final int numGlyphs;
102
 
103
  int[] tableTag, tableStart, tableLength;
104
 
105
 
106
  /**
107
   * The version of the font in 16.16 fixed-point encoding, for
108
   * example 0x00010000 for version 1.0. There are also two special
109
   * version IDs used by fonts for Apple Macintosh, namely 'true'
110
   * (0x74727565) and 'typ1'. OpenType fonts sometimes have 'OTTO' as
111
   * their version.
112
   */
113
  private int version;
114
 
115
 
116
  /**
117
   * The number of font units per em. For fonts with TrueType
118
   * outlines, this is usually a power of two (such as 2048). For
119
   * OpenType fonts with PostScript outlines, other values are
120
   * acceptable (such as 1000).
121
   */
122
  public int unitsPerEm;
123
 
124
 
125
  /**
126
   * A factor to convert font units into ems. This value is <code>1 /
127
   * unitsPerEm</code>.
128
   */
129
  private float emsPerUnit;
130
 
131
 
132
  /**
133
   * The scaler to which the actual scaling work is delegated.
134
   */
135
  private Scaler scaler;
136
 
137
 
138
  /**
139
   * A delegate object for mapping Unicode UCS-4 codepoints to glyph
140
   * IDs.
141
   */
142
  private CharGlyphMap cmap;
143
 
144
 
145
  /**
146
   * A delegate object for providing a name for each glyph.
147
   */
148
  private GlyphNamer glyphNamer;
149
 
150
  private Hinter hinter;
151
 
152
  /**
153
   * Constructs an OpenType or TrueType font.
154
   *
155
   * @param buf a buffer with the contents of the font file. It is
156
   * recommended to use a <code>MappedByteBuffer</code> for very
157
   * large font files.
158
   *
159
   * @param offsetTablePosition the position of the OpenType offset
160
   * table in the font file. The offset table of most OpenType and
161
   * TrueType fonts starts at position 0.  However, so-called TrueType
162
   * Collections support multiple OpenType fonts in a single file,
163
   * which allows sharing some glyphs between fonts. If many glyphs
164
   * are shared (for example all the Kanji glyphs between multiple
165
   * Japanese fonts), the space savings can be considerable. In that
166
   * case, the offset table of each individual font would start at its
167
   * own position.
168
   *
169
   * @throws java.awt.FontFormatException if the font data is
170
   * not in OpenType or TrueType format.
171
   */
172
  OpenTypeFont(ByteBuffer buf, int offsetTablePosition)
173
    throws FontFormatException
174
  {
175
    int numTables, searchRange, entrySelector, rangeShift;
176
 
177
    //buf = buf.duplicate();
178
    this.buf = buf;
179
    buf.limit(buf.capacity());
180
    buf.position(offsetTablePosition);
181
 
182
    /* Check that the font data is in a supported format. */
183
    version = buf.getInt();
184
    switch (version)
185
    {
186
    case 0x00010000:        // Microsoft TrueType
187
    case OpenType.TAG_TYP1: // Adobe PostScript embeded in Apple SFNT ('typ1')
188
    case TAG_SFNT:          // Apple TrueType
189
    case TAG_TRUE:          // Apple TrueType
190
    case TAG_OTTO:          // OpenType
191
      break;
192
 
193
    default:
194
      throw new FontFormatException("not in OpenType or TrueType format");
195
    }
196
 
197
    numTables = buf.getShort();
198
    searchRange = buf.getShort();
199
    entrySelector = buf.getShort();
200
    rangeShift = buf.getShort();
201
 
202
    tableTag = new int[numTables];
203
    tableStart = new int[numTables];
204
    tableLength = new int[numTables];
205
    int lastTag = 0;
206
    for (int i = 0; i < numTables; i++)
207
    {
208
      tableTag[i] = buf.getInt();
209
      if (lastTag >= tableTag[i])
210
        throw new FontFormatException("unordered OpenType table");
211
 
212
      buf.getInt(); // ignore checksum
213
      tableStart[i] = buf.getInt();
214
      tableLength[i] = buf.getInt();
215
 
216
      //System.out.println(tagToString(tableTag[i]) + ", " + tableLength[i]);
217
    }
218
 
219
    ByteBuffer head = getFontTable(OpenType.TAG_HEAD);
220
    if ((head.getInt(0) != 0x00010000)
221
        || (head.getInt(12) != 0x5f0f3cf5))
222
        throw new FontFormatException("unsupported head version");
223
 
224
    unitsPerEm = head.getChar(18);
225
    emsPerUnit = 1.0f / (float) unitsPerEm;
226
 
227
 
228
    ByteBuffer maxp = getFontTable(OpenType.TAG_MAXP);
229
    int maxpVersion = maxp.getInt(0);
230
    switch (maxpVersion)
231
    {
232
    case 0x00005000: /* version 0.5, with wrong fractional part */
233
      numGlyphs = maxp.getChar(4);
234
      break;
235
 
236
    case 0x00010000: /* version 1.0 */
237
      numGlyphs = maxp.getChar(4);
238
      scaler = new TrueTypeScaler(unitsPerEm,
239
                                  getFontTable(OpenType.TAG_HHEA),
240
                                  getFontTable(OpenType.TAG_HMTX),
241
                                  getFontTable(OpenType.TAG_VHEA),
242
                                  getFontTable(OpenType.TAG_VMTX),
243
                                  maxp,
244
                                  getFontTable(OpenType.TAG_CVT),
245
                                  getFontTable(OpenType.TAG_FPGM),
246
                                  /* loca format */ head.getShort(50),
247
                                  getFontTable(OpenType.TAG_LOCA),
248
                                  getFontTable(OpenType.TAG_GLYF),
249
                                  getFontTable(OpenType.TAG_PREP));
250
      break;
251
 
252
    default:
253
      throw new FontFormatException("unsupported maxp version");
254
    }
255
  }
256
 
257
 
258
  /**
259
   * Determines the index of a table into the offset table.  The
260
   * result can be used to find the offset and length of a table, as
261
   * in <code>tableStart[getTableIndex(TAG_NAME)]</code>.
262
   *
263
   * @param tag the table identifier, for instance
264
   * <code>OpenType.TAG_NAME</code>.
265
   *
266
   * @return the index of that table into the offset table, or
267
   * -1 if the font does not contain the table specified by
268
   * <code>tag</code>.
269
   */
270
  private int getTableIndex(int tag)
271
  {
272
    /* FIXME: Since the font specification requires tableTag[] to be
273
     * ordered, one should do binary search here.
274
     */
275
    for (int i = 0; i < tableTag.length; i++)
276
      if (tableTag[i] == tag)
277
        return i;
278
    return -1;
279
  }
280
 
281
 
282
 
283
  /**
284
   * Returns the name of the family to which this font face belongs,
285
   * for example <i>&#x201c;Univers&#x201d;</i>.
286
   *
287
   * @param locale the locale for which to localize the name.
288
   *
289
   * @return the family name.
290
   */
291
  public synchronized String getFamilyName(Locale locale)
292
  {
293
    String name;
294
 
295
    if (locale == null)
296
      locale = Locale.getDefault();
297
 
298
    name = getName(NameDecoder.NAME_FAMILY, locale);
299
    if (name == null)
300
      name = getName(NameDecoder.NAME_FAMILY, Locale.ENGLISH);
301
    if (name == null)
302
      name = getName(NameDecoder.NAME_FAMILY, /* any language */ null);
303
    if (name == null)
304
      name = getName(NameDecoder.NAME_FULL, locale);
305
    if (name == null)
306
      name = getName(NameDecoder.NAME_FULL, /* any language */ null);
307
    return name;
308
  }
309
 
310
 
311
  /**
312
   * Returns the name of this font face inside the family, for example
313
   * <i>&#x201c;Light&#x201d;</i>.
314
   *
315
   * @param locale the locale for which to localize the name.
316
   *
317
   * @return the name of the face inside its family.
318
   */
319
  public synchronized String getSubFamilyName(Locale locale)
320
  {
321
    String name;
322
 
323
    if (locale == null)
324
      locale = Locale.getDefault();
325
 
326
    name = getName(NameDecoder.NAME_SUBFAMILY, locale);
327
    if (name == null)
328
    {
329
      name = getName(NameDecoder.NAME_SUBFAMILY, Locale.ENGLISH);
330
      if ("Regular".equals(name))
331
        name = null;
332
    }
333
 
334
    if (name == null)
335
    {
336
      String lang = locale.getLanguage();
337
      if ("de".equals(lang))
338
        name = "Standard";
339
      else if ("fr".equals(lang))
340
        name = "Standard";
341
      else if ("it".equals(lang))
342
        name = "Normale";
343
      else if ("nl".equals(lang))
344
        name = "Normaal";
345
      else if ("fi".equals(lang))
346
        name = "Normaali";
347
      else if ("sv".equals(lang))
348
        name = "Normal";
349
      else
350
        name = "Regular";
351
    }
352
 
353
    return name;
354
  }
355
 
356
 
357
 
358
  /**
359
   * Returns the full name of this font face, for example
360
   * <i>&#x201c;Univers Light&#x201d;</i>.
361
   *
362
   * @param locale the locale for which to localize the name.
363
   *
364
   * @return the face name.
365
   */
366
  public synchronized String getFullName(Locale locale)
367
  {
368
    String name;
369
 
370
    if (locale == null)
371
      locale = Locale.getDefault();
372
 
373
    name = getName(NameDecoder.NAME_FULL, locale);
374
    if (name == null)
375
      name = getName(NameDecoder.NAME_FULL, Locale.ENGLISH);
376
    if (name == null)
377
      name = getName(NameDecoder.NAME_FULL, /* any language */ null);
378
 
379
    return name;
380
  }
381
 
382
 
383
  /**
384
   * Returns the PostScript name of this font face, for example
385
   * <i>&#x201c;Univers-Light&#x201d;</i>.
386
   *
387
   * @return the PostScript name, or <code>null</code> if the font
388
   * does not provide a PostScript name.
389
   */
390
  public synchronized String getPostScriptName()
391
  {
392
    return getName(NameDecoder.NAME_POSTSCRIPT, /* any language */ null);
393
  }
394
 
395
 
396
  /**
397
   * Returns the number of glyphs in this font face.
398
   */
399
  public int getNumGlyphs()
400
  {
401
    /* No synchronization is needed because the number of glyphs is
402
     * set in the constructor, and it cannot change during the
403
     * lifetime of the object.
404
     */
405
    return numGlyphs;
406
  }
407
 
408
 
409
  /**
410
   * Returns the index of the glyph which gets displayed if the font
411
   * cannot map a Unicode code point to a glyph. Many fonts show this
412
   * glyph as an empty box.
413
   */
414
  public int getMissingGlyphCode()
415
  {
416
    /* No synchronization is needed because the result is constant. */
417
    return 0;
418
  }
419
 
420
 
421
  /**
422
   * The font&#x2019;s name table, or <code>null</code> if this
423
   * table has not yet been accessed.
424
   */
425
  private ByteBuffer nameTable;
426
 
427
 
428
  /**
429
   * Extracts a String from the font&#x2019;s name table.
430
   *
431
   * @param name the numeric TrueType or OpenType name ID.
432
   *
433
   * @param locale the locale for which names shall be localized, or
434
   * <code>null</code> if the locale does mot matter because the name
435
   * is known to be language-independent (for example, because it is
436
   * the PostScript name).
437
   */
438
  private String getName(int name, Locale locale)
439
  {
440
    if (nameTable == null)
441
      nameTable = getFontTable(OpenType.TAG_NAME);
442
    return NameDecoder.getName(nameTable, name, locale);
443
  }
444
 
445
 
446
  /**
447
   * Returns the version of the font.
448
   *
449
   * @see java.awt.font.OpenType#getVersion
450
   *
451
   * @return the version in 16.16 fixed-point encoding, for example
452
   * 0x00010000 for version 1.0.
453
   */
454
  public int getVersion()
455
  {
456
    /* No synchronization is needed because the version is set in the
457
     * constructor, and it cannot change during the lifetime of the
458
     * object.
459
     */
460
    return version;
461
  }
462
 
463
 
464
  /**
465
   * Creates a view buffer for an OpenType table. The caller can
466
   * access the returned buffer without needing to synchronize access
467
   * from multiple threads.
468
   *
469
   * @param tag the table identifier, for example
470
   * <code>OpenType.GLYF</code>.
471
   *
472
   * @return a slice of the underlying buffer containing the table, or
473
   * <code>null</code> if the font does not contain the requested
474
   * table.
475
   */
476
  public synchronized ByteBuffer getFontTable(int tag)
477
  {
478
    int index, start, len;
479
    ByteBuffer result;
480
 
481
    index = getTableIndex(tag);
482
    if (index < 0)
483
      return null;
484
 
485
    start = tableStart[index];
486
    len = tableLength[index];
487
    buf.limit(start + len).position(start);
488
    result = buf.slice();
489
    result.limit(len);
490
    return result;
491
  }
492
 
493
 
494
  /**
495
   * Returns the size of one of the tables in the font,
496
   * or -1 if the table does not exist.
497
   */
498
  public int getFontTableSize(int tag)
499
  {
500
    int index = getTableIndex(tag);
501
    if (index == -1)
502
      return index;
503
    return tableLength[index];
504
  }
505
 
506
 
507
  private CharGlyphMap getCharGlyphMap()
508
  {
509
    if (cmap != null)
510
      return cmap;
511
 
512
    synchronized (this)
513
    {
514
      if (cmap == null)
515
      {
516
        int index = getTableIndex(OpenType.TAG_CMAP);
517
        int start = tableStart[index];
518
        buf.limit(start + tableLength[index]).position(start);
519
        cmap = CharGlyphMap.forTable(buf);
520
      }
521
      return cmap;
522
    }
523
  }
524
 
525
 
526
 
527
  /**
528
   * Looks up a glyph in the font&#x2019;s <code>cmap</code> tables,
529
   * without performing any glyph substitution or reordering. Because
530
   * of this limitation, this method cannot be used for script systems
531
   * that need advanced glyph mapping, such as Arabic, Korean, or even
532
   * Latin with exotic accents.
533
   *
534
   * <p>It is safe to call this method from any thread.
535
   *
536
   * @param ucs4 the Unicode codepoint in the 32-bit Unicode character
537
   * set UCS-4. Because UTF-16 surrogates do not correspond to a single
538
   * glyph, it does not make sense to pass them here.
539
   *
540
   * @return the glyph index, or zero if the font does not contain
541
   * a glyph for the specified codepoint.
542
   */
543
  public int getGlyph(int ucs4)
544
  {
545
    return getCharGlyphMap().getGlyph(ucs4);
546
  }
547
 
548
 
549
  /**
550
   * Creates a GlyphVector by mapping each character in a
551
   * CharacterIterator to the corresponding glyph.
552
   *
553
   * <p>The mapping takes only the font&#x2019;s <code>cmap</code>
554
   * tables into consideration. No other operations (such as glyph
555
   * re-ordering, composition, or ligature substitution) are
556
   * performed. This means that the resulting GlyphVector will not be
557
   * correct for text in languages that have complex
558
   * character-to-glyph mappings, such as Arabic, Hebrew, Hindi, or
559
   * Thai.
560
   *
561
   * @param font the font object that the created GlyphVector
562
   * will return when it gets asked for its font. This argument is
563
   * needed because the public API works with java.awt.Font,
564
   * not with some private delegate like OpenTypeFont.
565
   *
566
   * @param frc the font rendering parameters that are used for
567
   * measuring glyphs. The exact placement of text slightly depends on
568
   * device-specific characteristics, for instance the device
569
   * resolution or anti-aliasing. For this reason, any measurements
570
   * will only be accurate if the passed
571
   * <code>FontRenderContext</code> correctly reflects the relevant
572
   * parameters. Hence, <code>frc</code> should be obtained from the
573
   * same <code>Graphics2D</code> that will be used for drawing, and
574
   * any rendering hints should be set to the desired values before
575
   * obtaining <code>frc</code>.
576
   *
577
   * @param ci a CharacterIterator for iterating over the
578
   * characters to be displayed.
579
   */
580
  public synchronized GlyphVector createGlyphVector(Font font,
581
                                                    FontRenderContext frc,
582
                                                    CharacterIterator ci)
583
  {
584
    // Initialize hinter if necessary.
585
    checkHinter(FontDelegate.FLAG_FITTED);
586
 
587
    CharGlyphMap cmap;
588
    int numGlyphs;
589
    int[] glyphs;
590
    int glyph;
591
    int c;
592
 
593
    cmap = getCharGlyphMap();
594
    numGlyphs = ci.getEndIndex() - ci.getBeginIndex();
595
    glyphs = new int[numGlyphs];
596
    glyph = 0;
597
    for (c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
598
    {
599
      /* handle surrogate pairs */
600
      if (c >> 10 == 0x36) // U+D800 .. U+DBFF: High surrogate
601
        c = (((c & 0x3ff) << 10) | (ci.next() & 0x3ff)) + 0x10000;
602
      glyphs[glyph] = cmap.getGlyph(c);
603
      glyph += 1;
604
    }
605
 
606
    /* If we had surrogates, the allocated array is too large.
607
     * Because this will occur very rarely, it seems acceptable to
608
     * re-allocate a shorter array and copy the contents around.
609
     */
610
    if (glyph != numGlyphs)
611
    {
612
      int[] newGlyphs = new int[glyph];
613
      System.arraycopy(glyphs, 0, newGlyphs, 0, glyph);
614
      glyphs = newGlyphs;
615
    }
616
 
617
    return new GNUGlyphVector(this, font, frc, glyphs);
618
  }
619
 
620
  /**
621
   * Returns the glyph code for the specified character.
622
   *
623
   * @param c the character to map
624
   *
625
   * @return the glyph code
626
   */
627
  public int getGlyphIndex(int c)
628
  {
629
    return getCharGlyphMap().getGlyph(c);
630
  }
631
 
632
  /**
633
   * Determines the advance width for a glyph.
634
   *
635
   * @param glyphIndex the glyph whose advance width is to be
636
   * determined.
637
   *
638
   * @param pointSize the point size of the font.
639
   *
640
   * @param transform a transform that is applied in addition to
641
   * scaling to the specified point size. This is often used for
642
   * scaling according to the device resolution. Those who lack any
643
   * aesthetic sense may also use the transform to slant or stretch
644
   * glyphs.
645
   *
646
   * @param antialias <code>true</code> for anti-aliased rendering,
647
   * <code>false</code> for normal rendering. For hinted fonts,
648
   * this parameter may indeed affect the result.
649
   *
650
   * @param fractionalMetrics <code>true</code> for fractional metrics,
651
   * <code>false</code> for rounding the result to a pixel boundary.
652
   *
653
   * @param horizontal <code>true</code> for horizontal line layout,
654
   * <code>false</code> for vertical line layout.
655
   *
656
   * @param advance a point whose <code>x</code> and <code>y</code>
657
   * fields will hold the advance in each direction. It is possible
658
   * that both values are non-zero, for example if
659
   * <code>transform</code> is a rotation, or in the case of Urdu
660
   * fonts.
661
   */
662
  public synchronized void getAdvance(int glyphIndex,
663
                                      float pointSize,
664
                                      AffineTransform transform,
665
                                      boolean antialias,
666
                                      boolean fractionalMetrics,
667
                                      boolean horizontal,
668
                                      Point2D advance)
669
  {
670
    /* Delegate the measurement to the scaler.  The synchronization is
671
     * needed because the scaler is not synchronized.
672
     */
673
    scaler.getAdvance(glyphIndex, pointSize, transform,
674
                      antialias, fractionalMetrics, horizontal,
675
                      advance);
676
  }
677
 
678
 
679
  /**
680
   * Returns the shape of a glyph.
681
   *
682
   * @param glyph the glyph whose advance width is to be determined
683
   *
684
   * @param pointSize the point size of the font.
685
   *
686
   * @param transform a transform that is applied in addition to
687
   * scaling to the specified point size. This is often used for
688
   * scaling according to the device resolution. Those who lack any
689
   * aesthetic sense may also use the transform to slant or stretch
690
   * glyphs.
691
   *
692
   * @param antialias <code>true</code> for anti-aliased rendering,
693
   * <code>false</code> for normal rendering. For hinted fonts, this
694
   * parameter may indeed affect the result.
695
   *
696
   * @param fractionalMetrics <code>true</code> for fractional
697
   * metrics, <code>false</code> for rounding the result to a pixel
698
   * boundary.
699
   *
700
   * @return the scaled and grid-fitted outline of the specified
701
   * glyph, or <code>null</code> for bitmap fonts.
702
   */
703
  public synchronized GeneralPath getGlyphOutline(int glyph,
704
                                                  float pointSize,
705
                                                  AffineTransform transform,
706
                                                  boolean antialias,
707
                                                  boolean fractionalMetrics,
708
                                                  int flags)
709
  {
710
    /* The synchronization is needed because the scaler is not
711
     * synchronized.
712
     */
713
    checkHinter(flags);
714
    return scaler.getOutline(glyph, pointSize, transform,
715
                             antialias, fractionalMetrics, hinter, flags);
716
  }
717
 
718
  /**
719
   * Fetches the raw glyph outline for the specified glyph index. This is used
720
   * for the autofitter only ATM and is otherwise not usable for outside code.
721
   *
722
   * @param glyph the glyph index to fetch
723
   * @param transform the transform to apply
724
   *
725
   * @return the raw outline of that glyph
726
   */
727
  public synchronized Zone getRawGlyphOutline(int glyph,
728
                                              AffineTransform transform)
729
  {
730
    return scaler.getRawOutline(glyph, transform);
731
  }
732
 
733
  /**
734
   * Returns a name for the specified glyph. This is useful for
735
   * generating PostScript or PDF files that embed some glyphs of a
736
   * font.
737
   *
738
   * <p><b>Names are not unique:</b> Under some rare circumstances,
739
   * the same name can be returned for different glyphs. It is
740
   * therefore recommended that printer drivers check whether the same
741
   * name has already been returned for antoher glyph, and make the
742
   * name unique by adding the string ".alt" followed by the glyph
743
   * index.</p>
744
   *
745
   * <p>This situation would occur for an OpenType or TrueType font
746
   * that has a <code>post</code> table of format 3 and provides a
747
   * mapping from glyph IDs to Unicode sequences through a
748
   * <code>Zapf</code> table. If the same sequence of Unicode
749
   * codepoints leads to different glyphs (depending on contextual
750
   * position, for example, or on typographic sophistication level),
751
   * the same name would get synthesized for those glyphs.
752
   *
753
   * @param glyphIndex the glyph whose name the caller wants to
754
   * retrieve.
755
   */
756
  public synchronized String getGlyphName(int glyphIndex)
757
  {
758
    if (glyphNamer == null)
759
      glyphNamer = GlyphNamer.forTables(numGlyphs,
760
                                        getFontTable(OpenType.TAG_POST),
761
                                        getFontTable(TAG_ZAPF));
762
 
763
    return glyphNamer.getGlyphName(glyphIndex);
764
  }
765
 
766
 
767
  /**
768
   * Determines the distance between the base line and the highest
769
   * ascender.
770
   *
771
   * @param pointSize the point size of the font.
772
   *
773
   * @param transform a transform that is applied in addition to
774
   * scaling to the specified point size. This is often used for
775
   * scaling according to the device resolution. Those who lack any
776
   * aesthetic sense may also use the transform to slant or stretch
777
   * glyphs.
778
   *
779
   * @param antialiased <code>true</code> for anti-aliased rendering,
780
   * <code>false</code> for normal rendering. For hinted fonts,
781
   * this parameter may indeed affect the result.
782
   *
783
   * @param fractionalMetrics <code>true</code> for fractional metrics,
784
   * <code>false</code> for rounding the result to a pixel boundary.
785
   *
786
   * @param horizontal <code>true</code> for horizontal line layout,
787
   * <code>false</code> for vertical line layout.
788
   *
789
   * @return the ascent, which usually is a positive number.
790
   */
791
  public synchronized float getAscent(float pointSize,
792
                                      AffineTransform transform,
793
                                      boolean antialiased,
794
                                      boolean fractionalMetrics,
795
                                      boolean horizontal)
796
  {
797
    return scaler.getAscent(pointSize, transform,
798
                            antialiased, fractionalMetrics,
799
                            horizontal);
800
  }
801
 
802
 
803
  /**
804
   * Determines the distance between the base line and the lowest
805
   * descender.
806
   *
807
   * @param pointSize the point size of the font.
808
   *
809
   * @param transform a transform that is applied in addition to
810
   * scaling to the specified point size. This is often used for
811
   * scaling according to the device resolution. Those who lack any
812
   * aesthetic sense may also use the transform to slant or stretch
813
   * glyphs.
814
   *
815
   * @param antialiased <code>true</code> for anti-aliased rendering,
816
   * <code>false</code> for normal rendering. For hinted fonts,
817
   * this parameter may indeed affect the result.
818
   *
819
   * @param fractionalMetrics <code>true</code> for fractional metrics,
820
   * <code>false</code> for rounding the result to a pixel boundary.
821
   *
822
   * @param horizontal <code>true</code> for horizontal line layout,
823
   * <code>false</code> for vertical line layout.
824
   *
825
   * @return the descent, which usually is a nagative number.
826
   */
827
  public synchronized float getDescent(float pointSize,
828
                                       AffineTransform transform,
829
                                       boolean antialiased,
830
                                       boolean fractionalMetrics,
831
                                       boolean horizontal)
832
  {
833
    return scaler.getDescent(pointSize, transform,
834
                             antialiased, fractionalMetrics,
835
                             horizontal);
836
  }
837
 
838
 
839
  /**
840
   * Converts a four-byte tag identifier into a String that can be
841
   * displayed when debugging this class.
842
   *
843
   * @param tag the tag as an <code>int</code>.
844
   *
845
   * @return the tag in human-readable form, for example
846
   * <code>name</code> or <code>glyf</code>.
847
   */
848
  static String tagToString(int tag)
849
  {
850
    char[] c = new char[4];
851
    c[0] = (char) ((tag >> 24) & 0xff);
852
    c[1] = (char) ((tag >> 16) & 0xff);
853
    c[2] = (char) ((tag >> 8) & 0xff);
854
    c[3] = (char) (tag & 0xff);
855
    return new String(c);
856
  }
857
 
858
  /**
859
   * Checks if a hinter is installed and installs one when not.
860
   */
861
  private void checkHinter(int flags)
862
  {
863
    // When another hinting impl gets added (maybe a true TrueType hinter)
864
    // then add some options here. The Hinter interface might need to be
865
    // tweaked.
866
    if (hinter == null)
867
      {
868
        try
869
          {
870
            hinter = new AutoHinter();
871
            hinter.init(this);
872
          }
873
        catch (Exception ex)
874
          {
875
            // Protect from problems inside hinter.
876
            hinter = null;
877
            ex.printStackTrace();
878
          }
879
      }
880
    hinter.setFlags(flags);
881
  }
882
}

powered by: WebSVN 2.1.0

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