GrShape& GrShape::operator=(const GrShape& that) { bool wasPath = Type::kPath == fType; fStyle = that.fStyle; fType = that.fType; switch (fType) { case Type::kEmpty: if (wasPath) { fPath.reset(); } break; case Type::kRRect: if (wasPath) { fPath.reset(); } fRRect = that.fRRect; break; case Type::kPath: if (wasPath) { *fPath.get() = *that.fPath.get(); } else { fPath.set(*that.fPath.get()); } break; } fInheritedKey.reset(that.fInheritedKey.count()); sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count()); return *this; }
void flushAttributes() { SkASSERT(fLevel > 0); int attrCount = fAttrs.count(); SkDOM::Node* node = (SkDOM::Node*)fAlloc->alloc(sizeof(SkDOM::Node) + attrCount * sizeof(SkDOM::Attr), SkChunkAlloc::kThrow_AllocFailType); node->fName = fElemName; node->fFirstChild = nullptr; node->fAttrCount = SkToU16(attrCount); node->fType = fElemType; if (fRoot == nullptr) { node->fNextSibling = nullptr; fRoot = node; } else // this adds siblings in reverse order. gets corrected in onEndElement() { SkDOM::Node* parent = fParentStack.top(); SkASSERT(fRoot && parent); node->fNextSibling = parent->fFirstChild; parent->fFirstChild = node; } *fParentStack.push() = node; sk_careful_memcpy(node->attrs(), fAttrs.begin(), attrCount * sizeof(SkDOM::Attr)); fAttrs.reset(); }
GrShape& GrShape::operator=(const GrShape& that) { fStyle = that.fStyle; this->changeType(that.fType, Type::kPath == that.fType ? &that.path() : nullptr); switch (fType) { case Type::kEmpty: break; case Type::kInvertedEmpty: break; case Type::kRRect: fRRectData = that.fRRectData; break; case Type::kArc: fArcData = that.fArcData; break; case Type::kLine: fLineData = that.fLineData; break; case Type::kPath: fPathData.fGenID = that.fPathData.fGenID; break; } fInheritedKey.reset(that.fInheritedKey.count()); sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count()); if (that.fInheritedPathForListeners.isValid()) { fInheritedPathForListeners.set(*that.fInheritedPathForListeners.get()); } else { fInheritedPathForListeners.reset(); } return *this; }
// Writes the path data key into the passed pointer. static void write_path_key_from_data(const SkPath& path, uint32_t* origKey) { uint32_t* key = origKey; // The check below should take care of negative values casted positive. const int verbCnt = path.countVerbs(); const int pointCnt = path.countPoints(); const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path); SkASSERT(verbCnt <= GrShape::kMaxKeyFromDataVerbCnt); SkASSERT(pointCnt && verbCnt); *key++ = path.getFillType(); *key++ = verbCnt; memcpy(key, SkPathPriv::VerbData(path), verbCnt * sizeof(uint8_t)); int verbKeySize = SkAlign4(verbCnt); // pad out to uint32_t alignment using value that will stand out when debugging. uint8_t* pad = reinterpret_cast<uint8_t*>(key)+ verbCnt; memset(pad, 0xDE, verbKeySize - verbCnt); key += verbKeySize >> 2; memcpy(key, SkPathPriv::PointData(path), sizeof(SkPoint) * pointCnt); GR_STATIC_ASSERT(sizeof(SkPoint) == 2 * sizeof(uint32_t)); key += 2 * pointCnt; sk_careful_memcpy(key, SkPathPriv::ConicWeightData(path), sizeof(SkScalar) * conicWeightCnt); GR_STATIC_ASSERT(sizeof(SkScalar) == sizeof(uint32_t)); SkDEBUGCODE(key += conicWeightCnt); SkASSERT(key - origKey == path_key_from_data_size(path)); }
Request(const char* name, size_t nameLen, const SkFontStyle& style) : fStyle(style) { /** Pointer to just after the last field of this class. */ char* content = const_cast<char*>(SkTAfter<const char>(&this->fStyle)); // No holes. SkASSERT(SkTAddOffset<char>(this, sizeof(SkResourceCache::Key) + keySize) == content); // Has a size divisible by size of uint32_t. SkASSERT((content - reinterpret_cast<char*>(this)) % sizeof(uint32_t) == 0); size_t contentLen = SkAlign4(nameLen); sk_careful_memcpy(content, name, nameLen); sk_bzero(content + nameLen, contentLen - nameLen); this->init(nullptr, 0, keySize + contentLen); }
// Sort of like makeSpace(0) but the the additional requirement that we actively shrink the // allocations to just fit the current needs. makeSpace() will only grow, but never shrinks. // void SkPath::shrinkToFit() { const size_t kMinFreeSpaceForShrink = 8; // just made up a small number if (fPathRef->fFreeSpace <= kMinFreeSpaceForShrink) { return; } if (fPathRef->unique()) { int pointCount = fPathRef->fPointCnt; int verbCount = fPathRef->fVerbCnt; size_t ptsSize = sizeof(SkPoint) * pointCount; size_t vrbSize = sizeof(uint8_t) * verbCount; size_t minSize = ptsSize + vrbSize; void* newAlloc = sk_malloc_canfail(minSize); if (!newAlloc) { return; // couldn't allocate the smaller buffer, but that's ok } sk_careful_memcpy(newAlloc, fPathRef->fPoints, ptsSize); sk_careful_memcpy((char*)newAlloc + minSize - vrbSize, fPathRef->verbsMemBegin(), vrbSize); sk_free(fPathRef->fPoints); fPathRef->fPoints = static_cast<SkPoint*>(newAlloc); fPathRef->fVerbs = (uint8_t*)newAlloc + minSize; fPathRef->fFreeSpace = 0; fPathRef->fConicWeights.shrinkToFit(); } else { sk_sp<SkPathRef> pr(new SkPathRef); pr->copy(*fPathRef, 0, 0); fPathRef = std::move(pr); } SkDEBUGCODE(fPathRef->validate();) }
static void copy_v(void* dst, const S* src, int n, Rest&&... rest) { SkASSERTF(((uintptr_t)dst & (alignof(S)-1)) == 0, "Expected %p to be aligned for at least %zu bytes.", dst, alignof(S)); sk_careful_memcpy(dst, src, n*sizeof(S)); copy_v(SkTAddOffset<void>(dst, n*sizeof(S)), std::forward<Rest>(rest)...); }