public void CanGeneratePdfAFile(PdfAStandard standard) { var builder = new PdfDocumentBuilder { ArchiveStandard = standard }; var page = builder.AddPage(PageSize.A4); var imgBytes = File.ReadAllBytes(IntegrationHelpers.GetDocumentPath("smile-250-by-160.jpg", false)); page.AddJpeg(imgBytes, new PdfRectangle(50, 70, 150, 130)); var font = builder.AddTrueTypeFont(TrueTypeTestHelper.GetFileBytes("Roboto-Regular.ttf")); page.AddText($"Howdy PDF/{standard}!", 10, new PdfPoint(25, 700), font); var bytes = builder.Build(); WriteFile(nameof(CanGeneratePdfAFile) + standard, bytes); using (var pdf = PdfDocument.Open(bytes, ParsingOptions.LenientParsingOff)) { Assert.Equal(1, pdf.NumberOfPages); Assert.True(pdf.TryGetXmpMetadata(out var xmp)); Assert.NotNull(xmp.GetXDocument()); } }
public static void Obey(Dictionary <NameToken, IToken> catalog, Func <IToken, ObjectToken> writerFunc, PdfDocumentBuilder.DocumentInformationBuilder documentInformationBuilder, PdfAStandard archiveStandard) { catalog[NameToken.OutputIntents] = OutputIntentsFactory.GetOutputIntentsArray(writerFunc); var xmpStream = XmpWriter.GenerateXmpStream(documentInformationBuilder, 1.7m, archiveStandard); var xmpObj = writerFunc(xmpStream); catalog[NameToken.Metadata] = new IndirectReferenceToken(xmpObj.Number); }
public static StreamToken GenerateXmpStream(PdfDocumentBuilder.DocumentInformationBuilder builder, decimal version, PdfAStandard standard) { XNamespace xmpMeta = XmpMetaNamespace; XNamespace rdf = RdfNamespace; var emptyRdfAbout = new XAttribute(rdf + "about", string.Empty); var rdfDescriptionElement = new XElement(rdf + "Description", emptyRdfAbout); // Dublin Core Schema AddElementsForSchema(rdfDescriptionElement, DublinCorePrefix, DublinCoreNamespace, builder, new List <SchemaMapper> { new SchemaMapper("format", b => "application/pdf"), new SchemaMapper("creator", b => b.Author), new SchemaMapper("description", b => b.Subject), new SchemaMapper("title", b => b.Title) }); // XMP Basic Schema AddElementsForSchema(rdfDescriptionElement, XmpBasicPrefix, XmpBasicNamespace, builder, new List <SchemaMapper> { new SchemaMapper("CreatorTool", b => b.Creator) }); // Adobe PDF Schema AddElementsForSchema(rdfDescriptionElement, AdobePdfPrefix, AdobePdfNamespace, builder, new List <SchemaMapper> { new SchemaMapper("PDFVersion", b => "1.7"), new SchemaMapper("Producer", b => b.Producer) }); var pdfAIdContainer = GetVersionAndConformanceLevelIdentificationElement(rdf, emptyRdfAbout, standard); var document = new XDocument( new XElement(xmpMeta + "xmpmeta", GetNamespaceAttribute(XmpMetaPrefix, XmpMetaNamespace), new XAttribute(xmpMeta + "xmptk", Xmptk), new XElement(rdf + "RDF", GetNamespaceAttribute("rdf", rdf), rdfDescriptionElement, pdfAIdContainer ) ) ); var xml = document.ToString(SaveOptions.None).Replace("\r\n", "\n"); xml = $"<?xpacket begin=\"\ufeff\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n{xml}\n<?xpacket end=\"r\"?>"; var bytes = Encoding.UTF8.GetBytes(xml); return(new StreamToken(new DictionaryToken(new Dictionary <NameToken, IToken> { { NameToken.Type, NameToken.Metadata }, { NameToken.Subtype, NameToken.Xml }, { NameToken.Length, new NumericToken(bytes.Length) } }), bytes)); }
private static XElement GetVersionAndConformanceLevelIdentificationElement(XNamespace rdf, XAttribute emptyRdfAbout, PdfAStandard standard) { /* * The only mandatory XMP entries are those which indicate that the file is a PDF/A-1 file and its conformance level. * The PDF/A version and conformance level of a file shall be specified using the PDF/A Identification extension schema. */ XNamespace pdfaid = PdfAIdentificationExtensionNamespace; var pdfAidContainer = new XElement(rdf + "Description", emptyRdfAbout, GetNamespaceAttribute(PdfAIdentificationExtensionPrefix, pdfaid)); int part; string conformance; switch (standard) { case PdfAStandard.A1B: part = 1; conformance = "B"; break; case PdfAStandard.A1A: part = 1; conformance = "A"; break; case PdfAStandard.A2B: part = 2; conformance = "B"; break; default: throw new ArgumentOutOfRangeException(nameof(standard), standard, null); } pdfAidContainer.Add(new XElement(pdfaid + "part", part)); pdfAidContainer.Add(new XElement(pdfaid + "conformance", conformance)); return(pdfAidContainer); }