1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
28459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
48459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
78459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org */
88459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
98459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org#include "SkPDFTypes.h"
10bc4696b9176e05940a7c2d6778276cdbc55ccd61halcanary#include "SkPDFUtils.h"
118459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org#include "SkStream.h"
128459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
13094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org#ifdef SK_BUILD_FOR_WIN
14094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org    #define SNPRINTF    _snprintf
15094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org#else
16094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org    #define SNPRINTF    snprintf
17094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org#endif
18094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org
196a144345d742a53ffb15bbd83f2718022fca8df5halcanary////////////////////////////////////////////////////////////////////////////////
206a144345d742a53ffb15bbd83f2718022fca8df5halcanary
21130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkString* pun(char* x) { return reinterpret_cast<SkString*>(x); }
22130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryconst SkString* pun(const char* x) {
23130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return reinterpret_cast<const SkString*>(x);
24d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org}
25d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org
26130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion::SkPDFUnion(Type t) : fType(t) {}
27421d6443fbd3a913dfa32b6492c4a2969bc6314bvandebo@chromium.org
28130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion::~SkPDFUnion() {
29130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    switch (fType) {
30130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kNameSkS:
31130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kStringSkS:
32130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            pun(fSkString)->~SkString();
33130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
34130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObjRef:
35130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObject:
36130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkSafeUnref(fObject);
37130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
38130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        default:
39130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
40130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    }
41bf799cd228282431e6311900dd383083f8af7164halcanary}
42bf799cd228282431e6311900dd383083f8af7164halcanary
43130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion& SkPDFUnion::operator=(SkPDFUnion&& other) {
44130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    if (this != &other) {
45130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        this->~SkPDFUnion();
46130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        SkNEW_PLACEMENT_ARGS(this, SkPDFUnion, (other.move()));
47130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    }
48130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return *this;
49130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
50130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
51130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion::SkPDFUnion(SkPDFUnion&& other) {
52130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(this != &other);
53130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    memcpy(this, &other, sizeof(*this));
54130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    other.fType = Type::kDestroyed;
55130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
56130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
57130444fdaf737c5931a934018ab50b0c91a3499ehalcanary#if 0
58130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::copy() const {
59130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(fType);
60130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    memcpy(&u, this, sizeof(u));
61130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    switch (fType) {
62130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kNameSkS:
63130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kStringSkS:
64130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString,
65130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                                 (*pun(fSkString)));
66130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return u.move();
67130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObjRef:
68130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObject:
69130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkRef(u.fObject);
70130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return u.move();
71130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        default:
72130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return u.move();
73bf799cd228282431e6311900dd383083f8af7164halcanary    }
748459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
75130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion& SkPDFUnion::operator=(const SkPDFUnion& other) {
76130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return *this = other.copy();
77130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
78130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion::SkPDFUnion(const SkPDFUnion& other) {
79130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    *this = other.copy();
80130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
81130444fdaf737c5931a934018ab50b0c91a3499ehalcanary#endif
828459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
83130444fdaf737c5931a934018ab50b0c91a3499ehalcanarybool SkPDFUnion::isName() const {
84130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return Type::kName == fType || Type::kNameSkS == fType;
85130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
866a144345d742a53ffb15bbd83f2718022fca8df5halcanary
87130444fdaf737c5931a934018ab50b0c91a3499ehalcanary#ifdef SK_DEBUG
88130444fdaf737c5931a934018ab50b0c91a3499ehalcanary// Most names need no escaping.  Such names are handled as static
89130444fdaf737c5931a934018ab50b0c91a3499ehalcanary// const strings.
90130444fdaf737c5931a934018ab50b0c91a3499ehalcanarybool is_valid_name(const char* n) {
91130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    static const char kControlChars[] = "/%()<>[]{}";
92130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    while (*n) {
93130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        if (*n < '!' || *n > '~' || strchr(kControlChars, *n)) {
94130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return false;
95130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        }
96130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        ++n;
97130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    }
98130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return true;
99130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
100130444fdaf737c5931a934018ab50b0c91a3499ehalcanary#endif  // SK_DEBUG
101130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
102130444fdaf737c5931a934018ab50b0c91a3499ehalcanary// Given an arbitrary string, convert it to a valid name.
103130444fdaf737c5931a934018ab50b0c91a3499ehalcanarystatic SkString escape_name(const char* name, size_t len) {
104130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    static const char kToEscape[] = "#/%()<>[]{}";
105130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    int count = 0;
106130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    const char* const end = &name[len];
107130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (const char* n = name; n != end; ++n) {
108130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) {
109130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            count += 2;
110130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        }
111130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        ++count;
112130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    }
113130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkString result(count);
114130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    char* s = result.writable_str();
115130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    static const char kHex[] = "0123456789ABCDEF";
116130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (const char* n = name; n != end; ++n) {
117130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) {
118130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            *s++ = '#';
119130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            *s++ = kHex[(*n >> 4) & 0xF];
120130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            *s++ = kHex[*n & 0xF];
121130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        } else {
122130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            *s++ = *n;
123130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        }
124130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    }
125130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(&result.writable_str()[count] == s);  // don't over-write
126130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return result;                                 // allocated space
127130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
128f66025d59ab4c8c4439fabf6ad89ddf35a19d1fdvandebo@chromium.org
129130444fdaf737c5931a934018ab50b0c91a3499ehalcanarystatic SkString escape_name(const SkString& name) {
130130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return escape_name(name.c_str(), name.size());
1318459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
1328459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
133130444fdaf737c5931a934018ab50b0c91a3499ehalcanarystatic void write_string(SkWStream* o, const SkString& s) {
134130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    o->write(s.c_str(), s.size());
135130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
1366a144345d742a53ffb15bbd83f2718022fca8df5halcanary
137130444fdaf737c5931a934018ab50b0c91a3499ehalcanarystatic SkString format_string(const SkString& s) {
138bc4696b9176e05940a7c2d6778276cdbc55ccd61halcanary    return SkPDFUtils::FormatString(s.c_str(), s.size());
139130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
1409b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
141130444fdaf737c5931a934018ab50b0c91a3499ehalcanarystatic SkString format_string(const char* s) {
142bc4696b9176e05940a7c2d6778276cdbc55ccd61halcanary    return SkPDFUtils::FormatString(s, strlen(s));
1439b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org}
1449b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
145130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFUnion::emitObject(SkWStream* stream,
146130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                            const SkPDFObjNumMap& objNumMap,
147130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                            const SkPDFSubstituteMap& substitutes) const {
148130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    switch (fType) {
149130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kInt:
150130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            stream->writeDecAsText(fIntValue);
151130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
152130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kBool:
153130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            stream->writeText(fBoolValue ? "true" : "false");
154130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
155130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kScalar:
156bc4696b9176e05940a7c2d6778276cdbc55ccd61halcanary            SkPDFUtils::AppendScalar(fScalarValue, stream);
157130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
158130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kName:
159130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            stream->writeText("/");
160130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkASSERT(is_valid_name(fStaticString));
161130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            stream->writeText(fStaticString);
162130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
163130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kString:
164130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkASSERT(fStaticString);
165130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            write_string(stream, format_string(fStaticString));
166130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
167130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kNameSkS:
168130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            stream->writeText("/");
169130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            write_string(stream, escape_name(*pun(fSkString)));
170130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
171130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kStringSkS:
172130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            write_string(stream, format_string(*pun(fSkString)));
173130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
174130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObjRef:
175130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            stream->writeDecAsText(objNumMap.getObjectNumber(
176130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                    substitutes.getSubstitute(fObject)));
177130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            stream->writeText(" 0 R");  // Generation number is always 0.
178130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
179130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObject:
180130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            fObject->emitObject(stream, objNumMap, substitutes);
181130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
182130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        default:
183130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkDEBUGFAIL("SkPDFUnion::emitObject with bad type");
184130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    }
185130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
186130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
187130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFUnion::addResources(SkPDFObjNumMap* objNumMap,
188130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                              const SkPDFSubstituteMap& substituteMap) const {
189130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    switch (fType) {
190130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kInt:
191130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kBool:
192130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kScalar:
193130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kName:
194130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kString:
195130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kNameSkS:
196130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kStringSkS:
197130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;  // These have no resources.
198130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObjRef: {
199130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkPDFObject* obj = substituteMap.getSubstitute(fObject);
200130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            if (objNumMap->addObject(obj)) {
201130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                obj->addResources(objNumMap, substituteMap);
202130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            }
203130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
204130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        }
205130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        case Type::kObject:
206130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            fObject->addResources(objNumMap, substituteMap);
207130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            return;
208130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        default:
209130444fdaf737c5931a934018ab50b0c91a3499ehalcanary            SkDEBUGFAIL("SkPDFUnion::addResources with bad type");
210130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    }
211130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
212130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
213130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::Int(int32_t value) {
214130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kInt);
215130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    u.fIntValue = value;
216130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
217130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
218130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
219130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::Bool(bool value) {
220130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kBool);
221130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    u.fBoolValue = value;
222130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
223130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
224130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
225130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::Scalar(SkScalar value) {
226130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kScalar);
227130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    u.fScalarValue = value;
228130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
229130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
230130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
231130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::Name(const char* value) {
232130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kName);
233130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(value);
234130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(is_valid_name(value));
235130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    u.fStaticString = value;
236130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
237130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
238130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
239130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::String(const char* value) {
240130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kString);
241130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(value);
242130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    u.fStaticString = value;
243130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
244130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
245130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
246130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::Name(const SkString& s) {
247130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kNameSkS);
248130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString, (s));
249130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
250130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
251130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
252130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::String(const SkString& s) {
253130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kStringSkS);
254130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString, (s));
255130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
256130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
257130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
258130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::ObjRef(SkPDFObject* ptr) {
259130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kObjRef);
260130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(ptr);
261130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    u.fObject = ptr;
262130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
263130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
264130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
265130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFUnion SkPDFUnion::Object(SkPDFObject* ptr) {
266130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkPDFUnion u(Type::kObject);
267130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(ptr);
268130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    u.fObject = ptr;
269130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    return u.move();
270130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
2716a144345d742a53ffb15bbd83f2718022fca8df5halcanary
272130444fdaf737c5931a934018ab50b0c91a3499ehalcanary////////////////////////////////////////////////////////////////////////////////
273f66025d59ab4c8c4439fabf6ad89ddf35a19d1fdvandebo@chromium.org
274002653e78c1eef4430abe457f6f91add24a69093halcanary#if 0  // Enable if needed.
275130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFAtom::emitObject(SkWStream* stream,
276130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                           const SkPDFObjNumMap& objNumMap,
277130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                           const SkPDFSubstituteMap& substitutes) {
278130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    fValue.emitObject(stream, objNumMap, substitutes);
279130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
280130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFAtom::addResources(SkPDFObjNumMap* map,
281130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                             const SkPDFSubstituteMap& substitutes) const {
282130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    fValue.addResources(map, substitutes);
283094316bd284372c2a3d8ef02eec589901e503c59vandebo@chromium.org}
284002653e78c1eef4430abe457f6f91add24a69093halcanary#endif  // 0
2858459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
2866a144345d742a53ffb15bbd83f2718022fca8df5halcanary////////////////////////////////////////////////////////////////////////////////
2876a144345d742a53ffb15bbd83f2718022fca8df5halcanary
288130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFArray::SkPDFArray() {}
289130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFArray::~SkPDFArray() {
290130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (SkPDFUnion& value : fValues) {
291130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        value.~SkPDFUnion();
2928459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org    }
293130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    fValues.reset();
2948459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
2958459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
296130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryint SkPDFArray::size() const { return fValues.count(); }
2976a144345d742a53ffb15bbd83f2718022fca8df5halcanary
298130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::reserve(int length) { fValues.setReserve(length); }
2998459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
30037c46cad21632cfc1411b08d73af37a1fffe2944halcanaryvoid SkPDFArray::emitObject(SkWStream* stream,
30137c46cad21632cfc1411b08d73af37a1fffe2944halcanary                             const SkPDFObjNumMap& objNumMap,
30237c46cad21632cfc1411b08d73af37a1fffe2944halcanary                             const SkPDFSubstituteMap& substitutes) {
3038459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org    stream->writeText("[");
304130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (int i = 0; i < fValues.count(); i++) {
305130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        fValues[i].emitObject(stream, objNumMap, substitutes);
306130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        if (i + 1 < fValues.count()) {
3078459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org            stream->writeText(" ");
308769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        }
3098459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org    }
3108459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org    stream->writeText("]");
3118459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
3128459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
31337c46cad21632cfc1411b08d73af37a1fffe2944halcanaryvoid SkPDFArray::addResources(SkPDFObjNumMap* catalog,
31437c46cad21632cfc1411b08d73af37a1fffe2944halcanary                              const SkPDFSubstituteMap& substitutes) const {
315130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (const SkPDFUnion& value : fValues) {
316130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        value.addResources(catalog, substitutes);
317bf799cd228282431e6311900dd383083f8af7164halcanary    }
318bf799cd228282431e6311900dd383083f8af7164halcanary}
319bf799cd228282431e6311900dd383083f8af7164halcanary
320130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::append(SkPDFUnion&& value) {
321130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkNEW_PLACEMENT_ARGS(fValues.append(), SkPDFUnion, (value.move()));
3228459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
3238459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
324c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.comvoid SkPDFArray::appendInt(int32_t value) {
325130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::Int(value));
326130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
327130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
328130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::appendBool(bool value) {
329130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::Bool(value));
330c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com}
331c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com
332c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.comvoid SkPDFArray::appendScalar(SkScalar value) {
333130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::Scalar(value));
334c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com}
335c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com
336c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.comvoid SkPDFArray::appendName(const char name[]) {
337130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::Name(SkString(name)));
338c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com}
339c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com
340130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::appendName(const SkString& name) {
341130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::Name(name));
342130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
343c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com
344130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::appendString(const SkString& value) {
345130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::String(value));
346130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
347d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org
348130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::appendString(const char value[]) {
349130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::String(value));
350d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org}
351d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org
352130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::appendObject(SkPDFObject* value) {
353130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::Object(value));
3548459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
3558459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
356130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFArray::appendObjRef(SkPDFObject* value) {
357130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->append(SkPDFUnion::ObjRef(value));
3581f8ed022226c9f960b9fc95af9297d5111a07eadhalcanary}
3591f8ed022226c9f960b9fc95af9297d5111a07eadhalcanary
360130444fdaf737c5931a934018ab50b0c91a3499ehalcanary///////////////////////////////////////////////////////////////////////////////
361130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
362130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFDict::SkPDFDict() {}
363130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
364130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFDict::~SkPDFDict() { this->clear(); }
365130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
366130444fdaf737c5931a934018ab50b0c91a3499ehalcanarySkPDFDict::SkPDFDict(const char type[]) { this->insertName("Type", type); }
367130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
36837c46cad21632cfc1411b08d73af37a1fffe2944halcanaryvoid SkPDFDict::emitObject(SkWStream* stream,
36937c46cad21632cfc1411b08d73af37a1fffe2944halcanary                           const SkPDFObjNumMap& objNumMap,
37037c46cad21632cfc1411b08d73af37a1fffe2944halcanary                           const SkPDFSubstituteMap& substitutes) {
3718459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org    stream->writeText("<<");
372130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (int i = 0; i < fRecords.count(); i++) {
373130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        fRecords[i].fKey.emitObject(stream, objNumMap, substitutes);
3748459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org        stream->writeText(" ");
375130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        fRecords[i].fValue.emitObject(stream, objNumMap, substitutes);
376130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        if (i + 1 < fRecords.count()) {
37737c46cad21632cfc1411b08d73af37a1fffe2944halcanary            stream->writeText("\n");
37837c46cad21632cfc1411b08d73af37a1fffe2944halcanary        }
3798459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org    }
3808459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org    stream->writeText(">>");
3818459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
3828459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org
38337c46cad21632cfc1411b08d73af37a1fffe2944halcanaryvoid SkPDFDict::addResources(SkPDFObjNumMap* catalog,
38437c46cad21632cfc1411b08d73af37a1fffe2944halcanary                             const SkPDFSubstituteMap& substitutes) const {
385130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (int i = 0; i < fRecords.count(); i++) {
386130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        fRecords[i].fKey.addResources(catalog, substitutes);
387130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        fRecords[i].fValue.addResources(catalog, substitutes);
388bf799cd228282431e6311900dd383083f8af7164halcanary    }
389bf799cd228282431e6311900dd383083f8af7164halcanary}
390bf799cd228282431e6311900dd383083f8af7164halcanary
391130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::set(SkPDFUnion&& name, SkPDFUnion&& value) {
392130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    Record* rec = fRecords.append();
393130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkASSERT(name.isName());
394130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkNEW_PLACEMENT_ARGS(&rec->fKey, SkPDFUnion, (name.move()));
395130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    SkNEW_PLACEMENT_ARGS(&rec->fValue, SkPDFUnion, (value.move()));
3968459d4e5e32608ec6da3f2b81731aaeb7b038843vandebo@chromium.org}
397d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org
398130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryint SkPDFDict::size() const { return fRecords.count(); }
399130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
400130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertObjRef(const char key[], SkPDFObject* value) {
401130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(value));
402130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
403130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertObjRef(const SkString& key, SkPDFObject* value) {
404130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(value));
4051f8ed022226c9f960b9fc95af9297d5111a07eadhalcanary}
4061f8ed022226c9f960b9fc95af9297d5111a07eadhalcanary
407130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertObject(const char key[], SkPDFObject* value) {
408130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(value));
409130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
410130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertObject(const SkString& key, SkPDFObject* value) {
411130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(value));
412130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
413130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
414a25b3371a7209105e6c05f7bbb53d19e2b14498bhalcanaryvoid SkPDFDict::insertBool(const char key[], bool value) {
415a25b3371a7209105e6c05f7bbb53d19e2b14498bhalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::Bool(value));
416a25b3371a7209105e6c05f7bbb53d19e2b14498bhalcanary}
417a25b3371a7209105e6c05f7bbb53d19e2b14498bhalcanary
418c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.comvoid SkPDFDict::insertInt(const char key[], int32_t value) {
419130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::Int(value));
420130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
421130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
422130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertInt(const char key[], size_t value) {
423130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->insertInt(key, SkToS32(value));
424c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com}
425c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com
426c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.comvoid SkPDFDict::insertScalar(const char key[], SkScalar value) {
427130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::Scalar(value));
428c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com}
429c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com
430c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.comvoid SkPDFDict::insertName(const char key[], const char name[]) {
431130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name));
432c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com}
433c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com
434130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertName(const char key[], const SkString& name) {
435130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name));
436130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
437130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
438130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertString(const char key[], const char value[]) {
439130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value));
440421d6443fbd3a913dfa32b6492c4a2969bc6314bvandebo@chromium.org}
441421d6443fbd3a913dfa32b6492c4a2969bc6314bvandebo@chromium.org
442130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::insertString(const char key[], const SkString& value) {
443130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value));
444130444fdaf737c5931a934018ab50b0c91a3499ehalcanary}
445130444fdaf737c5931a934018ab50b0c91a3499ehalcanary
446130444fdaf737c5931a934018ab50b0c91a3499ehalcanaryvoid SkPDFDict::clear() {
447130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    for (Record& rec : fRecords) {
448130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        rec.fKey.~SkPDFUnion();
449130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        rec.fValue.~SkPDFUnion();
450421d6443fbd3a913dfa32b6492c4a2969bc6314bvandebo@chromium.org    }
451130444fdaf737c5931a934018ab50b0c91a3499ehalcanary    fRecords.reset();
452421d6443fbd3a913dfa32b6492c4a2969bc6314bvandebo@chromium.org}
45337c46cad21632cfc1411b08d73af37a1fffe2944halcanary
45437c46cad21632cfc1411b08d73af37a1fffe2944halcanary////////////////////////////////////////////////////////////////////////////////
45537c46cad21632cfc1411b08d73af37a1fffe2944halcanary
45637c46cad21632cfc1411b08d73af37a1fffe2944halcanarySkPDFSubstituteMap::~SkPDFSubstituteMap() {
45737c46cad21632cfc1411b08d73af37a1fffe2944halcanary    fSubstituteMap.foreach(
45837c46cad21632cfc1411b08d73af37a1fffe2944halcanary            [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); });
45937c46cad21632cfc1411b08d73af37a1fffe2944halcanary}
46037c46cad21632cfc1411b08d73af37a1fffe2944halcanary
46137c46cad21632cfc1411b08d73af37a1fffe2944halcanaryvoid SkPDFSubstituteMap::setSubstitute(SkPDFObject* original,
46237c46cad21632cfc1411b08d73af37a1fffe2944halcanary                                       SkPDFObject* substitute) {
46337c46cad21632cfc1411b08d73af37a1fffe2944halcanary    SkASSERT(original != substitute);
46437c46cad21632cfc1411b08d73af37a1fffe2944halcanary    SkASSERT(!fSubstituteMap.find(original));
46537c46cad21632cfc1411b08d73af37a1fffe2944halcanary    fSubstituteMap.set(original, SkRef(substitute));
46637c46cad21632cfc1411b08d73af37a1fffe2944halcanary}
46737c46cad21632cfc1411b08d73af37a1fffe2944halcanary
46837c46cad21632cfc1411b08d73af37a1fffe2944halcanarySkPDFObject* SkPDFSubstituteMap::getSubstitute(SkPDFObject* object) const {
46937c46cad21632cfc1411b08d73af37a1fffe2944halcanary    SkPDFObject** found = fSubstituteMap.find(object);
47037c46cad21632cfc1411b08d73af37a1fffe2944halcanary    return found ? *found : object;
47137c46cad21632cfc1411b08d73af37a1fffe2944halcanary}
47237c46cad21632cfc1411b08d73af37a1fffe2944halcanary
47337c46cad21632cfc1411b08d73af37a1fffe2944halcanary////////////////////////////////////////////////////////////////////////////////
47437c46cad21632cfc1411b08d73af37a1fffe2944halcanary
47537c46cad21632cfc1411b08d73af37a1fffe2944halcanarybool SkPDFObjNumMap::addObject(SkPDFObject* obj) {
47637c46cad21632cfc1411b08d73af37a1fffe2944halcanary    if (fObjectNumbers.find(obj)) {
47737c46cad21632cfc1411b08d73af37a1fffe2944halcanary        return false;
47837c46cad21632cfc1411b08d73af37a1fffe2944halcanary    }
47937c46cad21632cfc1411b08d73af37a1fffe2944halcanary    fObjectNumbers.set(obj, fObjectNumbers.count() + 1);
48037c46cad21632cfc1411b08d73af37a1fffe2944halcanary    fObjects.push(obj);
48137c46cad21632cfc1411b08d73af37a1fffe2944halcanary    return true;
48237c46cad21632cfc1411b08d73af37a1fffe2944halcanary}
48337c46cad21632cfc1411b08d73af37a1fffe2944halcanary
48437c46cad21632cfc1411b08d73af37a1fffe2944halcanaryint32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const {
48537c46cad21632cfc1411b08d73af37a1fffe2944halcanary    int32_t* objectNumberFound = fObjectNumbers.find(obj);
48637c46cad21632cfc1411b08d73af37a1fffe2944halcanary    SkASSERT(objectNumberFound);
48737c46cad21632cfc1411b08d73af37a1fffe2944halcanary    return *objectNumberFound;
48837c46cad21632cfc1411b08d73af37a1fffe2944halcanary}
48937c46cad21632cfc1411b08d73af37a1fffe2944halcanary
490