diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/image/SkImage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/image/SkImage.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,138 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkImagePriv.h" +#include "SkImage_Base.h" + +static SkImage_Base* as_IB(SkImage* image) { + return static_cast(image); +} + +static const SkImage_Base* as_IB(const SkImage* image) { + return static_cast(image); +} + +uint32_t SkImage::NextUniqueID() { + static int32_t gUniqueID; + + // never return 0; + uint32_t id; + do { + id = sk_atomic_inc(&gUniqueID) + 1; + } while (0 == id); + return id; +} + +void SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, + const SkPaint* paint) { + as_IB(this)->onDraw(canvas, x, y, paint); +} + +void SkImage::draw(SkCanvas* canvas, const SkRect* src, const SkRect& dst, + const SkPaint* paint) { + as_IB(this)->onDrawRectToRect(canvas, src, dst, paint); +} + +const void* SkImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const { + SkImageInfo infoStorage; + size_t rowBytesStorage; + if (NULL == info) { + info = &infoStorage; + } + if (NULL == rowBytes) { + rowBytes = &rowBytesStorage; + } + return as_IB(this)->onPeekPixels(info, rowBytes); +} + +bool SkImage::readPixels(SkBitmap* bitmap, const SkIRect* subset) const { + if (NULL == bitmap) { + return false; + } + + SkIRect bounds = SkIRect::MakeWH(this->width(), this->height()); + + // trim against the bitmap, if its already been allocated + if (bitmap->pixelRef()) { + bounds.fRight = SkMin32(bounds.fRight, bitmap->width()); + bounds.fBottom = SkMin32(bounds.fBottom, bitmap->height()); + if (bounds.isEmpty()) { + return false; + } + } + + if (subset && !bounds.intersect(*subset)) { + // perhaps we could return true + empty-bitmap? + return false; + } + return as_IB(this)->onReadPixels(bitmap, bounds); +} + +GrTexture* SkImage::getTexture() { + return as_IB(this)->onGetTexture(); +} + +SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const { + SkBitmap bm; + if (as_IB(this)->getROPixels(&bm)) { + return SkImageEncoder::EncodeData(bm, type, quality); + } + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// + +static bool raster_canvas_supports(const SkImageInfo& info) { + switch (info.fColorType) { + case kPMColor_SkColorType: + return kUnpremul_SkAlphaType != info.fAlphaType; + case kRGB_565_SkColorType: + return true; + case kAlpha_8_SkColorType: + return true; + default: + break; + } + return false; +} + +bool SkImage_Base::onReadPixels(SkBitmap* bitmap, const SkIRect& subset) const { + SkImageInfo info; + + if (bitmap->pixelRef()) { + if (!bitmap->asImageInfo(&info)) { + return false; + } + if (!raster_canvas_supports(info)) { + return false; + } + } else { + SkImageInfo info = SkImageInfo::MakeN32Premul(subset.width(), + subset.height()); + SkBitmap tmp; + if (!tmp.allocPixels(info)) { + return false; + } + *bitmap = tmp; + } + + SkRect srcR, dstR; + srcR.set(subset); + dstR = srcR; + dstR.offset(-dstR.left(), -dstR.top()); + + SkCanvas canvas(*bitmap); + + SkPaint paint; + paint.setXfermodeMode(SkXfermode::kClear_Mode); + canvas.drawRect(dstR, paint); + + const_cast(this)->onDrawRectToRect(&canvas, &srcR, dstR, NULL); + return true; +}