1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/image/SkImage.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,138 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkBitmap.h" 1.12 +#include "SkCanvas.h" 1.13 +#include "SkImagePriv.h" 1.14 +#include "SkImage_Base.h" 1.15 + 1.16 +static SkImage_Base* as_IB(SkImage* image) { 1.17 + return static_cast<SkImage_Base*>(image); 1.18 +} 1.19 + 1.20 +static const SkImage_Base* as_IB(const SkImage* image) { 1.21 + return static_cast<const SkImage_Base*>(image); 1.22 +} 1.23 + 1.24 +uint32_t SkImage::NextUniqueID() { 1.25 + static int32_t gUniqueID; 1.26 + 1.27 + // never return 0; 1.28 + uint32_t id; 1.29 + do { 1.30 + id = sk_atomic_inc(&gUniqueID) + 1; 1.31 + } while (0 == id); 1.32 + return id; 1.33 +} 1.34 + 1.35 +void SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, 1.36 + const SkPaint* paint) { 1.37 + as_IB(this)->onDraw(canvas, x, y, paint); 1.38 +} 1.39 + 1.40 +void SkImage::draw(SkCanvas* canvas, const SkRect* src, const SkRect& dst, 1.41 + const SkPaint* paint) { 1.42 + as_IB(this)->onDrawRectToRect(canvas, src, dst, paint); 1.43 +} 1.44 + 1.45 +const void* SkImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const { 1.46 + SkImageInfo infoStorage; 1.47 + size_t rowBytesStorage; 1.48 + if (NULL == info) { 1.49 + info = &infoStorage; 1.50 + } 1.51 + if (NULL == rowBytes) { 1.52 + rowBytes = &rowBytesStorage; 1.53 + } 1.54 + return as_IB(this)->onPeekPixels(info, rowBytes); 1.55 +} 1.56 + 1.57 +bool SkImage::readPixels(SkBitmap* bitmap, const SkIRect* subset) const { 1.58 + if (NULL == bitmap) { 1.59 + return false; 1.60 + } 1.61 + 1.62 + SkIRect bounds = SkIRect::MakeWH(this->width(), this->height()); 1.63 + 1.64 + // trim against the bitmap, if its already been allocated 1.65 + if (bitmap->pixelRef()) { 1.66 + bounds.fRight = SkMin32(bounds.fRight, bitmap->width()); 1.67 + bounds.fBottom = SkMin32(bounds.fBottom, bitmap->height()); 1.68 + if (bounds.isEmpty()) { 1.69 + return false; 1.70 + } 1.71 + } 1.72 + 1.73 + if (subset && !bounds.intersect(*subset)) { 1.74 + // perhaps we could return true + empty-bitmap? 1.75 + return false; 1.76 + } 1.77 + return as_IB(this)->onReadPixels(bitmap, bounds); 1.78 +} 1.79 + 1.80 +GrTexture* SkImage::getTexture() { 1.81 + return as_IB(this)->onGetTexture(); 1.82 +} 1.83 + 1.84 +SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const { 1.85 + SkBitmap bm; 1.86 + if (as_IB(this)->getROPixels(&bm)) { 1.87 + return SkImageEncoder::EncodeData(bm, type, quality); 1.88 + } 1.89 + return NULL; 1.90 +} 1.91 + 1.92 +/////////////////////////////////////////////////////////////////////////////// 1.93 + 1.94 +static bool raster_canvas_supports(const SkImageInfo& info) { 1.95 + switch (info.fColorType) { 1.96 + case kPMColor_SkColorType: 1.97 + return kUnpremul_SkAlphaType != info.fAlphaType; 1.98 + case kRGB_565_SkColorType: 1.99 + return true; 1.100 + case kAlpha_8_SkColorType: 1.101 + return true; 1.102 + default: 1.103 + break; 1.104 + } 1.105 + return false; 1.106 +} 1.107 + 1.108 +bool SkImage_Base::onReadPixels(SkBitmap* bitmap, const SkIRect& subset) const { 1.109 + SkImageInfo info; 1.110 + 1.111 + if (bitmap->pixelRef()) { 1.112 + if (!bitmap->asImageInfo(&info)) { 1.113 + return false; 1.114 + } 1.115 + if (!raster_canvas_supports(info)) { 1.116 + return false; 1.117 + } 1.118 + } else { 1.119 + SkImageInfo info = SkImageInfo::MakeN32Premul(subset.width(), 1.120 + subset.height()); 1.121 + SkBitmap tmp; 1.122 + if (!tmp.allocPixels(info)) { 1.123 + return false; 1.124 + } 1.125 + *bitmap = tmp; 1.126 + } 1.127 + 1.128 + SkRect srcR, dstR; 1.129 + srcR.set(subset); 1.130 + dstR = srcR; 1.131 + dstR.offset(-dstR.left(), -dstR.top()); 1.132 + 1.133 + SkCanvas canvas(*bitmap); 1.134 + 1.135 + SkPaint paint; 1.136 + paint.setXfermodeMode(SkXfermode::kClear_Mode); 1.137 + canvas.drawRect(dstR, paint); 1.138 + 1.139 + const_cast<SkImage_Base*>(this)->onDrawRectToRect(&canvas, &srcR, dstR, NULL); 1.140 + return true; 1.141 +}