1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2010 The Android Open Source Project
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SkPDFTypes_DEFINED
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkPDFTypes_DEFINED
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRefCnt.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkScalar.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTHash.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypes.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkData;
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFObjNumMap;
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFObject;
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkStreamAsset;
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkString;
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkWStream;
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_PDF_IMAGE_STATS
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkAtomics.h"
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkPDFObject
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    A PDF Object is the base class for primitive elements in a PDF file.  A
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    common subtype is used to ease the use of indirect object references,
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    which are common in the PDF format.
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot*/
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFObject : public SkRefCnt {
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Subclasses must implement this method to print the object to the
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  PDF file.
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param catalog  The object catalog to use.
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param stream   The writable output stream to send the output to.
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void emitObject(SkWStream* stream,
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            const SkPDFObjNumMap& objNumMap) const = 0;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  Adds all transitive dependencies of this object to the
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  catalog.  Implementations should respect the catalog's object
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  substitution map.
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void addResources(SkPDFObjNumMap* catalog) const {}
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  Release all resources associated with this SkPDFObject.  It is
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  an error to call emitObject() or addResources() after calling
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  drop().
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void drop() {}
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual ~SkPDFObject() {}
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkRefCnt INHERITED;
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////////
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/**
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot   A SkPDFUnion is a non-virtualized implementation of the
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot   non-compound, non-specialized PDF Object types: Name, String,
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot   Number, Boolean.
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFUnion {
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Move contstructor and assignemnt operator destroy the argument
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // and steal their references (if needed).
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFUnion(SkPDFUnion&& other);
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFUnion& operator=(SkPDFUnion&& other);
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~SkPDFUnion();
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** The following nine functions are the standard way of creating
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPDFUnion objects. */
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion Int(int32_t);
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion Int(size_t v) { return SkPDFUnion::Int(SkToS32(v)); }
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion Bool(bool);
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion Scalar(SkScalar);
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion ColorComponent(uint8_t);
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** These two functions do NOT take ownership of char*, and do NOT
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        copy the string.  Suitable for passing in static const
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        strings. For example:
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot          SkPDFUnion n = SkPDFUnion::Name("Length");
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot          SkPDFUnion u = SkPDFUnion::String("Identity"); */
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** SkPDFUnion::Name(const char*) assumes that the passed string
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        is already a valid name (that is: it has no control or
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        whitespace characters).  This will not copy the name. */
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion Name(const char*);
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** SkPDFUnion::String will encode the passed string.  This will
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        not copy the name. */
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion String(const char*);
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** SkPDFUnion::Name(const SkString&) does not assume that the
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        passed string is already a valid name and it will escape the
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        string. */
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion Name(const SkString&);
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** SkPDFUnion::String will encode the passed string. */
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion String(const SkString&);
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion Object(sk_sp<SkPDFObject>);
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static SkPDFUnion ObjRef(sk_sp<SkPDFObject>);
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** These two non-virtual methods mirror SkPDFObject's
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        corresponding virtuals. */
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void emitObject(SkWStream*, const SkPDFObjNumMap&) const;
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addResources(SkPDFObjNumMap*) const;
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isName() const;
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    union {
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int32_t fIntValue;
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool fBoolValue;
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar fScalarValue;
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* fStaticString;
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        char fSkString[sizeof(SkString)];
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPDFObject* fObject;
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Type : char {
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        /** It is an error to call emitObject() or addResources() on an
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            kDestroyed object. */
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kDestroyed = 0,
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kInt,
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kColorComponent,
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBool,
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kScalar,
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kName,
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kString,
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNameSkS,
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kStringSkS,
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kObjRef,
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kObject,
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Type fType;
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFUnion(Type);
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // We do not now need copy constructor and copy assignment, so we
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // will disable this functionality.
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFUnion& operator=(const SkPDFUnion&) = delete;
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFUnion(const SkPDFUnion&) = delete;
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic_assert(sizeof(SkString) == sizeof(void*), "SkString_size");
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////////
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0  // Enable if needed.
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** This class is a SkPDFUnion with SkPDFObject virtuals attached.
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    The only use case of this is when a non-compound PDF object is
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    referenced indirectly. */
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFAtom final : public SkPDFObject {
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void emitObject(SkWStream* stream,
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    const SkPDFObjNumMap& objNumMap) final;
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addResources(SkPDFObjNumMap* const final;
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFAtom(SkPDFUnion&& v) : fValue(std::move(v) {}
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkPDFUnion fValue;
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkPDFObject INHERITED;
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif  // 0
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////////
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkPDFArray
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    An array object in a PDF.
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot*/
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFArray final : public SkPDFObject {
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Create a PDF array. Maximum length is 8191.
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFArray();
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~SkPDFArray() override;
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // The SkPDFObject interface.
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void emitObject(SkWStream* stream,
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    const SkPDFObjNumMap& objNumMap) const override;
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addResources(SkPDFObjNumMap*) const override;
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void drop() override;
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** The size of the array.
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int size() const;
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Preallocate space for the given number of entries.
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param length The number of array slots to preallocate.
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reserve(int length);
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Appends a value to the end of the array.
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param value The value to add to the array.
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendInt(int32_t);
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendColorComponent(uint8_t);
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendBool(bool);
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendScalar(SkScalar);
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendName(const char[]);
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendName(const SkString&);
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendString(const char[]);
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendString(const SkString&);
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendObject(sk_sp<SkPDFObject>);
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void appendObjRef(sk_sp<SkPDFObject>);
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTArray<SkPDFUnion> fValues;
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void append(SkPDFUnion&& value);
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(bool fDumped;)
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkPDFDict
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    A dictionary object in a PDF.
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot*/
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFDict : public SkPDFObject {
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Create a PDF dictionary.
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param type   The value of the Type entry, nullptr for no type.
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    explicit SkPDFDict(const char type[] = nullptr);
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~SkPDFDict() override;
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // The SkPDFObject interface.
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void emitObject(SkWStream* stream,
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    const SkPDFObjNumMap& objNumMap) const override;
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addResources(SkPDFObjNumMap*) const override;
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void drop() override;
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** The size of the dictionary.
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int size() const;
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Preallocate space for n key-value pairs */
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void reserve(int n);
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Add the value to the dictionary with the given key.
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param key   The text of the key for this dictionary entry.
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param value The value for this dictionary entry.
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertObject(const char key[], sk_sp<SkPDFObject>);
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertObject(const SkString& key, sk_sp<SkPDFObject>);
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertObjRef(const char key[], sk_sp<SkPDFObject>);
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertObjRef(const SkString& key, sk_sp<SkPDFObject>);
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Add the value to the dictionary with the given key.
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param key   The text of the key for this dictionary entry.
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param value The value for this dictionary entry.
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertBool(const char key[], bool value);
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertInt(const char key[], int32_t value);
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertInt(const char key[], size_t value);
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertScalar(const char key[], SkScalar value);
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertName(const char key[], const char nameValue[]);
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertName(const char key[], const SkString& nameValue);
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertString(const char key[], const char value[]);
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void insertString(const char key[], const SkString& value);
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Emit the dictionary, without the "<<" and ">>".
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void emitAll(SkWStream* stream,
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                 const SkPDFObjNumMap& objNumMap) const;
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct Record {
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPDFUnion fKey;
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPDFUnion fValue;
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTArray<Record> fRecords;
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(bool fDumped;)
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkPDFSharedStream
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    This class takes an asset and assumes that it is backed by
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    long-lived shared data (for example, an open file
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    descriptor). That is: no memory savings can be made by holding on
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    to a compressed version instead.
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFSharedStream final : public SkPDFObject {
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFSharedStream(std::unique_ptr<SkStreamAsset> data);
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~SkPDFSharedStream() override;
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFDict* dict() { return &fDict; }
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void emitObject(SkWStream*,
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    const SkPDFObjNumMap&) const override;
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addResources(SkPDFObjNumMap*) const override;
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void drop() override;
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    std::unique_ptr<SkStreamAsset> fAsset;
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFDict fDict;
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkPDFObject INHERITED;
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkPDFStream
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    This class takes an asset and assumes that it is the only owner of
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    the asset's data.  It immediately compresses the asset to save
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    memory.
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFStream final : public SkPDFObject {
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Create a PDF stream. A Length entry is automatically added to the
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  stream dictionary.
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param data   The data part of the stream.
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param stream The data part of the stream. */
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    explicit SkPDFStream(sk_sp<SkData> data);
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    explicit SkPDFStream(std::unique_ptr<SkStreamAsset> stream);
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~SkPDFStream() override;
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFDict* dict() { return &fDict; }
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // The SkPDFObject interface.
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void emitObject(SkWStream* stream,
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    const SkPDFObjNumMap& objNumMap) const override;
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addResources(SkPDFObjNumMap*) const final;
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void drop() override;
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /* Create a PDF stream with no data.  The setData method must be called to
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * set the data. */
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFStream();
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Only call this function once. */
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setData(std::unique_ptr<SkStreamAsset> stream);
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    std::unique_ptr<SkStreamAsset> fCompressedData;
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPDFDict fDict;
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkPDFDict INHERITED;
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////////
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkPDFObjNumMap
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    The PDF Object Number Map manages object numbers.  It is used to
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    create the PDF cross reference table.
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot*/
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkPDFObjNumMap : SkNoncopyable {
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Add the passed object to the catalog, as well as all its dependencies.
363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param obj   The object to add.  If nullptr, this is a noop.
364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void addObjectRecursively(SkPDFObject* obj);
366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Get the object number for the passed object.
368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  @param obj         The object of interest.
369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int32_t getObjectNumber(SkPDFObject* obj) const;
371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkTArray<sk_sp<SkPDFObject>>& objects() const { return fObjects; }
373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTArray<sk_sp<SkPDFObject>> fObjects;
376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTHashMap<SkPDFObject*, int32_t> fObjectNumbers;
377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////////
380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_PDF_IMAGE_STATS
382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotextern SkAtomic<int> gDrawImageCalls;
383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotextern SkAtomic<int> gJpegImageObjects;
384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotextern SkAtomic<int> gRegularImageObjects;
385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotextern void SkPDFImageDumpStats();
386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif // SK_PDF_IMAGE_STATS
387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
389