1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPictureData_DEFINED
#define SkPictureData_DEFINED
#include "SkBitmap.h"
#include "SkDrawable.h"
#include "SkPicture.h"
#include "SkPictureContentInfo.h"
#include "SkPictureFlat.h"
class SkData;
class SkPictureRecord;
class SkPixelSerializer;
class SkReader32;
class SkStream;
class SkWStream;
class SkBBoxHierarchy;
class SkMatrix;
class SkPaint;
class SkPath;
class SkReadBuffer;
class SkTextBlob;
struct SkPictInfo {
enum Flags {
kCrossProcess_Flag = 1 << 0,
kScalarIsFloat_Flag = 1 << 1,
kPtrIs64Bit_Flag = 1 << 2,
};
char fMagic[8];
uint32_t fVersion;
SkRect fCullRect;
uint32_t fFlags;
};
#define SK_PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd')
#define SK_PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't')
#define SK_PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c')
#define SK_PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r')
#define SK_PICT_DRAWABLE_TAG SkSetFourByteTag('d', 'r', 'a', 'w')
// This tag specifies the size of the ReadBuffer, needed for the following tags
#define SK_PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y')
// these are all inside the ARRAYS tag
#define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p')
#define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ')
#define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ')
#define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
#define SK_PICT_IMAGE_BUFFER_TAG SkSetFourByteTag('i', 'm', 'a', 'g')
// Always write this guy last (with no length field afterwards)
#define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ')
class SkPictureData {
public:
SkPictureData(const SkPictureRecord& record, const SkPictInfo&);
// Does not affect ownership of SkStream.
static SkPictureData* CreateFromStream(SkStream*,
const SkPictInfo&,
SkPicture::InstallPixelRefProc,
SkTypefacePlayback*);
static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
virtual ~SkPictureData();
void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet*) const;
void flatten(SkWriteBuffer&) const;
bool containsBitmaps() const;
bool hasText() const { return fContentInfo.hasText(); }
int opCount() const { return fContentInfo.numOperations(); }
const sk_sp<SkData>& opData() const { return fOpData; }
protected:
explicit SkPictureData(const SkPictInfo& info);
// Does not affect ownership of SkStream.
bool parseStream(SkStream*, SkPicture::InstallPixelRefProc, SkTypefacePlayback*);
bool parseBuffer(SkReadBuffer& buffer);
public:
const SkBitmap& getBitmap(SkReadBuffer* reader) const {
const int index = reader->readInt();
return reader->validateIndex(index, fBitmaps.count()) ? fBitmaps[index] : fEmptyBitmap;
}
const SkImage* getImage(SkReadBuffer* reader) const {
const int index = reader->readInt();
return reader->validateIndex(index, fImageCount) ? fImageRefs[index] : nullptr;
}
const SkPath& getPath(SkReadBuffer* reader) const {
const int index = reader->readInt() - 1;
return reader->validateIndex(index, fPaths.count()) ? fPaths[index] : fEmptyPath;
}
const SkPicture* getPicture(SkReadBuffer* reader) const {
const int index = reader->readInt() - 1;
return reader->validateIndex(index, fPictureCount) ? fPictureRefs[index] : nullptr;
}
SkDrawable* getDrawable(SkReadBuffer* reader) const {
int index = reader->readInt();
SkASSERT(index > 0 && index <= fDrawableCount);
return fDrawableRefs[index - 1];
}
const SkPaint* getPaint(SkReadBuffer* reader) const {
const int index = reader->readInt() - 1;
return reader->validateIndex(index, fPaints.count()) ? &fPaints[index] : nullptr;
}
const SkTextBlob* getTextBlob(SkReadBuffer* reader) const {
const int index = reader->readInt() - 1;
return reader->validateIndex(index, fTextBlobCount) ? fTextBlobRefs[index] : nullptr;
}
#if SK_SUPPORT_GPU
/**
* sampleCount is the number of samples-per-pixel or zero if non-MSAA.
* It is defaulted to be zero.
*/
bool suitableForGpuRasterization(GrContext* context, const char **reason,
int sampleCount = 0) const;
/**
* Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount
* and then calls the above version of suitableForGpuRasterization
*/
bool suitableForGpuRasterization(GrContext* context, const char **reason,
GrPixelConfig config, SkScalar dpi) const;
bool suitableForLayerOptimization() const;
#endif
private:
void init();
// these help us with reading/writing
// Does not affect ownership of SkStream.
bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size,
SkPicture::InstallPixelRefProc, SkTypefacePlayback*);
bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
void flattenToBuffer(SkWriteBuffer&) const;
SkTArray<SkBitmap> fBitmaps;
SkTArray<SkPaint> fPaints;
SkTArray<SkPath> fPaths;
sk_sp<SkData> fOpData; // opcodes and parameters
const SkPath fEmptyPath;
const SkBitmap fEmptyBitmap;
const SkPicture** fPictureRefs;
int fPictureCount;
SkDrawable** fDrawableRefs;
int fDrawableCount;
const SkTextBlob** fTextBlobRefs;
int fTextBlobCount;
const SkImage** fImageRefs;
int fImageCount;
SkPictureContentInfo fContentInfo;
SkTypefacePlayback fTFPlayback;
SkFactoryPlayback* fFactoryPlayback;
const SkPictInfo fInfo;
static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec);
void initForPlayback() const;
};
#endif
|