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

📄 truetypefont.java

📁 java itext java itext java itext
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        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();
        os_2.sTypoLineGap = rf.readShort();
        os_2.usWinAscent = rf.readUnsignedShort();
        os_2.usWinDescent = rf.readUnsignedShort();
        if (version > 1) {
            rf.skipBytes(10);
            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 = (double)mantissa + (double)fraction / 16384.0;
        rf.skipBytes(4);
        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();
        String postscriptName;
        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(' ', '-');
    }
    
    /** Reads the font data.
     * @throws DocumentException the font is invalid
     * @throws IOException the font file could not be read
     */
    void process() throws DocumentException, IOException {
        tables = new HashMap();
        
        try {
            rf = new RandomAccessFile(fileName, "r");
            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);
            if (rf.readInt() != 0x00010000)
                throw new DocumentException(fileName + " is not a valid TTF 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);
            }
            fontName = getBaseFont();
            fillTables();
            readGlyphWidths();
            readCMaps();
            readKerning();
        }
        finally {
            if (rf != null)
                rf.close();
        }
    }
    
    /** 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
     */
    private String readStandardString(int length) throws IOException {
        byte buf[] = new byte[length];
        rf.readFully(buf);
        try {
            return new String(buf, PdfObject.ENCODING);
        }
        catch (Exception e) {
            return new String(buf);
        }
    }
    
    /** 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
     */
    private 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
     */
    public int getGlyphWidth(int glyph) {
        if (glyph >= GlyphWidths.length)
            glyph = GlyphWidths.length - 1;
        return GlyphWidths[glyph];
    }
    
    /** Reads the several maps from the table 'cmap'. The maps of interest are 1.0 for symbolic
     *  fonts and 3.1 for all others. A symbolic font is defined as having the map 3.0.
     * @throws DocumentException the font is invalid
     * @throws IOException the font file could not be read
     */
    void readCMaps() throws DocumentException, IOException {
        int table_location[];
        table_location = (int[])tables.get("cmap");
        if (table_location == null)
            throw new DocumentException("Table 'cmap' does not exist in " + fileName + style);
        rf.seek(table_location[0]);
        rf.skipBytes(2);
        int num_tables = rf.readUnsignedShort();
        fontSpecific = false;
        int map10 = 0;
        int map31 = 0;
        for (int k = 0; k < num_tables; ++k) {
            int platId = rf.readUnsignedShort();
            int platSpecId = rf.readUnsignedShort();
            int offset = rf.readInt();
            if (platId == 3 && platSpecId == 0) {
                fontSpecific = true;
            }
            else if (platId == 3 && platSpecId == 1) {
                map31 = offset;
            }
            if (platId == 1 && platSpecId == 0) {
                map10 = offset;
            }
        }
        if (map10 > 0) {
            rf.seek(table_location[0] + map10);
            int format = rf.readUnsignedShort();
            switch (format) {
                case 0:
                    cmap10 = readFormat0();
                    break;
                case 4:
                    cmap10 = readFormat4();
                    break;
                case 6:
                    cmap10 = readFormat6();
                    break;
            }
        }
        if (map31 > 0) {
            rf.seek(table_location[0] + map31);
            int format = rf.readUnsignedShort();
            if (format == 4) {
                cmap31 = readFormat4();
            }
        }
    }
    
    /** The information in the maps of the table 'cmap' is coded in several formats.
     *  Format 0 is the Apple standard character to glyph index mapping table.
     * @return a <CODE>HashMap</CODE> representing this map
     * @throws IOException the font file could not be read
     */
    HashMap readFormat0() throws IOException {
        HashMap h = new HashMap();
        rf.skipBytes(4);
        for (int k = 0; k < 256; ++k) {
            int r[] = new int[2];
            r[0] = rf.readUnsignedByte();
            r[1] = getGlyphWidth(r[0]);
            h.put(new Integer(k), r);
        }
        return h;
    }
    
    /** The information in the maps of the table 'cmap' is coded in several formats.
     *  Format 4 is the Microsoft standard character to glyph index mapping table.
     * @return a <CODE>HashMap</CODE> representing this map
     * @throws IOException the font file could not be read
     */
    HashMap readFormat4() throws IOException {
        HashMap h = new HashMap();
        int table_lenght = rf.readUnsignedShort();
        rf.skipBytes(2);
        int segCount = rf.readUnsignedShort() / 2;
        rf.skipBytes(6);
        int endCount[] = new int[segCount];
        for (int k = 0; k < segCount; ++k) {
            endCount[k] = rf.readUnsignedShort();
        }
        rf.skipBytes(2);
        int startCount[] = new int[segCount];
        for (int k = 0; k < segCount; ++k) {
            startCount[k] = rf.readUnsignedShort();
        }
        int idDelta[] = new int[segCount];
        for (int k = 0; k < segCount; ++k) {
            idDelta[k] = rf.readUnsignedShort();
        }
        int idRO[] = new int[segCount];
        for (int k = 0; k < segCount; ++k) {
            idRO[k] = rf.readUnsignedShort();
        }
        int glyphId[] = new int[table_lenght / 2 - 8 - segCount * 4];
        for (int k = 0; k < glyphId.length; ++k) {
            glyphId[k] = rf.readUnsignedShort();
        }
        for (int k = 0; k < segCount; ++k) {
            int glyph;
            for (int j = startCount[k]; j <= endCount[k] && j != 0xFFFF; ++j) {
                if (idRO[k] == 0) {
                    glyph = (j + idDelta[k]) & 0xFFFF;
                }
                else {
                    int idx = k + idRO[k] / 2 - segCount + j - startCount[k];
                    glyph = (glyphId[idx] + idDelta[k]) & 0xFFFF;
                }
                int r[] = new int[2];
                r[0] = glyph;

⌨️ 快捷键说明

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