void SkWriteMatrix(SkWriter32* writer, const SkMatrix& matrix) { size_t size = matrix.flatten(NULL); SkASSERT(SkAlign4(size) == size); matrix.flatten(writer->reserve(size)); }
SkChunkAlloc::SkChunkAlloc(size_t minSize) : fBlock(NULL), fMinSize(SkAlign4(minSize)), fPool(NULL), fTotalCapacity(0) { }
void SkReadMatrix(SkReader32* reader, SkMatrix* matrix) { size_t size = matrix->unflatten(reader->peek()); SkASSERT(SkAlign4(size) == size); (void)reader->skip(size); }
void SkScalerContext::getImage(const SkGlyph& origGlyph) { const SkGlyph* glyph = &origGlyph; SkGlyph tmpGlyph; // in case we need to call generateImage on a mask-format that is different // (i.e. larger) than what our caller allocated by looking at origGlyph. SkAutoMalloc tmpGlyphImageStorage; // If we are going to draw-from-path, then we cannot generate color, since // the path only makes a mask. This case should have been caught up in // generateMetrics(). SkASSERT(!fGenerateImageFromPath || SkMask::kARGB32_Format != origGlyph.fMaskFormat); if (fMaskFilter) { // restore the prefilter bounds tmpGlyph.initGlyphIdFrom(origGlyph); // need the original bounds, sans our maskfilter SkMaskFilter* mf = fMaskFilter; fMaskFilter = nullptr; // temp disable this->getMetrics(&tmpGlyph); fMaskFilter = mf; // restore // we need the prefilter bounds to be <= filter bounds SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth); SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight); if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) { tmpGlyph.fImage = origGlyph.fImage; } else { tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize()); tmpGlyph.fImage = tmpGlyphImageStorage.get(); } glyph = &tmpGlyph; } if (fGenerateImageFromPath) { SkPath devPath, fillPath; SkMatrix fillToDevMatrix; SkMask mask; this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); glyph->toMask(&mask); if (fRasterizer) { mask.fFormat = SkMask::kA8_Format; sk_bzero(glyph->fImage, mask.computeImageSize()); if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, nullptr, fMaskFilter, &mask, SkMask::kJustRenderImage_CreateMode)) { return; } if (fPreBlend.isApplicable()) { applyLUTToA8Mask(mask, fPreBlend.fG); } } else { SkASSERT(SkMask::kARGB32_Format != mask.fFormat); generateMask(mask, devPath, fPreBlend); } } else { generateImage(*glyph); } if (fMaskFilter) { SkMask srcM, dstM; SkMatrix matrix; // the src glyph image shouldn't be 3D SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat); SkAutoSMalloc<32*32> a8storage; glyph->toMask(&srcM); if (SkMask::kARGB32_Format == srcM.fFormat) { // now we need to extract the alpha-channel from the glyph's image // and copy it into a temp buffer, and then point srcM at that temp. srcM.fFormat = SkMask::kA8_Format; srcM.fRowBytes = SkAlign4(srcM.fBounds.width()); size_t size = srcM.computeImageSize(); a8storage.reset(size); srcM.fImage = (uint8_t*)a8storage.get(); extract_alpha(srcM, (const SkPMColor*)glyph->fImage, glyph->rowBytes()); } fRec.getMatrixFrom2x2(&matrix); if (fMaskFilter->filterMask(&dstM, srcM, matrix, nullptr)) { int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width()); int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height()); int dstRB = origGlyph.rowBytes(); int srcRB = dstM.fRowBytes; const uint8_t* src = (const uint8_t*)dstM.fImage; uint8_t* dst = (uint8_t*)origGlyph.fImage; if (SkMask::k3D_Format == dstM.fFormat) { // we have to copy 3 times as much height *= 3; } // clean out our glyph, since it may be larger than dstM //sk_bzero(dst, height * dstRB); while (--height >= 0) { memcpy(dst, src, width); src += srcRB; dst += dstRB; } SkMask::FreeImage(dstM.fImage); if (fPreBlendForFilter.isApplicable()) { applyLUTToA8Mask(srcM, fPreBlendForFilter.fG); } } } }
/** We explicitly use this allocator for SkBimap pixels, so that we can freely assign memory allocated by one class to the other. */ uint8_t* SkMask::AllocImage(size_t size) { return (uint8_t*)sk_malloc_throw(SkAlign4(size)); }
int32_t SkReadBuffer::read32() { return fReader.readInt(); } void SkReadBuffer::readString(SkString* string) { size_t len; const char* strContents = fReader.readString(&len); string->set(strContents, len); } void* SkReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncoding encoding) { SkDEBUGCODE(int32_t encodingType = ) fReader.readInt(); SkASSERT(encodingType == encoding); *length = fReader.readInt(); void* data = sk_malloc_throw(*length); memcpy(data, fReader.skip(SkAlign4(*length)), *length); return data; } void SkReadBuffer::readPoint(SkPoint* point) { point->fX = fReader.readScalar(); point->fY = fReader.readScalar(); } void SkReadBuffer::readMatrix(SkMatrix* matrix) { fReader.readMatrix(matrix); } void SkReadBuffer::readIRect(SkIRect* rect) { memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect)); }
uint32_t SkOrderedReadBuffer::readByteArray(void* value) { const uint32_t length = fReader.readU32(); memcpy(value, fReader.skip(SkAlign4(length)), length); return length; }
void SkValidatingReadBuffer::setMemory(const void* data, size_t size) { this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size)); if (!fError) { fReader.setMemory(data, size); } }
fHead = fTail = block = Block::Create(SkMax32(size, fMinSize)); } else if (block->available() < size) { fTail = Block::Create(SkMax32(size, fMinSize)); block->fNext = fTail; block = fTail; } fSize += size; return block->alloc(size); } uint32_t* SkWriter32::peek32(size_t offset) { SkDEBUGCODE(this->validate();) SkASSERT(SkAlign4(offset) == offset); SkASSERT(offset <= fSize); if (fSingleBlock) { return (uint32_t*)(fSingleBlock + offset); } Block* block = fHead; SkASSERT(NULL != block); while (offset >= block->fAllocatedSoFar) { offset -= block->fAllocatedSoFar; block = block->fNext; SkASSERT(NULL != block); } return block->peek32(offset);
template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) { SkASSERT(count >= 0); size_t size = SkAlign4(sizeof(T) * count); return reinterpret_cast<const T*>(reader->skip(size)); }
bool make_ringed_bitmap(TestPixels* result, int width, int height, SkColorType ct, SkAlphaType at, PIXEL_TYPE outerRingColor, PIXEL_TYPE innerRingColor, PIXEL_TYPE checkColor1, PIXEL_TYPE checkColor2) { SkASSERT(0 == width % 2 && 0 == height % 2); SkASSERT(width >= 6 && height >= 6); result->fType = TestPixels::kBitmap; SkImageInfo info = SkImageInfo::Make(width, height, ct, at); size_t rowBytes = SkAlign4(info.minRowBytes()); result->fBitmap.allocPixels(info, rowBytes); PIXEL_TYPE* scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, 0); for (int x = 0; x < width; ++x) { scanline[x] = outerRingColor; } scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, 1); scanline[0] = outerRingColor; for (int x = 1; x < width - 1; ++x) { scanline[x] = innerRingColor; } scanline[width - 1] = outerRingColor; for (int y = 2; y < height / 2; ++y) { scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, y); scanline[0] = outerRingColor; scanline[1] = innerRingColor; for (int x = 2; x < width / 2; ++x) { scanline[x] = checkColor1; } for (int x = width / 2; x < width - 2; ++x) { scanline[x] = checkColor2; } scanline[width - 2] = innerRingColor; scanline[width - 1] = outerRingColor; } for (int y = height / 2; y < height - 2; ++y) { scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, y); scanline[0] = outerRingColor; scanline[1] = innerRingColor; for (int x = 2; x < width / 2; ++x) { scanline[x] = checkColor2; } for (int x = width / 2; x < width - 2; ++x) { scanline[x] = checkColor1; } scanline[width - 2] = innerRingColor; scanline[width - 1] = outerRingColor; } scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, height - 2); scanline[0] = outerRingColor; for (int x = 1; x < width - 1; ++x) { scanline[x] = innerRingColor; } scanline[width - 1] = outerRingColor; scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, height - 1); for (int x = 0; x < width; ++x) { scanline[x] = outerRingColor; } result->fBitmap.setImmutable(); result->fRect.set(2, 2, width - 2, height - 2); return true; }
uint32_t SkOrderedReadBuffer::readScalarArray(SkScalar* values) { const uint32_t count = fReader.readU32(); const uint32_t byteLength = count * sizeof(SkScalar); memcpy(values, fReader.skip(SkAlign4(byteLength)), byteLength); return count; }
uint32_t SkOrderedReadBuffer::readPointArray(SkPoint* points) { const uint32_t count = fReader.readU32(); const uint32_t byteLength = count * sizeof(SkPoint); memcpy(points, fReader.skip(SkAlign4(byteLength)), byteLength); return count; }
uint32_t SkOrderedReadBuffer::readColorArray(SkColor* colors) { const uint32_t count = fReader.readU32(); const uint32_t byteLength = count * sizeof(SkColor); memcpy(colors, fReader.skip(SkAlign4(byteLength)), byteLength); return count; }
void SkReadRegion(SkReader32* reader, SkRegion* rgn) { size_t size = rgn->unflatten(reader->peek()); SkASSERT(SkAlign4(size) == size); (void)reader->skip(size); }
void addTypeface() { size_t size = fReader->read32(); const void* data = fReader->skip(SkAlign4(size)); SkMemoryStream stream(data, size, false); *fTypefaces.append() = SkTypeface::Deserialize(&stream); }
void SkWriteRegion(SkWriter32* writer, const SkRegion& rgn) { size_t size = rgn.flatten(NULL); SkASSERT(SkAlign4(size) == size); rgn.flatten(writer->reserve(size)); }
static Request* Create(const char* name, const SkFontStyle& style) { size_t nameLen = name ? strlen(name) : 0; size_t contentLen = SkAlign4(nameLen); char* storage = new char[sizeof(Request) + contentLen]; return new (storage) Request(name, nameLen, style); }
void SkPictureRecord::onDrawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[], const SkColor colors[], SkXfermode* xfer, const uint16_t indices[], int indexCount, const SkPaint& paint) { uint32_t flags = 0; if (texs) { flags |= DRAW_VERTICES_HAS_TEXS; } if (colors) { flags |= DRAW_VERTICES_HAS_COLORS; } if (indexCount > 0) { flags |= DRAW_VERTICES_HAS_INDICES; } if (xfer) { SkXfermode::Mode mode; if (xfer->asMode(&mode) && SkXfermode::kModulate_Mode != mode) { flags |= DRAW_VERTICES_HAS_XFER; } } // op + paint index + flags + vmode + vCount + vertices size_t size = 5 * kUInt32Size + vertexCount * sizeof(SkPoint); if (flags & DRAW_VERTICES_HAS_TEXS) { size += vertexCount * sizeof(SkPoint); // + uvs } if (flags & DRAW_VERTICES_HAS_COLORS) { size += vertexCount * sizeof(SkColor); // + vert colors } if (flags & DRAW_VERTICES_HAS_INDICES) { // + num indices + indices size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); } if (flags & DRAW_VERTICES_HAS_XFER) { size += kUInt32Size; // mode enum } size_t initialOffset = this->addDraw(DRAW_VERTICES, &size); SkASSERT(initialOffset+get_paint_offset(DRAW_VERTICES, size) == fWriter.bytesWritten()); this->addPaint(paint); this->addInt(flags); this->addInt(vmode); this->addInt(vertexCount); this->addPoints(vertices, vertexCount); if (flags & DRAW_VERTICES_HAS_TEXS) { this->addPoints(texs, vertexCount); } if (flags & DRAW_VERTICES_HAS_COLORS) { fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); } if (flags & DRAW_VERTICES_HAS_INDICES) { this->addInt(indexCount); fWriter.writePad(indices, indexCount * sizeof(uint16_t)); } if (flags & DRAW_VERTICES_HAS_XFER) { SkXfermode::Mode mode = SkXfermode::kModulate_Mode; (void)xfer->asMode(&mode); this->addInt(mode); } this->validate(initialOffset, size); }
template <typename T> const T* skip(SkReader32* reader, size_t count = 1) { size_t size = sizeof(T) * count; SkASSERT(SkAlign4(size) == size); return reinterpret_cast<const T*>(reader->skip(size)); }