本文整理汇总了C++中SkIRect::size方法的典型用法代码示例。如果您正苦于以下问题:C++ SkIRect::size方法的具体用法?C++ SkIRect::size怎么用?C++ SkIRect::size使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkIRect
的用法示例。
在下文中一共展示了SkIRect::size方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ReadHeader
/*
* Read enough of the stream to initialize the SkGifCodec.
* Returns a bool representing success or failure.
*
* @param codecOut
* If it returned true, and codecOut was not nullptr,
* codecOut will be set to a new SkGifCodec.
*
* @param gifOut
* If it returned true, and codecOut was nullptr,
* gifOut must be non-nullptr and gifOut will be set to a new
* GifFileType pointer.
*
* @param stream
* Deleted on failure.
* codecOut will take ownership of it in the case where we created a codec.
* Ownership is unchanged when we returned a gifOut.
*
*/
bool SkGifCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, GifFileType** gifOut) {
SkAutoTDelete<SkStream> streamDeleter(stream);
// Read gif header, logical screen descriptor, and global color table
SkAutoTCallVProc<GifFileType, CloseGif> gif(open_gif(stream));
if (nullptr == gif) {
gif_error("DGifOpen failed.\n");
return false;
}
// Read through gif extensions to get to the image data. Set the
// transparent index based on the extension data.
uint32_t transIndex;
SkCodec::Result result = ReadUpToFirstImage(gif, &transIndex);
if (kSuccess != result){
return false;
}
// Read the image descriptor
if (GIF_ERROR == DGifGetImageDesc(gif)) {
return false;
}
// If reading the image descriptor is successful, the image count will be
// incremented.
SkASSERT(gif->ImageCount >= 1);
if (nullptr != codecOut) {
SkISize size;
SkIRect frameRect;
if (!GetDimensions(gif, &size, &frameRect)) {
gif_error("Invalid gif size.\n");
return false;
}
bool frameIsSubset = (size != frameRect.size());
// Determine the encoded alpha type. The transIndex might be valid if it less
// than 256. We are not certain that the index is valid until we process the color
// table, since some gifs have color tables with less than 256 colors. If
// there might be a valid transparent index, we must indicate that the image has
// alpha.
// In the case where we must support alpha, we indicate kBinary, since every
// pixel will either be fully opaque or fully transparent.
SkEncodedInfo::Alpha alpha = (transIndex < 256) ? SkEncodedInfo::kBinary_Alpha :
SkEncodedInfo::kOpaque_Alpha;
// Return the codec
// Use kPalette since Gifs are encoded with a color table.
// Use 8-bits per component, since this is the output we get from giflib.
// FIXME: Gifs can actually be encoded with 4-bits per pixel. Can we support this?
SkEncodedInfo info = SkEncodedInfo::Make(SkEncodedInfo::kPalette_Color, alpha, 8);
*codecOut = new SkGifCodec(size.width(), size.height(), info, streamDeleter.release(),
gif.release(), transIndex, frameRect, frameIsSubset);
} else {
SkASSERT(nullptr != gifOut);
streamDeleter.release();
*gifOut = gif.release();
}
return true;
}
示例2: MakeFromImage
sk_sp<SkSpecialImage> SkImageSource::onFilterImage(SkSpecialImage* source, const Context& ctx,
SkIPoint* offset) const {
SkRect dstRect;
ctx.ctm().mapRect(&dstRect, fDstRect);
SkRect bounds = SkRect::MakeIWH(fImage->width(), fImage->height());
if (fSrcRect == bounds) {
int iLeft = dstRect.fLeft;
int iTop = dstRect.fTop;
// TODO: this seems to be a very noise-prone way to determine this (esp. the floating-point
// widths & heights).
if (dstRect.width() == bounds.width() && dstRect.height() == bounds.height() &&
iLeft == dstRect.fLeft && iTop == dstRect.fTop) {
// The dest is just an un-scaled integer translation of the entire image; return it
offset->fX = iLeft;
offset->fY = iTop;
return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(fImage->width(), fImage->height()),
fImage, ctx.outputProperties().colorSpace(),
&source->props());
}
}
const SkIRect dstIRect = dstRect.roundOut();
sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), dstIRect.size()));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
// TODO: it seems like this clear shouldn't be necessary (see skbug.com/5075)
canvas->clear(0x0);
SkPaint paint;
// Subtract off the integer component of the translation (will be applied in offset, below).
dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
paint.setBlendMode(SkBlendMode::kSrc);
// FIXME: this probably shouldn't be necessary, but drawImageRect asserts
// None filtering when it's translate-only
paint.setFilterQuality(
fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ?
kNone_SkFilterQuality : fFilterQuality);
canvas->drawImageRect(fImage.get(), fSrcRect, dstRect, &paint,
SkCanvas::kStrict_SrcRectConstraint);
offset->fX = dstIRect.fLeft;
offset->fY = dstIRect.fTop;
return surf->makeImageSnapshot();
}
示例3: input
sk_sp<SkSpecialImage> SkDropShadowImageFilter::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint inputOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
if (!input) {
return nullptr;
}
const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
input->width(), input->height());
SkIRect bounds;
if (!this->applyCropRect(ctx, inputBounds, &bounds)) {
return nullptr;
}
sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size()));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
canvas->clear(0x0);
SkVector sigma = SkVector::Make(fSigmaX, fSigmaY);
ctx.ctm().mapVectors(&sigma, 1);
sigma.fX = SkMaxScalar(0, sigma.fX);
sigma.fY = SkMaxScalar(0, sigma.fY);
SkPaint paint;
paint.setAntiAlias(true);
paint.setImageFilter(SkBlurImageFilter::Make(sigma.fX, sigma.fY, nullptr));
paint.setColorFilter(SkColorFilter::MakeModeFilter(fColor, SkBlendMode::kSrcIn));
SkVector offsetVec = SkVector::Make(fDx, fDy);
ctx.ctm().mapVectors(&offsetVec, 1);
canvas->translate(SkIntToScalar(inputOffset.fX - bounds.fLeft),
SkIntToScalar(inputOffset.fY - bounds.fTop));
input->draw(canvas, offsetVec.fX, offsetVec.fY, &paint);
if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
input->draw(canvas, 0, 0, nullptr);
}
offset->fX = bounds.fLeft;
offset->fY = bounds.fTop;
return surf->makeImageSnapshot();
}
示例4: input
sk_sp<SkSpecialImage> SkOffsetImageFilter::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint srcOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &srcOffset));
if (!input) {
return nullptr;
}
SkIPoint vec = map_offset_vector(ctx.ctm(), fOffset);
if (!this->cropRectIsSet()) {
offset->fX = Sk32_sat_add(srcOffset.fX, vec.fX);
offset->fY = Sk32_sat_add(srcOffset.fY, vec.fY);
return input;
} else {
SkIRect bounds;
SkIRect srcBounds = SkIRect::MakeWH(input->width(), input->height());
srcBounds.offset(srcOffset);
if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
return nullptr;
}
sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size()));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
// TODO: it seems like this clear shouldn't be necessary (see skbug.com/5075)
canvas->clear(0x0);
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
canvas->translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
SkIntToScalar(srcOffset.fY - bounds.fTop));
input->draw(canvas, vec.fX, vec.fY, &paint);
offset->fX = bounds.fLeft;
offset->fY = bounds.fTop;
return surf->makeImageSnapshot();
}
}
示例5: getSampledSubsetDimensions
SkISize SkAndroidCodec::getSampledSubsetDimensions(int sampleSize, const SkIRect& subset) const {
if (!is_valid_sample_size(sampleSize)) {
return SkISize::Make(0, 0);
}
// We require that the input subset is a subset that is supported by SkAndroidCodec.
// We test this by calling getSupportedSubset() and verifying that no modifications
// are made to the subset.
SkIRect copySubset = subset;
if (!this->getSupportedSubset(©Subset) || copySubset != subset) {
return SkISize::Make(0, 0);
}
// If the subset is the entire image, for consistency, use getSampledDimensions().
if (fInfo.dimensions() == subset.size()) {
return this->getSampledDimensions(sampleSize);
}
// This should perhaps call a virtual function, but currently both of our subclasses
// want the same implementation.
return SkISize::Make(get_scaled_dimension(subset.width(), sampleSize),
get_scaled_dimension(subset.height(), sampleSize));
}
示例6: onGetAndroidPixels
SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void* pixels,
size_t rowBytes, const AndroidOptions& options) {
// Create an Options struct for the codec.
SkCodec::Options codecOptions;
codecOptions.fZeroInitialized = options.fZeroInitialized;
codecOptions.fPremulBehavior = SkTransferFunctionBehavior::kIgnore;
SkIRect* subset = options.fSubset;
if (!subset || subset->size() == this->codec()->getInfo().dimensions()) {
if (this->codec()->dimensionsSupported(info.dimensions())) {
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions);
}
// If the native codec does not support the requested scale, scale by sampling.
return this->sampledDecode(info, pixels, rowBytes, options);
}
// We are performing a subset decode.
int sampleSize = options.fSampleSize;
SkISize scaledSize = this->getSampledDimensions(sampleSize);
if (!this->codec()->dimensionsSupported(scaledSize)) {
// If the native codec does not support the requested scale, scale by sampling.
return this->sampledDecode(info, pixels, rowBytes, options);
}
// Calculate the scaled subset bounds.
int scaledSubsetX = subset->x() / sampleSize;
int scaledSubsetY = subset->y() / sampleSize;
int scaledSubsetWidth = info.width();
int scaledSubsetHeight = info.height();
const SkImageInfo scaledInfo = info.makeWH(scaledSize.width(), scaledSize.height());
{
// Although startScanlineDecode expects the bottom and top to match the
// SkImageInfo, startIncrementalDecode uses them to determine which rows to
// decode.
SkIRect incrementalSubset = SkIRect::MakeXYWH(scaledSubsetX, scaledSubsetY,
scaledSubsetWidth, scaledSubsetHeight);
codecOptions.fSubset = &incrementalSubset;
const SkCodec::Result startResult = this->codec()->startIncrementalDecode(
scaledInfo, pixels, rowBytes, &codecOptions);
if (SkCodec::kSuccess == startResult) {
int rowsDecoded;
const SkCodec::Result incResult = this->codec()->incrementalDecode(&rowsDecoded);
if (incResult == SkCodec::kSuccess) {
return SkCodec::kSuccess;
}
SkASSERT(SkCodec::kIncompleteInput == incResult);
// FIXME: Can zero initialized be read from SkCodec::fOptions?
this->codec()->fillIncompleteImage(scaledInfo, pixels, rowBytes,
options.fZeroInitialized, scaledSubsetHeight, rowsDecoded);
return SkCodec::kIncompleteInput;
} else if (startResult != SkCodec::kUnimplemented) {
return startResult;
}
// Otherwise fall down to use the old scanline decoder.
// codecOptions.fSubset will be reset below, so it will not continue to
// point to the object that is no longer on the stack.
}
// Start the scanline decode.
SkIRect scanlineSubset = SkIRect::MakeXYWH(scaledSubsetX, 0, scaledSubsetWidth,
scaledSize.height());
codecOptions.fSubset = &scanlineSubset;
SkCodec::Result result = this->codec()->startScanlineDecode(scaledInfo,
&codecOptions);
if (SkCodec::kSuccess != result) {
return result;
}
// At this point, we are only concerned with subsetting. Either no scale was
// requested, or the this->codec() is handling the scale.
// Note that subsetting is only supported for kTopDown, so this code will not be
// reached for other orders.
SkASSERT(this->codec()->getScanlineOrder() == SkCodec::kTopDown_SkScanlineOrder);
if (!this->codec()->skipScanlines(scaledSubsetY)) {
this->codec()->fillIncompleteImage(info, pixels, rowBytes, options.fZeroInitialized,
scaledSubsetHeight, 0);
return SkCodec::kIncompleteInput;
}
int decodedLines = this->codec()->getScanlines(pixels, scaledSubsetHeight, rowBytes);
if (decodedLines != scaledSubsetHeight) {
return SkCodec::kIncompleteInput;
}
return SkCodec::kSuccess;
}
示例7: input
sk_sp<SkSpecialImage> SkTileImageFilter::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint inputOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
if (!input) {
return nullptr;
}
SkRect dstRect;
ctx.ctm().mapRect(&dstRect, fDstRect);
if (!dstRect.intersect(SkRect::Make(ctx.clipBounds()))) {
return nullptr;
}
const SkIRect dstIRect = dstRect.roundOut();
if (!fSrcRect.width() || !fSrcRect.height() || !dstIRect.width() || !dstIRect.height()) {
return nullptr;
}
SkRect srcRect;
ctx.ctm().mapRect(&srcRect, fSrcRect);
SkIRect srcIRect;
srcRect.roundOut(&srcIRect);
srcIRect.offset(-inputOffset);
const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height());
if (!SkIRect::Intersects(srcIRect, inputBounds)) {
return nullptr;
}
// We create an SkImage here b.c. it needs to be a tight fit for the tiling
sk_sp<SkImage> subset;
if (inputBounds.contains(srcIRect)) {
subset = input->makeTightSubset(srcIRect);
if (!subset) {
return nullptr;
}
} else {
sk_sp<SkSurface> surf(input->makeTightSurface(ctx.outputProperties(), srcIRect.size()));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
input->draw(canvas,
SkIntToScalar(inputOffset.x()), SkIntToScalar(inputOffset.y()),
&paint);
subset = surf->makeImageSnapshot();
}
SkASSERT(subset->width() == srcIRect.width());
SkASSERT(subset->height() == srcIRect.height());
sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), dstIRect.size()));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
paint.setShader(subset->makeShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
canvas->translate(-dstRect.fLeft, -dstRect.fTop);
canvas->drawRect(dstRect, paint);
offset->fX = dstIRect.fLeft;
offset->fY = dstIRect.fTop;
return surf->makeImageSnapshot();
}
示例8: ReadHeader
/*
* Read enough of the stream to initialize the SkGifCodec.
* Returns a bool representing success or failure.
*
* @param codecOut
* If it returned true, and codecOut was not nullptr,
* codecOut will be set to a new SkGifCodec.
*
* @param gifOut
* If it returned true, and codecOut was nullptr,
* gifOut must be non-nullptr and gifOut will be set to a new
* GifFileType pointer.
*
* @param stream
* Deleted on failure.
* codecOut will take ownership of it in the case where we created a codec.
* Ownership is unchanged when we returned a gifOut.
*
*/
bool SkGifCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, GifFileType** gifOut) {
SkAutoTDelete<SkStream> streamDeleter(stream);
// Read gif header, logical screen descriptor, and global color table
SkAutoTCallVProc<GifFileType, CloseGif> gif(open_gif(stream));
if (nullptr == gif) {
gif_error("DGifOpen failed.\n");
return false;
}
// Read through gif extensions to get to the image data. Set the
// transparent index based on the extension data.
uint32_t transIndex;
SkCodec::Result result = ReadUpToFirstImage(gif, &transIndex);
if (kSuccess != result){
return false;
}
// Read the image descriptor
if (GIF_ERROR == DGifGetImageDesc(gif)) {
return false;
}
// If reading the image descriptor is successful, the image count will be
// incremented.
SkASSERT(gif->ImageCount >= 1);
if (nullptr != codecOut) {
SkISize size;
SkIRect frameRect;
if (!GetDimensions(gif, &size, &frameRect)) {
gif_error("Invalid gif size.\n");
return false;
}
bool frameIsSubset = (size != frameRect.size());
// Determine the recommended alpha type. The transIndex might be valid if it less
// than 256. We are not certain that the index is valid until we process the color
// table, since some gifs have color tables with less than 256 colors. If
// there might be a valid transparent index, we must indicate that the image has
// alpha.
// In the case where we must support alpha, we have the option to set the
// suggested alpha type to kPremul or kUnpremul. Both are valid since the alpha
// component will always be 0xFF or the entire 32-bit pixel will be set to zero.
// We prefer kPremul because we support kPremul, and it is more efficient to use
// kPremul directly even when kUnpremul is supported.
SkAlphaType alphaType = (transIndex < 256) ? kPremul_SkAlphaType : kOpaque_SkAlphaType;
// Return the codec
// kIndex is the most natural color type for gifs, so we set this as
// the default.
SkImageInfo imageInfo = SkImageInfo::Make(size.width(), size.height(), kIndex_8_SkColorType,
alphaType);
*codecOut = new SkGifCodec(imageInfo, streamDeleter.detach(), gif.detach(), transIndex,
frameRect, frameIsSubset);
} else {
SkASSERT(nullptr != gifOut);
streamDeleter.detach();
*gifOut = gif.detach();
}
return true;
}
示例9: test_image
// Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw)
static void test_image(const sk_sp<SkSpecialImage>& img, skiatest::Reporter* reporter,
GrContext* context, bool isGPUBacked,
int offset, int size) {
const SkIRect subset = img->subset();
REPORTER_ASSERT(reporter, offset == subset.left());
REPORTER_ASSERT(reporter, offset == subset.top());
REPORTER_ASSERT(reporter, kSmallerSize == subset.width());
REPORTER_ASSERT(reporter, kSmallerSize == subset.height());
//--------------
// Test that isTextureBacked reports the correct backing type
REPORTER_ASSERT(reporter, isGPUBacked == img->isTextureBacked());
#if SK_SUPPORT_GPU
//--------------
// Test asTextureProxyRef - as long as there is a context this should succeed
if (context) {
sk_sp<GrTextureProxy> proxy(img->asTextureProxyRef(context));
REPORTER_ASSERT(reporter, proxy);
}
#endif
//--------------
// Test getROPixels - this should always succeed regardless of backing store
SkBitmap bitmap;
REPORTER_ASSERT(reporter, img->getROPixels(&bitmap));
if (context) {
REPORTER_ASSERT(reporter, kSmallerSize == bitmap.width());
REPORTER_ASSERT(reporter, kSmallerSize == bitmap.height());
} else {
REPORTER_ASSERT(reporter, size == bitmap.width());
REPORTER_ASSERT(reporter, size == bitmap.height());
}
//--------------
// Test that draw restricts itself to the subset
SkImageFilter::OutputProperties outProps(img->getColorSpace());
sk_sp<SkSpecialSurface> surf(img->makeSurface(outProps, SkISize::Make(kFullSize, kFullSize),
kPremul_SkAlphaType));
SkCanvas* canvas = surf->getCanvas();
canvas->clear(SK_ColorBLUE);
img->draw(canvas, SkIntToScalar(kPad), SkIntToScalar(kPad), nullptr);
SkBitmap bm;
bm.allocN32Pixels(kFullSize, kFullSize, false);
bool result = canvas->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), 0, 0);
SkASSERT_RELEASE(result);
// Only the center (red) portion should've been drawn into the canvas
REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kPad-1, kPad-1));
REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kPad, kPad));
REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kSmallerSize+kPad-1,
kSmallerSize+kPad-1));
REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kSmallerSize+kPad,
kSmallerSize+kPad));
//--------------
// Test that asImage & makeTightSurface return appropriately sized objects
// of the correct backing type
SkIRect newSubset = SkIRect::MakeWH(subset.width(), subset.height());
{
sk_sp<SkImage> tightImg(img->asImage(&newSubset));
REPORTER_ASSERT(reporter, tightImg->width() == subset.width());
REPORTER_ASSERT(reporter, tightImg->height() == subset.height());
REPORTER_ASSERT(reporter, isGPUBacked == tightImg->isTextureBacked());
SkPixmap tmpPixmap;
REPORTER_ASSERT(reporter, isGPUBacked != !!tightImg->peekPixels(&tmpPixmap));
}
{
SkImageFilter::OutputProperties outProps(img->getColorSpace());
sk_sp<SkSurface> tightSurf(img->makeTightSurface(outProps, subset.size()));
REPORTER_ASSERT(reporter, tightSurf->width() == subset.width());
REPORTER_ASSERT(reporter, tightSurf->height() == subset.height());
REPORTER_ASSERT(reporter, isGPUBacked ==
!!tightSurf->getTextureHandle(SkSurface::kDiscardWrite_BackendHandleAccess));
SkPixmap tmpPixmap;
REPORTER_ASSERT(reporter, isGPUBacked != !!tightSurf->peekPixels(&tmpPixmap));
}
}
示例10: onGetAndroidPixels
SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void* pixels,
size_t rowBytes, const AndroidOptions& options) {
// Create an Options struct for the codec.
SkCodec::Options codecOptions;
codecOptions.fZeroInitialized = options.fZeroInitialized;
SkIRect* subset = options.fSubset;
if (!subset || subset->size() == this->codec()->getInfo().dimensions()) {
if (this->codec()->dimensionsSupported(info.dimensions())) {
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions,
options.fColorPtr, options.fColorCount);
}
// If the native codec does not support the requested scale, scale by sampling.
return this->sampledDecode(info, pixels, rowBytes, options);
}
// We are performing a subset decode.
int sampleSize = options.fSampleSize;
SkISize scaledSize = this->getSampledDimensions(sampleSize);
if (!this->codec()->dimensionsSupported(scaledSize)) {
// If the native codec does not support the requested scale, scale by sampling.
return this->sampledDecode(info, pixels, rowBytes, options);
}
// Calculate the scaled subset bounds.
int scaledSubsetX = subset->x() / sampleSize;
int scaledSubsetY = subset->y() / sampleSize;
int scaledSubsetWidth = info.width();
int scaledSubsetHeight = info.height();
// Start the scanline decode.
SkIRect scanlineSubset = SkIRect::MakeXYWH(scaledSubsetX, 0, scaledSubsetWidth,
scaledSize.height());
codecOptions.fSubset = &scanlineSubset;
SkCodec::Result result = this->codec()->startScanlineDecode(info.makeWH(scaledSize.width(),
scaledSize.height()), &codecOptions, options.fColorPtr, options.fColorCount);
if (SkCodec::kSuccess != result) {
return result;
}
// At this point, we are only concerned with subsetting. Either no scale was
// requested, or the this->codec() is handling the scale.
switch (this->codec()->getScanlineOrder()) {
case SkCodec::kTopDown_SkScanlineOrder:
case SkCodec::kNone_SkScanlineOrder: {
if (!this->codec()->skipScanlines(scaledSubsetY)) {
this->codec()->fillIncompleteImage(info, pixels, rowBytes, options.fZeroInitialized,
scaledSubsetHeight, 0);
return SkCodec::kIncompleteInput;
}
int decodedLines = this->codec()->getScanlines(pixels, scaledSubsetHeight, rowBytes);
if (decodedLines != scaledSubsetHeight) {
return SkCodec::kIncompleteInput;
}
return SkCodec::kSuccess;
}
default:
SkASSERT(false);
return SkCodec::kUnimplemented;
}
}
示例11: inputs
sk_sp<SkSpecialImage> SkMergeImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
SkIPoint* offset) const {
int inputCount = this->countInputs();
if (inputCount < 1) {
return nullptr;
}
SkIRect bounds;
bounds.setEmpty();
SkAutoTDeleteArray<sk_sp<SkSpecialImage>> inputs(new sk_sp<SkSpecialImage>[inputCount]);
SkAutoTDeleteArray<SkIPoint> offsets(new SkIPoint[inputCount]);
// Filter all of the inputs.
for (int i = 0; i < inputCount; ++i) {
offsets[i].setZero();
inputs[i] = this->filterInput(i, source, ctx, &offsets[i]);
if (!inputs[i]) {
continue;
}
const SkIRect inputBounds = SkIRect::MakeXYWH(offsets[i].fX, offsets[i].fY,
inputs[i]->width(), inputs[i]->height());
bounds.join(inputBounds);
}
if (bounds.isEmpty()) {
return nullptr;
}
// Apply the crop rect to the union of the inputs' bounds.
// Note that the crop rect can only reduce the bounds, since this
// filter does not affect transparent black.
bool embiggen = false;
this->getCropRect().applyTo(bounds, ctx.ctm(), embiggen, &bounds);
if (!bounds.intersect(ctx.clipBounds())) {
return nullptr;
}
const int x0 = bounds.left();
const int y0 = bounds.top();
sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size()));
if (!surf) {
return nullptr;
}
SkCanvas* canvas = surf->getCanvas();
SkASSERT(canvas);
canvas->clear(0x0);
// Composite all of the filter inputs.
for (int i = 0; i < inputCount; ++i) {
if (!inputs[i]) {
continue;
}
SkPaint paint;
if (fModes) {
paint.setBlendMode((SkBlendMode)fModes[i]);
}
inputs[i]->draw(canvas,
SkIntToScalar(offsets[i].x() - x0), SkIntToScalar(offsets[i].y() - y0),
&paint);
}
offset->fX = bounds.left();
offset->fY = bounds.top();
return surf->makeImageSnapshot();
}