📄 type1font.java
字号:
else if (ident.equals("XHeight")) XHeight = (int)Float.valueOf(tok.nextToken()).floatValue(); else if (ident.equals("Ascender")) Ascender = (int)Float.valueOf(tok.nextToken()).floatValue(); else if (ident.equals("Descender")) Descender = (int)Float.valueOf(tok.nextToken()).floatValue(); else if (ident.equals("StdHW")) StdHW = (int)Float.valueOf(tok.nextToken()).floatValue(); else if (ident.equals("StdVW")) StdVW = (int)Float.valueOf(tok.nextToken()).floatValue(); else if (ident.equals("StartCharMetrics")) { isMetrics = true; break; } } if (!isMetrics) throw new DocumentException("Missing StartCharMetrics in " + fileName); while ((line = rf.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line); if (!tok.hasMoreTokens()) continue; String ident = tok.nextToken(); if (ident.equals("EndCharMetrics")) { isMetrics = false; break; } Integer C = new Integer(-1); Integer WX = new Integer(250); String N = ""; tok = new StringTokenizer(line, ";"); while (tok.hasMoreTokens()) { StringTokenizer tokc = new StringTokenizer(tok.nextToken()); if (!tokc.hasMoreTokens()) continue; ident = tokc.nextToken(); if (ident.equals("C")) C = Integer.valueOf(tokc.nextToken()); else if (ident.equals("WX")) WX = Integer.valueOf(tokc.nextToken()); else if (ident.equals("N")) N = tokc.nextToken(); } CharMetrics.add(new Object[]{C, WX, N}); } if (isMetrics) throw new DocumentException("Missing EndCharMetrics in " + fileName); while ((line = rf.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line); if (!tok.hasMoreTokens()) continue; String ident = tok.nextToken(); if (ident.equals("EndFontMetrics")) return; if (ident.equals("StartKernPairs")) { isMetrics = true; break; } } if (!isMetrics) throw new DocumentException("Missing EndFontMetrics in " + fileName); while ((line = rf.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line); if (!tok.hasMoreTokens()) continue; String ident = tok.nextToken(); if (ident.equals("KPX")) { String first = tok.nextToken(); String second = tok.nextToken(); Integer width = new Integer((int)Float.valueOf(tok.nextToken()).floatValue()); Object relates[] = (Object[])KernPairs.get(first); if (relates == null) KernPairs.put(first, new Object[]{second, width}); else { int n = relates.length; Object relates2[] = new Object[n + 2]; System.arraycopy(relates, 0, relates2, 0, n); relates2[n] = second; relates2[n + 1] = width; KernPairs.put(first, relates2); } } else if (ident.equals("EndKernPairs")) { isMetrics = false; break; } } if (isMetrics) throw new DocumentException("Missing EndKernPairs in " + fileName); rf.close(); } /** If the embedded flag is <CODE>false</CODE> or if the font is * one of the 14 built in types, 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 */ private PdfStream getFontStream() throws DocumentException { if (builtinFont || !embedded) return null; RandomAccessFileOrArray rf = null; try { String filePfb = fileName.substring(0, fileName.length() - 3) + "pfb"; if (pfb == null) rf = new RandomAccessFileOrArray(filePfb); else rf = new RandomAccessFileOrArray(pfb); int fileLength = rf.length(); byte st[] = new byte[fileLength - 18]; int lengths[] = new int[3]; int bytePtr = 0; for (int k = 0; k < 3; ++k) { if (rf.read() != 0x80) throw new DocumentException("Start marker missing in " + filePfb); if (rf.read() != pfbTypes[k]) throw new DocumentException("Incorrect segment type in " + filePfb); int size = rf.read(); size += rf.read() << 8; size += rf.read() << 16; size += rf.read() << 24; lengths[k] = size; while (size != 0) { int got = rf.read(st, bytePtr, size); if (got < 0) throw new DocumentException("Premature end in " + filePfb); bytePtr += got; size -= got; } } return new StreamFont(st, lengths); } catch (Exception e) { throw new DocumentException(e.getMessage()); } finally { if (rf != null) { try { rf.close(); } catch (Exception e) { // empty on purpose } } } } /** Generates the font descriptor for this font or <CODE>null</CODE> if it is * one of the 14 built in fonts. * @param fontStream the indirect reference to a PdfStream containing the font or <CODE>null</CODE> * @return the PdfDictionary containing the font descriptor or <CODE>null</CODE> */ private PdfDictionary getFontDescriptor(PdfIndirectReference fontStream) { if (builtinFont) return null; PdfDictionary dic = new PdfDictionary(new PdfName("FontDescriptor")); dic.put(new PdfName("Ascent"), new PdfNumber(Ascender)); dic.put(new PdfName("CapHeight"), new PdfNumber(CapHeight)); dic.put(new PdfName("Descent"), new PdfNumber(Descender)); dic.put(new PdfName("FontBBox"), new PdfRectangle(llx, lly, urx, ury)); dic.put(new PdfName("FontName"), new PdfName(FontName)); dic.put(new PdfName("ItalicAngle"), new PdfNumber(ItalicAngle)); dic.put(new PdfName("StemV"), new PdfNumber(StdVW)); if (fontStream != null) dic.put(new PdfName("FontFile"), fontStream); int flags = 0; if (IsFixedPitch) flags |= 1; flags |= fontSpecific ? 4 : 32; if (ItalicAngle < 0) flags |= 64; if (FontName.indexOf("Caps") >= 0 || FontName.endsWith("SC")) flags |= 131072; if (Weight.equals("Bold")) 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 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> */ private PdfDictionary getFontBaseType(PdfIndirectReference fontDescriptor, int firstChar, int lastChar, byte shortTag[]) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.SUBTYPE, PdfName.TYPE1); dic.put(PdfName.BASEFONT, new PdfName(FontName)); boolean stdEncoding = encoding.equals("Cp1252") || encoding.equals("MacRoman"); if (!fontSpecific) { for (int k = firstChar; k <= lastChar; ++k) { if (!differences[k].equals(notdef)) { firstChar = k; break; } } if (stdEncoding) 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); } } if (forceWidthsOutput || !(builtinFont && (fontSpecific || stdEncoding))) { 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 (!builtinFont && 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]; if (!subset) { 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; pobj = getFontStream(); if (pobj != null){ obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } pobj = getFontDescriptor(ind_font); if (pobj != null){ obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } pobj = getFontBaseType(ind_font, 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>, * <CODE>ITALICANGLE</CODE>, <CODE>BBOXLLX</CODE>, <CODE>BBOXLLY</CODE>, <CODE>BBOXURX</CODE> * and <CODE>BBOXURY</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 AWT_ASCENT: case ASCENT: return Ascender * fontSize / 1000; case CAPHEIGHT: return CapHeight * fontSize / 1000; case AWT_DESCENT: case DESCENT: return Descender * fontSize / 1000; case ITALICANGLE: return ItalicAngle; case BBOXLLX: return llx * fontSize / 1000; case BBOXLLY: return lly * fontSize / 1000; case BBOXURX: return urx * fontSize / 1000; case BBOXURY: return ury * fontSize / 1000; case AWT_LEADING: return 0; case AWT_MAXADVANCE: return (urx - llx) * fontSize / 1000; } return 0; } /** Gets the postscript font name. * @return the postscript font name */ public String getPostscriptFontName() { return FontName; } /** 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 new String[][]{{"", "", "", 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 new String[][]{{"", "", "", FamilyName}}; } /** Checks if the font has any kerning pairs. * @return <CODE>true</CODE> if the font has any kerning pairs */ public boolean hasKernPairs() { return KernPairs.size() > 0; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -