/// <summary> /// Writes PDF document page tree into file stream /// </summary> /// <param name="pageTree">PDF document page tree</param> internal void Write(PdfPageTree pageTree) { if (pageTree.Pages.Count == 0) { throw new InvalidOperationException("PDF document has no pages"); } var pages = string.Join(Constants.SPACE, pageTree.Pages.Select(p => p.GetReference())); writeBeginObject(pageTree.ObjectId); writeBeginDictionary(); writeDictionaryEntry("/Type", "/Pages"); writeDictionaryEntry("/Count", pageTree.Pages.Count); writeDictionaryEntry("/Kids", ARRAY_PDF_FORMAT.Args(pages)); writeEndDictionary(); writeEndObject(); }
public void SetParent(PdfPageTree parent) { this[PdfName.Names.Parent] = parent.GetReference(); }
// add another test comment // more and more comments public PdfDocument(String content) { _offset = 0; _buffers = new List <String>(); _offsets = new List <int>(); // header _buffers.Add("%PDF-1.4\n%âãÏÓ\n"); _offset += _buffers.Last().Length; _offsets.Add(_offset); // pages PdfPageTree pageTree = PdfPageTree.GetPdfPageTree(); // page PdfPage page = new PdfPage(); PdfFont font = new PdfFont(); page.SetFont(font); PdfStream stream = new PdfStream(content); page.AddContent(stream); pageTree.AddPage(page); _buffers.Add(pageTree.ToPDF()); _offset += _buffers.Last().Length; _offsets.Add(_offset); _buffers.Add(page.ToPDF()); _offset += _buffers.Last().Length; _offsets.Add(_offset); _buffers.Add(font.ToPDF()); _offset += _buffers.Last().Length; _offsets.Add(_offset); _buffers.Add(stream.ToPDF()); _offset += _buffers.Last().Length; _offsets.Add(_offset); PdfCatalog catalog = PdfCatalog.GetPdfCatalog(); _buffers.Add(catalog.ToPDF()); _offset += _buffers.Last().Length; // x ref table String table = String.Empty; table += "xref" + "\n"; table += "0 " + _buffers.Count.ToString() + "\n"; table += "0000000000 65535 f \n"; foreach (var offset in _offsets) { table += offset.ToString().PadLeft(10, '0') + " " + "00000" + " " + "n " + "\n"; } _buffers.Add(table); // trailer String trailer = String.Empty; trailer += "trailer" + "\n" + "\n"; trailer += "<<" + "\n"; trailer += "/Root " + catalog.GetRefStr() + "\n"; trailer += "/Size " + (_buffers.Count - 1).ToString() + "\n"; trailer += ">>" + "\n"; _buffers.Add(trailer); _buffers.Add("startxref" + "\n" + _offset.ToString() + "\n" + "%%EOF\n"); }
public void SetParent(PdfPageTree parent) { this[PdfName.Names.Parent] = parent.GetReference(); }
public async Task SaveAsync(Stream stream) { var pdfDocumentCatalog = new PdfDocumentCatalog(); var pdfPageTree = new PdfPageTree(); pdfDocumentCatalog.PagesReference = pdfPageTree.Reference; var pdfFonts = new List <PdfFont>(); var pdfFontDescriptors = new List <PdfFontDescriptor>(); var pdfCharWidthsObjects = new List <PdfCharWidths>(); var pdfFontStreams = new List <PdfFontStream>(); var fontToPdfFont = new Dictionary <Font, PdfFont>(); foreach (var font in Fonts) { var fontStream = new PdfFontStream(); fontStream.Filter = PdfStreamFilter.FlateDecode; fontStream.Stream = new PdfStream(File.ReadAllBytes(font.FileName)); pdfFontStreams.Add(fontStream); var fontInfo = font.FontInfo; var factor = 1000.0 / fontInfo.HeadTable.UnitsPerEm; var charWidths = new int[129]; for (int i = 0; i < 129; i++) { fontInfo.CharacterMapTable.Encodings.Last().Value.TryGetGlyphId(i, out var glyphIndex); charWidths[i] = fontInfo.HorizontalMetricsTable.HMetrics[glyphIndex].AdvanceWidth; // Don't normalize //fontInfo.CharacterMapTable.Encodings.Last().Value.TryGetGlyphId(i, out var glyphIndex); //var blockLocation = fontInfo.IndexLocationTable.GetLocation(glyphIndex); //var glyphHeader = fontInfo.GlyphTable.ReadHeader(blockLocation); //charWidths[i] = glyphHeader.XMax - glyphHeader.XMin; } var pdfCharWidths = new PdfCharWidths { Widths = new PdfArray(charWidths.Select(x => (PdfObject) new PdfReal(Normalize(x, factor))).ToList()) }; pdfCharWidthsObjects.Add(pdfCharWidths); var pdfFontDescriptor = new PdfFontDescriptor { Ascent = new PdfInteger(Normalize(fontInfo.HorizontalHeaderTable.Ascender, factor)), Descent = new PdfInteger(Normalize(fontInfo.HorizontalHeaderTable.Descender, factor)), FontName = new PdfName(font.Name), FontBBox = new PdfRectangle(Normalize(fontInfo.HeadTable.XMin, factor), Normalize(fontInfo.HeadTable.YMin, factor), Normalize(fontInfo.HeadTable.XMax, factor), Normalize(fontInfo.HeadTable.YMax, factor)), FontWeight = new PdfInteger(fontInfo.Os2Table.UsWeightClass), AvgWidth = new PdfInteger(Normalize(fontInfo.Os2Table.XAvgCharWidth, factor)), CapHeight = new PdfInteger(Normalize(fontInfo.Os2Table.SCapHeight, factor)), ItalicAngle = new PdfReal(Normalize((double)fontInfo.PostScriptTable.ItalicAngle, factor)), // MaxWidth = new PdfInteger(0), // TODO // XHeight = new PdfInteger(0), // TODO StemV = new PdfInteger(50), // TODO Flags = new PdfInteger(32), // TODO FontFile2 = new PdfIndirectObjectReference(fontStream) }; pdfFontDescriptors.Add(pdfFontDescriptor); var pdfFont = new PdfFont { Subtype = new PdfName(font.Type), BaseFont = new PdfName(font.Name), Encoding = new PdfName(font.Encoding.ToString()), FontDescriptor = pdfFontDescriptor.Reference, Widths = pdfCharWidths.Reference, FirstChar = new PdfInteger(0), LastChar = new PdfInteger(127) }; pdfFonts.Add(pdfFont); fontToPdfFont[font] = pdfFont; } pdfPageTree.MediaBox = new PdfRectangle(0, 0, DefaultPageWidth, DefaultPageHeight); pdfPageTree.Resources = new PdfResources { Fonts = new PdfFontResources() }; foreach (var font in Fonts) { pdfPageTree.Resources.Fonts.Add($"F{_nextFontId++}", fontToPdfFont[font].Reference); } var pdfContentStreams = new List <PdfContentStream>(); var pdfPages = new List <PdfPage>(); foreach (var page in Pages) { var pdfPage = new PdfPage(); pdfPages.Add(pdfPage); pdfPage.Parent = pdfPageTree.Reference; if (page.Unit != 1.0) { pdfPage.UserUnit = new PdfReal(page.Unit); } if (page.Width != DefaultPageWidth || page.Height != DefaultPageHeight) { pdfPage.MediaBox = new PdfRectangle(0, 0, page.Width, page.Height); } var instructions = page.Paint(); if (!string.IsNullOrWhiteSpace(instructions)) { var pdfContentStream = new PdfContentStream { Stream = new PdfStream(Encoding.ASCII.GetBytes(instructions)), // Filter = PdfStreamFilter.FlateDecode // Temporarily no using. Uncomment after development complete }; pdfContentStreams.Add(pdfContentStream); pdfPage.Contents = pdfContentStream.Reference; } } pdfPageTree.Kids = pdfPages.Select(x => x.Reference).ToList(); var writer = new PdfWriter(stream); await writer.WriteAsync(pdfDocumentCatalog); await writer.WriteAsync(pdfPageTree); foreach (var pdfFont in pdfFonts) { await writer.WriteAsync(pdfFont); } foreach (var pdfFontDescriptor in pdfFontDescriptors) { await writer.WriteAsync(pdfFontDescriptor); } foreach (var pdfCharWidths in pdfCharWidthsObjects) { await writer.WriteAsync(pdfCharWidths); } foreach (var pdfFontStream in pdfFontStreams) { await writer.WriteAsync(pdfFontStream); } foreach (var pdfPage in pdfPages) { await writer.WriteAsync(pdfPage); } foreach (var pdfContentStream in pdfContentStreams) { await writer.WriteAsync(pdfContentStream); } await writer.CloseAsync(pdfDocumentCatalog, null); }