1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkImagePriv.h" 9 #include "SkCanvas.h" 10 #include "SkPicture.h" 11 12 SkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info, 13 bool* isOpaque) { 14 switch (info.fColorType) { 15 case SkImage::kAlpha_8_ColorType: 16 switch (info.fAlphaType) { 17 case SkImage::kIgnore_AlphaType: 18 // makes no sense 19 return SkBitmap::kNo_Config; 20 21 case SkImage::kOpaque_AlphaType: 22 *isOpaque = true; 23 return SkBitmap::kA8_Config; 24 25 case SkImage::kPremul_AlphaType: 26 case SkImage::kUnpremul_AlphaType: 27 *isOpaque = false; 28 return SkBitmap::kA8_Config; 29 } 30 break; 31 32 case SkImage::kRGB_565_ColorType: 33 // we ignore fAlpahType, though some would not make sense 34 *isOpaque = true; 35 return SkBitmap::kRGB_565_Config; 36 37 case SkImage::kRGBA_8888_ColorType: 38 case SkImage::kBGRA_8888_ColorType: 39 // not supported yet 40 return SkBitmap::kNo_Config; 41 42 case SkImage::kPMColor_ColorType: 43 switch (info.fAlphaType) { 44 case SkImage::kIgnore_AlphaType: 45 case SkImage::kUnpremul_AlphaType: 46 // not supported yet 47 return SkBitmap::kNo_Config; 48 case SkImage::kOpaque_AlphaType: 49 *isOpaque = true; 50 return SkBitmap::kARGB_8888_Config; 51 case SkImage::kPremul_AlphaType: 52 *isOpaque = false; 53 return SkBitmap::kARGB_8888_Config; 54 } 55 break; 56 } 57 SkASSERT(!"how did we get here"); 58 return SkBitmap::kNo_Config; 59 } 60 61 int SkImageBytesPerPixel(SkImage::ColorType ct) { 62 static const uint8_t gColorTypeBytesPerPixel[] = { 63 1, // kAlpha_8_ColorType 64 2, // kRGB_565_ColorType 65 4, // kRGBA_8888_ColorType 66 4, // kBGRA_8888_ColorType 67 4, // kPMColor_ColorType 68 }; 69 70 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel)); 71 return gColorTypeBytesPerPixel[ct]; 72 } 73 74 bool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) { 75 switch (bm.config()) { 76 case SkBitmap::kA8_Config: 77 info->fColorType = SkImage::kAlpha_8_ColorType; 78 break; 79 80 case SkBitmap::kRGB_565_Config: 81 info->fColorType = SkImage::kRGB_565_ColorType; 82 break; 83 84 case SkBitmap::kARGB_8888_Config: 85 info->fColorType = SkImage::kPMColor_ColorType; 86 break; 87 88 default: 89 return false; 90 } 91 92 info->fWidth = bm.width(); 93 info->fHeight = bm.height(); 94 info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType : 95 SkImage::kPremul_AlphaType; 96 return true; 97 } 98 99 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) { 100 SkImage::Info info; 101 if (!SkBitmapToImageInfo(bm, &info)) { 102 return NULL; 103 } 104 105 SkImage* image = NULL; 106 if (canSharePixelRef || bm.isImmutable()) { 107 image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes()); 108 } else { 109 bm.lockPixels(); 110 if (bm.getPixels()) { 111 image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes()); 112 } 113 bm.unlockPixels(); 114 } 115 return image; 116 } 117 118 static bool needs_layer(const SkPaint& paint) { 119 return 0xFF != paint.getAlpha() || 120 paint.getColorFilter() || 121 paint.getImageFilter() || 122 SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); 123 } 124 125 void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 126 SkScalar x, SkScalar y, const SkPaint* paint) { 127 int saveCount = canvas->getSaveCount(); 128 129 if (paint && needs_layer(*paint)) { 130 SkRect bounds; 131 bounds.set(x, y, 132 x + SkIntToScalar(picture->width()), 133 y + SkIntToScalar(picture->height())); 134 canvas->saveLayer(&bounds, paint); 135 canvas->translate(x, y); 136 } else if (x || y) { 137 canvas->save(); 138 canvas->translate(x, y); 139 } 140 141 canvas->drawPicture(*picture); 142 canvas->restoreToCount(saveCount); 143 } 144 145 void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 146 const SkRect* src, const SkRect& dst, const SkPaint* paint) { 147 int saveCount = canvas->getSaveCount(); 148 149 SkMatrix matrix; 150 SkRect tmpSrc; 151 152 if (NULL != src) { 153 tmpSrc = *src; 154 } else { 155 tmpSrc.set(0, 0, 156 SkIntToScalar(picture->width()), 157 SkIntToScalar(picture->height())); 158 } 159 160 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); 161 if (paint && needs_layer(*paint)) { 162 canvas->saveLayer(&dst, paint); 163 } else { 164 canvas->save(); 165 } 166 canvas->concat(matrix); 167 if (!paint || !needs_layer(*paint)) { 168 canvas->clipRect(tmpSrc); 169 } 170 171 canvas->drawPicture(*picture); 172 canvas->restoreToCount(saveCount); 173 } 174