blob: eeeb9d87f77738599018d1f752299dc00ce70b18 [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
reed@google.com383a6972013-10-21 14:00:07 +000012SkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info) {
reed@google.com889b09e2012-07-27 21:10:42 +000013 switch (info.fColorType) {
14 case SkImage::kAlpha_8_ColorType:
reed@google.com383a6972013-10-21 14:00:07 +000015 return SkBitmap::kA8_Config;
reed@google.com889b09e2012-07-27 21:10:42 +000016
17 case SkImage::kRGB_565_ColorType:
reed@google.com889b09e2012-07-27 21:10:42 +000018 return SkBitmap::kRGB_565_Config;
19
reed@google.com889b09e2012-07-27 21:10:42 +000020 case SkImage::kPMColor_ColorType:
reed@google.com383a6972013-10-21 14:00:07 +000021 return SkBitmap::kARGB_8888_Config;
skia.committer@gmail.com572a8652013-09-21 07:01:53 +000022
reed@google.comd28ba802013-09-20 19:33:52 +000023 default:
24 // break for unsupported colortypes
25 break;
reed@google.com889b09e2012-07-27 21:10:42 +000026 }
reed@google.com889b09e2012-07-27 21:10:42 +000027 return SkBitmap::kNo_Config;
28}
29
30int SkImageBytesPerPixel(SkImage::ColorType ct) {
31 static const uint8_t gColorTypeBytesPerPixel[] = {
32 1, // kAlpha_8_ColorType
33 2, // kRGB_565_ColorType
34 4, // kRGBA_8888_ColorType
35 4, // kBGRA_8888_ColorType
36 4, // kPMColor_ColorType
37 };
38
39 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
40 return gColorTypeBytesPerPixel[ct];
41}
42
43bool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) {
44 switch (bm.config()) {
45 case SkBitmap::kA8_Config:
46 info->fColorType = SkImage::kAlpha_8_ColorType;
47 break;
48
49 case SkBitmap::kRGB_565_Config:
50 info->fColorType = SkImage::kRGB_565_ColorType;
51 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000052
reed@google.com889b09e2012-07-27 21:10:42 +000053 case SkBitmap::kARGB_8888_Config:
54 info->fColorType = SkImage::kPMColor_ColorType;
55 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000056
reed@google.com889b09e2012-07-27 21:10:42 +000057 default:
58 return false;
59 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000060
reed@google.com889b09e2012-07-27 21:10:42 +000061 info->fWidth = bm.width();
62 info->fHeight = bm.height();
reed@google.comd28ba802013-09-20 19:33:52 +000063 info->fAlphaType = bm.isOpaque() ? kOpaque_SkAlphaType :
64 kPremul_SkAlphaType;
reed@google.com889b09e2012-07-27 21:10:42 +000065 return true;
66}
67
reed@google.com97af1a62012-08-28 12:19:02 +000068SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
reed@google.com889b09e2012-07-27 21:10:42 +000069 SkImage::Info info;
70 if (!SkBitmapToImageInfo(bm, &info)) {
71 return NULL;
72 }
73
74 SkImage* image = NULL;
reed@google.com97af1a62012-08-28 12:19:02 +000075 if (canSharePixelRef || bm.isImmutable()) {
reed@google.com889b09e2012-07-27 21:10:42 +000076 image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
77 } else {
78 bm.lockPixels();
mike@reedtribe.org70e35902012-07-29 20:38:16 +000079 if (bm.getPixels()) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +000080 image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
reed@google.com889b09e2012-07-27 21:10:42 +000081 }
82 bm.unlockPixels();
83 }
84 return image;
85}
86
mike@reedtribe.org70e35902012-07-29 20:38:16 +000087static bool needs_layer(const SkPaint& paint) {
88 return 0xFF != paint.getAlpha() ||
89 paint.getColorFilter() ||
90 paint.getImageFilter() ||
91 SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
92}
93
94void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
95 SkScalar x, SkScalar y, const SkPaint* paint) {
96 int saveCount = canvas->getSaveCount();
rmistry@google.comfbfcd562012-08-23 18:09:54 +000097
mike@reedtribe.org70e35902012-07-29 20:38:16 +000098 if (paint && needs_layer(*paint)) {
99 SkRect bounds;
100 bounds.set(x, y,
101 x + SkIntToScalar(picture->width()),
102 y + SkIntToScalar(picture->height()));
103 canvas->saveLayer(&bounds, paint);
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000104 canvas->translate(x, y);
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000105 } else if (x || y) {
106 canvas->save();
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000107 canvas->translate(x, y);
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000108 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000109
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000110 canvas->drawPicture(*picture);
111 canvas->restoreToCount(saveCount);
112}
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000113
114void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +0000115 const SkRect* src, const SkRect& dst, const SkPaint* paint) {
116 int saveCount = canvas->getSaveCount();
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000117
118 SkMatrix matrix;
119 SkRect tmpSrc;
120
121 if (NULL != src) {
122 tmpSrc = *src;
123 } else {
124 tmpSrc.set(0, 0,
125 SkIntToScalar(picture->width()),
126 SkIntToScalar(picture->height()));
127 }
128
129 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
130 if (paint && needs_layer(*paint)) {
131 canvas->saveLayer(&dst, paint);
132 } else {
133 canvas->save();
134 }
135 canvas->concat(matrix);
136 if (!paint || !needs_layer(*paint)) {
137 canvas->clipRect(tmpSrc);
138 }
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +0000139
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000140 canvas->drawPicture(*picture);
141 canvas->restoreToCount(saveCount);
142}