jdk/src/share/classes/sun/font/Type1Font.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 558 14291c56e115
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.lang.ref.WeakReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.FontFormatException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.FileNotFoundException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.RandomAccessFile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.UnsupportedEncodingException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.lang.ref.WeakReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.nio.ByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.nio.ByteOrder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.nio.MappedByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.nio.BufferUnderflowException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.nio.channels.ClosedChannelException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.nio.channels.FileChannel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import sun.java2d.Disposer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.util.HashSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.awt.Font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * Adobe Technical Note 5040 details the format of PFB files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * the file is divided into ascii and binary sections. Each section
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * starts with a header
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * 0x8001 - start of binary data, is followed by 4 bytes length, then data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * 0x8002 - start of ascii data, is followed by 4 bytes length, then data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * 0x8003 - end of data segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * The length is organised as LSB->MSB.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * Note: I experimented with using a MappedByteBuffer and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * there were two problems/questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * 1. If a global buffer is used rather than one allocated in the calling
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * context, then we need to synchronize on all uses of that data, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * means more code would beed to be synchronized with probable repercussions
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * elsewhere.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * 2. It is not clear whether to free the buffer when the file is closed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * If we have the contents in memory then why keep open files around?
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * The mmapped buffer doesn't need it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * Also regular GC is what frees the buffer. So closing the file and nulling
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * out the reference still needs to wait for the buffer to be GC'd to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * reclaim the storage.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * If the contents of the buffer are persistent there's no need
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * to worry about synchronization.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * Perhaps could use a WeakReference, and when its referent is gone, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * need it can just reopen the file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * Type1 fonts thus don't use up file descriptor references, but can
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * use memory footprint in a way that's managed by the host O/S.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * The main "pain" may be the different model means code needs to be written
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * without assumptions as to how this is handled by the different subclasses
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * of FileFont.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
public class Type1Font extends FileFont {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    WeakReference bufferRef = new WeakReference(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    private String psName = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    static private HashMap styleAbbreviationsMapping;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    static private HashSet styleNameTokes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        styleAbbreviationsMapping = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        styleNameTokes = new HashSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        /* These abbreviation rules are taken from Appendix 1 of Adobe Technical Note #5088 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        /* NB: this list is not complete - we did not include abbreviations which contain
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
               several capital letters because current expansion algorithm do not support this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
               (namely we have omited MM aka "Multiple Master", OsF aka "Oldstyle figures",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
                           OS aka "Oldstyle", SC aka "Small caps" and  DS aka "Display" */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        String nm[] = {"Black", "Bold", "Book", "Demi", "Heavy", "Light",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
                       "Meduium", "Nord", "Poster", "Regular", "Super", "Thin",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
                       "Compressed", "Condensed", "Compact", "Extended", "Narrow",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                       "Inclined", "Italic", "Kursiv", "Oblique", "Upright", "Sloped",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                       "Semi", "Ultra", "Extra",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                       "Alternate", "Alternate", "Deutsche Fraktur", "Expert", "Inline", "Ornaments",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                       "Outline", "Roman", "Rounded", "Script", "Shaded", "Swash", "Titling", "Typewriter"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        String abbrv[] = {"Blk", "Bd", "Bk", "Dm", "Hv", "Lt",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                          "Md", "Nd", "Po", "Rg", "Su", "Th",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                          "Cm", "Cn", "Ct", "Ex", "Nr",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                          "Ic", "It", "Ks", "Obl", "Up", "Sl",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                          "Sm", "Ult", "X",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                          "A", "Alt", "Dfr", "Exp", "In", "Or",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                          "Ou", "Rm", "Rd", "Scr", "Sh", "Sw", "Ti", "Typ"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
       /* This is only subset of names from nm[] because we want to distinguish things
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
           like "Lucida Sans TypeWriter Bold" and "Lucida Sans Bold".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
           Names from "Design and/or special purpose" group are omitted. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
       String styleTokens[] = {"Black", "Bold", "Book", "Demi", "Heavy", "Light",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                       "Medium", "Nord", "Poster", "Regular", "Super", "Thin",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                       "Compressed", "Condensed", "Compact", "Extended", "Narrow",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                       "Inclined", "Italic", "Kursiv", "Oblique", "Upright", "Sloped", "Slanted",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                       "Semi", "Ultra", "Extra"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        for(int i=0; i<nm.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            styleAbbreviationsMapping.put(abbrv[i], nm[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        for(int i=0; i<styleTokens.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            styleNameTokes.add(styleTokens[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * - does basic verification of the file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     * - reads the names (full, family).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * - determines the style of the font.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * @throws FontFormatException - if the font can't be opened
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * or fails verification,  or there's no usable cmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    public Type1Font(String platname, Object nativeNames)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        throws FontFormatException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        super(platname, nativeNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        fontRank = Font2D.TYPE1_RANK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        checkedNatives = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        verify();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    private synchronized ByteBuffer getBuffer() throws FontFormatException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        MappedByteBuffer mapBuf = (MappedByteBuffer)bufferRef.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        if (mapBuf == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
          //System.out.println("open T1 " + platName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                RandomAccessFile raf = (RandomAccessFile)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                java.security.AccessController.doPrivileged(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                    new java.security.PrivilegedAction() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                        public Object run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                                return new RandomAccessFile(platName, "r");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                            } catch (FileNotFoundException ffne) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                FileChannel fc = raf.getChannel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                fileSize = (int)fc.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                mapBuf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fileSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                mapBuf.position(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                bufferRef = new WeakReference(mapBuf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                fc.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            } catch (NullPointerException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                throw new FontFormatException(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            } catch (ClosedChannelException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                /* NIO I/O is interruptible, recurse to retry operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                 * Clear interrupts before recursing in case NIO didn't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                Thread.interrupted();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                return getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                throw new FontFormatException(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        return mapBuf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    protected void close() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    /* called from native code to read file into a direct byte buffer */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    void readFile(ByteBuffer buffer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        RandomAccessFile raf = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        FileChannel fc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            raf = (RandomAccessFile)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                java.security.AccessController.doPrivileged(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                    new java.security.PrivilegedAction() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                        public Object run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                                return new RandomAccessFile(platName, "r");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                            } catch (FileNotFoundException fnfe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            fc = raf.getChannel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            while (buffer.remaining() > 0 && fc.read(buffer) != -1) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        } catch (NullPointerException npe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        } catch (ClosedChannelException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                if (raf != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                    raf.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                    raf = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            } catch (IOException ioe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            /* NIO I/O is interruptible, recurse to retry operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
             * Clear interrupts before recursing in case NIO didn't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            Thread.interrupted();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            readFile(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        } finally  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            if (raf != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                    raf.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    public synchronized ByteBuffer readBlock(int offset, int length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        ByteBuffer mappedBuf = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            mappedBuf = getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            if (offset > fileSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                offset = fileSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            mappedBuf.position(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            return mappedBuf.slice();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        } catch (FontFormatException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    private void verify() throws FontFormatException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        /* Normal usage should not call getBuffer(), as its state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
         * ie endianness, position etc, are shared. verify() can do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
         * this as its called only from within the constructor before
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
         * there are other users of this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        ByteBuffer bb = getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        if (bb.capacity() < 6) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
            throw new FontFormatException("short file");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        int val = bb.get(0) & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        if ((bb.get(0) & 0xff) == 0x80) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            verifyPFB(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            bb.position(6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            verifyPFA(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            bb.position(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        initNames(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        if (familyName == null || fullName == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            throw new FontFormatException("Font name not found");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        setStyle();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    public int getFileSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        if (fileSize == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                getBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            } catch (FontFormatException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        return fileSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    private void verifyPFA(ByteBuffer bb) throws FontFormatException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        if (bb.getShort() != 0x2521) { // 0x2521 is %!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            throw new FontFormatException("bad pfa font");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        // remind - additional verification needed?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    private void verifyPFB(ByteBuffer bb) throws FontFormatException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        int pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                int segType = bb.getShort(pos) & 0xffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                if (segType == 0x8001 || segType == 0x8002) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                    bb.order(ByteOrder.LITTLE_ENDIAN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                    int segLen = bb.getInt(pos+2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                    bb.order(ByteOrder.BIG_ENDIAN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                    if (segLen <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                        throw new FontFormatException("bad segment length");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                    pos += segLen+6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                } else if (segType == 0x8003) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                    return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                    throw new FontFormatException("bad pfb file");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            } catch (BufferUnderflowException bue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                throw new FontFormatException(bue.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                throw new FontFormatException(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    private static final int PSEOFTOKEN = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    private static final int PSNAMETOKEN = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    private static final int PSSTRINGTOKEN = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    /* Need to parse the ascii contents of the Type1 font file,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * looking for FullName, FamilyName and FontName.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * If explicit names are not found then extract them from first text line.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * Operating on bytes so can't use Java String utilities, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * is a large part of why this is a hack.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * Also check for mandatory FontType and verify if it is supported.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    private void initNames(ByteBuffer bb) throws FontFormatException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        boolean eof = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        String fontType = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            //Parse font looking for explicit FullName, FamilyName and FontName
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            //  (acording to Type1 spec they are optional)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            while ((fullName == null || familyName == null || psName == null || fontType == null) && !eof) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                int tokenType = nextTokenType(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                if (tokenType == PSNAMETOKEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                    int pos = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                    if (bb.get(pos) == 'F') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                        String s = getSimpleToken(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                        if ("FullName".equals(s)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                            if (nextTokenType(bb)==PSSTRINGTOKEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                                fullName = getString(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                        } else if ("FamilyName".equals(s)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                            if (nextTokenType(bb)==PSSTRINGTOKEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                                familyName = getString(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                        } else if ("FontName".equals(s)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                            if (nextTokenType(bb)==PSNAMETOKEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                                psName = getSimpleToken(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                        } else if ("FontType".equals(s)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                            /* look for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                                 /FontType id def
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                            */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                            String token = getSimpleToken(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                            if ("def".equals(getSimpleToken(bb))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                                fontType = token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                        while (bb.get() > ' '); // skip token
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                } else if (tokenType == PSEOFTOKEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                    eof = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                throw new FontFormatException(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        /* Ignore all fonts besides Type1 (e.g. Type3 fonts) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        if (!"1".equals(fontType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            throw new FontFormatException("Unsupported font type");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    if (psName == null) { //no explicit FontName
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                // Try to extract font name from the first text line.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                // According to Type1 spec first line consist of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                //  "%!FontType1-SpecVersion: FontName FontVersion"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                // or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                //  "%!PS-AdobeFont-1.0: FontName version"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                bb.position(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                if (bb.getShort() != 0x2521) { //if pfb (do not start with "%!")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                    //skip segment header and "%!"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                    bb.position(8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                    //NB: assume that first segment is ASCII one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                    //  (is it possible to have valid Type1 font with first binary segment?)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                String formatType = getSimpleToken(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                if (!formatType.startsWith("FontType1-") && !formatType.startsWith("PS-AdobeFont-")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                        throw new FontFormatException("Unsupported font format [" + formatType + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                psName = getSimpleToken(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    //if we got to the end of file then we did not find at least one of FullName or FamilyName
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    //Try to deduce missing names from present ones
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    //NB: At least psName must be already initialized by this moment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        if (eof) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            //if we find fullName or familyName then use it as another name too
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
            if (fullName != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                familyName = fullName2FamilyName(fullName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            } else if (familyName != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                fullName = familyName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            } else { //fallback - use postscript font name to deduce full and family names
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                fullName = psName2FullName(psName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                familyName = psName2FamilyName(psName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    private String fullName2FamilyName(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        String res, token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        int len, start, end; //length of family name part
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        //FamilyName is truncated version of FullName
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        //Truncated tail must contain only style modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        end = name.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        while (end > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            start = end - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            while (start > 0 && name.charAt(start) != ' ')
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
              start--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            //as soon as we meet first non style token truncate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            // current tail and return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                        if (!isStyleToken(name.substring(start+1, end))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                                return name.substring(0, end);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                        end = start;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                return name; //should not happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    private String expandAbbreviation(String abbr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        if (styleAbbreviationsMapping.containsKey(abbr))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                        return (String) styleAbbreviationsMapping.get(abbr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        return abbr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    private boolean isStyleToken(String token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        return styleNameTokes.contains(token);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    private String psName2FullName(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        String res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        //According to Adobe technical note #5088 psName (aka FontName) has form
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        //   <Family Name><VendorID>-<Weight><Width><Slant><Character Set>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        //where spaces are not allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        //Conversion: Expand abbreviations in style portion (everything after '-'),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        //            replace '-' with space and insert missing spaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        pos = name.indexOf("-");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            res =  expandName(name.substring(0, pos), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            res += " " + expandName(name.substring(pos+1), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            res = expandName(name, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        return res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    private String psName2FamilyName(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        String tmp = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
        //According to Adobe technical note #5088 psName (aka FontName) has form
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        //   <Family Name><VendorID>-<Weight><Width><Slant><Character Set>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        //where spaces are not allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        //Conversion: Truncate style portion (everything after '-')
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        //            and insert missing spaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        if (tmp.indexOf("-") > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            tmp = tmp.substring(0, tmp.indexOf("-"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        return expandName(tmp, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    private int nextCapitalLetter(String s, int off) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        for (; (off >=0) && off < s.length(); off++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            if (s.charAt(off) >= 'A' && s.charAt(off) <= 'Z')
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                return off;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    private String expandName(String s, boolean tryExpandAbbreviations) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        StringBuffer res = new StringBuffer(s.length() + 10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        int start=0, end;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        while(start < s.length()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            end = nextCapitalLetter(s, start + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
            if (end < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                end = s.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
            if (start != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                res.append(" ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            if (tryExpandAbbreviations) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                res.append(expandAbbreviation(s.substring(start, end)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                res.append(s.substring(start, end));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            start = end;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        return res.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    /* skip lines beginning with "%" and leading white space on a line */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    private byte skip(ByteBuffer bb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        byte b = bb.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        while (b == '%') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                b = bb.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                if (b == '\r' || b == '\n') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        while (b <= ' ') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            b = bb.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        return b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
     * Token types:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     * PSNAMETOKEN - /
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
     * PSSTRINGTOKEN - literal text string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    private int nextTokenType(ByteBuffer bb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            byte b = skip(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                if (b == (byte)'/') { // PS defined name follows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                    return PSNAMETOKEN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                } else if (b == (byte)'(') { // PS string follows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                    return PSSTRINGTOKEN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                } else if ((b == (byte)'\r') || (b == (byte)'\n')) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                b = skip(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                    b = bb.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        } catch (BufferUnderflowException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            return PSEOFTOKEN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    /* Read simple token (sequence of non-whitespace characters)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
         starting from the current position.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
         Skip leading whitespaces (if any). */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    private String getSimpleToken(ByteBuffer bb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        while (bb.get() <= ' ');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        int pos1 = bb.position()-1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        while (bb.get() > ' ');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        int pos2 = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        byte[] nameBytes = new byte[pos2-pos1-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        bb.position(pos1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
        bb.get(nameBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            return new String(nameBytes, "US-ASCII");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        } catch (UnsupportedEncodingException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            return new String(nameBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    private String getString(ByteBuffer bb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        int pos1 = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        while (bb.get() != ')');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        int pos2 = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        byte[] nameBytes = new byte[pos2-pos1-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        bb.position(pos1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        bb.get(nameBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            return new String(nameBytes, "US-ASCII");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        } catch (UnsupportedEncodingException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            return new String(nameBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    public String getPostscriptName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        return psName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    protected synchronized FontScaler getScaler() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        if (scaler == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            return FontManager.getScaler(this, 0, false, fileSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        return scaler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    CharToGlyphMapper getMapper() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        if (mapper == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
            mapper = new Type1GlyphMapper(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        return mapper;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    public int getNumGlyphs() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            return getScaler().getNumGlyphs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        } catch (FontScalerException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
            scaler = FontManager.getNullScaler();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            return getNumGlyphs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    public int getMissingGlyphCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            return getScaler().getMissingGlyphCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        } catch (FontScalerException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
            scaler = FontManager.getNullScaler();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            return getMissingGlyphCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    public int getGlyphCode(char charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
            return getScaler().getGlyphCode(charCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        } catch (FontScalerException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
            scaler = FontManager.getNullScaler();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            return getGlyphCode(charCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        return "** Type1 Font: Family="+familyName+ " Name="+fullName+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
            " style="+style+" fileName="+platName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
}