/** Creates the new PDF by merging the fields and forms. */ protected void closeIt() throws IOException { for (int k = 0; k < readers.size(); ++k) { readers.get(k).removeFields(); } for (int r = 0; r < readers.size(); ++r) { PdfReader reader = readers.get(r); for (int page = 1; page <= reader.getNumberOfPages(); ++page) { pageRefs.add(getNewReference(reader.getPageOrigRef(page))); pageDics.add(reader.getPageN(page)); } } mergeFields(); createAcroForms(); for (int r = 0; r < readers.size(); ++r) { PdfReader reader = readers.get(r); for (int page = 1; page <= reader.getNumberOfPages(); ++page) { PdfDictionary dic = reader.getPageN(page); PdfIndirectReference pageRef = getNewReference(reader.getPageOrigRef(page)); PdfIndirectReference parent = root.addPageRef(pageRef); dic.put(PdfName.PARENT, parent); propagate(dic, pageRef, false); } } for (Map.Entry<PdfReader, IntHashtable> entry : readers2intrefs.entrySet()) { PdfReader reader = entry.getKey(); try { file = reader.getSafeFile(); file.reOpen(); IntHashtable t = entry.getValue(); int keys[] = t.toOrderedKeys(); for (int k = 0; k < keys.length; ++k) { PRIndirectReference ref = new PRIndirectReference(reader, keys[k]); addToBody(PdfReader.getPdfObjectRelease(ref), t.get(keys[k])); } } finally { try { file.close(); // TODO: Removed - the user should be responsible for closing all PdfReaders. But, this // could cause a lot of memory leaks in code out there that hasn't been properly closing // things - maybe add a finalizer to PdfReader that calls PdfReader#close() ?? // reader.close(); } catch (Exception e) { // empty on purpose } } } pdf.close(); }
private PdfDictionary getCIDFont(PdfIndirectReference fontDescriptor, IntHashtable cjkTag) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE0); dic.put(PdfName.BASEFONT, new PdfName(fontName + style)); dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor); int keys[] = cjkTag.toOrderedKeys(); String w = convertToHCIDMetrics(keys, hMetrics); if (w != null) dic.put(PdfName.W, new PdfLiteral(w)); if (vertical) { w = convertToVCIDMetrics(keys, vMetrics, hMetrics); if (w != null) dic.put(PdfName.W2, new PdfLiteral(w)); } else dic.put(PdfName.DW, new PdfNumber(1000)); PdfDictionary cdic = new PdfDictionary(); cdic.put(PdfName.REGISTRY, new PdfString((String) fontDesc.get("Registry"), null)); cdic.put(PdfName.ORDERING, new PdfString((String) fontDesc.get("Ordering"), null)); cdic.put(PdfName.SUPPLEMENT, new PdfLiteral((String) fontDesc.get("Supplement"))); dic.put(PdfName.CIDSYSTEMINFO, cdic); return dic; }
private void doType1TT() { CMapToUnicode toUnicode = null; PdfObject enc = PdfReader.getPdfObject(font.get(PdfName.ENCODING)); if (enc == null) { fillEncoding(null); try { toUnicode = processToUnicode(); if (toUnicode != null) { Map<Integer, Integer> rm = toUnicode.createReverseMapping(); for (Map.Entry<Integer, Integer> kv : rm.entrySet()) { uni2byte.put(kv.getKey().intValue(), kv.getValue().intValue()); } } } catch (Exception ex) { throw new ExceptionConverter(ex); } } else { if (enc.isName()) fillEncoding((PdfName) enc); else if (enc.isDictionary()) { PdfDictionary encDic = (PdfDictionary) enc; enc = PdfReader.getPdfObject(encDic.get(PdfName.BASEENCODING)); if (enc == null) fillEncoding(null); else fillEncoding((PdfName) enc); PdfArray diffs = encDic.getAsArray(PdfName.DIFFERENCES); if (diffs != null) { diffmap = new IntHashtable(); int currentNumber = 0; for (int k = 0; k < diffs.size(); ++k) { PdfObject obj = diffs.getPdfObject(k); if (obj.isNumber()) currentNumber = ((PdfNumber) obj).intValue(); else { int c[] = GlyphList.nameToUnicode(PdfName.decodeName(((PdfName) obj).toString())); if (c != null && c.length > 0) { uni2byte.put(c[0], currentNumber); diffmap.put(c[0], currentNumber); } else { if (toUnicode == null) { toUnicode = processToUnicode(); if (toUnicode == null) { toUnicode = new CMapToUnicode(); } } final String unicode = toUnicode.lookup(new byte[] {(byte) currentNumber}, 0, 1); if ((unicode != null) && (unicode.length() == 1)) { this.uni2byte.put(unicode.charAt(0), currentNumber); this.diffmap.put(unicode.charAt(0), currentNumber); } } ++currentNumber; } } } } } PdfArray newWidths = font.getAsArray(PdfName.WIDTHS); PdfNumber first = font.getAsNumber(PdfName.FIRSTCHAR); PdfNumber last = font.getAsNumber(PdfName.LASTCHAR); if (BuiltinFonts14.containsKey(fontName)) { BaseFont bf; try { bf = BaseFont.createFont(fontName, WINANSI, false); } catch (Exception e) { throw new ExceptionConverter(e); } int e[] = uni2byte.toOrderedKeys(); for (int k = 0; k < e.length; ++k) { int n = uni2byte.get(e[k]); widths[n] = bf.getRawWidth(n, GlyphList.unicodeToName(e[k])); } if (diffmap != null) { // widths for diffmap must override existing ones e = diffmap.toOrderedKeys(); for (int k = 0; k < e.length; ++k) { int n = diffmap.get(e[k]); widths[n] = bf.getRawWidth(n, GlyphList.unicodeToName(e[k])); } diffmap = null; } ascender = bf.getFontDescriptor(ASCENT, 1000); capHeight = bf.getFontDescriptor(CAPHEIGHT, 1000); descender = bf.getFontDescriptor(DESCENT, 1000); italicAngle = bf.getFontDescriptor(ITALICANGLE, 1000); fontWeight = bf.getFontDescriptor(FONT_WEIGHT, 1000); llx = bf.getFontDescriptor(BBOXLLX, 1000); lly = bf.getFontDescriptor(BBOXLLY, 1000); urx = bf.getFontDescriptor(BBOXURX, 1000); ury = bf.getFontDescriptor(BBOXURY, 1000); } if (first != null && last != null && newWidths != null) { int f = first.intValue(); int nSize = f + newWidths.size(); if (widths.length < nSize) { int[] tmp = new int[nSize]; System.arraycopy(widths, 0, tmp, 0, f); widths = tmp; } for (int k = 0; k < newWidths.size(); ++k) { widths[f + k] = newWidths.getAsNumber(k).intValue(); } } fillFontDesc(font.getAsDict(PdfName.FONTDESCRIPTOR)); }