diff options
Diffstat (limited to 'src/core/SkPath.cpp')
-rw-r--r-- | src/core/SkPath.cpp | 145 |
1 files changed, 1 insertions, 144 deletions
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 95fa37f7a6..279615d799 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -16,6 +16,7 @@ #include "SkPathRef.h" #include "SkPointPriv.h" #include "SkRRect.h" +#include "SkSafeMath.h" static float poly_eval(float A, float B, float C, float t) { return (A * t + B) * t + C; @@ -2073,150 +2074,6 @@ SkPath::Verb SkPath::Iter::doNext(SkPoint ptsParam[4]) { /////////////////////////////////////////////////////////////////////////////// -/* - Format in compressed buffer: [ptCount, verbCount, pts[], verbs[]] -*/ - -size_t SkPath::writeToMemoryAsRRect(int32_t packedHeader, void* storage) const { - SkRect oval; - SkRRect rrect; - bool isCCW; - unsigned start; - if (fPathRef->isOval(&oval, &isCCW, &start)) { - rrect.setOval(oval); - // Convert to rrect start indices. - start *= 2; - } else if (!fPathRef->isRRect(&rrect, &isCCW, &start)) { - return false; - } - if (!storage) { - // packed header, rrect, start index. - return sizeof(int32_t) + SkRRect::kSizeInMemory + sizeof(int32_t); - } - - SkWBuffer buffer(storage); - // Rewrite header's first direction based on rrect direction. - uint8_t firstDir = isCCW ? SkPathPriv::kCCW_FirstDirection : SkPathPriv::kCW_FirstDirection; - packedHeader &= ~(0x3 << kDirection_SerializationShift); - packedHeader |= firstDir << kDirection_SerializationShift; - packedHeader |= SerializationType::kRRect << kType_SerializationShift; - buffer.write32(packedHeader); - rrect.writeToBuffer(&buffer); - buffer.write32(SkToS32(start)); - buffer.padToAlign4(); - return buffer.pos(); -} - -size_t SkPath::writeToMemory(void* storage) const { - SkDEBUGCODE(this->validate();) - - int32_t packed = (fConvexity << kConvexity_SerializationShift) | - (fFillType << kFillType_SerializationShift) | - (fFirstDirection << kDirection_SerializationShift) | - (fIsVolatile << kIsVolatile_SerializationShift) | - kCurrent_Version; - if (size_t bytes = this->writeToMemoryAsRRect(packed, storage)) { - return bytes; - } - - SkWBuffer buffer(storage); - - static_assert(0 == SerializationType::kGeneral, "packed has zero in type bits"); - if (nullptr == storage) { - // packed header, pathref, start index - const int byteCount = sizeof(int32_t) * 2 + fPathRef->writeSize(); - return SkAlign4(byteCount); - } - buffer.write32(packed); - buffer.write32(fLastMoveToIndex); - - fPathRef->writeToBuffer(&buffer); - - buffer.padToAlign4(); - return buffer.pos(); -} - -sk_sp<SkData> SkPath::serialize() const { - size_t size = this->writeToMemory(nullptr); - sk_sp<SkData> data = SkData::MakeUninitialized(size); - this->writeToMemory(data->writable_data()); - return data; -} - -size_t SkPath::readFromMemory(const void* storage, size_t length) { - SkRBuffer buffer(storage, length); - - int32_t packed; - if (!buffer.readS32(&packed)) { - return 0; - } - - unsigned version = packed & 0xFF; - uint8_t dir = (packed >> kDirection_SerializationShift) & 0x3; - FillType fillType = static_cast<FillType>((packed >> kFillType_SerializationShift) & 0x3); - if (version >= kPathPrivTypeEnumVersion) { - SerializationType type = - static_cast<SerializationType>((packed >> kType_SerializationShift) & 0xF); - switch (type) { - case SerializationType::kRRect: { - Direction rrectDir; - SkRRect rrect; - int32_t start; - switch (dir) { - case SkPathPriv::kCW_FirstDirection: - rrectDir = kCW_Direction; - break; - case SkPathPriv::kCCW_FirstDirection: - rrectDir = kCCW_Direction; - break; - default: - return 0; - } - if (!rrect.readFromBuffer(&buffer)) { - return 0; - } - if (!buffer.readS32(&start) || start != SkTPin(start, 0, 7)) { - return 0; - } - this->reset(); - this->addRRect(rrect, rrectDir, SkToUInt(start)); - this->setFillType(fillType); - buffer.skipToAlign4(); - return buffer.pos(); - } - case SerializationType::kGeneral: - // Fall through to general path deserialization - break; - default: - return 0; - } - } - if (version >= kPathPrivLastMoveToIndex_Version && !buffer.readS32(&fLastMoveToIndex)) { - return 0; - } - - // These are written into the serialized data but we no longer use them in the deserialized - // path. If convexity is corrupted it may cause the GPU backend to make incorrect - // rendering choices, possibly crashing. We set them to unknown so that they'll be recomputed if - // requested. - fConvexity = kUnknown_Convexity; - fFirstDirection = SkPathPriv::kUnknown_FirstDirection; - - fFillType = fillType; - fIsVolatile = (packed >> kIsVolatile_SerializationShift) & 0x1; - SkPathRef* pathRef = SkPathRef::CreateFromBuffer(&buffer); - if (!pathRef) { - return 0; - } - - fPathRef.reset(pathRef); - SkDEBUGCODE(this->validate();) - buffer.skipToAlign4(); - return buffer.pos(); -} - -/////////////////////////////////////////////////////////////////////////////// - #include "SkString.h" #include "SkStringUtils.h" #include "SkStream.h" |