42 char timezoneSign = timeZoneMinutes >= 0 ?
'+' :
'-';
43 int timeZoneHours =
SkTAbs(timeZoneMinutes) / 60;
44 timeZoneMinutes =
SkTAbs(timeZoneMinutes) % 60;
46 "D:%04u%02u%02u%02u%02u%02u%c%02d'%02d'",
47 static_cast<unsigned>(dt.
fYear),
static_cast<unsigned>(dt.
fMonth),
48 static_cast<unsigned>(dt.
fDay),
static_cast<unsigned>(dt.
fHour),
49 static_cast<unsigned>(dt.
fMinute),
50 static_cast<unsigned>(dt.
fSecond), timezoneSign, timeZoneHours,
56 const char*
const key;
71 for (
const auto keyValuePtr : gMetadataKeys) {
73 if (
value.size() > 0) {
74 dict->insertTextString(keyValuePtr.key,
value);
90 const char uuidNamespace[] =
"org.skia.pdf\n";
91 md5.writeText(uuidNamespace);
93 md5.write(&msec,
sizeof(msec));
96 md5.write(&dateTime,
sizeof(dateTime));
100 for (
const auto keyValuePtr : gMetadataKeys) {
101 md5.writeText(keyValuePtr.key);
102 md5.write(
"\037", 1);
105 md5.write(
"\036", 1);
109 digest.
data[6] = (digest.
data[6] & 0x0F) | 0x30;
110 digest.
data[8] = (digest.
data[6] & 0x3F) | 0x80;
111 static_assert(
sizeof(digest) ==
sizeof(
SkUUID),
"uuid_size");
113 memcpy((
void*)&uuid, &digest,
sizeof(digest));
121 static_assert(
sizeof(
SkUUID) == 16,
"uuid_size");
122 array->appendByteString(
SkString(
reinterpret_cast<const char*
>(&doc ),
sizeof(
SkUUID)));
129static void hexify(
const uint8_t** inputPtr,
char** outputPtr,
int count) {
132 while (
count-- > 0) {
133 uint8_t
value = *(*inputPtr)++;
161 PDFXMLObject(
SkString xml) : fXML(
std::move(xml)) {}
164 dict.insertName(
"Subtype",
"XML");
165 dict.insertInt(
"Length", fXML.size());
167 static const char streamBegin[] =
" stream\n";
168 stream->writeText(streamBegin);
172 stream->write(fXML.c_str(), fXML.size());
173 static const char streamEnd[] =
"\nendstream";
174 stream->writeText(streamEnd);
184 for (
size_t i = 0;
i < input.
size(); ++
i) {
185 if (input[
i] ==
'&') {
187 }
else if (input[
i] ==
'<') {
195 const char* before =
nullptr,
196 const char* after =
nullptr) {
197 if (input.
size() == 0) {
203 size_t beforeLen = before ? strlen(before) : 0;
204 size_t afterLen = after ? strlen(after) : 0;
209 strncpy(
out, before, beforeLen);
212 static const char kAmp[] =
"&";
213 static const char kLt[] =
"<";
214 for (
size_t i = 0;
i < input.
size(); ++
i) {
215 if (input[
i] ==
'&') {
216 memcpy(
out, kAmp, strlen(kAmp));
218 }
else if (input[
i] ==
'<') {
219 memcpy(
out, kLt, strlen(kLt));
226 strncpy(
out, after, afterLen);
240 static const char templateString[] =
241 "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n"
242 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"\n"
243 " x:xmptk=\"Adobe XMP Core 5.4-c005 78.147326, "
244 "2012/08/23-13:03:03\">\n"
246 "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
247 "<rdf:Description rdf:about=\"\"\n"
248 " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n"
249 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
250 " xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n"
251 " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\"\n"
252 " xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\">\n"
253 "<pdfaid:part>2</pdfaid:part>\n"
254 "<pdfaid:conformance>B</pdfaid:conformance>\n"
258 "<dc:format>application/pdf</dc:format>\n"
263 "<xmpMM:DocumentID>uuid:%s</xmpMM:DocumentID>\n"
264 "<xmpMM:InstanceID>uuid:%s</xmpMM:InstanceID>\n"
267 "</rdf:Description>\n"
270 "<?xpacket end=\"w\"?>\n";
279 creationDate =
SkStringPrintf(
"<xmp:CreateDate>%s</xmp:CreateDate>\n",
287 "<xmp:ModifyDate>%s</xmp:ModifyDate>\n", tmp.
c_str());
291 "<dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">",
292 "</rdf:li></rdf:Alt></dc:title>\n");
295 "</rdf:li></rdf:Seq></dc:creator>\n");
299 "<dc:description><rdf:Alt><rdf:li xml:lang=\"x-default\">",
300 "</rdf:li></rdf:Alt></dc:description>\n");
303 "</rdf:li></rdf:Bag></dc:subject>\n");
305 "</pdf:Keywords>\n");
311 "</xmp:CreatorTool>\n");
319 templateString, modificationDate.
c_str(), creationDate.
c_str(),
325 dict->insertName(
"Subtype",
"XML");
331#undef SKPDF_CUSTOM_PRODUCER_KEY
334#undef SKPDF_STRING_IMPL
static SkMD5::Digest md5(const SkBitmap &bm)
SkPDFIndirectReference SkPDFStreamOut(std::unique_ptr< SkPDFDict > dict, std::unique_ptr< SkStreamAsset > content, SkPDFDocument *doc, SkPDFSteamCompressionEnabled compress)
static std::unique_ptr< SkPDFDict > SkPDFMakeDict(const char *type=nullptr)
static std::unique_ptr< SkPDFArray > SkPDFMakeArray(Args... args)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
constexpr int SkToInt(S x)
static std::unique_ptr< SkMemoryStream > MakeCopy(const void *data, size_t length)
virtual void emitObject(SkWStream *stream) const =0
const char * c_str() const
void GetDateTime(SkPDF::DateTime *)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
void toISO8601(SkString *dst) const
uint8_t fDayOfWeek
0..6, 0==Sunday
std::shared_ptr< const fml::Mapping > data