blob: a79f8dba651c12be66c7a58acb4ef4f50729ebb8 [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.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
reed@google.com2bd8b812013-11-01 13:46:54 +000030int SkImageBytesPerPixel(SkColorType ct) {
reed@google.com889b09e2012-07-27 21:10:42 +000031 static const uint8_t gColorTypeBytesPerPixel[] = {
reed@google.com2bd8b812013-11-01 13:46:54 +000032 1, // kAlpha_8_SkColorType
33 2, // kRGB_565_SkColorType
34 4, // kRGBA_8888_SkColorType
35 4, // kBGRA_8888_SkColorType
36 4, // kPMColor_SkColorType
reed@google.com889b09e2012-07-27 21:10:42 +000037 };
38
39 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
40 return gColorTypeBytesPerPixel[ct];
41}
42
reed@google.com2bd8b812013-11-01 13:46:54 +000043bool SkBitmapToImageInfo(const SkBitmap& bm, SkImageInfo* info) {
reed@google.com889b09e2012-07-27 21:10:42 +000044 switch (bm.config()) {
45 case SkBitmap::kA8_Config:
reed@google.com2bd8b812013-11-01 13:46:54 +000046 info->fColorType = kAlpha_8_SkColorType;
reed@google.com889b09e2012-07-27 21:10:42 +000047 break;
48
49 case SkBitmap::kRGB_565_Config:
reed@google.com2bd8b812013-11-01 13:46:54 +000050 info->fColorType = kRGB_565_SkColorType;
reed@google.com889b09e2012-07-27 21:10:42 +000051 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000052
reed@google.com889b09e2012-07-27 21:10:42 +000053 case SkBitmap::kARGB_8888_Config:
reed@google.com2bd8b812013-11-01 13:46:54 +000054 info->fColorType = kPMColor_SkColorType;
reed@google.com889b09e2012-07-27 21:10:42 +000055 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.com2bd8b812013-11-01 13:46:54 +000069 SkImageInfo info;
reed@google.com889b09e2012-07-27 21:10:42 +000070 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}