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

📄 truetypefont.java

📁 处理PDF
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        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) {                pobj = new StreamFont(readCffFont(), "Type1C", compressionLevel);                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, compressionLevel);                obj = writer.addToBody(pobj);                ind_font = obj.getIndirectReference();            }        }        pobj = getFontDescriptor(ind_font, subsetPrefix, null);        if (pobj != null){            obj = writer.addToBody(pobj);            ind_font = obj.getIndirectReference();        }        pobj = getFontBaseType(ind_font, subsetPrefix, firstChar, lastChar, shortTag);        writer.addToBody(pobj, ref);    }        /**     * If this font file is using the Compact Font File Format, then this method     * will return the raw bytes needed for the font stream. If this method is     * ever made public: make sure to add a test if (cff == true).     * @return	a byte array     * @since	2.1.3     */    protected byte[] readCffFont() throws IOException {        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            }        }    	return b;    }    /**     * Returns a PdfStream object with the full font program.     * @return	a PdfStream with the font program     * @since	2.1.3     */    public PdfStream getFullFontStream() throws IOException, DocumentException {        if (cff) {            return new StreamFont(readCffFont(), "Type1C", compressionLevel);        }        else {        	byte[] b = getFullFont();        	int lengths[] = new int[]{b.length};        	return new StreamFont(b, lengths, compressionLevel);        }    }        /** 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 os_2.sTypoAscender * fontSize / head.unitsPerEm;            case CAPHEIGHT:                return os_2.sCapHeight * fontSize / head.unitsPerEm;            case DESCENT:                return os_2.sTypoDescender * fontSize / head.unitsPerEm;            case ITALICANGLE:                return (float)italicAngle;            case BBOXLLX:                return fontSize * head.xMin / head.unitsPerEm;            case BBOXLLY:                return fontSize * head.yMin / head.unitsPerEm;            case BBOXURX:                return fontSize * head.xMax / head.unitsPerEm;            case BBOXURY:                return fontSize * head.yMax / head.unitsPerEm;            case AWT_ASCENT:                return fontSize * hhea.Ascender / head.unitsPerEm;            case AWT_DESCENT:                return fontSize * hhea.Descender / head.unitsPerEm;            case AWT_LEADING:                return fontSize * hhea.LineGap / head.unitsPerEm;            case AWT_MAXADVANCE:                return fontSize * hhea.advanceWidthMax / head.unitsPerEm;            case UNDERLINE_POSITION:                return (underlinePosition - underlineThickness / 2) * fontSize / head.unitsPerEm;            case UNDERLINE_THICKNESS:                return underlineThickness * fontSize / head.unitsPerEm;            case STRIKETHROUGH_POSITION:                return os_2.yStrikeoutPosition * fontSize / head.unitsPerEm;            case STRIKETHROUGH_THICKNESS:                return os_2.yStrikeoutSize * fontSize / head.unitsPerEm;            case SUBSCRIPT_SIZE:                return os_2.ySubscriptYSize * fontSize / head.unitsPerEm;            case SUBSCRIPT_OFFSET:                return -os_2.ySubscriptYOffset * fontSize / head.unitsPerEm;            case SUPERSCRIPT_SIZE:                return os_2.ySuperscriptYSize * fontSize / head.unitsPerEm;            case SUPERSCRIPT_OFFSET:                return os_2.ySuperscriptYOffset * fontSize / 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 (cmapExt != null)            return (int[])cmapExt.get(new Integer(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) + (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 all the entries of the Names-Table. If it is a True Type font     * each array element will have {Name ID, 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[][] getAllNameEntries() {        return allNameEntries;    }        /** 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(int char1, int 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 + -