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

📄 truetypefont.java

📁 处理PDF
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
            for (int k = 0; k < entries; ++k)                locaTable[k] = rf.readInt();        }        tableLocation = (int[])tables.get("glyf");        if (tableLocation == null)            throw new DocumentException("Table 'glyf' does not exist in " + fileName + style);        int tableGlyphOffset = tableLocation[0];        bboxes = new int[locaTable.length - 1][];        for (int glyph = 0; glyph < locaTable.length - 1; ++glyph) {            int start = locaTable[glyph];            if (start != locaTable[glyph + 1]) {                rf.seek(tableGlyphOffset + start + 2);                bboxes[glyph] = new int[]{                    (rf.readShort() * 1000) / head.unitsPerEm,                    (rf.readShort() * 1000) / head.unitsPerEm,                    (rf.readShort() * 1000) / head.unitsPerEm,                    (rf.readShort() * 1000) / head.unitsPerEm};            }        }    }        /** 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;        int map30 = 0;        int mapExt = 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;                map30 = offset;            }            else if (platId == 3 && platSpecId == 1) {                map31 = offset;            }            else if (platId == 3 && platSpecId == 10) {                mapExt = 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();            }        }        if (map30 > 0) {            rf.seek(table_location[0] + map30);            int format = rf.readUnsignedShort();            if (format == 4) {                cmap10 = readFormat4();            }        }        if (mapExt > 0) {            rf.seek(table_location[0] + mapExt);            int format = rf.readUnsignedShort();            switch (format) {                case 0:                    cmapExt = readFormat0();                    break;                case 4:                    cmapExt = readFormat4();                    break;                case 6:                    cmapExt = readFormat6();                    break;                case 12:                    cmapExt = readFormat12();                    break;            }        }    }    HashMap readFormat12() throws IOException {        HashMap h = new HashMap();        rf.skipBytes(2);        int table_lenght = rf.readInt();        rf.skipBytes(4);        int nGroups = rf.readInt();        for (int k = 0; k < nGroups; k++) {            int startCharCode = rf.readInt();            int endCharCode = rf.readInt();            int startGlyphID = rf.readInt();            for (int i = startCharCode; i <= endCharCode; i++) {                int[] r = new int[2];                r[0] = startGlyphID;                r[1] = getGlyphWidth(r[0]);                h.put(new Integer(i), r);                startGlyphID++;            }        }        return h;    }        /** 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];                    if (idx >= glyphId.length)                        continue;                    glyph = (glyphId[idx] + idDelta[k]) & 0xFFFF;                }                int r[] = new int[2];                r[0] = glyph;                r[1] = getGlyphWidth(r[0]);                h.put(new Integer(fontSpecific ? ((j & 0xff00) == 0xf000 ? j & 0xff : j) : j), r);            }        }        return h;    }        /** The information in the maps of the table 'cmap' is coded in several formats.     *  Format 6 is a trimmed table mapping. It is similar to format 0 but can have     *  less than 256 entries.     * @return a <CODE>HashMap</CODE> representing this map     * @throws IOException the font file could not be read     */    HashMap readFormat6() throws IOException {        HashMap h = new HashMap();        rf.skipBytes(4);        int start_code = rf.readUnsignedShort();        int code_count = rf.readUnsignedShort();        for (int k = 0; k < code_count; ++k) {            int r[] = new int[2];            r[0] = rf.readUnsignedShort();            r[1] = getGlyphWidth(r[0]);            h.put(new Integer(k + start_code), r);        }        return h;    }        /** Reads the kerning information from the 'kern' table.     * @throws IOException the font file could not be read     */    void readKerning() throws IOException {        int table_location[];        table_location = (int[])tables.get("kern");        if (table_location == null)            return;        rf.seek(table_location[0] + 2);        int nTables = rf.readUnsignedShort();        int checkpoint = table_location[0] + 4;        int length = 0;        for (int k = 0; k < nTables; ++k) {            checkpoint += length;            rf.seek(checkpoint);            rf.skipBytes(2);            length = rf.readUnsignedShort();            int coverage = rf.readUnsignedShort();            if ((coverage & 0xfff7) == 0x0001) {                int nPairs = rf.readUnsignedShort();                rf.skipBytes(6);                for (int j = 0; j < nPairs; ++j) {                    int pair = rf.readInt();                    int value = rf.readShort() * 1000 / head.unitsPerEm;                    kerning.put(pair, value);                }            }        }    }        /** Gets the kerning between two Unicode chars.     * @param char1 the first char     * @param char2 the second char     * @return the kerning to be applied     */    public int getKerning(int char1, int char2) {        int metrics[] = getMetricsTT(char1);        if (metrics == null)            return 0;        int c1 = metrics[0];        metrics = getMetricsTT(char2);        if (metrics == null)            return 0;        int c2 = metrics[0];        return kerning.get((c1 << 16) + c2);    }        /** Gets the width from the font according to the unicode char <CODE>c</CODE>.     * If the <CODE>name</CODE> is null it's a symbolic font.     * @param c the unicode char     * @param name the glyph name     * @return the width of the char     */    int getRawWidth(int c, String name) {        int[] metric = getMetricsTT(c);        if (metric == null)            return 0;        return metric[1];    }        /** Generates the font descriptor for this font.     * @return the PdfDictionary containing the font descriptor or <CODE>null</CODE>     * @param subsetPrefix the subset prefix     * @param fontStream the indirect reference to a PdfStream containing the font or <CODE>null</CODE>     * @throws DocumentException if there is an error     */    protected PdfDictionary getFontDescriptor(PdfIndirectReference fontStream, String subsetPrefix, PdfIndirectReference cidset) {        PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR);        dic.put(PdfName.ASCENT, new PdfNumber(os_2.sTypoAscender * 1000 / head.unitsPerEm));        dic.put(PdfName.CAPHEIGHT, new PdfNumber(os_2.sCapHeight * 1000 / head.unitsPerEm));        dic.put(PdfName.DESCENT, new PdfNumber(os_2.sTypoDescender * 1000 / head.unitsPerEm));        dic.put(PdfName.FONTBBOX, new PdfRectangle(        head.xMin * 1000 / head.unitsPerEm,        head.yMin * 1000 / head.unitsPerEm,        head.xMax * 1000 / head.unitsPerEm,        head.yMax * 1000 / head.unitsPerEm));        if (cidset != null)            dic.put(PdfName.CIDSET, cidset);        if (cff) {            if (encoding.startsWith("Identity-"))                dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName+"-"+encoding));            else                dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style));        }        else            dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style));        dic.put(PdfName.ITALICANGLE, new PdfNumber(italicAngle));        dic.put(PdfName.STEMV, new PdfNumber(80));        if (fontStream != null) {            if (cff)                dic.put(PdfName.FONTFILE3, fontStream);            else                dic.put(PdfName.FONTFILE2, fontStream);        }        int flags = 0;        if (isFixedPitch)            flags |= 1;        flags |= fontSpecific ? 4 : 32;        if ((head.macStyle & 2) != 0)            flags |= 64;        if ((head.macStyle & 1) != 0)            flags |= 262144;        dic.put(PdfName.FLAGS, new PdfNumber(flags));                return dic;    }        /** Generates the font dictionary for this font.     * @return the PdfDictionary containing the font dictionary     * @param subsetPrefix the subset prefx     * @param firstChar the first valid character     * @param lastChar the last valid character     * @param shortTag a 256 bytes long <CODE>byte</CODE> array where each unused byte is represented by 0     * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor or <CODE>null</CODE>     * @throws DocumentException if there is an error     */    protected PdfDictionary getFontBaseType(PdfIndirectReference fontDescriptor, String subsetPrefix, int firstChar, int lastChar, byte shortTag[]) {        PdfDictionary dic = new PdfDictionary(PdfName.FONT);        if (cff) {            dic.put(PdfName.SUBTYPE, PdfName.TYPE1);            dic.put(PdfName.BASEFONT, new PdfName(fontName + style));        }        else {            dic.put(PdfName.SUBTYPE, PdfName.TRUETYPE);            dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style));        }        dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style));        if (!fontSpecific) {            for (int k = firstChar; k <= lastChar; ++k) {                if (!differences[k].equals(notdef)) {                    firstChar = k;                    break;                }            }        if (encoding.equals("Cp1252") || encoding.equals("MacRoman"))                dic.put(PdfName.ENCODING, encoding.equals("Cp1252") ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING);            else {                PdfDictionary enc = new PdfDictionary(PdfName.ENCODING);                PdfArray dif = new PdfArray();                boolean gap = true;                                for (int k = firstChar; k <= lastChar; ++k) {                    if (shortTag[k] != 0) {                        if (gap) {                            dif.add(new PdfNumber(k));                            gap = false;                        }                        dif.add(new PdfName(differences[k]));                    }                    else                        gap = true;                }                enc.put(PdfName.DIFFERENCES, dif);                dic.put(PdfName.ENCODING, enc);            }        }        dic.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));        dic.put(PdfName.LASTCHAR, new PdfNumber(lastChar));        PdfArray wd = new PdfArray();        for (int k = firstChar; k <= lastChar; ++k) {            if (shortTag[k] == 0)                wd.add(new PdfNumber(0));            else                wd.add(new PdfNumber(widths[k]));        }        dic.put(PdfName.WIDTHS, wd);        if (fontDescriptor != null)            dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor);

⌨️ 快捷键说明

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