Make SkTypefacePlayback use smart pointers.

This clarifies the ownership of the typefaces as well as removes a use
of SkRefCnt_SafeAssign which is currently a code smell.

Change-Id: I8fec541f71f555c2182b77870979ece87b501901
Reviewed-on: https://skia-review.googlesource.com/140249
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
Ben Wagner 2018-07-10 14:20:15 -04:00 committed by Skia Commit-Bot
parent 1994f20d79
commit 5d948228d9
5 changed files with 21 additions and 67 deletions

View File

@ -258,17 +258,6 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
uint32_t size,
const SkDeserialProcs& procs,
SkTypefacePlayback* topLevelTFPlayback) {
/*
* By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
* its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
* but if they are present, they need to have been seen before the buffer.
*
* We assert that if/when we see either of these, that we have not yet seen
* the buffer tag, because if we have, then its too-late to deal with the
* factories or typefaces.
*/
SkDEBUGCODE(bool haveBuffer = false;)
switch (tag) {
case SK_PICT_READER_TAG:
SkASSERT(nullptr == fOpData);
@ -278,7 +267,6 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
}
break;
case SK_PICT_FACTORY_TAG: {
SkASSERT(!haveBuffer);
if (!stream->readU32(&size)) { return false; }
fFactoryPlayback = skstd::make_unique<SkFactoryPlayback>(size);
for (size_t i = 0; i < size; i++) {
@ -293,17 +281,15 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
}
} break;
case SK_PICT_TYPEFACE_TAG: {
SkASSERT(!haveBuffer);
const int count = SkToInt(size);
fTFPlayback.setCount(count);
for (int i = 0; i < count; i++) {
fTFPlayback.setCount(size);
for (uint32_t i = 0; i < size; ++i) {
sk_sp<SkTypeface> tf(SkTypeface::MakeDeserialize(stream));
if (!tf.get()) { // failed to deserialize
// fTFPlayback asserts it never has a null, so we plop in
// the default here.
tf = SkTypeface::MakeDefault();
}
fTFPlayback.set(i, tf.get());
fTFPlayback[i] = std::move(tf);
}
} break;
case SK_PICT_PICTURE_TAG: {
@ -349,7 +335,6 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
if (!buffer.isValid()) {
return false;
}
SkDEBUGCODE(haveBuffer = true;)
} break;
}
return true; // success

View File

@ -15,42 +15,9 @@
///////////////////////////////////////////////////////////////////////////////
SkTypefacePlayback::SkTypefacePlayback() : fCount(0), fArray(nullptr) {}
SkTypefacePlayback::~SkTypefacePlayback() {
this->reset(nullptr);
}
void SkTypefacePlayback::reset(const SkRefCntSet* rec) {
for (int i = 0; i < fCount; i++) {
SkASSERT(fArray[i]);
fArray[i]->unref();
}
delete[] fArray;
if (rec!= nullptr && rec->count() > 0) {
fCount = rec->count();
fArray = new SkRefCnt* [fCount];
rec->copyToArray(fArray);
for (int i = 0; i < fCount; i++) {
fArray[i]->ref();
}
} else {
fCount = 0;
fArray = nullptr;
}
}
void SkTypefacePlayback::setCount(int count) {
this->reset(nullptr);
SkTypefacePlayback::~SkTypefacePlayback() {}
void SkTypefacePlayback::setCount(size_t count) {
fCount = count;
fArray = new SkRefCnt* [count];
sk_bzero(fArray, count * sizeof(SkRefCnt*));
}
SkRefCnt* SkTypefacePlayback::set(int index, SkRefCnt* obj) {
SkASSERT((unsigned)index < (unsigned)fCount);
SkRefCnt_SafeAssign(fArray[index], obj);
return obj;
fArray.reset(new sk_sp<SkTypeface>[count]);
}

View File

@ -155,23 +155,25 @@ static inline bool ClipParams_unpackDoAA(uint32_t packed) {
class SkTypefacePlayback {
public:
SkTypefacePlayback();
virtual ~SkTypefacePlayback();
SkTypefacePlayback() : fCount(0), fArray(nullptr) {}
~SkTypefacePlayback();
int count() const { return fCount; }
void setCount(size_t count);
void reset(const SkRefCntSet*);
size_t count() const { return fCount; }
void setCount(int count);
SkRefCnt* set(int index, SkRefCnt*);
sk_sp<SkTypeface>& operator[](size_t index) {
SkASSERT(index < fCount);
return fArray[index];
}
void setupBuffer(SkReadBuffer& buffer) const {
buffer.setTypefaceArray((SkTypeface**)fArray, fCount);
buffer.setTypefaceArray(fArray.get(), fCount);
}
protected:
int fCount;
SkRefCnt** fArray;
size_t fCount;
std::unique_ptr<sk_sp<SkTypeface>[]> fArray;
};
class SkFactoryPlayback {

View File

@ -379,7 +379,7 @@ sk_sp<SkTypeface> SkReadBuffer::readTypeface() {
if (!this->validate(index <= fTFCount)) {
return nullptr;
}
return sk_ref_sp(fTFArray[index - 1]);
return fTFArray[index - 1];
} else { // custom
size_t size = sk_negate_to_size_t(index);
const void* data = this->skip(size);

View File

@ -180,7 +180,7 @@ public:
sk_sp<SkImage> readImage();
sk_sp<SkTypeface> readTypeface();
void setTypefaceArray(SkTypeface* array[], int count) {
void setTypefaceArray(sk_sp<SkTypeface> array[], int count) {
fTFArray = array;
fTFCount = count;
}
@ -282,8 +282,8 @@ private:
void* fMemoryPtr;
SkTypeface** fTFArray;
int fTFCount;
sk_sp<SkTypeface>* fTFArray;
int fTFCount;
SkFlattenable::Factory* fFactoryArray;
int fFactoryCount;