1
2/*
3 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef SkPDFStream_DEFINED
11#define SkPDFStream_DEFINED
12
13#include "SkPDFTypes.h"
14#include "SkRefCnt.h"
15#include "SkStream.h"
16#include "SkTemplates.h"
17
18class SkPDFCatalog;
19
20/** \class SkPDFStream
21
22    A stream object in a PDF.  Note, all streams must be indirect objects (via
23    SkObjRef).
24*/
25class SkPDFStream : public SkPDFDict {
26    SK_DECLARE_INST_COUNT(SkPDFStream)
27public:
28    /** Create a PDF stream. A Length entry is automatically added to the
29     *  stream dictionary.
30     *  @param data   The data part of the stream.  Will be ref()ed.
31     */
32    explicit SkPDFStream(SkData* data);
33
34    /** Create a PDF stream. A Length entry is automatically added to the
35     *  stream dictionary.
36     *  @param stream The data part of the stream.  Will be duplicate()d.
37     */
38    explicit SkPDFStream(SkStream* stream);
39
40    virtual ~SkPDFStream();
41
42    // The SkPDFObject interface.  These two methods use a mutex to
43    // allow multiple threads to call at the same time.
44    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
45                            bool indirect);
46    virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
47
48protected:
49    enum State {
50        kUnused_State,         //!< The stream hasn't been requested yet.
51        kNoCompression_State,  //!< The stream's been requested in an
52                               //   uncompressed form.
53        kCompressed_State,     //!< The stream's already been compressed.
54    };
55
56    /** Create a PDF stream with the same content and dictionary entries
57     *  as the passed one.
58     */
59    explicit SkPDFStream(const SkPDFStream& pdfStream);
60
61    /* Create a PDF stream with no data.  The setData method must be called to
62     * set the data.
63     */
64    SkPDFStream();
65
66    // Populate the stream dictionary.  This method returns false if
67    // fSubstitute should be used.
68    virtual bool populate(SkPDFCatalog* catalog);
69
70    void setSubstitute(SkPDFStream* stream) {
71        fSubstitute.reset(stream);
72    }
73
74    SkPDFStream* getSubstitute() const {
75        return fSubstitute.get();
76    }
77
78    void setData(SkData* data);
79    void setData(SkStream* stream);
80
81    size_t dataSize() const;
82
83    void setState(State state) {
84        fState = state;
85    }
86
87    State getState() const {
88        return fState;
89    }
90
91private:
92    // Indicates what form (or if) the stream has been requested.
93    State fState;
94
95    // Mutex guards fState, fDataStream, and fSubstitute in public interface.
96    SkMutex fMutex;
97
98    SkMemoryStream fMemoryStream;  // Used by fDataStream when
99                                   // fDataStream needs to be backed
100                                   // by SkData.
101    SkAutoTUnref<SkStreamRewindable> fDataStream;
102    SkAutoTUnref<SkPDFStream> fSubstitute;
103
104    typedef SkPDFDict INHERITED;
105};
106
107#endif
108