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

📄 truetypefont.java

📁 iText是一个能够快速产生PDF文件的java类库。iText的java类对于那些要产生包含文本
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                        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);
        return dic;
    }
    
    protected byte[] getFullFont() throws IOException {
        RandomAccessFileOrArray rf2 = null;
        try {
            rf2 = new RandomAccessFileOrArray(rf);
            rf2.reOpen();
            byte b[] = new byte[rf2.length()];
            rf2.readFully(b);
            return b;
        } 
        finally {
            try {if (rf2 != null) {rf2.close();}} catch (Exception e) {}
        }
    }
    
    protected static int[] compactRanges(ArrayList ranges) {
        ArrayList simp = new ArrayList();
        for (int k = 0; k < ranges.size(); ++k) {
            int[] r = (int[])ranges.get(k);
            for (int j = 0; j < r.length; j += 2) {
                simp.add(new int[]{Math.max(0, Math.min(r[j], r[j + 1])), Math.min(0xffff, Math.max(r[j], r[j + 1]))});
            }
        }
        for (int k1 = 0; k1 < simp.size() - 1; ++k1) {
            for (int k2 = k1 + 1; k2 < simp.size(); ++k2) {
                int[] r1 = (int[])simp.get(k1);
                int[] r2 = (int[])simp.get(k2);
                if ((r1[0] >= r2[0] && r1[0] <= r2[1]) || (r1[1] >= r2[0] && r1[0] <= r2[1])) {
                    r1[0] = Math.min(r1[0], r2[0]);
                    r1[1] = Math.max(r1[1], r2[1]);
                    simp.remove(k2);
                    --k2;
                }
            }
        }
        int[] s = new int[simp.size() * 2];
        for (int k = 0; k < simp.size(); ++k) {
            int[] r = (int[])simp.get(k);
            s[k * 2] = r[0];
            s[k * 2 + 1] = r[1];
        }
        return s;
    }
    
    protected void addRangeUni(HashMap longTag, boolean includeMetrics, boolean subsetp) {
        if (!subsetp && (subsetRanges != null || directoryOffset > 0)) {
            int[] rg = (subsetRanges == null && directoryOffset > 0) ? new int[]{0, 0xffff} : compactRanges(subsetRanges);
            HashMap usemap;
            if (!fontSpecific && cmap31 != null) 
                usemap = cmap31;
            else if (fontSpecific && cmap10 != null) 
                usemap = cmap10;
            else if (cmap31 != null) 
                usemap = cmap31;
            else 
                usemap = cmap10;
            for (Iterator it = usemap.entrySet().iterator(); it.hasNext();) {
                Map.Entry e = (Map.Entry)it.next();
                int[] v = (int[])e.getValue();
                Integer gi = new Integer(v[0]);
                if (longTag.containsKey(gi))
                    continue;
                int c = ((Integer)e.getKey()).intValue();
                boolean skip = true;
                for (int k = 0; k < rg.length; k += 2) {
                    if (c >= rg[k] && c <= rg[k + 1]) {
                        skip = false;
                        break;
                    }
                }
                if (!skip)
                    longTag.put(gi, includeMetrics ? new int[]{v[0], v[1], c} : null);
            }
        }
    }
    
    /** 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];
        boolean subsetp = ((Boolean)params[3]).booleanValue() && subset;
        
        if (!subsetp) {
            firstChar = 0;
            lastChar = shortTag.length - 1;
            for (int k = 0; k < shortTag.length; ++k)
                shortTag[k] = 1;
        }
        PdfIndirectReference ind_font = null;
        PdfObject pobj = null;
        PdfIndirectObject obj = null;
        String subsetPrefix = "";
        if (embedded) {
            if (cff) {
                RandomAccessFileOrArray rf2 = new RandomAccessFileOrArray(rf);
                byte b[] = new byte[cffLength];
                try {
                    rf2.reOpen();
                    rf2.seek(cffOffset);
                    rf2.readFully(b);
                }
                finally {
                    try {
                        rf2.close();
                    }
                    catch (Exception e) {
                        // empty on purpose
                    }
                }
                pobj = new StreamFont(b, "Type1C");
                obj = writer.addToBody(pobj);
                ind_font = obj.getIndirectReference();
            }
            else {
                if (subsetp)
                    subsetPrefix = createSubsetPrefix();
                HashMap glyphs = new HashMap();
                for (int k = firstChar; k <= lastChar; ++k) {
                    if (shortTag[k] != 0) {
                        int[] metrics = null;
                        if (specialMap != null) {
                            int[] cd = GlyphList.nameToUnicode(differences[k]);
                            if (cd != null)
                                metrics = getMetricsTT(cd[0]);
                        }
                        else {
                            if (fontSpecific)
                                metrics = getMetricsTT(k);
                            else
                                metrics = getMetricsTT(unicodeDifferences[k]);
                        }
                        if (metrics != null)
                            glyphs.put(new Integer(metrics[0]), null);
                    }
                }
                addRangeUni(glyphs, false, subsetp);
                byte[] b = null;
                if (subsetp || directoryOffset != 0 || subsetRanges != null) {
                    TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), glyphs, directoryOffset, true, !subsetp);
                    b = sb.process();
                }
                else {
                    b = getFullFont();
                }
                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;
            case AWT_ASCENT:
                return fontSize * (int)hhea.Ascender / head.unitsPerEm;
            case AWT_DESCENT:
                return fontSize * (int)hhea.Descender / head.unitsPerEm;
            case AWT_LEADING:
                return fontSize * (int)hhea.LineGap / head.unitsPerEm;
            case AWT_MAXADVANCE:
                return fontSize * (int)hhea.advanceWidthMax / 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));
        if (cmap31 != null) 
            return (int[])cmap31.get(new Integer(c));
        if (cmap10 != null) 
            return (int[])cmap10.get(new Integer(c));
        return null;
    }

    /** Gets the postscript font name.
     * @return the postscript font name
     */
    public String getPostscriptFontName() {
        return fontName;
    }

    /** Gets the code pages supported by the font.
     * @return the code pages supported by the font
     */
    public String[] getCodePagesSupported() {
        long cp = (((long)os_2.ulCodePageRange2) << 32) + ((long)os_2.ulCodePageRange1 & 0xffffffffL);
        int count = 0;
        long bit = 1;
        for (int k = 0; k < 64; ++k) {
            if ((cp & bit) != 0 && codePages[k] != null)
                ++count;
            bit <<= 1;
        }
        String ret[] = new String[count];
        count = 0;
        bit = 1;
        for (int k = 0; k < 64; ++k) {
            if ((cp & bit) != 0 && codePages[k] != null)
                ret[count++] = codePages[k];
            bit <<= 1;
        }
        return ret;
    }
    
    /** Gets the full name of the font. If it is a True Type font
     * each array element will have {Platform ID, Platform Encoding ID,
     * Language ID, font name}. The interpretation of this values can be
     * found in the Open Type specification, chapter 2, in the 'name' table.<br>
     * For the other fonts the array has a single element with {"", "", "",
     * font name}.
     * @return the full name of the font
     */
    public String[][] getFullFontName() {
        return fullName;
    }
    
    /** Gets the family name of the font. If it is a True Type font
     * each array element will have {Platform ID, Platform Encoding ID,
     * Language ID, font name}. The interpretation of this values can be
     * found in the Open Type specification, chapter 2, in the 'name' table.<br>
     * For the other fonts the array has a single element with {"", "", "",
     * font name}.
     * @return the family name of the font
     */
    public String[][] getFamilyFontName() {
        return familyName;
    }
    
    /** Checks if the font has any kerning pairs.
     * @return <CODE>true</CODE> if the font has any kerning pairs
     */    
    public boolean hasKernPairs() {
        return kerning.size() > 0;
    }    
    
    /**
     * Sets the font name that will appear in the pdf font dictionary.
     * Use with care as it can easily make a font unreadable if not embedded.
     * @param name the new font name
     */    
    public void setPostscriptFontName(String name) {
        fontName = name;
    }
    
    /**
     * Sets the kerning between two Unicode chars.
     * @param char1 the first char
     * @param char2 the second char
     * @param kern the kerning to apply in normalized 1000 units
     * @return <code>true</code> if the kerning was applied, <code>false</code> otherwise
     */
    public boolean setKerning(char char1, char char2, int kern) {
        int metrics[] = getMetricsTT(char1);
        if (metrics == null)
            return false;
        int c1 = metrics[0];
        metrics = getMetricsTT(char2);
        if (metrics == null)
            return false;
        int c2 = metrics[0];
        kerning.put((c1 << 16) + c2, kern);
        return true;
    }
    
    protected int[] getRawCharBBox(int c, String name) {
        HashMap map = null;
        if (name == null || cmap31 == null)
            map = cmap10;
        else
            map = cmap31;
        if (map == null)
            return null;
        int metric[] = (int[])map.get(new Integer(c));
        if (metric == null || bboxes == null)
            return null;
        return bboxes[metric[0]];
    }
}

⌨️ 快捷键说明

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