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

📄 truetypefont.java

📁 java itext java itext java itext
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                r[1] = getGlyphWidth(r[0]);
                h.put(new Integer(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();
        kerning = new HashMap();
        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) {
                    Integer pair = new Integer(rf.readInt());
                    Integer value = new Integer(((int)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(char char1, char char2) {
        Integer v = (Integer)kerning.get(new Integer((((int)char1) << 16) + ((int)char2)));
        if (v == null)
            return 0;
        else
            return v.intValue();
    }
    
    /** 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
     */
    protected int getRawWidth(int c, String name) {
        HashMap map = null;
        if (name == null)
            map = cmap10;
        else
            map = cmap31;
        if (map == null)
            return 0;
        int metric[] = (int[])map.get(new Integer(c));
        if (metric == null)
            return 0;
        return metric[1];
    }
    
    /** If the embedded flag is <CODE>false</CODE> it returns <CODE>null</CODE>,
     * otherwise the font is read and output in a PdfStream object.
     * @return the PdfStream containing the font or <CODE>null</CODE>
     * @throws DocumentException if there is an error reading the font
     */
    protected PdfStream getFontStream() throws DocumentException {
        if (!embedded)
            return null;
        InputStream is = null;
        try {
            File file = new File(fileName);
            int fileLength = (int)file.length();
            byte st[] = new byte[fileLength];
            is = new FileInputStream(file);
            int lengths[] = new int[]{fileLength};
            int bytePtr = 0;
            int size = fileLength;
            while (size != 0) {
                int got = is.read(st, bytePtr, size);
                if (got < 0)
                    throw new DocumentException("Premature end in " + file.getName());
                bytePtr += got;
                size -= got;
            }
            return new StreamFont(st, lengths);
        }
        catch (Exception e) {
            throw new DocumentException(e.getMessage());
        }
        finally {
            if (is != null) {
                try {
                    is.close();
                }
                catch (Exception e) {
                }
            }
        }
    }
    
    /** 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) throws DocumentException {
        PdfDictionary dic = new PdfDictionary(new PdfName("FontDescriptor"));
        dic.put(new PdfName("Ascent"), new PdfNumber((int)os_2.sTypoAscender * 1000 / head.unitsPerEm));
        dic.put(new PdfName("CapHeight"), new PdfNumber((int)os_2.sCapHeight * 1000 / head.unitsPerEm));
        dic.put(new PdfName("Descent"), new PdfNumber((int)os_2.sTypoDescender * 1000 / head.unitsPerEm));
        dic.put(new PdfName("FontBBox"), new PdfRectangle(
        (int)head.xMin * 1000 / head.unitsPerEm,
        (int)head.yMin * 1000 / head.unitsPerEm,
        (int)head.xMax * 1000 / head.unitsPerEm,
        (int)head.yMax * 1000 / head.unitsPerEm));
        dic.put(new PdfName("FontName"), new PdfName(subsetPrefix + fontName + style));
        dic.put(new PdfName("ItalicAngle"), new PdfNumber(italicAngle));
        dic.put(new PdfName("StemV"), new PdfNumber(80));
        if (fontStream != null)
            dic.put(new 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(new 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
     */
    private PdfDictionary getFontBaseType(PdfIndirectReference fontDescriptor, String subsetPrefix, int firstChar, int lastChar, byte shortTag[]) throws DocumentException {
        PdfDictionary dic = new PdfDictionary(PdfName.FONT);
        dic.put(PdfName.SUBTYPE, new PdfName("TrueType"));
        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(new 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(new PdfName("Differences"), dif);
                dic.put(PdfName.ENCODING, enc);
            }
        }
        dic.put(new PdfName("FirstChar"), new PdfNumber(firstChar));
        dic.put(new 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(new PdfName("Widths"), wd);
        if (fontDescriptor != null)
            dic.put(new PdfName("FontDescriptor"), fontDescriptor);
        return dic;
    }
    
    /** Outputs to the writer the font dictionaries and streams.
     * @param writer the writer for this document
     * @param ref the font indirect reference
     * @param params several parameters that depend on the font type
     * @throws IOException on error
     * @throws DocumentException error in generating the object
     */
    void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException {
        int firstChar = ((Integer)params[0]).intValue();
        int lastChar = ((Integer)params[1]).intValue();
        byte shortTag[] = (byte[])params[2];
        PdfIndirectReference ind_font = null;
        PdfObject pobj = null;
        PdfIndirectObject obj = null;
        String subsetPrefix = "";
        if (embedded) {
            subsetPrefix = createSubsetPrefix();
            HashMap glyphs = new HashMap();
            for (int k = firstChar; k <= lastChar; ++k) {
                if (shortTag[k] != 0) {
                    int metrics[];
                    if (fontSpecific)
                        metrics = getMetricsTT(k);
                    else
                        metrics = getMetricsTT(unicodeDifferences[k]);
                    if (metrics != null)
                        glyphs.put(new Integer(metrics[0]), null);
                }
            }
            TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, glyphs, directoryOffset, true);
            byte b[] = sb.process();
            int lengths[] = new int[]{b.length};
            pobj = new StreamFont(b, lengths);
            obj = writer.addToBody(pobj);
            ind_font = obj.getIndirectReference();
        }
        pobj = getFontDescriptor(ind_font, subsetPrefix);
        if (pobj != null){
            obj = writer.addToBody(pobj);
            ind_font = obj.getIndirectReference();
        }
        pobj = getFontBaseType(ind_font, subsetPrefix, firstChar, lastChar, shortTag);
        writer.addToBody(pobj, ref);
    }
    
    /** Gets the font parameter identified by <CODE>key</CODE>. Valid values
     * for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, <CODE>DESCENT</CODE>
     * and <CODE>ITALICANGLE</CODE>.
     * @param key the parameter to be extracted
     * @param fontSize the font size in points
     * @return the parameter in points
     */    
    public float getFontDescriptor(int key, float fontSize) {
        switch (key) {
            case ASCENT:
                return (float)os_2.sTypoAscender * fontSize / (float)head.unitsPerEm;
            case CAPHEIGHT:
                return (float)os_2.sCapHeight * fontSize / (float)head.unitsPerEm;
            case DESCENT:
                return (float)os_2.sTypoDescender * fontSize / (float)head.unitsPerEm;
            case ITALICANGLE:
                return (float)italicAngle;
            case BBOXLLX:
                return fontSize * (int)head.xMin / head.unitsPerEm;
            case BBOXLLY:
                return fontSize * (int)head.yMin / head.unitsPerEm;
            case BBOXURX:
                return fontSize * (int)head.xMax / head.unitsPerEm;
            case BBOXURY:
                return fontSize * (int)head.yMax / head.unitsPerEm;
        }
        return 0;
    }
    
    /** Gets the glyph index and metrics for a character.
     * @param c the character
     * @return an <CODE>int</CODE> array with {glyph index, width}
     */    
    public int[] getMetricsTT(int c) {
        if (!fontSpecific && cmap31 != null) 
            return (int[])cmap31.get(new Integer(c));
        if (fontSpecific && cmap10 != null) 
            return (int[])cmap10.get(new Integer(c));
        return null;
    }
}

⌨️ 快捷键说明

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