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