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
SkImageInfoToBitmapConfig(const SkImage::Info & info,bool * isOpaque)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
SkImageBytesPerPixel(SkImage::ColorType ct)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
SkBitmapToImageInfo(const SkBitmap & bm,SkImage::Info * info)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
SkNewImageFromBitmap(const SkBitmap & bm,bool canSharePixelRef)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
needs_layer(const SkPaint & paint)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
SkImagePrivDrawPicture(SkCanvas * canvas,SkPicture * picture,SkScalar x,SkScalar y,const SkPaint * paint)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