1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
11 #include <pdf/XmpMetadata.hxx>
12 #include <tools/XmlWriter.hxx>
18 constexpr const char* constPadding
= " "
26 XmpMetadata::XmpMetadata()
33 void XmpMetadata::write()
35 mpMemoryStream
= std::make_unique
<SvMemoryStream
>(4096 /*Initial*/, 64 /*Resize*/);
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 )
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();
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();
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();
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");
175 sal_uInt64
XmpMetadata::getSize()
179 return mpMemoryStream
->GetSize();
182 const void* XmpMetadata::getData()
186 return mpMemoryStream
->GetData();
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */