nss: upgrade to release 3.73
[LibreOffice.git] / vcl / source / pdf / XmpMetadata.cxx
blob180a8d037b46731b260772e38a5203d4fd9eb04f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
11 #include <pdf/XmpMetadata.hxx>
12 #include <tools/XmlWriter.hxx>
14 namespace vcl::pdf
16 namespace
18 constexpr const char* constPadding = " "
19 " "
20 " "
21 " "
22 " "
23 "\n";
26 XmpMetadata::XmpMetadata()
27 : mbWritten(false)
28 , mnPDF_A(0)
29 , mbPDF_UA(false)
33 void XmpMetadata::write()
35 mpMemoryStream = std::make_unique<SvMemoryStream>(4096 /*Initial*/, 64 /*Resize*/);
37 // Header
38 mpMemoryStream->WriteOString("<?xpacket begin=\"");
39 mpMemoryStream->WriteOString(OUStringToOString(OUString(u'\xFEFF'), RTL_TEXTENCODING_UTF8));
40 mpMemoryStream->WriteOString("\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n");
43 tools::XmlWriter aXmlWriter(mpMemoryStream.get());
44 aXmlWriter.startDocument(2, false);
45 aXmlWriter.startElement("x", "xmpmeta", "adobe:ns:meta/");
46 aXmlWriter.startElement("rdf", "RDF", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
48 // PDF/A part ( ISO 19005-1:2005 - 6.7.11 )
49 if (mnPDF_A > 0)
51 OString sPdfVersion = OString::number(mnPDF_A);
52 OString sPdfConformance = (mnPDF_A == 1) ? "A" : "B";
54 aXmlWriter.startElement("rdf:Description");
55 aXmlWriter.attribute("rdf:about", OString(""));
56 aXmlWriter.attribute("xmlns:pdfaid", OString("http://www.aiim.org/pdfa/ns/id/"));
58 aXmlWriter.startElement("pdfaid:part");
59 aXmlWriter.content(sPdfVersion);
60 aXmlWriter.endElement();
62 aXmlWriter.startElement("pdfaid:conformance");
63 aXmlWriter.content(sPdfConformance);
64 aXmlWriter.endElement();
66 aXmlWriter.endElement();
69 // Dublin Core properties
70 if (!msTitle.isEmpty() || !msAuthor.isEmpty() || !msSubject.isEmpty())
72 aXmlWriter.startElement("rdf:Description");
73 aXmlWriter.attribute("rdf:about", OString(""));
74 aXmlWriter.attribute("xmlns:dc", OString("http://purl.org/dc/elements/1.1/"));
75 if (!msTitle.isEmpty())
77 // this is according to PDF/A-1, technical corrigendum 1 (2007-04-01)
78 aXmlWriter.startElement("dc:title");
79 aXmlWriter.startElement("rdf:Alt");
80 aXmlWriter.startElement("rdf:li");
81 aXmlWriter.attribute("xml:lang", OString("x-default"));
82 aXmlWriter.content(msTitle);
83 aXmlWriter.endElement();
84 aXmlWriter.endElement();
85 aXmlWriter.endElement();
87 if (!msAuthor.isEmpty())
89 aXmlWriter.startElement("dc:creator");
90 aXmlWriter.startElement("rdf:Seq");
91 aXmlWriter.startElement("rdf:li");
92 aXmlWriter.content(msAuthor);
93 aXmlWriter.endElement();
94 aXmlWriter.endElement();
95 aXmlWriter.endElement();
97 if (!msSubject.isEmpty())
99 aXmlWriter.startElement("dc:description");
100 aXmlWriter.startElement("rdf:Alt");
101 aXmlWriter.startElement("rdf:li");
102 aXmlWriter.attribute("xml:lang", OString("x-default"));
103 aXmlWriter.content(msSubject);
104 aXmlWriter.endElement();
105 aXmlWriter.endElement();
106 aXmlWriter.endElement();
108 aXmlWriter.endElement();
111 // PDF/UA
112 if (mbPDF_UA)
114 OString sPdfUaVersion = OString::number(1);
115 aXmlWriter.startElement("rdf:Description");
116 aXmlWriter.attribute("rdf:about", OString(""));
117 aXmlWriter.attribute("xmlns:pdfuaid", OString("http://www.aiim.org/pdfua/ns/id/"));
119 aXmlWriter.startElement("pdfuaid:part");
120 aXmlWriter.content(sPdfUaVersion);
121 aXmlWriter.endElement();
123 aXmlWriter.endElement();
126 // PDF properties
127 if (!msProducer.isEmpty() || !msKeywords.isEmpty())
129 aXmlWriter.startElement("rdf:Description");
130 aXmlWriter.attribute("rdf:about", OString(""));
131 aXmlWriter.attribute("xmlns:pdf", OString("http://ns.adobe.com/pdf/1.3/"));
132 if (!msProducer.isEmpty())
134 aXmlWriter.startElement("pdf:Producer");
135 aXmlWriter.content(msProducer);
136 aXmlWriter.endElement();
138 if (!msKeywords.isEmpty())
140 aXmlWriter.startElement("pdf:Keywords");
141 aXmlWriter.content(msKeywords);
142 aXmlWriter.endElement();
144 aXmlWriter.endElement();
147 // XMP Basic schema
148 aXmlWriter.startElement("rdf:Description");
149 aXmlWriter.attribute("rdf:about", OString(""));
150 aXmlWriter.attribute("xmlns:xmp", OString("http://ns.adobe.com/xap/1.0/"));
151 if (!m_sCreatorTool.isEmpty())
153 aXmlWriter.startElement("xmp:CreatorTool");
154 aXmlWriter.content(m_sCreatorTool);
155 aXmlWriter.endElement();
157 aXmlWriter.startElement("xmp:CreateDate");
158 aXmlWriter.content(m_sCreateDate);
159 aXmlWriter.endElement();
160 aXmlWriter.endElement();
162 aXmlWriter.endElement();
163 aXmlWriter.endElement();
164 aXmlWriter.endDocument();
167 // add padding (needed so the metadata can be changed in-place"
168 for (sal_Int32 nSpaces = 1; nSpaces <= 21; nSpaces++)
169 mpMemoryStream->WriteOString(constPadding);
171 mpMemoryStream->WriteOString("<?xpacket end=\"w\"?>\n");
172 mbWritten = true;
175 sal_uInt64 XmpMetadata::getSize()
177 if (!mbWritten)
178 write();
179 return mpMemoryStream->GetSize();
182 const void* XmpMetadata::getData()
184 if (!mbWritten)
185 write();
186 return mpMemoryStream->GetData();
189 } // end vcl::pdf
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */