1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkFlattenable_DEFINED
18#define SkFlattenable_DEFINED
19
20#include "SkRefCnt.h"
21#include "SkBitmap.h"
22#include "SkReader32.h"
23#include "SkTDArray.h"
24#include "SkWriter32.h"
25
26class SkFlattenableReadBuffer;
27class SkFlattenableWriteBuffer;
28class SkString;
29
30/** \class SkFlattenable
31
32 SkFlattenable is the base class for objects that need to be flattened
33 into a data stream for either transport or as part of the key to the
34 font cache.
35 */
36class SK_API SkFlattenable : public SkRefCnt {
37public:
38    typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
39
40    SkFlattenable() {}
41
42    /** Implement this to return a factory function pointer that can be called
43     to recreate your class given a buffer (previously written to by your
44     override of flatten().
45     */
46    virtual Factory getFactory() = 0;
47    /** Override this to write data specific to your subclass into the buffer,
48     being sure to call your super-class' version first. This data will later
49     be passed to your Factory function, returned by getFactory().
50     */
51    virtual void flatten(SkFlattenableWriteBuffer&);
52
53    /** Set the string to describe the sublass and return true. If this is not
54        overridden, ignore the string param and return false.
55     */
56    virtual bool toDumpString(SkString*) const;
57
58    static Factory NameToFactory(const char name[]);
59    static const char* FactoryToName(Factory);
60    static void Register(const char name[], Factory);
61
62    class Registrar {
63    public:
64        Registrar(const char name[], Factory factory) {
65            SkFlattenable::Register(name, factory);
66        }
67    };
68
69protected:
70    SkFlattenable(SkFlattenableReadBuffer&) {}
71};
72
73// helpers for matrix and region
74
75class SkMatrix;
76extern void SkReadMatrix(SkReader32*, SkMatrix*);
77extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
78
79class SkRegion;
80extern void SkReadRegion(SkReader32*, SkRegion*);
81extern void SkWriteRegion(SkWriter32*, const SkRegion&);
82
83///////////////////////////////////////////////////////////////////////////////
84///////////////////////////////////////////////////////////////////////////////
85
86class SkTypeface;
87
88class SkFlattenableReadBuffer : public SkReader32 {
89public:
90    SkFlattenableReadBuffer();
91    explicit SkFlattenableReadBuffer(const void* data);
92    SkFlattenableReadBuffer(const void* data, size_t size);
93
94    void setRefCntArray(SkRefCnt* array[], int count) {
95        fRCArray = array;
96        fRCCount = count;
97    }
98
99    void setTypefaceArray(SkTypeface* array[], int count) {
100        fTFArray = array;
101        fTFCount = count;
102    }
103
104    void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
105        fFactoryArray = array;
106        fFactoryCount = count;
107    }
108
109    SkTypeface* readTypeface();
110    SkRefCnt* readRefCnt();
111    void* readFunctionPtr();
112    SkFlattenable* readFlattenable();
113
114private:
115    SkRefCnt** fRCArray;
116    int        fRCCount;
117
118    SkTypeface** fTFArray;
119    int        fTFCount;
120
121    SkFlattenable::Factory* fFactoryArray;
122    int                     fFactoryCount;
123
124    typedef SkReader32 INHERITED;
125};
126
127///////////////////////////////////////////////////////////////////////////////
128
129#include "SkPtrRecorder.h"
130
131/**
132 *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
133 *  base class's incPtr() and decPtr() are called. This makes it a valid owner
134 *  of each ptr, which is released when the set is reset or destroyed.
135 */
136class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
137public:
138    virtual ~SkRefCntSet();
139
140protected:
141    // overrides
142    virtual void incPtr(void*);
143    virtual void decPtr(void*);
144};
145
146class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
147
148class SkFlattenableWriteBuffer : public SkWriter32 {
149public:
150    SkFlattenableWriteBuffer(size_t minSize);
151    virtual ~SkFlattenableWriteBuffer();
152
153    void writeTypeface(SkTypeface*);
154    void writeRefCnt(SkRefCnt*);
155    void writeFunctionPtr(void*);
156    void writeFlattenable(SkFlattenable* flattenable);
157
158    SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
159    SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
160
161    SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
162    SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
163
164    SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
165    SkFactorySet* setFactoryRecorder(SkFactorySet*);
166
167    enum Flags {
168        kCrossProcess_Flag      = 0x01
169    };
170    Flags getFlags() const { return fFlags; }
171    void setFlags(Flags flags) { fFlags = flags; }
172
173    bool isCrossProcess() const { return (fFlags & kCrossProcess_Flag) != 0; }
174
175    bool persistBitmapPixels() const {
176        return (fFlags & kCrossProcess_Flag) != 0;
177    }
178
179    bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
180
181private:
182    Flags          fFlags;
183    SkRefCntSet*   fTFSet;
184    SkRefCntSet*   fRCSet;
185    SkFactorySet*  fFactorySet;
186
187    typedef SkWriter32 INHERITED;
188};
189
190#endif
191
192