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 | 9 |
10 #include "SkPDFTypes.h" | 10 #include "SkPDFTypes.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 //////////////////////////////////////////////////////////////////////////////// | 126 //////////////////////////////////////////////////////////////////////////////// |
127 | 127 |
128 SkPDFString::SkPDFString(const char value[]) | 128 SkPDFString::SkPDFString(const char value[]) |
129 : fValue(FormatString(value, strlen(value))) { | 129 : fValue(FormatString(value, strlen(value))) { |
130 } | 130 } |
131 | 131 |
132 SkPDFString::SkPDFString(const SkString& value) | 132 SkPDFString::SkPDFString(const SkString& value) |
133 : fValue(FormatString(value.c_str(), value.size())) { | 133 : fValue(FormatString(value.c_str(), value.size())) { |
134 } | 134 } |
135 | 135 |
136 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) | |
137 : fValue(FormatString(value, len, wideChars)) { | |
138 } | |
139 | |
140 SkPDFString::~SkPDFString() {} | 136 SkPDFString::~SkPDFString() {} |
141 | 137 |
142 void SkPDFString::emitObject(SkWStream* stream, | 138 void SkPDFString::emitObject(SkWStream* stream, |
143 const SkPDFObjNumMap&, | 139 const SkPDFObjNumMap&, |
144 const SkPDFSubstituteMap&) { | 140 const SkPDFSubstituteMap&) { |
145 stream->write(fValue.c_str(), fValue.size()); | 141 stream->write(fValue.c_str(), fValue.size()); |
146 } | 142 } |
147 | 143 |
148 // static | 144 // static |
149 SkString SkPDFString::FormatString(const char* input, size_t len) { | 145 SkString SkPDFString::FormatString(const char* cin, size_t len) { |
150 return DoFormatString(input, len, false, false); | |
151 } | |
152 | |
153 SkString SkPDFString::FormatString(const uint16_t* input, size_t len, | |
154 bool wideChars) { | |
155 return DoFormatString(input, len, true, wideChars); | |
156 } | |
157 | |
158 // static | |
159 SkString SkPDFString::DoFormatString(const void* input, size_t len, | |
160 bool wideInput, bool wideOutput) { | |
161 SkASSERT(len <= kMaxLen); | 146 SkASSERT(len <= kMaxLen); |
162 const uint16_t* win = (const uint16_t*) input; | |
163 const char* cin = (const char*) input; | |
164 | |
165 if (wideOutput) { | |
166 SkASSERT(wideInput); | |
167 SkString result; | |
168 result.append("<"); | |
169 for (size_t i = 0; i < len; i++) { | |
170 result.appendHex(win[i], 4); | |
171 } | |
172 result.append(">"); | |
173 return result; | |
174 } | |
175 | 147 |
176 // 7-bit clean is a heuristic to decide what string format to use; | 148 // 7-bit clean is a heuristic to decide what string format to use; |
177 // a 7-bit clean string should require little escaping. | 149 // a 7-bit clean string should require little escaping. |
178 bool sevenBitClean = true; | 150 bool sevenBitClean = true; |
| 151 size_t characterCount = 2 + len; |
179 for (size_t i = 0; i < len; i++) { | 152 for (size_t i = 0; i < len; i++) { |
180 SkASSERT(!wideInput || !(win[i] & ~0xFF)); | 153 if (cin[i] > '~' || cin[i] < ' ') { |
181 char val = wideInput ? win[i] : cin[i]; | |
182 if (val > '~' || val < ' ') { | |
183 sevenBitClean = false; | 154 sevenBitClean = false; |
184 break; | 155 break; |
185 } | 156 } |
| 157 if (cin[i] == '\\' || cin[i] == '(' || cin[i] == ')') { |
| 158 ++characterCount; |
| 159 } |
186 } | 160 } |
187 | |
188 SkString result; | 161 SkString result; |
189 if (sevenBitClean) { | 162 if (sevenBitClean) { |
190 result.append("("); | 163 result.resize(characterCount); |
| 164 char* str = result.writable_str(); |
| 165 *str++ = '('; |
191 for (size_t i = 0; i < len; i++) { | 166 for (size_t i = 0; i < len; i++) { |
192 SkASSERT(!wideInput || !(win[i] & ~0xFF)); | 167 if (cin[i] == '\\' || cin[i] == '(' || cin[i] == ')') { |
193 char val = wideInput ? win[i] : cin[i]; | 168 *str++ = '\\'; |
194 if (val == '\\' || val == '(' || val == ')') { | |
195 result.append("\\"); | |
196 } | 169 } |
197 result.append(&val, 1); | 170 *str++ = cin[i]; |
198 } | 171 } |
199 result.append(")"); | 172 *str++ = ')'; |
200 } else { | 173 } else { |
201 result.append("<"); | 174 result.resize(2 * len + 2); |
| 175 char* str = result.writable_str(); |
| 176 *str++ = '<'; |
202 for (size_t i = 0; i < len; i++) { | 177 for (size_t i = 0; i < len; i++) { |
203 SkASSERT(!wideInput || !(win[i] & ~0xFF)); | 178 uint8_t c = static_cast<uint8_t>(cin[i]); |
204 unsigned char val = wideInput ? win[i] : cin[i]; | 179 static const char gHex[] = "0123456789ABCDEF"; |
205 result.appendHex(val, 2); | 180 *str++ = gHex[(c >> 4) & 0xF]; |
| 181 *str++ = gHex[(c ) & 0xF]; |
206 } | 182 } |
207 result.append(">"); | 183 *str++ = '>'; |
208 } | 184 } |
209 | |
210 return result; | 185 return result; |
211 } | 186 } |
212 | 187 |
213 //////////////////////////////////////////////////////////////////////////////// | 188 //////////////////////////////////////////////////////////////////////////////// |
214 | 189 |
215 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} | 190 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} |
216 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} | 191 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} |
217 SkPDFName::~SkPDFName() {} | 192 SkPDFName::~SkPDFName() {} |
218 | 193 |
219 bool SkPDFName::operator==(const SkPDFName& b) const { | 194 bool SkPDFName::operator==(const SkPDFName& b) const { |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 fObjects.push(obj); | 419 fObjects.push(obj); |
445 return true; | 420 return true; |
446 } | 421 } |
447 | 422 |
448 int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const { | 423 int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const { |
449 int32_t* objectNumberFound = fObjectNumbers.find(obj); | 424 int32_t* objectNumberFound = fObjectNumbers.find(obj); |
450 SkASSERT(objectNumberFound); | 425 SkASSERT(objectNumberFound); |
451 return *objectNumberFound; | 426 return *objectNumberFound; |
452 } | 427 } |
453 | 428 |
OLD | NEW |