3f2ac36d79
SkPictureData::getPaint() is now SkPictureData::optionalPaint(), and it's got a sibling requiredPaint() that returns a const SkPaint&. This means we don't have to remember to null check the paints, and we can signal a bad .skp when a paint should be present but is missing. No way to know that for optional paints, of course; the only part of that function I changed is its name. Moved these methods out of line. I never know how that interacts with function local statics. They're complex enough to move out anyway. PS3 implements requiredPaint() with optionalPaint(), I think clearer. Change-Id: If8ef479262faa80be65eb98e2aef8b769cfa8aa6 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308763 Commit-Queue: Mike Klein <mtklein@google.com> Reviewed-by: Mike Reed <reed@google.com>
168 lines
5.6 KiB
C++
168 lines
5.6 KiB
C++
/*
|
|
* 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 "include/core/SkBitmap.h"
|
|
#include "include/core/SkDrawable.h"
|
|
#include "include/core/SkPicture.h"
|
|
#include "include/private/SkTArray.h"
|
|
#include "src/core/SkPictureFlat.h"
|
|
|
|
#include <memory>
|
|
|
|
class SkData;
|
|
class SkPictureRecord;
|
|
struct SkSerialProcs;
|
|
class SkStream;
|
|
class SkWStream;
|
|
class SkBBoxHierarchy;
|
|
class SkMatrix;
|
|
class SkPaint;
|
|
class SkPath;
|
|
class SkReadBuffer;
|
|
class SkTextBlob;
|
|
|
|
struct SkPictInfo {
|
|
SkPictInfo() : fVersion(~0U) {}
|
|
|
|
uint32_t getVersion() const {
|
|
SkASSERT(fVersion != ~0U);
|
|
return fVersion;
|
|
}
|
|
|
|
void setVersion(uint32_t version) {
|
|
SkASSERT(version != ~0U);
|
|
fVersion = version;
|
|
}
|
|
|
|
public:
|
|
char fMagic[8];
|
|
private:
|
|
uint32_t fVersion;
|
|
public:
|
|
SkRect fCullRect;
|
|
};
|
|
|
|
#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_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_VERTICES_BUFFER_TAG SkSetFourByteTag('v', 'e', 'r', 't')
|
|
#define SK_PICT_IMAGE_BUFFER_TAG SkSetFourByteTag('i', 'm', 'a', 'g')
|
|
|
|
// Always write this last (with no length field afterwards)
|
|
#define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ')
|
|
|
|
template <typename T>
|
|
T* read_index_base_1_or_null(SkReadBuffer* reader, const SkTArray<sk_sp<T>>& array) {
|
|
int index = reader->readInt();
|
|
return reader->validate(index > 0 && index <= array.count()) ? array[index - 1].get() : nullptr;
|
|
}
|
|
|
|
class SkPictureData {
|
|
public:
|
|
SkPictureData(const SkPictureRecord& record, const SkPictInfo&);
|
|
// Does not affect ownership of SkStream.
|
|
static SkPictureData* CreateFromStream(SkStream*,
|
|
const SkPictInfo&,
|
|
const SkDeserialProcs&,
|
|
SkTypefacePlayback*);
|
|
static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
|
|
|
|
void serialize(SkWStream*, const SkSerialProcs&, SkRefCntSet*, bool textBlobsOnly=false) const;
|
|
void flatten(SkWriteBuffer&) const;
|
|
|
|
const sk_sp<SkData>& opData() const { return fOpData; }
|
|
|
|
protected:
|
|
explicit SkPictureData(const SkPictInfo& info);
|
|
|
|
// Does not affect ownership of SkStream.
|
|
bool parseStream(SkStream*, const SkDeserialProcs&, SkTypefacePlayback*);
|
|
bool parseBuffer(SkReadBuffer& buffer);
|
|
|
|
public:
|
|
const SkImage* getImage(SkReadBuffer* reader) const {
|
|
// images are written base-0, unlike paths, pictures, drawables, etc.
|
|
const int index = reader->readInt();
|
|
return reader->validateIndex(index, fImages.count()) ? fImages[index].get() : nullptr;
|
|
}
|
|
|
|
const SkPath& getPath(SkReadBuffer* reader) const {
|
|
int index = reader->readInt();
|
|
return reader->validate(index > 0 && index <= fPaths.count()) ?
|
|
fPaths[index - 1] : fEmptyPath;
|
|
}
|
|
|
|
const SkPicture* getPicture(SkReadBuffer* reader) const {
|
|
return read_index_base_1_or_null(reader, fPictures);
|
|
}
|
|
|
|
SkDrawable* getDrawable(SkReadBuffer* reader) const {
|
|
return read_index_base_1_or_null(reader, fDrawables);
|
|
}
|
|
|
|
// Return a paint if one was used for this op, or nullptr if none was used.
|
|
const SkPaint* optionalPaint(SkReadBuffer* reader) const;
|
|
|
|
// Return the paint used for this op, invalidating the SkReadBuffer if there appears to be none.
|
|
// The returned paint is always safe to use.
|
|
const SkPaint& requiredPaint(SkReadBuffer* reader) const;
|
|
|
|
const SkTextBlob* getTextBlob(SkReadBuffer* reader) const {
|
|
return read_index_base_1_or_null(reader, fTextBlobs);
|
|
}
|
|
|
|
const SkVertices* getVertices(SkReadBuffer* reader) const {
|
|
return read_index_base_1_or_null(reader, fVertices);
|
|
}
|
|
|
|
private:
|
|
// these help us with reading/writing
|
|
// Does not affect ownership of SkStream.
|
|
bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size,
|
|
const SkDeserialProcs&, SkTypefacePlayback*);
|
|
void parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
|
|
void flattenToBuffer(SkWriteBuffer&, bool textBlobsOnly) const;
|
|
|
|
SkTArray<SkPaint> fPaints;
|
|
SkTArray<SkPath> fPaths;
|
|
|
|
sk_sp<SkData> fOpData; // opcodes and parameters
|
|
|
|
const SkPath fEmptyPath;
|
|
const SkBitmap fEmptyBitmap;
|
|
|
|
SkTArray<sk_sp<const SkPicture>> fPictures;
|
|
SkTArray<sk_sp<SkDrawable>> fDrawables;
|
|
SkTArray<sk_sp<const SkTextBlob>> fTextBlobs;
|
|
SkTArray<sk_sp<const SkVertices>> fVertices;
|
|
SkTArray<sk_sp<const SkImage>> fImages;
|
|
|
|
SkTypefacePlayback fTFPlayback;
|
|
std::unique_ptr<SkFactoryPlayback> fFactoryPlayback;
|
|
|
|
const SkPictInfo fInfo;
|
|
|
|
static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
|
|
static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec, const SkSerialProcs&);
|
|
|
|
void initForPlayback() const;
|
|
};
|
|
|
|
#endif
|