blob: f707543c2ab5d0972957f0499395950b54450d08 [file] [log] [blame]
reed@google.com6997ebb2012-07-30 19:50:31 +00001/*
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
reed@google.com889b09e2012-07-27 21:10:42 +00008#include "SkImagePriv.h"
mike@reedtribe.org70e35902012-07-29 20:38:16 +00009#include "SkCanvas.h"
10#include "SkPicture.h"
reed@google.com889b09e2012-07-27 21:10:42 +000011
12SkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info,
13 bool* isOpaque) {
14 switch (info.fColorType) {
15 case SkImage::kAlpha_8_ColorType:
16 switch (info.fAlphaType) {
reed@google.comd28ba802013-09-20 19:33:52 +000017 case kIgnore_SkAlphaType:
reed@google.com889b09e2012-07-27 21:10:42 +000018 // makes no sense
19 return SkBitmap::kNo_Config;
20
reed@google.comd28ba802013-09-20 19:33:52 +000021 case kOpaque_SkAlphaType:
reed@google.com889b09e2012-07-27 21:10:42 +000022 *isOpaque = true;
23 return SkBitmap::kA8_Config;
24
reed@google.comd28ba802013-09-20 19:33:52 +000025 case kPremul_SkAlphaType:
26 case kUnpremul_SkAlphaType:
reed@google.com889b09e2012-07-27 21:10:42 +000027 *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
reed@google.com889b09e2012-07-27 21:10:42 +000037 case SkImage::kPMColor_ColorType:
38 switch (info.fAlphaType) {
reed@google.comd28ba802013-09-20 19:33:52 +000039 case kIgnore_SkAlphaType:
40 case kUnpremul_SkAlphaType:
reed@google.com889b09e2012-07-27 21:10:42 +000041 // not supported yet
42 return SkBitmap::kNo_Config;
reed@google.comd28ba802013-09-20 19:33:52 +000043 case kOpaque_SkAlphaType:
reed@google.com889b09e2012-07-27 21:10:42 +000044 *isOpaque = true;
45 return SkBitmap::kARGB_8888_Config;
reed@google.comd28ba802013-09-20 19:33:52 +000046 case kPremul_SkAlphaType:
reed@google.com889b09e2012-07-27 21:10:42 +000047 *isOpaque = false;
48 return SkBitmap::kARGB_8888_Config;
49 }
50 break;
skia.committer@gmail.com572a8652013-09-21 07:01:53 +000051
reed@google.comd28ba802013-09-20 19:33:52 +000052 default:
53 // break for unsupported colortypes
54 break;
reed@google.com889b09e2012-07-27 21:10:42 +000055 }
reed@google.com889b09e2012-07-27 21:10:42 +000056 return SkBitmap::kNo_Config;
57}
58
59int SkImageBytesPerPixel(SkImage::ColorType ct) {
60 static const uint8_t gColorTypeBytesPerPixel[] = {
61 1, // kAlpha_8_ColorType
62 2, // kRGB_565_ColorType
63 4, // kRGBA_8888_ColorType
64 4, // kBGRA_8888_ColorType
65 4, // kPMColor_ColorType
66 };
67
68 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
69 return gColorTypeBytesPerPixel[ct];
70}
71
72bool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) {
73 switch (bm.config()) {
74 case SkBitmap::kA8_Config:
75 info->fColorType = SkImage::kAlpha_8_ColorType;
76 break;
77
78 case SkBitmap::kRGB_565_Config:
79 info->fColorType = SkImage::kRGB_565_ColorType;
80 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000081
reed@google.com889b09e2012-07-27 21:10:42 +000082 case SkBitmap::kARGB_8888_Config:
83 info->fColorType = SkImage::kPMColor_ColorType;
84 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000085
reed@google.com889b09e2012-07-27 21:10:42 +000086 default:
87 return false;
88 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000089
reed@google.com889b09e2012-07-27 21:10:42 +000090 info->fWidth = bm.width();
91 info->fHeight = bm.height();
reed@google.comd28ba802013-09-20 19:33:52 +000092 info->fAlphaType = bm.isOpaque() ? kOpaque_SkAlphaType :
93 kPremul_SkAlphaType;
reed@google.com889b09e2012-07-27 21:10:42 +000094 return true;
95}
96
reed@google.com97af1a62012-08-28 12:19:02 +000097SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
reed@google.com889b09e2012-07-27 21:10:42 +000098 SkImage::Info info;
99 if (!SkBitmapToImageInfo(bm, &info)) {
100 return NULL;
101 }
102
103 SkImage* image = NULL;
reed@google.com97af1a62012-08-28 12:19:02 +0000104 if (canSharePixelRef || bm.isImmutable()) {
reed@google.com889b09e2012-07-27 21:10:42 +0000105 image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
106 } else {
107 bm.lockPixels();
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000108 if (bm.getPixels()) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +0000109 image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
reed@google.com889b09e2012-07-27 21:10:42 +0000110 }
111 bm.unlockPixels();
112 }
113 return image;
114}
115
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000116static bool needs_layer(const SkPaint& paint) {
117 return 0xFF != paint.getAlpha() ||
118 paint.getColorFilter() ||
119 paint.getImageFilter() ||
120 SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
121}
122
123void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
124 SkScalar x, SkScalar y, const SkPaint* paint) {
125 int saveCount = canvas->getSaveCount();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000126
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000127 if (paint && needs_layer(*paint)) {
128 SkRect bounds;
129 bounds.set(x, y,
130 x + SkIntToScalar(picture->width()),
131 y + SkIntToScalar(picture->height()));
132 canvas->saveLayer(&bounds, paint);
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000133 canvas->translate(x, y);
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000134 } else if (x || y) {
135 canvas->save();
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000136 canvas->translate(x, y);
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000137 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000138
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000139 canvas->drawPicture(*picture);
140 canvas->restoreToCount(saveCount);
141}
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000142
143void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +0000144 const SkRect* src, const SkRect& dst, const SkPaint* paint) {
145 int saveCount = canvas->getSaveCount();
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000146
147 SkMatrix matrix;
148 SkRect tmpSrc;
149
150 if (NULL != src) {
151 tmpSrc = *src;
152 } else {
153 tmpSrc.set(0, 0,
154 SkIntToScalar(picture->width()),
155 SkIntToScalar(picture->height()));
156 }
157
158 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
159 if (paint && needs_layer(*paint)) {
160 canvas->saveLayer(&dst, paint);
161 } else {
162 canvas->save();
163 }
164 canvas->concat(matrix);
165 if (!paint || !needs_layer(*paint)) {
166 canvas->clipRect(tmpSrc);
167 }
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +0000168
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000169 canvas->drawPicture(*picture);
170 canvas->restoreToCount(saveCount);
171}