Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: src/pdf/SkPDFTypes.cpp

Issue 1049753002: SkPDF: Factor SkPDFCatalog into SkPDFObjNumMap and SkPDFSubstituteMap (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: full Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "SkPDFCatalog.h"
11 #include "SkPDFTypes.h" 10 #include "SkPDFTypes.h"
12 #include "SkStream.h" 11 #include "SkStream.h"
13 12
14 #ifdef SK_BUILD_FOR_WIN 13 #ifdef SK_BUILD_FOR_WIN
15 #define SNPRINTF _snprintf 14 #define SNPRINTF _snprintf
16 #else 15 #else
17 #define SNPRINTF snprintf 16 #define SNPRINTF snprintf
18 #endif 17 #endif
19 18
20 //////////////////////////////////////////////////////////////////////////////// 19 ////////////////////////////////////////////////////////////////////////////////
21 20
22 SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) { 21 SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) {
23 SkSafeRef(obj); 22 SkSafeRef(obj);
24 } 23 }
25 24
26 SkPDFObjRef::~SkPDFObjRef() {} 25 SkPDFObjRef::~SkPDFObjRef() {}
27 26
28 void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 27 void SkPDFObjRef::emitObject(SkWStream* stream,
29 SkPDFObject* obj = catalog->getSubstituteObject(fObj); 28 const SkPDFObjNumMap& objNumMap,
30 stream->writeDecAsText(catalog->getObjectNumber(obj)); 29 const SkPDFSubstituteMap& substitutes) {
30 SkPDFObject* obj = substitutes.getSubstitute(fObj);
31 stream->writeDecAsText(objNumMap.getObjectNumber(obj));
31 stream->writeText(" 0 R"); // Generation number is always 0. 32 stream->writeText(" 0 R"); // Generation number is always 0.
32 } 33 }
33 34
34 void SkPDFObjRef::addResources(SkPDFCatalog* catalog) const { 35 void SkPDFObjRef::addResources(SkPDFObjNumMap* catalog,
35 SkPDFObject* obj = catalog->getSubstituteObject(fObj); 36 const SkPDFSubstituteMap& substitutes) const {
37 SkPDFObject* obj = substitutes.getSubstitute(fObj);
36 SkASSERT(obj); 38 SkASSERT(obj);
37 if (catalog->addObject(obj)) { 39 if (catalog->addObject(obj)) {
38 obj->addResources(catalog); 40 obj->addResources(catalog, substitutes);
39 } 41 }
40 } 42 }
41 43
42 //////////////////////////////////////////////////////////////////////////////// 44 ////////////////////////////////////////////////////////////////////////////////
43 45
44 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {} 46 SkPDFInt::SkPDFInt(int32_t value) : fValue(value) {}
45 SkPDFInt::~SkPDFInt() {} 47 SkPDFInt::~SkPDFInt() {}
46 48
47 void SkPDFInt::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 49 void SkPDFInt::emitObject(SkWStream* stream,
50 const SkPDFObjNumMap&,
51 const SkPDFSubstituteMap&) {
48 stream->writeDecAsText(fValue); 52 stream->writeDecAsText(fValue);
49 } 53 }
50 54
51 //////////////////////////////////////////////////////////////////////////////// 55 ////////////////////////////////////////////////////////////////////////////////
52 56
53 SkPDFBool::SkPDFBool(bool value) : fValue(value) {} 57 SkPDFBool::SkPDFBool(bool value) : fValue(value) {}
54 SkPDFBool::~SkPDFBool() {} 58 SkPDFBool::~SkPDFBool() {}
55 59
56 void SkPDFBool::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 60 void SkPDFBool::emitObject(SkWStream* stream,
57 if (fValue) { 61 const SkPDFObjNumMap&,
58 stream->writeText("true"); 62 const SkPDFSubstituteMap&) {
59 } else { 63 stream->writeText(fValue ? "true" : "false");
60 stream->writeText("false");
61 }
62 } 64 }
63 65
64 //////////////////////////////////////////////////////////////////////////////// 66 ////////////////////////////////////////////////////////////////////////////////
65 67
66 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {} 68 SkPDFScalar::SkPDFScalar(SkScalar value) : fValue(value) {}
67 SkPDFScalar::~SkPDFScalar() {} 69 SkPDFScalar::~SkPDFScalar() {}
68 70
69 void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 71 void SkPDFScalar::emitObject(SkWStream* stream,
70 Append(fValue, stream); 72 const SkPDFObjNumMap&,
73 const SkPDFSubstituteMap&) {
74 SkPDFScalar::Append(fValue, stream);
71 } 75 }
72 76
73 // static 77 // static
74 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) { 78 void SkPDFScalar::Append(SkScalar value, SkWStream* stream) {
75 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and 79 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and
76 // +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31). 80 // +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31).
77 // When using floats that are outside the whole value range, we can use 81 // When using floats that are outside the whole value range, we can use
78 // integers instead. 82 // integers instead.
79 83
80 #if !defined(SK_ALLOW_LARGE_PDF_SCALARS) 84 #if !defined(SK_ALLOW_LARGE_PDF_SCALARS)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 SkPDFString::SkPDFString(const SkString& value) 132 SkPDFString::SkPDFString(const SkString& value)
129 : fValue(FormatString(value.c_str(), value.size())) { 133 : fValue(FormatString(value.c_str(), value.size())) {
130 } 134 }
131 135
132 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars) 136 SkPDFString::SkPDFString(const uint16_t* value, size_t len, bool wideChars)
133 : fValue(FormatString(value, len, wideChars)) { 137 : fValue(FormatString(value, len, wideChars)) {
134 } 138 }
135 139
136 SkPDFString::~SkPDFString() {} 140 SkPDFString::~SkPDFString() {}
137 141
138 void SkPDFString::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 142 void SkPDFString::emitObject(SkWStream* stream,
143 const SkPDFObjNumMap&,
144 const SkPDFSubstituteMap&) {
139 stream->write(fValue.c_str(), fValue.size()); 145 stream->write(fValue.c_str(), fValue.size());
140 } 146 }
141 147
142 // static 148 // static
143 SkString SkPDFString::FormatString(const char* input, size_t len) { 149 SkString SkPDFString::FormatString(const char* input, size_t len) {
144 return DoFormatString(input, len, false, false); 150 return DoFormatString(input, len, false, false);
145 } 151 }
146 152
147 SkString SkPDFString::FormatString(const uint16_t* input, size_t len, 153 SkString SkPDFString::FormatString(const uint16_t* input, size_t len,
148 bool wideChars) { 154 bool wideChars) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 //////////////////////////////////////////////////////////////////////////////// 213 ////////////////////////////////////////////////////////////////////////////////
208 214
209 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {} 215 SkPDFName::SkPDFName(const char name[]) : fValue(FormatName(SkString(name))) {}
210 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {} 216 SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {}
211 SkPDFName::~SkPDFName() {} 217 SkPDFName::~SkPDFName() {}
212 218
213 bool SkPDFName::operator==(const SkPDFName& b) const { 219 bool SkPDFName::operator==(const SkPDFName& b) const {
214 return fValue == b.fValue; 220 return fValue == b.fValue;
215 } 221 }
216 222
217 void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 223 void SkPDFName::emitObject(SkWStream* stream,
224 const SkPDFObjNumMap&,
225 const SkPDFSubstituteMap&) {
218 stream->write(fValue.c_str(), fValue.size()); 226 stream->write(fValue.c_str(), fValue.size());
219 } 227 }
220 228
221 // static 229 // static
222 SkString SkPDFName::FormatName(const SkString& input) { 230 SkString SkPDFName::FormatName(const SkString& input) {
223 SkASSERT(input.size() <= kMaxLen); 231 SkASSERT(input.size() <= kMaxLen);
224 // TODO(vandebo) If more escaping is needed, improve the linear scan. 232 // TODO(vandebo) If more escaping is needed, improve the linear scan.
225 static const char escaped[] = "#/%()<>[]{}"; 233 static const char escaped[] = "#/%()<>[]{}";
226 234
227 SkString result("/"); 235 SkString result("/");
(...skipping 10 matching lines...) Expand all
238 return result; 246 return result;
239 } 247 }
240 248
241 //////////////////////////////////////////////////////////////////////////////// 249 ////////////////////////////////////////////////////////////////////////////////
242 250
243 SkPDFArray::SkPDFArray() {} 251 SkPDFArray::SkPDFArray() {}
244 SkPDFArray::~SkPDFArray() { 252 SkPDFArray::~SkPDFArray() {
245 fValue.unrefAll(); 253 fValue.unrefAll();
246 } 254 }
247 255
248 void SkPDFArray::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 256 void SkPDFArray::emitObject(SkWStream* stream,
257 const SkPDFObjNumMap& objNumMap,
258 const SkPDFSubstituteMap& substitutes) {
249 stream->writeText("["); 259 stream->writeText("[");
250 for (int i = 0; i < fValue.count(); i++) { 260 for (int i = 0; i < fValue.count(); i++) {
251 catalog->getSubstituteObject(fValue[i])->emitObject(stream, catalog); 261 SkASSERT(substitutes.getSubstitute(fValue[i]) == fValue[i]);
262 fValue[i]->emitObject(stream, objNumMap, substitutes);
252 if (i + 1 < fValue.count()) { 263 if (i + 1 < fValue.count()) {
253 stream->writeText(" "); 264 stream->writeText(" ");
254 } 265 }
255 } 266 }
256 stream->writeText("]"); 267 stream->writeText("]");
257 } 268 }
258 269
259 void SkPDFArray::addResources(SkPDFCatalog* catalog) const { 270 void SkPDFArray::addResources(SkPDFObjNumMap* catalog,
271 const SkPDFSubstituteMap& substitutes) const {
260 for (int i = 0; i < fValue.count(); i++) { 272 for (int i = 0; i < fValue.count(); i++) {
261 catalog->getSubstituteObject(fValue[i])->addResources(catalog); 273 SkASSERT(substitutes.getSubstitute(fValue[i]) == fValue[i]);
274 fValue[i]->addResources(catalog, substitutes);
262 } 275 }
263 } 276 }
264 277
265 void SkPDFArray::reserve(int length) { 278 void SkPDFArray::reserve(int length) {
266 SkASSERT(length <= kMaxLen); 279 SkASSERT(length <= kMaxLen);
267 fValue.setReserve(length); 280 fValue.setReserve(length);
268 } 281 }
269 282
270 SkPDFObject* SkPDFArray::setAt(int offset, SkPDFObject* value) { 283 SkPDFObject* SkPDFArray::setAt(int offset, SkPDFObject* value) {
271 SkASSERT(offset < fValue.count()); 284 SkASSERT(offset < fValue.count());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 } 319 }
307 320
308 SkPDFDict::~SkPDFDict() { 321 SkPDFDict::~SkPDFDict() {
309 clear(); 322 clear();
310 } 323 }
311 324
312 int SkPDFDict::size() const { 325 int SkPDFDict::size() const {
313 return fValue.count(); 326 return fValue.count();
314 } 327 }
315 328
316 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { 329 void SkPDFDict::emitObject(SkWStream* stream,
330 const SkPDFObjNumMap& objNumMap,
331 const SkPDFSubstituteMap& substitutes) {
317 stream->writeText("<<"); 332 stream->writeText("<<");
318 for (int i = 0; i < fValue.count(); i++) { 333 for (int i = 0; i < fValue.count(); i++) {
319 SkASSERT(fValue[i].key); 334 SkASSERT(fValue[i].key);
320 SkASSERT(fValue[i].value); 335 SkASSERT(fValue[i].value);
321 fValue[i].key->emitObject(stream, catalog); 336 SkASSERT(substitutes.getSubstitute(fValue[i].key) == fValue[i].key);
337 SkASSERT(substitutes.getSubstitute(fValue[i].value) == fValue[i].value);
338 fValue[i].key->emitObject(stream, objNumMap, substitutes);
322 stream->writeText(" "); 339 stream->writeText(" ");
323 catalog->getSubstituteObject(fValue[i].value) 340 fValue[i].value->emitObject(stream, objNumMap, substitutes);
324 ->emitObject(stream, catalog); 341 if (i + 1 < fValue.count()) {
325 stream->writeText("\n"); 342 stream->writeText("\n");
343 }
326 } 344 }
327 stream->writeText(">>"); 345 stream->writeText(">>");
328 } 346 }
329 347
330 void SkPDFDict::addResources(SkPDFCatalog* catalog) const { 348 void SkPDFDict::addResources(SkPDFObjNumMap* catalog,
349 const SkPDFSubstituteMap& substitutes) const {
331 for (int i = 0; i < fValue.count(); i++) { 350 for (int i = 0; i < fValue.count(); i++) {
332 SkASSERT(fValue[i].key); 351 SkASSERT(fValue[i].key);
333 SkASSERT(fValue[i].value); 352 SkASSERT(fValue[i].value);
334 fValue[i].key->addResources(catalog); 353 fValue[i].key->addResources(catalog, substitutes);
335 catalog->getSubstituteObject(fValue[i].value)->addResources(catalog); 354 SkASSERT(substitutes.getSubstitute(fValue[i].value) == fValue[i].value);
355 fValue[i].value->addResources(catalog, substitutes);
336 } 356 }
337 } 357 }
338 358
339 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) { 359 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) {
340 SkASSERT(key); 360 SkASSERT(key);
341 SkASSERT(value); 361 SkASSERT(value);
342 *(fValue.append()) = Rec(key, value); 362 *(fValue.append()) = Rec(key, value);
343 return value; 363 return value;
344 } 364 }
345 365
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 407 }
388 } 408 }
389 } 409 }
390 410
391 void SkPDFDict::mergeFrom(const SkPDFDict& other) { 411 void SkPDFDict::mergeFrom(const SkPDFDict& other) {
392 for (int i = 0; i < other.fValue.count(); i++) { 412 for (int i = 0; i < other.fValue.count(); i++) {
393 *(fValue.append()) = 413 *(fValue.append()) =
394 Rec(SkRef(other.fValue[i].key), SkRef(other.fValue[i].value)); 414 Rec(SkRef(other.fValue[i].key), SkRef(other.fValue[i].value));
395 } 415 }
396 } 416 }
417
418 ////////////////////////////////////////////////////////////////////////////////
419
420 SkPDFSubstituteMap::~SkPDFSubstituteMap() {
421 fSubstituteMap.foreach(
422 [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); });
423 }
424
425 void SkPDFSubstituteMap::setSubstitute(SkPDFObject* original,
426 SkPDFObject* substitute) {
427 SkASSERT(original != substitute);
428 SkASSERT(!fSubstituteMap.find(original));
429 fSubstituteMap.set(original, SkRef(substitute));
430 }
431
432 SkPDFObject* SkPDFSubstituteMap::getSubstitute(SkPDFObject* object) const {
433 SkPDFObject** found = fSubstituteMap.find(object);
434 return found ? *found : object;
435 }
436
437 ////////////////////////////////////////////////////////////////////////////////
438
439 bool SkPDFObjNumMap::addObject(SkPDFObject* obj) {
440 if (fObjectNumbers.find(obj)) {
441 return false;
442 }
443 fObjectNumbers.set(obj, fObjectNumbers.count() + 1);
444 fObjects.push(obj);
445 return true;
446 }
447
448 int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const {
449 int32_t* objectNumberFound = fObjectNumbers.find(obj);
450 SkASSERT(objectNumberFound);
451 return *objectNumberFound;
452 }
453
OLDNEW
« src/pdf/SkPDFStream.cpp ('K') | « src/pdf/SkPDFTypes.h ('k') | tests/PDFPrimitivesTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698