| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "SkPDFTypes.h" | 9 #include "SkPDFTypes.h" |
| 10 #include "SkPDFUtils.h" | 10 #include "SkPDFUtils.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 while (*n) { | 92 while (*n) { |
| 93 if (*n < '!' || *n > '~' || strchr(kControlChars, *n)) { | 93 if (*n < '!' || *n > '~' || strchr(kControlChars, *n)) { |
| 94 return false; | 94 return false; |
| 95 } | 95 } |
| 96 ++n; | 96 ++n; |
| 97 } | 97 } |
| 98 return true; | 98 return true; |
| 99 } | 99 } |
| 100 #endif // SK_DEBUG | 100 #endif // SK_DEBUG |
| 101 | 101 |
| 102 // Given an arbitrary string, convert it to a valid name. | 102 // Given an arbitrary string, write it as a valid name (not including |
| 103 static SkString escape_name(const char* name, size_t len) { | 103 // leading slash). |
| 104 static void write_name_escaped(SkWStream* o, const char* name) { |
| 104 static const char kToEscape[] = "#/%()<>[]{}"; | 105 static const char kToEscape[] = "#/%()<>[]{}"; |
| 105 int count = 0; | 106 static const char kHex[] = "0123456789ABCDEF"; |
| 106 const char* const end = &name[len]; | 107 for (const uint8_t* n = reinterpret_cast<const uint8_t*>(name); *n; ++n) { |
| 107 for (const char* n = name; n != end; ++n) { | |
| 108 if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) { | 108 if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) { |
| 109 count += 2; | 109 char buffer[3] = {'#', '\0', '\0'}; |
| 110 } | 110 buffer[1] = kHex[(*n >> 4) & 0xF]; |
| 111 ++count; | 111 buffer[2] = kHex[*n & 0xF]; |
| 112 } | 112 o->write(buffer, sizeof(buffer)); |
| 113 SkString result(count); | |
| 114 char* s = result.writable_str(); | |
| 115 static const char kHex[] = "0123456789ABCDEF"; | |
| 116 for (const char* n = name; n != end; ++n) { | |
| 117 if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) { | |
| 118 *s++ = '#'; | |
| 119 *s++ = kHex[(*n >> 4) & 0xF]; | |
| 120 *s++ = kHex[*n & 0xF]; | |
| 121 } else { | 113 } else { |
| 122 *s++ = *n; | 114 o->write(n, 1); |
| 123 } | 115 } |
| 124 } | 116 } |
| 125 SkASSERT(&result.writable_str()[count] == s); // don't over-write | |
| 126 return result; // allocated space | |
| 127 } | |
| 128 | |
| 129 static SkString escape_name(const SkString& name) { | |
| 130 return escape_name(name.c_str(), name.size()); | |
| 131 } | 117 } |
| 132 | 118 |
| 133 static void write_string(SkWStream* o, const SkString& s) { | 119 static void write_string(SkWStream* o, const SkString& s) { |
| 134 o->write(s.c_str(), s.size()); | 120 o->write(s.c_str(), s.size()); |
| 135 } | 121 } |
| 136 | 122 |
| 137 static SkString format_string(const SkString& s) { | 123 static SkString format_string(const SkString& s) { |
| 138 return SkPDFUtils::FormatString(s.c_str(), s.size()); | 124 return SkPDFUtils::FormatString(s.c_str(), s.size()); |
| 139 } | 125 } |
| 140 | 126 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 159 stream->writeText("/"); | 145 stream->writeText("/"); |
| 160 SkASSERT(is_valid_name(fStaticString)); | 146 SkASSERT(is_valid_name(fStaticString)); |
| 161 stream->writeText(fStaticString); | 147 stream->writeText(fStaticString); |
| 162 return; | 148 return; |
| 163 case Type::kString: | 149 case Type::kString: |
| 164 SkASSERT(fStaticString); | 150 SkASSERT(fStaticString); |
| 165 write_string(stream, format_string(fStaticString)); | 151 write_string(stream, format_string(fStaticString)); |
| 166 return; | 152 return; |
| 167 case Type::kNameSkS: | 153 case Type::kNameSkS: |
| 168 stream->writeText("/"); | 154 stream->writeText("/"); |
| 169 write_string(stream, escape_name(*pun(fSkString))); | 155 write_name_escaped(stream, pun(fSkString)->c_str()); |
| 170 return; | 156 return; |
| 171 case Type::kStringSkS: | 157 case Type::kStringSkS: |
| 172 write_string(stream, format_string(*pun(fSkString))); | 158 write_string(stream, format_string(*pun(fSkString))); |
| 173 return; | 159 return; |
| 174 case Type::kObjRef: | 160 case Type::kObjRef: |
| 175 stream->writeDecAsText(objNumMap.getObjectNumber( | 161 stream->writeDecAsText(objNumMap.getObjectNumber( |
| 176 substitutes.getSubstitute(fObject))); | 162 substitutes.getSubstitute(fObject))); |
| 177 stream->writeText(" 0 R"); // Generation number is always 0. | 163 stream->writeText(" 0 R"); // Generation number is always 0. |
| 178 return; | 164 return; |
| 179 case Type::kObject: | 165 case Type::kObject: |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 fObjects.push(obj); | 466 fObjects.push(obj); |
| 481 return true; | 467 return true; |
| 482 } | 468 } |
| 483 | 469 |
| 484 int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const { | 470 int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const { |
| 485 int32_t* objectNumberFound = fObjectNumbers.find(obj); | 471 int32_t* objectNumberFound = fObjectNumbers.find(obj); |
| 486 SkASSERT(objectNumberFound); | 472 SkASSERT(objectNumberFound); |
| 487 return *objectNumberFound; | 473 return *objectNumberFound; |
| 488 } | 474 } |
| 489 | 475 |
| OLD | NEW |