OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkPDFMetadata.h" | 8 #include "SkPDFMetadata.h" |
9 #include "SkPDFTypes.h" | 9 #include "SkPDFTypes.h" |
| 10 #include <utility> |
10 | 11 |
11 #ifdef SK_PDF_GENERATE_PDFA | 12 #ifdef SK_PDF_GENERATE_PDFA |
12 #include "SkMD5.h" | 13 #include "SkMD5.h" |
13 #endif | 14 #endif |
14 | 15 |
15 static SkString pdf_date(const SkTime::DateTime& dt) { | 16 static SkString pdf_date(const SkTime::DateTime& dt) { |
16 int timeZoneMinutes = SkToInt(dt.fTimeZoneMinutes); | 17 int timeZoneMinutes = SkToInt(dt.fTimeZoneMinutes); |
17 char timezoneSign = timeZoneMinutes >= 0 ? '+' : '-'; | 18 char timezoneSign = timeZoneMinutes >= 0 ? '+' : '-'; |
18 int timeZoneHours = SkTAbs(timeZoneMinutes) / 60; | 19 int timeZoneHours = SkTAbs(timeZoneMinutes) / 60; |
19 timeZoneMinutes = SkTAbs(timeZoneMinutes) % 60; | 20 timeZoneMinutes = SkTAbs(timeZoneMinutes) % 60; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 length = _vscprintf(format, args); | 111 length = _vscprintf(format, args); |
111 va_end(args); | 112 va_end(args); |
112 | 113 |
113 SkString string((size_t)length); | 114 SkString string((size_t)length); |
114 va_start(args, format); | 115 va_start(args, format); |
115 SkDEBUGCODE(int check = ) _vsnprintf_s(string.writable_str(), length + 1, | 116 SkDEBUGCODE(int check = ) _vsnprintf_s(string.writable_str(), length + 1, |
116 _TRUNCATE, format, args); | 117 _TRUNCATE, format, args); |
117 va_end(args); | 118 va_end(args); |
118 SkASSERT(check == length); | 119 SkASSERT(check == length); |
119 SkASSERT(string[length] == '\0'); | 120 SkASSERT(string[length] == '\0'); |
120 return skstd::move(string); | 121 return std::move(string); |
121 #else // C99/C++11 standard vsnprintf | 122 #else // C99/C++11 standard vsnprintf |
122 // TODO: When all compilers support this, remove windows-specific code. | 123 // TODO: When all compilers support this, remove windows-specific code. |
123 va_list args; | 124 va_list args; |
124 va_start(args, format); | 125 va_start(args, format); |
125 char buffer[1024]; | 126 char buffer[1024]; |
126 int length = vsnprintf(buffer, sizeof(buffer), format, args); | 127 int length = vsnprintf(buffer, sizeof(buffer), format, args); |
127 va_end(args); | 128 va_end(args); |
128 if (length < 0) { | 129 if (length < 0) { |
129 return SkString(); | 130 return SkString(); |
130 } | 131 } |
131 if (length < (int)sizeof(buffer)) { | 132 if (length < (int)sizeof(buffer)) { |
132 return SkString(buffer, length); | 133 return SkString(buffer, length); |
133 } | 134 } |
134 SkString string((size_t)length); | 135 SkString string((size_t)length); |
135 va_start(args, format); | 136 va_start(args, format); |
136 SkDEBUGCODE(int check = ) | 137 SkDEBUGCODE(int check = ) |
137 vsnprintf(string.writable_str(), length + 1, format, args); | 138 vsnprintf(string.writable_str(), length + 1, format, args); |
138 va_end(args); | 139 va_end(args); |
139 SkASSERT(check == length); | 140 SkASSERT(check == length); |
140 SkASSERT(string[length] == '\0'); | 141 SkASSERT(string[length] == '\0'); |
141 return skstd::move(string); | 142 return std::move(string); |
142 #endif | 143 #endif |
143 } | 144 } |
144 | 145 |
145 static const SkString get(const SkTArray<SkDocument::Attribute>& info, | 146 static const SkString get(const SkTArray<SkDocument::Attribute>& info, |
146 const char* key) { | 147 const char* key) { |
147 for (const auto& keyValue : info) { | 148 for (const auto& keyValue : info) { |
148 if (keyValue.fKey.equals(key)) { | 149 if (keyValue.fKey.equals(key)) { |
149 return keyValue.fValue; | 150 return keyValue.fValue; |
150 } | 151 } |
151 } | 152 } |
(...skipping 26 matching lines...) Expand all Loading... |
178 HEXIFY(data, ptr, gHex, 6); | 179 HEXIFY(data, ptr, gHex, 6); |
179 SkASSERT(ptr == buffer + 36); | 180 SkASSERT(ptr == buffer + 36); |
180 SkASSERT(data == uuid.fData + 16); | 181 SkASSERT(data == uuid.fData + 16); |
181 return SkString(buffer, 36); | 182 return SkString(buffer, 36); |
182 } | 183 } |
183 #undef HEXIFY | 184 #undef HEXIFY |
184 | 185 |
185 namespace { | 186 namespace { |
186 class PDFXMLObject final : public SkPDFObject { | 187 class PDFXMLObject final : public SkPDFObject { |
187 public: | 188 public: |
188 PDFXMLObject(SkString xml) : fXML(skstd::move(xml)) {} | 189 PDFXMLObject(SkString xml) : fXML(std::move(xml)) {} |
189 void emitObject(SkWStream* stream, | 190 void emitObject(SkWStream* stream, |
190 const SkPDFObjNumMap& omap, | 191 const SkPDFObjNumMap& omap, |
191 const SkPDFSubstituteMap& smap) const override { | 192 const SkPDFSubstituteMap& smap) const override { |
192 SkPDFDict dict("Metadata"); | 193 SkPDFDict dict("Metadata"); |
193 dict.insertName("Subtype", "XML"); | 194 dict.insertName("Subtype", "XML"); |
194 dict.insertInt("Length", fXML.size()); | 195 dict.insertInt("Length", fXML.size()); |
195 dict.emitObject(stream, omap, smap); | 196 dict.emitObject(stream, omap, smap); |
196 static const char streamBegin[] = " stream\n"; | 197 static const char streamBegin[] = " stream\n"; |
197 stream->write(streamBegin, strlen(streamBegin)); | 198 stream->write(streamBegin, strlen(streamBegin)); |
198 // Do not compress this. The standard requires that a | 199 // Do not compress this. The standard requires that a |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 *out++ = input[i]; | 252 *out++ = input[i]; |
252 } | 253 } |
253 } | 254 } |
254 if (after) { | 255 if (after) { |
255 strncpy(out, after, afterLen); | 256 strncpy(out, after, afterLen); |
256 out += afterLen; | 257 out += afterLen; |
257 } | 258 } |
258 // Validate that we haven't written outside of our string. | 259 // Validate that we haven't written outside of our string. |
259 SkASSERT(out == &output.writable_str()[output.size()]); | 260 SkASSERT(out == &output.writable_str()[output.size()]); |
260 *out = '\0'; | 261 *out = '\0'; |
261 return skstd::move(output); | 262 return std::move(output); |
262 } | 263 } |
263 | 264 |
264 SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc, | 265 SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc, |
265 const UUID& instance) const { | 266 const UUID& instance) const { |
266 static const char templateString[] = | 267 static const char templateString[] = |
267 "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n" | 268 "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n" |
268 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"\n" | 269 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"\n" |
269 " x:xmptk=\"Adobe XMP Core 5.4-c005 78.147326, " | 270 " x:xmptk=\"Adobe XMP Core 5.4-c005 78.147326, " |
270 "2012/08/23-13:03:03\">\n" | 271 "2012/08/23-13:03:03\">\n" |
271 "<rdf:RDF " | 272 "<rdf:RDF " |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 SkString instanceID = uuid_to_string(instance); | 342 SkString instanceID = uuid_to_string(instance); |
342 SkASSERT(0 == count_xml_escape_size(instanceID)); | 343 SkASSERT(0 == count_xml_escape_size(instanceID)); |
343 return new PDFXMLObject(sk_string_printf( | 344 return new PDFXMLObject(sk_string_printf( |
344 templateString, modificationDate.c_str(), creationDate.c_str(), | 345 templateString, modificationDate.c_str(), creationDate.c_str(), |
345 metadataDate.c_str(), creator.c_str(), title.c_str(), | 346 metadataDate.c_str(), creator.c_str(), title.c_str(), |
346 subject.c_str(), author.c_str(), keywords1.c_str(), | 347 subject.c_str(), author.c_str(), keywords1.c_str(), |
347 documentID.c_str(), instanceID.c_str(), keywords2.c_str())); | 348 documentID.c_str(), instanceID.c_str(), keywords2.c_str())); |
348 } | 349 } |
349 | 350 |
350 #endif // SK_PDF_GENERATE_PDFA | 351 #endif // SK_PDF_GENERATE_PDFA |
OLD | NEW |