SkFlattenable.h revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
1
2/*
3 * Copyright 2006 The Android Open Source Project
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 SkFlattenable_DEFINED
11#define SkFlattenable_DEFINED
12
13#include "SkRefCnt.h"
14#include "SkBitmap.h"
15#include "SkReader32.h"
16#include "SkTDArray.h"
17#include "SkWriter32.h"
18
19class SkFlattenableReadBuffer;
20class SkFlattenableWriteBuffer;
21class SkString;
22
23/** \class SkFlattenable
24
25 SkFlattenable is the base class for objects that need to be flattened
26 into a data stream for either transport or as part of the key to the
27 font cache.
28 */
29class SK_API SkFlattenable : public SkRefCnt {
30public:
31    typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
32
33    SkFlattenable() {}
34
35    /** Implement this to return a factory function pointer that can be called
36     to recreate your class given a buffer (previously written to by your
37     override of flatten().
38     */
39    virtual Factory getFactory() = 0;
40    /** Override this to write data specific to your subclass into the buffer,
41     being sure to call your super-class' version first. This data will later
42     be passed to your Factory function, returned by getFactory().
43     */
44    virtual void flatten(SkFlattenableWriteBuffer&);
45
46    /** Set the string to describe the sublass and return true. If this is not
47        overridden, ignore the string param and return false.
48     */
49    virtual bool toDumpString(SkString*) const;
50
51    static Factory NameToFactory(const char name[]);
52    static const char* FactoryToName(Factory);
53    static void Register(const char name[], Factory);
54
55    class Registrar {
56    public:
57        Registrar(const char name[], Factory factory) {
58            SkFlattenable::Register(name, factory);
59        }
60    };
61
62protected:
63    SkFlattenable(SkFlattenableReadBuffer&) {}
64};
65
66// helpers for matrix and region
67
68class SkMatrix;
69extern void SkReadMatrix(SkReader32*, SkMatrix*);
70extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
71
72class SkRegion;
73extern void SkReadRegion(SkReader32*, SkRegion*);
74extern void SkWriteRegion(SkWriter32*, const SkRegion&);
75
76///////////////////////////////////////////////////////////////////////////////
77///////////////////////////////////////////////////////////////////////////////
78
79class SkTypeface;
80
81class SkFlattenableReadBuffer : public SkReader32 {
82public:
83    SkFlattenableReadBuffer();
84    explicit SkFlattenableReadBuffer(const void* data);
85    SkFlattenableReadBuffer(const void* data, size_t size);
86
87    void setRefCntArray(SkRefCnt* array[], int count) {
88        fRCArray = array;
89        fRCCount = count;
90    }
91
92    void setTypefaceArray(SkTypeface* array[], int count) {
93        fTFArray = array;
94        fTFCount = count;
95    }
96
97    /**
98     *  Call this with a pre-loaded array of Factories, in the same order as
99     *  were created/written by the writer. SkPicture uses this.
100     */
101    void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
102        fFactoryTDArray = NULL;
103        fFactoryArray = array;
104        fFactoryCount = count;
105    }
106
107    /**
108     *  Call this with an initially empty array, so the reader can cache each
109     *  factory it sees by name. Used by the pipe code in conjunction with
110     *  the writer's kInlineFactoryNames_Flag.
111     */
112    void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) {
113        fFactoryTDArray = array;
114        fFactoryArray = NULL;
115        fFactoryCount = 0;
116    }
117
118    SkTypeface* readTypeface();
119    SkRefCnt* readRefCnt();
120    void* readFunctionPtr();
121    SkFlattenable* readFlattenable();
122
123private:
124    SkRefCnt** fRCArray;
125    int        fRCCount;
126
127    SkTypeface** fTFArray;
128    int        fTFCount;
129
130    SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
131    SkFlattenable::Factory* fFactoryArray;
132    int                     fFactoryCount;
133
134    typedef SkReader32 INHERITED;
135};
136
137///////////////////////////////////////////////////////////////////////////////
138
139#include "SkPtrRecorder.h"
140
141/**
142 *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
143 *  base class's incPtr() and decPtr() are called. This makes it a valid owner
144 *  of each ptr, which is released when the set is reset or destroyed.
145 */
146class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
147public:
148    virtual ~SkRefCntSet();
149
150protected:
151    // overrides
152    virtual void incPtr(void*);
153    virtual void decPtr(void*);
154};
155
156class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
157
158class SkFlattenableWriteBuffer : public SkWriter32 {
159public:
160    SkFlattenableWriteBuffer(size_t minSize);
161    virtual ~SkFlattenableWriteBuffer();
162
163    void writeTypeface(SkTypeface*);
164    void writeRefCnt(SkRefCnt*);
165    void writeFunctionPtr(void*);
166    void writeFlattenable(SkFlattenable* flattenable);
167
168    SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
169    SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
170
171    SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
172    SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
173
174    SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
175    SkFactorySet* setFactoryRecorder(SkFactorySet*);
176
177    enum Flags {
178        kCrossProcess_Flag       = 0x01,
179        /**
180         *  Instructs the writer to inline Factory names as there are seen the
181         *  first time (after that we store an index). The pipe code uses this.
182         */
183        kInlineFactoryNames_Flag = 0x02,
184    };
185    Flags getFlags() const { return (Flags)fFlags; }
186    void setFlags(Flags flags) { fFlags = flags; }
187
188    bool isCrossProcess() const {
189        return SkToBool(fFlags & kCrossProcess_Flag);
190    }
191    bool inlineFactoryNames() const {
192        return SkToBool(fFlags & kInlineFactoryNames_Flag);
193    }
194
195    bool persistBitmapPixels() const {
196        return (fFlags & kCrossProcess_Flag) != 0;
197    }
198
199    bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
200
201private:
202    uint32_t        fFlags;
203    SkRefCntSet*    fTFSet;
204    SkRefCntSet*    fRCSet;
205    SkFactorySet*   fFactorySet;
206
207    typedef SkWriter32 INHERITED;
208};
209
210#endif
211
212