📄 truetypefontunicode.java
字号:
dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE2); dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName)); } dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor); if (!cff) dic.put(PdfName.CIDTOGIDMAP,PdfName.IDENTITY); PdfDictionary cdic = new PdfDictionary(); cdic.put(PdfName.REGISTRY, new PdfString("Adobe")); cdic.put(PdfName.ORDERING, new PdfString("Identity")); cdic.put(PdfName.SUPPLEMENT, new PdfNumber(0)); dic.put(PdfName.CIDSYSTEMINFO, cdic); if (!vertical) { dic.put(PdfName.DW, new PdfNumber(1000)); StringBuffer buf = new StringBuffer("["); int lastNumber = -10; boolean firstTime = true; for (int k = 0; k < metrics.length; ++k) { int metric[] = (int[])metrics[k]; if (metric[1] == 1000) continue; int m = metric[0]; if (m == lastNumber + 1) { buf.append(' ').append(metric[1]); } else { if (!firstTime) { buf.append(']'); } firstTime = false; buf.append(m).append('[').append(metric[1]); } lastNumber = m; } if (buf.length() > 1) { buf.append("]]"); dic.put(PdfName.W, new PdfLiteral(buf.toString())); } } return dic; } /** Generates the font dictionary. * @param descendant the descendant dictionary * @param subsetPrefix the subset prefix * @param toUnicode the ToUnicode stream * @return the stream */ private PdfDictionary getFontBaseType(PdfIndirectReference descendant, String subsetPrefix, PdfIndirectReference toUnicode) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.SUBTYPE, PdfName.TYPE0); // The PDF Reference manual advises to add -encoding to CID font names if (cff) dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName+"-"+encoding)); //dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName)); else dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName)); //dic.put(PdfName.BASEFONT, new PdfName(fontName)); dic.put(PdfName.ENCODING, new PdfName(encoding)); dic.put(PdfName.DESCENDANTFONTS, new PdfArray(descendant)); if (toUnicode != null) dic.put(PdfName.TOUNICODE, toUnicode); return dic; } /** The method used to sort the metrics array. * @param o1 the first element * @param o2 the second element * @return the comparison */ public int compare(Object o1, Object o2) { int m1 = ((int[])o1)[0]; int m2 = ((int[])o2)[0]; if (m1 < m2) return -1; if (m1 == m2) return 0; return 1; } private static final byte[] rotbits = {(byte)0x80,(byte)0x40,(byte)0x20,(byte)0x10,(byte)0x08,(byte)0x04,(byte)0x02,(byte)0x01}; /** 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 { HashMap longTag = (HashMap)params[0]; addRangeUni(longTag, true, subset); Object metrics[] = longTag.values().toArray(); Arrays.sort(metrics, this); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; PdfIndirectReference cidset = null; if (writer.getPDFXConformance() == PdfWriter.PDFA1A || writer.getPDFXConformance() == PdfWriter.PDFA1B) { PdfStream stream; if (metrics.length == 0) { stream = new PdfStream(new byte[]{(byte)0x80}); } else { int top = ((int[])metrics[metrics.length - 1])[0]; byte[] bt = new byte[top / 8 + 1]; for (int k = 0; k < metrics.length; ++k) { int v = ((int[])metrics[k])[0]; bt[v / 8] |= rotbits[v % 8]; } stream = new PdfStream(bt); stream.flateCompress(compressionLevel); } cidset = writer.addToBody(stream).getIndirectReference(); } // sivan: cff if (cff) { byte b[] = readCffFont(); if (subset || subsetRanges != null) { CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b),longTag); b = cff.Process(cff.getNames()[0]); } pobj = new StreamFont(b, "CIDFontType0C", compressionLevel); obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } else { byte[] b; if (subset || directoryOffset != 0) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), longTag, directoryOffset, false, false); 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(); } String subsetPrefix = ""; if (subset) subsetPrefix = createSubsetPrefix(); PdfDictionary dic = getFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.addToBody(dic); ind_font = obj.getIndirectReference(); pobj = getCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); pobj = getToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.addToBody(pobj); toUnicodeRef = obj.getIndirectReference(); } pobj = getFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.addToBody(pobj, ref); } /** * 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(), "CIDFontType0C", compressionLevel); } return super.getFullFontStream(); } /** A forbidden operation. Will throw a null pointer exception. * @param text the text * @return always <CODE>null</CODE> */ byte[] convertToBytes(String text) { return null; } byte[] convertToBytes(int char1) { return null; } /** 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)); HashMap map = null; if (fontSpecific) map = cmap10; else map = cmap31; if (map == null) return null; if (fontSpecific) { if ((c & 0xffffff00) == 0 || (c & 0xffffff00) == 0xf000) return (int[])map.get(new Integer(c & 0xff)); else return null; } else return (int[])map.get(new Integer(c)); } /** * Checks if a character exists in this font. * @param c the character to check * @return <CODE>true</CODE> if the character has a glyph, * <CODE>false</CODE> otherwise */ public boolean charExists(int c) { return getMetricsTT(c) != null; } /** * Sets the character advance. * @param c the character * @param advance the character advance normalized to 1000 units * @return <CODE>true</CODE> if the advance was set, * <CODE>false</CODE> otherwise */ public boolean setCharAdvance(int c, int advance) { int[] m = getMetricsTT(c); if (m == null) return false; m[1] = advance; return true; } public int[] getCharBBox(int c) { if (bboxes == null) return null; int[] m = getMetricsTT(c); if (m == null) return null; return bboxes[m[0]]; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -