本文整理汇总了C++中SkIRect类的典型用法代码示例。如果您正苦于以下问题:C++ SkIRect类的具体用法?C++ SkIRect怎么用?C++ SkIRect使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SkIRect类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SkRect
void FindCanvas::findHelper(const void* text, size_t byteLength,
const SkPaint& paint, const SkScalar positions[],
SkScalar y,
SkRect (FindCanvas::*addMatch)(int index,
const SkPaint& paint, int count,
const uint16_t* glyphs,
const SkScalar positions[], SkScalar y)) {
//SkASSERT(paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
SkASSERT(mMatches);
GlyphSet* glyphSet = getGlyphs(paint);
const int count = glyphSet->getCount();
int numCharacters = byteLength >> 1;
const uint16_t* chars = (const uint16_t*) text;
// This block will check to see if we are continuing from another line. If
// so, the user needs to have added a space, which we do not draw.
if (mWorkingIndex) {
SkPoint newY;
getTotalMatrix().mapXY(0, y, &newY);
SkIRect workingBounds = mWorkingRegion.getBounds();
int newYInt = SkScalarRound(newY.fY);
if (workingBounds.fTop > newYInt) {
// The new text is above the working region, so we know it's not
// a continuation.
resetWorkingCanvas();
mWorkingIndex = 0;
mWorkingRegion.setEmpty();
} else if (workingBounds.fBottom < newYInt) {
// Now we know that this line is lower than our partial match.
SkPaint clonePaint(paint);
clonePaint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
uint16_t space;
clonePaint.textToGlyphs(" ", 1, &space);
if (glyphSet->characterMatches(space, mWorkingIndex)) {
mWorkingIndex++;
if (mWorkingIndex == count) {
// We already know that it is not clipped out because we
// checked for that before saving the working region.
insertMatchInfo(mWorkingRegion);
resetWorkingCanvas();
mWorkingIndex = 0;
mWorkingRegion.setEmpty();
// We have found a match, so continue on this line from
// scratch.
}
} else {
resetWorkingCanvas();
mWorkingIndex = 0;
mWorkingRegion.setEmpty();
}
}
// If neither one is true, then we are likely continuing on the same
// line, but are in a new draw call because the paint has changed. In
// this case, we can continue without adding a space.
}
// j is the position in the search text
// Start off with mWorkingIndex in case we are continuing from a prior call
int j = mWorkingIndex;
// index is the position in the drawn text
int index = 0;
for ( ; index != numCharacters; index++) {
if (glyphSet->characterMatches(chars[index], j)) {
// The jth character in the search text matches the indexth position
// in the drawn text, so increase j.
j++;
if (j != count) {
continue;
}
// The last count characters match, so we found the entire
// search string.
int remaining = count - mWorkingIndex;
int matchIndex = index - remaining + 1;
// Set up a pointer to the matching text in 'chars'.
const uint16_t* glyphs = chars + matchIndex;
SkRect rect = (this->*addMatch)(matchIndex, paint,
remaining, glyphs, positions, y);
// We need an SkIRect for SkRegion operations.
SkIRect iRect;
rect.roundOut(&iRect);
// If the rectangle is partially clipped, assume that the text is
// not visible, so skip this match.
if (getTotalClip().contains(iRect)) {
// Want to outset the drawn rectangle by the same amount as
// mOutset
iRect.inset(-INTEGER_OUTSET, -INTEGER_OUTSET);
SkRegion regionToAdd(iRect);
if (!mWorkingRegion.isEmpty()) {
// If this is on the same line as our working region, make
// sure that they are close enough together that they are
// supposed to be part of the same text string.
// The width of two spaces has arbitrarily been chosen.
const SkIRect& workingBounds = mWorkingRegion.getBounds();
if (workingBounds.fTop <= iRect.fBottom &&
workingBounds.fBottom >= iRect.fTop &&
SkIntToScalar(iRect.fLeft - workingBounds.fRight) >
approximateSpaceWidth(paint)) {
index = -1; // Will increase to 0 on next run
// In this case, we need to start from the beginning of
// the text being searched and our search term.
j = 0;
//.........这里部分代码省略.........
示例2: offset_center_to
static SkRect offset_center_to(const SkIRect& src, SkScalar x, SkScalar y) {
SkScalar halfW = 0.5f * src.width();
SkScalar halfH = 0.5f * src.height();
return SkRect::MakeLTRB(x - halfW, y - halfH, x + halfW, y + halfH);
}
示例3: FindLayersToAtlas
// Atlased layers must be small enough to fit in the atlas, not have a
// paint with an image filter and be neither nested nor nesting.
// TODO: allow leaf nested layers to appear in the atlas.
void GrLayerHoister::FindLayersToAtlas(GrContext* context,
const SkPicture* topLevelPicture,
const SkMatrix& initialMat,
const SkRect& query,
SkTDArray<GrHoistedLayer>* atlased,
SkTDArray<GrHoistedLayer>* recycled,
int numSamples) {
if (0 != numSamples) {
// MSAA layers are currently never atlased
return;
}
GrLayerCache* layerCache = context->getLayerCache();
layerCache->processDeletedPictures();
const SkBigPicture::AccelData* topLevelData = nullptr;
if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
topLevelData = bp->accelData();
}
if (!topLevelData) {
return;
}
const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
if (0 == topLevelGPUData->numBlocks()) {
return;
}
atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks());
for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
// TODO: ignore perspective projected layers here?
bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested ||
(info.fPaint && info.fPaint->getImageFilter());
if (disallowAtlasing) {
continue;
}
SkRect layerRect;
initialMat.mapRect(&layerRect, info.fBounds);
if (!layerRect.intersect(query)) {
continue;
}
const SkIRect dstIR = layerRect.roundOut();
SkIRect srcIR;
if (!compute_source_rect(info, initialMat, dstIR, &srcIR) ||
!GrLayerCache::PlausiblyAtlasable(srcIR.width(), srcIR.height())) {
continue;
}
prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
info, srcIR, dstIR, atlased, recycled, true, 0);
}
}
示例4: unpremultiply_bitmap
static SkBitmap unpremultiply_bitmap(const SkBitmap& bitmap,
const SkIRect& srcRect) {
SkBitmap outBitmap;
outBitmap.allocPixels(bitmap.info().makeWH(srcRect.width(), srcRect.height()));
int dstRow = 0;
SkAutoLockPixels outBitmapPixelLock(outBitmap);
SkAutoLockPixels bitmapPixelLock(bitmap);
switch (bitmap.colorType()) {
case kARGB_4444_SkColorType: {
for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
uint16_t* dst = outBitmap.getAddr16(0, dstRow);
uint16_t* src = bitmap.getAddr16(0, y);
for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
uint8_t a = SkGetPackedA4444(src[x]);
// It is necessary to average the color component of
// transparent pixels with their surrounding neighbors
// since the PDF renderer may separately re-sample the
// alpha and color channels when the image is not
// displayed at its native resolution. Since an alpha of
// zero gives no information about the color component,
// the pathological case is a white image with sharp
// transparency bounds - the color channel goes to black,
// and the should-be-transparent pixels are rendered
// as grey because of the separate soft mask and color
// resizing.
if (a == (SK_AlphaTRANSPARENT & 0x0F)) {
*dst = get_argb4444_neighbor_avg_color(bitmap, x, y);
} else {
*dst = remove_alpha_argb4444(src[x]);
}
dst++;
}
dstRow++;
}
break;
}
case kN32_SkColorType: {
for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
uint32_t* dst = outBitmap.getAddr32(0, dstRow);
uint32_t* src = bitmap.getAddr32(0, y);
for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
uint8_t a = SkGetPackedA32(src[x]);
if (a == SK_AlphaTRANSPARENT) {
*dst = get_argb8888_neighbor_avg_color(bitmap, x, y);
} else {
*dst = remove_alpha_argb8888(src[x]);
}
dst++;
}
dstRow++;
}
break;
}
default:
SkASSERT(false);
}
outBitmap.setImmutable();
return outBitmap;
}
示例5: draw_nine_clipped
static void draw_nine_clipped(const SkMask& mask, const SkIRect& outerR,
const SkIPoint& center, bool fillCenter,
const SkIRect& clipR, SkBlitter* blitter) {
int cx = center.x();
int cy = center.y();
SkMask m;
// top-left
m.fBounds = mask.fBounds;
m.fBounds.fRight = cx;
m.fBounds.fBottom = cy;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.left(), outerR.top());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
// top-right
m.fBounds = mask.fBounds;
m.fBounds.fLeft = cx + 1;
m.fBounds.fBottom = cy;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.right() - m.fBounds.width(), outerR.top());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
// bottom-left
m.fBounds = mask.fBounds;
m.fBounds.fRight = cx;
m.fBounds.fTop = cy + 1;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.left(), outerR.bottom() - m.fBounds.height());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
// bottom-right
m.fBounds = mask.fBounds;
m.fBounds.fLeft = cx + 1;
m.fBounds.fTop = cy + 1;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.right() - m.fBounds.width(),
outerR.bottom() - m.fBounds.height());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
SkIRect innerR;
innerR.set(outerR.left() + cx - mask.fBounds.left(),
outerR.top() + cy - mask.fBounds.top(),
outerR.right() + (cx + 1 - mask.fBounds.right()),
outerR.bottom() + (cy + 1 - mask.fBounds.bottom()));
if (fillCenter) {
blitClippedRect(blitter, innerR, clipR);
}
const int innerW = innerR.width();
size_t storageSize = (innerW + 1) * (sizeof(int16_t) + sizeof(uint8_t));
SkAutoSMalloc<4*1024> storage(storageSize);
int16_t* runs = (int16_t*)storage.get();
uint8_t* alpha = (uint8_t*)(runs + innerW + 1);
SkIRect r;
// top
r.set(innerR.left(), outerR.top(), innerR.right(), innerR.top());
if (r.intersect(clipR)) {
int startY = SkMax32(0, r.top() - outerR.top());
int stopY = startY + r.height();
int width = r.width();
for (int y = startY; y < stopY; ++y) {
runs[0] = width;
runs[width] = 0;
alpha[0] = *mask.getAddr8(cx, mask.fBounds.top() + y);
blitter->blitAntiH(r.left(), outerR.top() + y, alpha, runs);
}
}
// bottom
r.set(innerR.left(), innerR.bottom(), innerR.right(), outerR.bottom());
if (r.intersect(clipR)) {
int startY = outerR.bottom() - r.bottom();
int stopY = startY + r.height();
int width = r.width();
for (int y = startY; y < stopY; ++y) {
runs[0] = width;
runs[width] = 0;
alpha[0] = *mask.getAddr8(cx, mask.fBounds.bottom() - y - 1);
blitter->blitAntiH(r.left(), outerR.bottom() - y - 1, alpha, runs);
}
}
// left
r.set(outerR.left(), innerR.top(), innerR.left(), innerR.bottom());
if (r.intersect(clipR)) {
int startX = r.left() - outerR.left();
int stopX = startX + r.width();
int height = r.height();
for (int x = startX; x < stopX; ++x) {
blitter->blitV(outerR.left() + x, r.top(), height,
*mask.getAddr8(mask.fBounds.left() + x, mask.fBounds.top() + cy));
}
//.........这里部分代码省略.........
示例6:
IntRect::IntRect(const SkIRect& r)
: m_location(r.fLeft, r.fTop)
, m_size(r.width(), r.height())
{
}
示例7: SkASSERT
void GrVkGpuCommandBuffer::onClear(GrRenderTarget* target, const GrFixedClip& clip, GrColor color) {
// parent class should never let us get here with no RT
SkASSERT(target);
SkASSERT(!clip.hasWindowRectangles());
VkClearColorValue vkColor;
GrColorToRGBAFloat(color, vkColor.float32);
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
if (fIsEmpty && !clip.scissorEnabled()) {
// We will change the render pass to do a clear load instead
GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
VK_ATTACHMENT_STORE_OP_STORE);
GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE);
const GrVkRenderPass* oldRP = fRenderPass;
const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
vkRT->compatibleRenderPassHandle();
if (rpHandle.isValid()) {
fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps,
vkStencilOps);
} else {
fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
vkColorOps,
vkStencilOps);
}
SkASSERT(fRenderPass->isCompatible(*oldRP));
oldRP->unref(fGpu);
GrColorToRGBAFloat(color, fColorClearValue.color.float32);
fStartsWithClear = true;
return;
}
// We always do a sub rect clear with clearAttachments since we are inside a render pass
VkClearRect clearRect;
// Flip rect if necessary
SkIRect vkRect;
if (!clip.scissorEnabled()) {
vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height());
} else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) {
vkRect = clip.scissorRect();
} else {
const SkIRect& scissor = clip.scissorRect();
vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom,
scissor.fRight, vkRT->height() - scissor.fTop);
}
clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
clearRect.baseArrayLayer = 0;
clearRect.layerCount = 1;
uint32_t colorIndex;
SkAssertResult(fRenderPass->colorAttachmentIndex(&colorIndex));
VkClearAttachment attachment;
attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
attachment.colorAttachment = colorIndex;
attachment.clearValue.color = vkColor;
fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
fIsEmpty = false;
return;
}
示例8: fState
//.........这里部分代码省略.........
SkPaint paint;
SkRect rect;
rect = SkRect::MakeLTRB(deviceBounds.left(), deviceBounds.top(), 0, 0);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(0, 0));
canvas.drawRect(rect, paint);
}
rect = SkRect::MakeLTRB(width, deviceBounds.top(),
deviceBounds.right(), 0);
if (!rect.isEmpty()) {
paint.setColor(image->getColor(image->width() - 1, 0));
canvas.drawRect(rect, paint);
}
rect = SkRect::MakeLTRB(width, height,
deviceBounds.right(), deviceBounds.bottom());
if (!rect.isEmpty()) {
paint.setColor(image->getColor(image->width() - 1,
image->height() - 1));
canvas.drawRect(rect, paint);
}
rect = SkRect::MakeLTRB(deviceBounds.left(), height,
0, deviceBounds.bottom());
if (!rect.isEmpty()) {
paint.setColor(image->getColor(0, image->height() - 1));
canvas.drawRect(rect, paint);
}
}
// Then expand the left, right, top, then bottom.
if (tileModes[0] == SkShader::kClamp_TileMode) {
SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, image->height());
if (deviceBounds.left() < 0) {
SkBitmap left;
SkAssertResult(image->extractSubset(&left, subset));
SkMatrix leftMatrix;
leftMatrix.setScale(-deviceBounds.left(), 1);
leftMatrix.postTranslate(deviceBounds.left(), 0);
canvas.drawBitmapMatrix(left, leftMatrix);
if (tileModes[1] == SkShader::kMirror_TileMode) {
leftMatrix.postScale(SK_Scalar1, -SK_Scalar1);
leftMatrix.postTranslate(0, 2 * height);
canvas.drawBitmapMatrix(left, leftMatrix);
}
patternBBox.fLeft = 0;
}
if (deviceBounds.right() > width) {
SkBitmap right;
subset.offset(image->width() - 1, 0);
SkAssertResult(image->extractSubset(&right, subset));
SkMatrix rightMatrix;
rightMatrix.setScale(deviceBounds.right() - width, 1);
rightMatrix.postTranslate(width, 0);
canvas.drawBitmapMatrix(right, rightMatrix);
if (tileModes[1] == SkShader::kMirror_TileMode) {
rightMatrix.postScale(SK_Scalar1, -SK_Scalar1);
rightMatrix.postTranslate(0, 2 * height);
canvas.drawBitmapMatrix(right, rightMatrix);
}
示例9: setupDstReadIfNecessary
bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
GrXferProcessor::DstTexture* dstTexture,
const SkRect* drawBounds) {
if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), colorPOI, coveragePOI)) {
return true;
}
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
if (this->caps()->textureBarrierSupport()) {
if (GrTexture* rtTex = rt->asTexture()) {
// The render target is a texture, so we can read from it directly in the shader. The XP
// will be responsible to detect this situation and request a texture barrier.
dstTexture->setTexture(rtTex);
dstTexture->setOffset(0, 0);
return true;
}
}
SkIRect copyRect;
pipelineBuilder.clip().getConservativeBounds(rt, ©Rect);
if (drawBounds) {
SkIRect drawIBounds;
drawBounds->roundOut(&drawIBounds);
if (!copyRect.intersect(drawIBounds)) {
#ifdef SK_DEBUG
GrCapsDebugf(fCaps, "Missed an early reject. "
"Bailing on draw from setupDstReadIfNecessary.\n");
#endif
return false;
}
} else {
#ifdef SK_DEBUG
//SkDebugf("No dev bounds when dst copy is made.\n");
#endif
}
// MSAA consideration: When there is support for reading MSAA samples in the shader we could
// have per-sample dst values by making the copy multisampled.
GrSurfaceDesc desc;
if (!this->getGpu()->initCopySurfaceDstDesc(rt, &desc)) {
desc.fOrigin = kDefault_GrSurfaceOrigin;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = rt->config();
}
desc.fWidth = copyRect.width();
desc.fHeight = copyRect.height();
SkAutoTUnref<GrTexture> copy(
fResourceProvider->refScratchTexture(desc, GrTextureProvider::kApprox_ScratchTexMatch));
if (!copy) {
SkDebugf("Failed to create temporary copy of destination texture.\n");
return false;
}
SkIPoint dstPoint = {0, 0};
this->copySurface(copy, rt, copyRect, dstPoint);
dstTexture->setTexture(copy);
dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
return true;
}
示例10: init
bool GrSWMaskHelper::init(const SkIRect& resultBounds,
const SkMatrix* matrix,
bool allowCompression) {
if (matrix) {
fMatrix = *matrix;
} else {
fMatrix.setIdentity();
}
// Now translate so the bound's UL corner is at the origin
fMatrix.postTranslate(-resultBounds.fLeft * SK_Scalar1,
-resultBounds.fTop * SK_Scalar1);
SkIRect bounds = SkIRect::MakeWH(resultBounds.width(),
resultBounds.height());
if (allowCompression &&
fContext->caps()->drawPathMasksToCompressedTexturesSupport() &&
choose_compressed_fmt(fContext->caps(), &fCompressedFormat)) {
fCompressionMode = kCompress_CompressionMode;
}
// Make sure that the width is a multiple of the desired block dimensions
// to allow for specialized SIMD instructions that compress multiple blocks at a time.
int cmpWidth = bounds.fRight;
int cmpHeight = bounds.fBottom;
if (kCompress_CompressionMode == fCompressionMode) {
int dimX, dimY;
SkTextureCompressor::GetBlockDimensions(fCompressedFormat, &dimX, &dimY);
cmpWidth = dimX * ((cmpWidth + (dimX - 1)) / dimX);
cmpHeight = dimY * ((cmpHeight + (dimY - 1)) / dimY);
// Can we create a blitter?
if (SkTextureCompressor::ExistsBlitterForFormat(fCompressedFormat)) {
int cmpSz = SkTextureCompressor::GetCompressedDataSize(
fCompressedFormat, cmpWidth, cmpHeight);
SkASSERT(cmpSz > 0);
SkASSERT(nullptr == fCompressedBuffer.get());
fCompressedBuffer.reset(cmpSz);
fCompressionMode = kBlitter_CompressionMode;
}
}
sk_bzero(&fDraw, sizeof(fDraw));
// If we don't have a custom blitter, then we either need a bitmap to compress
// from or a bitmap that we're going to use as a texture. In any case, we should
// allocate the pixels for a bitmap
const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(cmpWidth, cmpHeight);
if (kBlitter_CompressionMode != fCompressionMode) {
if (!fPixels.tryAlloc(bmImageInfo)) {
return false;
}
fPixels.erase(0);
} else {
// Otherwise, we just need to remember how big the buffer is...
fPixels.reset(bmImageInfo);
}
fDraw.fDst = fPixels;
fRasterClip.setRect(bounds);
fDraw.fRC = &fRasterClip;
fDraw.fClip = &fRasterClip.bwRgn();
fDraw.fMatrix = &fMatrix;
return true;
}
示例11: canvas
SkPDFShader::State::State(const SkShader& shader, const SkMatrix& canvasTransform,
const SkIRect& bbox, SkScalar rasterScale)
: fCanvasTransform(canvasTransform),
fBBox(bbox),
fPixelGeneration(0) {
fInfo.fColorCount = 0;
fInfo.fColors = NULL;
fInfo.fColorOffsets = NULL;
fShaderTransform = shader.getLocalMatrix();
fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;
fType = shader.asAGradient(&fInfo);
if (fType == SkShader::kNone_GradientType) {
SkMatrix matrix;
if (shader.isABitmap(&fImage, &matrix, fImageTileModes)) {
SkASSERT(matrix.isIdentity());
} else {
// Generic fallback for unsupported shaders:
// * allocate a bbox-sized bitmap
// * shade the whole area
// * use the result as a bitmap shader
// bbox is in device space. While that's exactly what we want for sizing our bitmap,
// we need to map it into shader space for adjustments (to match
// SkPDFImageShader::Create's behavior).
SkRect shaderRect = SkRect::Make(bbox);
if (!inverse_transform_bbox(canvasTransform, &shaderRect)) {
fImage.reset();
return;
}
// Clamp the bitmap size to about 1M pixels
static const SkScalar kMaxBitmapArea = 1024 * 1024;
SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbox.height();
if (bitmapArea > kMaxBitmapArea) {
rasterScale *= SkScalarSqrt(kMaxBitmapArea / bitmapArea);
}
SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.width()),
SkScalarRoundToInt(rasterScale * bbox.height()));
SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / shaderRect.width(),
SkIntToScalar(size.height()) / shaderRect.height());
fImage.allocN32Pixels(size.width(), size.height());
fImage.eraseColor(SK_ColorTRANSPARENT);
SkPaint p;
p.setShader(const_cast<SkShader*>(&shader));
SkCanvas canvas(fImage);
canvas.scale(scale.width(), scale.height());
canvas.translate(-shaderRect.x(), -shaderRect.y());
canvas.drawPaint(p);
fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
}
fPixelGeneration = fImage.getGenerationID();
} else {
AllocateGradientInfoStorage();
shader.asAGradient(&fInfo);
}
}
示例12: build_base_rgn
void build_base_rgn(SkRegion* rgn) {
rgn->setRect(fBase);
SkIRect r = fBase;
r.offset(75, 20);
rgn->op(r, SkRegion::kUnion_Op);
}
示例13: alp
bool SkBicubicImageFilter::onFilterImage(Proxy* proxy,
const SkBitmap& source,
const SkMatrix& matrix,
SkBitmap* result,
SkIPoint* loc) {
SkBitmap src = source;
if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, loc)) {
return false;
}
if (src.config() != SkBitmap::kARGB_8888_Config) {
return false;
}
SkAutoLockPixels alp(src);
if (!src.getPixels()) {
return false;
}
SkRect dstRect = SkRect::MakeWH(SkScalarMul(SkIntToScalar(src.width()), fScale.fWidth),
SkScalarMul(SkIntToScalar(src.height()), fScale.fHeight));
SkIRect dstIRect;
dstRect.roundOut(&dstIRect);
if (dstIRect.isEmpty()) {
return false;
}
result->setConfig(src.config(), dstIRect.width(), dstIRect.height());
result->allocPixels();
if (!result->getPixels()) {
return false;
}
SkRect srcRect;
src.getBounds(&srcRect);
SkMatrix inverse;
inverse.setRectToRect(dstRect, srcRect, SkMatrix::kFill_ScaleToFit);
inverse.postTranslate(SkFloatToScalar(-0.5f), SkFloatToScalar(-0.5f));
for (int y = dstIRect.fTop; y < dstIRect.fBottom; ++y) {
SkPMColor* dptr = result->getAddr32(dstIRect.fLeft, y);
for (int x = dstIRect.fLeft; x < dstIRect.fRight; ++x) {
SkPoint srcPt, dstPt = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
inverse.mapPoints(&srcPt, &dstPt, 1);
SkScalar fractx = srcPt.fX - SkScalarFloorToScalar(srcPt.fX);
SkScalar fracty = srcPt.fY - SkScalarFloorToScalar(srcPt.fY);
int sx = SkScalarFloorToInt(srcPt.fX);
int sy = SkScalarFloorToInt(srcPt.fY);
int x0 = SkClampMax(sx - 1, src.width() - 1);
int x1 = SkClampMax(sx , src.width() - 1);
int x2 = SkClampMax(sx + 1, src.width() - 1);
int x3 = SkClampMax(sx + 2, src.width() - 1);
int y0 = SkClampMax(sy - 1, src.height() - 1);
int y1 = SkClampMax(sy , src.height() - 1);
int y2 = SkClampMax(sy + 1, src.height() - 1);
int y3 = SkClampMax(sy + 2, src.height() - 1);
SkPMColor s00 = *src.getAddr32(x0, y0);
SkPMColor s10 = *src.getAddr32(x1, y0);
SkPMColor s20 = *src.getAddr32(x2, y0);
SkPMColor s30 = *src.getAddr32(x3, y0);
SkPMColor s0 = cubicBlend(fCoefficients, fractx, s00, s10, s20, s30);
SkPMColor s01 = *src.getAddr32(x0, y1);
SkPMColor s11 = *src.getAddr32(x1, y1);
SkPMColor s21 = *src.getAddr32(x2, y1);
SkPMColor s31 = *src.getAddr32(x3, y1);
SkPMColor s1 = cubicBlend(fCoefficients, fractx, s01, s11, s21, s31);
SkPMColor s02 = *src.getAddr32(x0, y2);
SkPMColor s12 = *src.getAddr32(x1, y2);
SkPMColor s22 = *src.getAddr32(x2, y2);
SkPMColor s32 = *src.getAddr32(x3, y2);
SkPMColor s2 = cubicBlend(fCoefficients, fractx, s02, s12, s22, s32);
SkPMColor s03 = *src.getAddr32(x0, y3);
SkPMColor s13 = *src.getAddr32(x1, y3);
SkPMColor s23 = *src.getAddr32(x2, y3);
SkPMColor s33 = *src.getAddr32(x3, y3);
SkPMColor s3 = cubicBlend(fCoefficients, fractx, s03, s13, s23, s33);
*dptr++ = cubicBlend(fCoefficients, fracty, s0, s1, s2, s3);
}
}
return true;
}
示例14: autoRestore
bool CopyTilesRenderer::render(SkBitmap** out) {
int i = 0;
bool success = true;
SkBitmap dst;
for (int x = 0; x < this->getViewWidth(); x += fLargeTileWidth) {
for (int y = 0; y < this->getViewHeight(); y += fLargeTileHeight) {
SkAutoCanvasRestore autoRestore(fCanvas, true);
// Translate so that we draw the correct portion of the picture.
// Perform a postTranslate so that the scaleFactor does not interfere with the
// positioning.
SkMatrix mat(fCanvas->getTotalMatrix());
mat.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
fCanvas->setMatrix(mat);
// Draw the picture
if (fUseMultiPictureDraw) {
SkMultiPictureDraw mpd;
mpd.add(fCanvas, fPicture);
mpd.draw();
} else {
fCanvas->drawPicture(fPicture);
}
// Now extract the picture into tiles
SkBitmap baseBitmap;
fCanvas->readPixels(SkIRect::MakeSize(fCanvas->getBaseLayerSize()), &baseBitmap);
SkIRect subset;
for (int tileY = 0; tileY < fLargeTileHeight; tileY += this->getTileHeight()) {
for (int tileX = 0; tileX < fLargeTileWidth; tileX += this->getTileWidth()) {
subset.set(tileX, tileY, tileX + this->getTileWidth(),
tileY + this->getTileHeight());
SkDEBUGCODE(bool extracted =)
baseBitmap.extractSubset(&dst, subset);
SkASSERT(extracted);
if (!fWritePath.isEmpty()) {
// Similar to write() in PictureRenderer.cpp, but just encodes
// a bitmap directly.
// TODO: Share more common code with write() to do this, to properly
// write out the JSON summary, etc.
SkString pathWithNumber = SkOSPath::Join(fWritePath.c_str(),
fInputFilename.c_str());
pathWithNumber.remove(pathWithNumber.size() - 4, 4);
pathWithNumber.appendf("%i.png", i++);
SkBitmap copy;
#if SK_SUPPORT_GPU
if (isUsingGpuDevice()) {
dst.pixelRef()->readPixels(©, &subset);
} else {
#endif
dst.copyTo(©);
#if SK_SUPPORT_GPU
}
#endif
success &= SkImageEncoder::EncodeFile(pathWithNumber.c_str(), copy,
SkImageEncoder::kPNG_Type, 100);
}
}
}
}
}
return success;
}
示例15: blitClippedRect
static void blitClippedRect(SkBlitter* blitter, const SkIRect& rect, const SkIRect& clipR) {
SkIRect r;
if (r.intersect(rect, clipR)) {
blitter->blitRect(r.left(), r.top(), r.width(), r.height());
}
}