/* * 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 "SkImagePriv.h" #include "SkCanvas.h" #include "SkPicture.h" SkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info, bool* isOpaque) { switch (info.fColorType) { case SkImage::kAlpha_8_ColorType: switch (info.fAlphaType) { case SkImage::kIgnore_AlphaType: // makes no sense return SkBitmap::kNo_Config; case SkImage::kOpaque_AlphaType: *isOpaque = true; return SkBitmap::kA8_Config; case SkImage::kPremul_AlphaType: case SkImage::kUnpremul_AlphaType: *isOpaque = false; return SkBitmap::kA8_Config; } break; case SkImage::kRGB_565_ColorType: // we ignore fAlpahType, though some would not make sense *isOpaque = true; return SkBitmap::kRGB_565_Config; case SkImage::kRGBA_8888_ColorType: case SkImage::kBGRA_8888_ColorType: // not supported yet return SkBitmap::kNo_Config; case SkImage::kPMColor_ColorType: switch (info.fAlphaType) { case SkImage::kIgnore_AlphaType: case SkImage::kUnpremul_AlphaType: // not supported yet return SkBitmap::kNo_Config; case SkImage::kOpaque_AlphaType: *isOpaque = true; return SkBitmap::kARGB_8888_Config; case SkImage::kPremul_AlphaType: *isOpaque = false; return SkBitmap::kARGB_8888_Config; } break; } SkASSERT(!"how did we get here"); return SkBitmap::kNo_Config; } int SkImageBytesPerPixel(SkImage::ColorType ct) { static const uint8_t gColorTypeBytesPerPixel[] = { 1, // kAlpha_8_ColorType 2, // kRGB_565_ColorType 4, // kRGBA_8888_ColorType 4, // kBGRA_8888_ColorType 4, // kPMColor_ColorType }; SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel)); return gColorTypeBytesPerPixel[ct]; } bool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) { switch (bm.config()) { case SkBitmap::kA8_Config: info->fColorType = SkImage::kAlpha_8_ColorType; break; case SkBitmap::kRGB_565_Config: info->fColorType = SkImage::kRGB_565_ColorType; break; case SkBitmap::kARGB_8888_Config: info->fColorType = SkImage::kPMColor_ColorType; break; default: return false; } info->fWidth = bm.width(); info->fHeight = bm.height(); info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType : SkImage::kPremul_AlphaType; return true; } SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) { SkImage::Info info; if (!SkBitmapToImageInfo(bm, &info)) { return NULL; } SkImage* image = NULL; if (canSharePixelRef || bm.isImmutable()) { image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes()); } else { bm.lockPixels(); if (bm.getPixels()) { image = SkImage::NewRasterCopy(info, NULL, bm.getPixels(), bm.rowBytes()); } bm.unlockPixels(); } return image; } static bool needs_layer(const SkPaint& paint) { return 0xFF != paint.getAlpha() || paint.getColorFilter() || paint.getImageFilter() || SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); } void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, SkScalar x, SkScalar y, const SkPaint* paint) { int saveCount = canvas->getSaveCount(); if (paint && needs_layer(*paint)) { SkRect bounds; bounds.set(x, y, x + SkIntToScalar(picture->width()), y + SkIntToScalar(picture->height())); canvas->saveLayer(&bounds, paint); canvas->translate(x, y); } else if (x || y) { canvas->save(); canvas->translate(x, y); } canvas->drawPicture(*picture); canvas->restoreToCount(saveCount); }