⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 truetypefont.java

📁 处理PDF
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        createEncoding();    }        /** Gets the name from a composed TTC file name.     * If I have for input "myfont.ttc,2" the return will     * be "myfont.ttc".     * @param name the full name     * @return the simple file name     */        protected static String getTTCName(String name) {        int idx = name.toLowerCase().indexOf(".ttc,");        if (idx < 0)            return name;        else            return name.substring(0, idx + 4);    }            /**     * Reads the tables 'head', 'hhea', 'OS/2' and 'post' filling several variables.     * @throws DocumentException the font is invalid     * @throws IOException the font file could not be read     */    void fillTables() throws DocumentException, IOException {        int table_location[];        table_location = (int[])tables.get("head");        if (table_location == null)            throw new DocumentException("Table 'head' does not exist in " + fileName + style);        rf.seek(table_location[0] + 16);        head.flags = rf.readUnsignedShort();        head.unitsPerEm = rf.readUnsignedShort();        rf.skipBytes(16);        head.xMin = rf.readShort();        head.yMin = rf.readShort();        head.xMax = rf.readShort();        head.yMax = rf.readShort();        head.macStyle = rf.readUnsignedShort();                table_location = (int[])tables.get("hhea");        if (table_location == null)            throw new DocumentException("Table 'hhea' does not exist " + fileName + style);        rf.seek(table_location[0] + 4);        hhea.Ascender = rf.readShort();        hhea.Descender = rf.readShort();        hhea.LineGap = rf.readShort();        hhea.advanceWidthMax = rf.readUnsignedShort();        hhea.minLeftSideBearing = rf.readShort();        hhea.minRightSideBearing = rf.readShort();        hhea.xMaxExtent = rf.readShort();        hhea.caretSlopeRise = rf.readShort();        hhea.caretSlopeRun = rf.readShort();        rf.skipBytes(12);        hhea.numberOfHMetrics = rf.readUnsignedShort();                table_location = (int[])tables.get("OS/2");        if (table_location == null)            throw new DocumentException("Table 'OS/2' does not exist in " + fileName + style);        rf.seek(table_location[0]);        int version = rf.readUnsignedShort();        os_2.xAvgCharWidth = rf.readShort();        os_2.usWeightClass = rf.readUnsignedShort();        os_2.usWidthClass = rf.readUnsignedShort();        os_2.fsType = rf.readShort();        os_2.ySubscriptXSize = rf.readShort();        os_2.ySubscriptYSize = rf.readShort();        os_2.ySubscriptXOffset = rf.readShort();        os_2.ySubscriptYOffset = rf.readShort();        os_2.ySuperscriptXSize = rf.readShort();        os_2.ySuperscriptYSize = rf.readShort();        os_2.ySuperscriptXOffset = rf.readShort();        os_2.ySuperscriptYOffset = rf.readShort();        os_2.yStrikeoutSize = rf.readShort();        os_2.yStrikeoutPosition = rf.readShort();        os_2.sFamilyClass = rf.readShort();        rf.readFully(os_2.panose);        rf.skipBytes(16);        rf.readFully(os_2.achVendID);        os_2.fsSelection = rf.readUnsignedShort();        os_2.usFirstCharIndex = rf.readUnsignedShort();        os_2.usLastCharIndex = rf.readUnsignedShort();        os_2.sTypoAscender = rf.readShort();        os_2.sTypoDescender = rf.readShort();        if (os_2.sTypoDescender > 0)            os_2.sTypoDescender = (short)(-os_2.sTypoDescender);        os_2.sTypoLineGap = rf.readShort();        os_2.usWinAscent = rf.readUnsignedShort();        os_2.usWinDescent = rf.readUnsignedShort();        os_2.ulCodePageRange1 = 0;        os_2.ulCodePageRange2 = 0;        if (version > 0) {            os_2.ulCodePageRange1 = rf.readInt();            os_2.ulCodePageRange2 = rf.readInt();        }        if (version > 1) {            rf.skipBytes(2);            os_2.sCapHeight = rf.readShort();        }        else            os_2.sCapHeight = (int)(0.7 * head.unitsPerEm);                table_location = (int[])tables.get("post");        if (table_location == null) {            italicAngle = -Math.atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI;            return;        }        rf.seek(table_location[0] + 4);        short mantissa = rf.readShort();        int fraction = rf.readUnsignedShort();        italicAngle = mantissa + fraction / 16384.0d;        underlinePosition = rf.readShort();        underlineThickness = rf.readShort();        isFixedPitch = rf.readInt() != 0;    }        /**     * Gets the Postscript font name.     * @throws DocumentException the font is invalid     * @throws IOException the font file could not be read     * @return the Postscript font name     */    String getBaseFont() throws DocumentException, IOException {        int table_location[];        table_location = (int[])tables.get("name");        if (table_location == null)            throw new DocumentException("Table 'name' does not exist in " + fileName + style);        rf.seek(table_location[0] + 2);        int numRecords = rf.readUnsignedShort();        int startOfStorage = rf.readUnsignedShort();        for (int k = 0; k < numRecords; ++k) {            int platformID = rf.readUnsignedShort();            int platformEncodingID = rf.readUnsignedShort();            int languageID = rf.readUnsignedShort();            int nameID = rf.readUnsignedShort();            int length = rf.readUnsignedShort();            int offset = rf.readUnsignedShort();            if (nameID == 6) {                rf.seek(table_location[0] + startOfStorage + offset);                if (platformID == 0 || platformID == 3)                    return readUnicodeString(length);                else                    return readStandardString(length);            }        }        File file = new File(fileName);        return file.getName().replace(' ', '-');    }        /** Extracts the names of the font in all the languages available.     * @param id the name id to retrieve     * @throws DocumentException on error     * @throws IOException on error     */        String[][] getNames(int id) throws DocumentException, IOException {        int table_location[];        table_location = (int[])tables.get("name");        if (table_location == null)            throw new DocumentException("Table 'name' does not exist in " + fileName + style);        rf.seek(table_location[0] + 2);        int numRecords = rf.readUnsignedShort();        int startOfStorage = rf.readUnsignedShort();        ArrayList names = new ArrayList();        for (int k = 0; k < numRecords; ++k) {            int platformID = rf.readUnsignedShort();            int platformEncodingID = rf.readUnsignedShort();            int languageID = rf.readUnsignedShort();            int nameID = rf.readUnsignedShort();            int length = rf.readUnsignedShort();            int offset = rf.readUnsignedShort();            if (nameID == id) {                int pos = rf.getFilePointer();                rf.seek(table_location[0] + startOfStorage + offset);                String name;                if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)){                    name = readUnicodeString(length);                }                else {                    name = readStandardString(length);                }                names.add(new String[]{String.valueOf(platformID),                    String.valueOf(platformEncodingID), String.valueOf(languageID), name});                rf.seek(pos);            }        }        String thisName[][] = new String[names.size()][];        for (int k = 0; k < names.size(); ++k)            thisName[k] = (String[])names.get(k);        return thisName;    }        /** Extracts all the names of the names-Table     * @throws DocumentException on error     * @throws IOException on error     */        String[][] getAllNames() throws DocumentException, IOException {        int table_location[];        table_location = (int[])tables.get("name");        if (table_location == null)            throw new DocumentException("Table 'name' does not exist in " + fileName + style);        rf.seek(table_location[0] + 2);        int numRecords = rf.readUnsignedShort();        int startOfStorage = rf.readUnsignedShort();        ArrayList names = new ArrayList();        for (int k = 0; k < numRecords; ++k) {            int platformID = rf.readUnsignedShort();            int platformEncodingID = rf.readUnsignedShort();            int languageID = rf.readUnsignedShort();            int nameID = rf.readUnsignedShort();            int length = rf.readUnsignedShort();            int offset = rf.readUnsignedShort();            int pos = rf.getFilePointer();            rf.seek(table_location[0] + startOfStorage + offset);            String name;            if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)){                name = readUnicodeString(length);            }            else {                name = readStandardString(length);            }            names.add(new String[]{String.valueOf(nameID), String.valueOf(platformID),                    String.valueOf(platformEncodingID), String.valueOf(languageID), name});            rf.seek(pos);        }        String thisName[][] = new String[names.size()][];        for (int k = 0; k < names.size(); ++k)            thisName[k] = (String[])names.get(k);        return thisName;    }        void checkCff() {        int table_location[];        table_location = (int[])tables.get("CFF ");        if (table_location != null) {            cff = true;            cffOffset = table_location[0];            cffLength = table_location[1];        }    }    /** Reads the font data.     * @param ttfAfm the font as a <CODE>byte</CODE> array, possibly <CODE>null</CODE>     * @throws DocumentException the font is invalid     * @throws IOException the font file could not be read     */    void process(byte ttfAfm[]) throws DocumentException, IOException {        tables = new HashMap();                try {            if (ttfAfm == null)                rf = new RandomAccessFileOrArray(fileName);            else                rf = new RandomAccessFileOrArray(ttfAfm);            if (ttcIndex.length() > 0) {                int dirIdx = Integer.parseInt(ttcIndex);                if (dirIdx < 0)                    throw new DocumentException("The font index for " + fileName + " must be positive.");                String mainTag = readStandardString(4);                if (!mainTag.equals("ttcf"))                    throw new DocumentException(fileName + " is not a valid TTC file.");                rf.skipBytes(4);                int dirCount = rf.readInt();                if (dirIdx >= dirCount)                    throw new DocumentException("The font index for " + fileName + " must be between 0 and " + (dirCount - 1) + ". It was " + dirIdx + ".");                rf.skipBytes(dirIdx * 4);                directoryOffset = rf.readInt();            }            rf.seek(directoryOffset);            int ttId = rf.readInt();            if (ttId != 0x00010000 && ttId != 0x4F54544F)                throw new DocumentException(fileName + " is not a valid TTF or OTF file.");            int num_tables = rf.readUnsignedShort();            rf.skipBytes(6);            for (int k = 0; k < num_tables; ++k) {                String tag = readStandardString(4);                rf.skipBytes(4);                int table_location[] = new int[2];                table_location[0] = rf.readInt();                table_location[1] = rf.readInt();                tables.put(tag, table_location);            }            checkCff();            fontName = getBaseFont();            fullName = getNames(4); //full name            familyName = getNames(1); //family name            allNameEntries = getAllNames();            if (!justNames) {                fillTables();                readGlyphWidths();                readCMaps();                readKerning();                readBbox();                GlyphWidths = null;            }        }        finally {            if (rf != null) {                rf.close();                if (!embedded)                    rf = null;            }        }    }        /** Reads a <CODE>String</CODE> from the font file as bytes using the Cp1252     *  encoding.     * @param length the length of bytes to read     * @return the <CODE>String</CODE> read     * @throws IOException the font file could not be read     */    protected String readStandardString(int length) throws IOException {        byte buf[] = new byte[length];        rf.readFully(buf);        try {            return new String(buf, WINANSI);        }        catch (Exception e) {            throw new ExceptionConverter(e);        }    }        /** Reads a Unicode <CODE>String</CODE> from the font file. Each character is     *  represented by two bytes.     * @param length the length of bytes to read. The <CODE>String</CODE> will have <CODE>length</CODE>/2     * characters     * @return the <CODE>String</CODE> read     * @throws IOException the font file could not be read     */    protected String readUnicodeString(int length) throws IOException {        StringBuffer buf = new StringBuffer();        length /= 2;        for (int k = 0; k < length; ++k) {            buf.append(rf.readChar());        }        return buf.toString();    }        /** Reads the glyphs widths. The widths are extracted from the table 'hmtx'.     *  The glyphs are normalized to 1000 units.     * @throws DocumentException the font is invalid     * @throws IOException the font file could not be read     */    protected void readGlyphWidths() throws DocumentException, IOException {        int table_location[];        table_location = (int[])tables.get("hmtx");        if (table_location == null)            throw new DocumentException("Table 'hmtx' does not exist in " + fileName + style);        rf.seek(table_location[0]);        GlyphWidths = new int[hhea.numberOfHMetrics];        for (int k = 0; k < hhea.numberOfHMetrics; ++k) {            GlyphWidths[k] = (rf.readUnsignedShort() * 1000) / head.unitsPerEm;            rf.readUnsignedShort();        }    }        /** Gets a glyph width.     * @param glyph the glyph to get the width of     * @return the width of the glyph in normalized 1000 units     */    protected int getGlyphWidth(int glyph) {        if (glyph >= GlyphWidths.length)            glyph = GlyphWidths.length - 1;        return GlyphWidths[glyph];    }        private void readBbox() throws DocumentException, IOException {        int tableLocation[];        tableLocation = (int[])tables.get("head");        if (tableLocation == null)            throw new DocumentException("Table 'head' does not exist in " + fileName + style);        rf.seek(tableLocation[0] + TrueTypeFontSubSet.HEAD_LOCA_FORMAT_OFFSET);        boolean locaShortTable = (rf.readUnsignedShort() == 0);        tableLocation = (int[])tables.get("loca");        if (tableLocation == null)            return;        rf.seek(tableLocation[0]);        int locaTable[];        if (locaShortTable) {            int entries = tableLocation[1] / 2;            locaTable = new int[entries];            for (int k = 0; k < entries; ++k)                locaTable[k] = rf.readUnsignedShort() * 2;        }        else {            int entries = tableLocation[1] / 4;            locaTable = new int[entries];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -