blob: 0eb6478083c1fd3cf594a32ad6d6c46c2b1072db [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.com2bd8b812013-11-01 13:46:54 +000012SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) {
reed@google.com889b09e2012-07-27 21:10:42 +000013 switch (info.fColorType) {
reed@google.com2bd8b812013-11-01 13:46:54 +000014 case kAlpha_8_SkColorType:
reed@google.com383a6972013-10-21 14:00:07 +000015 return SkBitmap::kA8_Config;
reed@google.com889b09e2012-07-27 21:10:42 +000016
reed@google.com2bd8b812013-11-01 13:46:54 +000017 case kRGB_565_SkColorType:
reed@google.com889b09e2012-07-27 21:10:42 +000018 return SkBitmap::kRGB_565_Config;
19
reed@google.com2bd8b812013-11-01 13:46:54 +000020 case kPMColor_SkColorType:
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.com23be7a52013-11-12 16:11:07 +000023 case kIndex8_SkColorType:
24 return SkBitmap::kIndex8_Config;
25
reed@google.comd28ba802013-09-20 19:33:52 +000026 default:
27 // break for unsupported colortypes
28 break;
reed@google.com889b09e2012-07-27 21:10:42 +000029 }
reed@google.com889b09e2012-07-27 21:10:42 +000030 return SkBitmap::kNo_Config;
31}
32
reed@google.com2bd8b812013-11-01 13:46:54 +000033int SkImageBytesPerPixel(SkColorType ct) {
reed@google.com889b09e2012-07-27 21:10:42 +000034 static const uint8_t gColorTypeBytesPerPixel[] = {
reed@google.com2bd8b812013-11-01 13:46:54 +000035 1, // kAlpha_8_SkColorType
36 2, // kRGB_565_SkColorType
37 4, // kRGBA_8888_SkColorType
38 4, // kBGRA_8888_SkColorType
39 4, // kPMColor_SkColorType
reed@google.com23be7a52013-11-12 16:11:07 +000040 1, // kIndex8_SkColorType
reed@google.com889b09e2012-07-27 21:10:42 +000041 };
42
43 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
44 return gColorTypeBytesPerPixel[ct];
45}
46
reed@google.com2bd8b812013-11-01 13:46:54 +000047bool SkBitmapToImageInfo(const SkBitmap& bm, SkImageInfo* info) {
reed@google.com889b09e2012-07-27 21:10:42 +000048 switch (bm.config()) {
49 case SkBitmap::kA8_Config:
reed@google.com2bd8b812013-11-01 13:46:54 +000050 info->fColorType = kAlpha_8_SkColorType;
reed@google.com889b09e2012-07-27 21:10:42 +000051 break;
reed@google.com23be7a52013-11-12 16:11:07 +000052
53 case SkBitmap::kIndex8_Config:
54 info->fColorType = kIndex8_SkColorType;
55 break;
56
reed@google.com889b09e2012-07-27 21:10:42 +000057 case SkBitmap::kRGB_565_Config:
reed@google.com2bd8b812013-11-01 13:46:54 +000058 info->fColorType = kRGB_565_SkColorType;
reed@google.com889b09e2012-07-27 21:10:42 +000059 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000060
reed@google.com889b09e2012-07-27 21:10:42 +000061 case SkBitmap::kARGB_8888_Config:
reed@google.com2bd8b812013-11-01 13:46:54 +000062 info->fColorType = kPMColor_SkColorType;
reed@google.com889b09e2012-07-27 21:10:42 +000063 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000064
reed@google.com889b09e2012-07-27 21:10:42 +000065 default:
66 return false;
67 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000068
reed@google.com889b09e2012-07-27 21:10:42 +000069 info->fWidth = bm.width();
70 info->fHeight = bm.height();
reed@google.comd28ba802013-09-20 19:33:52 +000071 info->fAlphaType = bm.isOpaque() ? kOpaque_SkAlphaType :
72 kPremul_SkAlphaType;
reed@google.com889b09e2012-07-27 21:10:42 +000073 return true;
74}
75
reed@google.com97af1a62012-08-28 12:19:02 +000076SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
reed@google.com2bd8b812013-11-01 13:46:54 +000077 SkImageInfo info;
reed@google.com889b09e2012-07-27 21:10:42 +000078 if (!SkBitmapToImageInfo(bm, &info)) {
79 return NULL;
80 }
81
82 SkImage* image = NULL;
reed@google.com97af1a62012-08-28 12:19:02 +000083 if (canSharePixelRef || bm.isImmutable()) {
reed@google.com889b09e2012-07-27 21:10:42 +000084 image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
85 } else {
86 bm.lockPixels();
mike@reedtribe.org70e35902012-07-29 20:38:16 +000087 if (bm.getPixels()) {
mike@reedtribe.orgb9476252012-11-15 02:37:45 +000088 image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
reed@google.com889b09e2012-07-27 21:10:42 +000089 }
90 bm.unlockPixels();
91 }
92 return image;
93}
94
mike@reedtribe.org70e35902012-07-29 20:38:16 +000095static bool needs_layer(const SkPaint& paint) {
96 return 0xFF != paint.getAlpha() ||
97 paint.getColorFilter() ||
98 paint.getImageFilter() ||
99 SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
100}
101
102void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
103 SkScalar x, SkScalar y, const SkPaint* paint) {
104 int saveCount = canvas->getSaveCount();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000105
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000106 if (paint && needs_layer(*paint)) {
107 SkRect bounds;
108 bounds.set(x, y,
109 x + SkIntToScalar(picture->width()),
110 y + SkIntToScalar(picture->height()));
111 canvas->saveLayer(&bounds, paint);
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000112 canvas->translate(x, y);
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000113 } else if (x || y) {
114 canvas->save();
reed@google.com9ea5a3b2012-07-30 21:03:46 +0000115 canvas->translate(x, y);
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000116 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000117
mike@reedtribe.org70e35902012-07-29 20:38:16 +0000118 canvas->drawPicture(*picture);
119 canvas->restoreToCount(saveCount);
120}
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000121
122void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +0000123 const SkRect* src, const SkRect& dst, const SkPaint* paint) {
124 int saveCount = canvas->getSaveCount();
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000125
126 SkMatrix matrix;
127 SkRect tmpSrc;
128
129 if (NULL != src) {
130 tmpSrc = *src;
131 } else {
132 tmpSrc.set(0, 0,
133 SkIntToScalar(picture->width()),
134 SkIntToScalar(picture->height()));
135 }
136
137 matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
138 if (paint && needs_layer(*paint)) {
139 canvas->saveLayer(&dst, paint);
140 } else {
141 canvas->save();
142 }
143 canvas->concat(matrix);
144 if (!paint || !needs_layer(*paint)) {
145 canvas->clipRect(tmpSrc);
146 }
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +0000147
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +0000148 canvas->drawPicture(*picture);
149 canvas->restoreToCount(saveCount);
150}