/** * This will load a PFB to be embedded into a document. * * @param doc The PDF document that will hold the embedded font. * @param dict The Font dictionary to write to. * @param pfbStream The pfb input. * @throws IOException If there is an error loading the data. */ public PdfType1FontEmbedder(Document doc, PdfDictionary dict, Bytes.IInputStream pfbStream, Encoding encoding) { dict[PdfName.Subtype] = PdfName.Type1; // read the pfb byte[] pfbBytes = pfbStream.ToByteArray(); PfbParser pfbParser = new PfbParser(pfbBytes); type1 = Type1Font.CreateWithPFB(pfbBytes); if (encoding == null) { fontEncoding = Type1Encoding.FromFontBox(type1.Encoding); } else { fontEncoding = encoding; } // build font descriptor FontDescriptor fd = BuildFontDescriptor(type1); PdfStream fontStream = new PdfStream(pfbParser.GetInputStream()); fontStream.Header[PdfName.Length] = PdfInteger.Get(pfbParser.Size); for (int i = 0; i < pfbParser.Lengths.Length; i++) { fontStream.Header[new PdfName("Length" + (i + 1))] = PdfInteger.Get(pfbParser.Lengths[i]); } fd.FontFile = new FontFile(doc, fontStream); // set the values dict[PdfName.FontDescriptor] = fd.BaseObject; dict[PdfName.BaseFont] = PdfName.Get(type1.Name); // widths List <int> widths = new List <int>(256); for (int code = 0; code <= 255; code++) { string name = fontEncoding.GetName(code); int width = (int)Math.Round(type1.GetWidth(name)); widths.Add(width); } dict[PdfName.FirstChar] = PdfInteger.Get(0); dict[PdfName.LastChar] = PdfInteger.Get(255); dict[PdfName.Widths] = new PdfArray(widths.Select(p => PdfInteger.Get(p))); dict[PdfName.Encoding] = encoding.GetPdfObject(); }
internal static Type1Font LoadType1Font(FontFile fontFile) { Type1Font t1 = null; var stream = fontFile.BaseDataObject; int length1 = fontFile.Length1; int length2 = fontFile.Length2; // repair Length1 and Length2 if necessary byte[] bytes = stream.ExtractBody(true).GetBuffer(); length1 = RepairLength1(bytes, length1); length2 = RepairLength2(bytes, length1, length2); if (bytes.Length > 0 && (bytes[0] & 0xff) == PFB_START_MARKER) { // some bad files embed the entire PFB, see PDFBOX-2607 t1 = Type1Font.CreateWithPFB(bytes); } else { // the PFB embedded as two segments back-to-back byte[] segment1 = new byte[length1]; Array.Copy(bytes, 0, segment1, 0, length1); byte[] segment2 = new byte[length2]; Array.Copy(bytes, length1, segment2, 0, length2); // empty streams are simply ignored if (length1 > 0 && length2 > 0) { t1 = Type1Font.CreateWithSegments(segment1, segment2); } } return(t1); }