michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #include "SkImagePriv.h" michael@0: #include "SkCanvas.h" michael@0: #include "SkPicture.h" michael@0: michael@0: SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType colorType) { michael@0: switch (colorType) { michael@0: case kAlpha_8_SkColorType: michael@0: return SkBitmap::kA8_Config; michael@0: michael@0: case kARGB_4444_SkColorType: michael@0: return SkBitmap::kARGB_4444_Config; michael@0: michael@0: case kRGB_565_SkColorType: michael@0: return SkBitmap::kRGB_565_Config; michael@0: michael@0: case kPMColor_SkColorType: michael@0: return SkBitmap::kARGB_8888_Config; michael@0: michael@0: case kIndex_8_SkColorType: michael@0: return SkBitmap::kIndex8_Config; michael@0: michael@0: default: michael@0: // break for unsupported colortypes michael@0: break; michael@0: } michael@0: return SkBitmap::kNo_Config; michael@0: } michael@0: michael@0: SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) { michael@0: return SkColorTypeToBitmapConfig(info.fColorType); michael@0: } michael@0: michael@0: SkColorType SkBitmapConfigToColorType(SkBitmap::Config config) { michael@0: static const SkColorType gCT[] = { michael@0: kUnknown_SkColorType, // kNo_Config michael@0: kAlpha_8_SkColorType, // kA8_Config michael@0: kIndex_8_SkColorType, // kIndex8_Config michael@0: kRGB_565_SkColorType, // kRGB_565_Config michael@0: kARGB_4444_SkColorType, // kARGB_4444_Config michael@0: kPMColor_SkColorType, // kARGB_8888_Config michael@0: }; michael@0: SkASSERT((unsigned)config < SK_ARRAY_COUNT(gCT)); michael@0: return gCT[config]; michael@0: } michael@0: michael@0: SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) { michael@0: SkImageInfo info; michael@0: if (!bm.asImageInfo(&info)) { michael@0: return NULL; michael@0: } michael@0: michael@0: SkImage* image = NULL; michael@0: if (canSharePixelRef || bm.isImmutable()) { michael@0: image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes()); michael@0: } else { michael@0: bm.lockPixels(); michael@0: if (bm.getPixels()) { michael@0: image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes()); michael@0: } michael@0: bm.unlockPixels(); michael@0: } michael@0: return image; michael@0: } michael@0: michael@0: static bool needs_layer(const SkPaint& paint) { michael@0: return 0xFF != paint.getAlpha() || michael@0: paint.getColorFilter() || michael@0: paint.getImageFilter() || michael@0: SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); michael@0: } michael@0: michael@0: void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, michael@0: SkScalar x, SkScalar y, const SkPaint* paint) { michael@0: int saveCount = canvas->getSaveCount(); michael@0: michael@0: if (paint && needs_layer(*paint)) { michael@0: SkRect bounds; michael@0: bounds.set(x, y, michael@0: x + SkIntToScalar(picture->width()), michael@0: y + SkIntToScalar(picture->height())); michael@0: canvas->saveLayer(&bounds, paint); michael@0: canvas->translate(x, y); michael@0: } else if (x || y) { michael@0: canvas->save(); michael@0: canvas->translate(x, y); michael@0: } michael@0: michael@0: canvas->drawPicture(*picture); michael@0: canvas->restoreToCount(saveCount); michael@0: } michael@0: michael@0: void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, michael@0: const SkRect* src, const SkRect& dst, const SkPaint* paint) { michael@0: int saveCount = canvas->getSaveCount(); michael@0: michael@0: SkMatrix matrix; michael@0: SkRect tmpSrc; michael@0: michael@0: if (NULL != src) { michael@0: tmpSrc = *src; michael@0: } else { michael@0: tmpSrc.set(0, 0, michael@0: SkIntToScalar(picture->width()), michael@0: SkIntToScalar(picture->height())); michael@0: } michael@0: michael@0: matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); michael@0: if (paint && needs_layer(*paint)) { michael@0: canvas->saveLayer(&dst, paint); michael@0: } else { michael@0: canvas->save(); michael@0: } michael@0: canvas->concat(matrix); michael@0: if (!paint || !needs_layer(*paint)) { michael@0: canvas->clipRect(tmpSrc); michael@0: } michael@0: michael@0: canvas->drawPicture(*picture); michael@0: canvas->restoreToCount(saveCount); michael@0: }