SkImagePriv.cpp revision 9230ea29718bcf1a92a89a1a518fb896bbbe00cf
16997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com/*
26997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * Copyright 2012 Google Inc.
36997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com *
46997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * Use of this source code is governed by a BSD-style license that can be
56997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * found in the LICENSE file.
66997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com */
76997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com
8889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkImagePriv.h"
970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkCanvas.h"
1070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkPicture.h"
11889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
122bd8b8100529c96c81c30f749f672f4caf775b04reed@google.comSkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) {
13889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    switch (info.fColorType) {
142bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com        case kAlpha_8_SkColorType:
15383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com            return SkBitmap::kA8_Config;
16889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
179230ea29718bcf1a92a89a1a518fb896bbbe00cfreed@google.com        case kARGB_4444_SkColorType:
189230ea29718bcf1a92a89a1a518fb896bbbe00cfreed@google.com            return SkBitmap::kARGB_4444_Config;
199230ea29718bcf1a92a89a1a518fb896bbbe00cfreed@google.com
202bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com        case kRGB_565_SkColorType:
21889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            return SkBitmap::kRGB_565_Config;
229230ea29718bcf1a92a89a1a518fb896bbbe00cfreed@google.com
232bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com        case kPMColor_SkColorType:
24383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com            return SkBitmap::kARGB_8888_Config;
25572a86584602bcd9709d60f3c857750c4018c3d1skia.committer@gmail.com
269230ea29718bcf1a92a89a1a518fb896bbbe00cfreed@google.com        case kIndex_8_SkColorType:
2723be7a58d9d69ae0a06788c2d798f2f92baea29creed@google.com            return SkBitmap::kIndex8_Config;
2823be7a58d9d69ae0a06788c2d798f2f92baea29creed@google.com
29d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com        default:
30d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com            // break for unsupported colortypes
31d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com            break;
32889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    }
33889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    return SkBitmap::kNo_Config;
34889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
35889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
3697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comSkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
372bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com    SkImageInfo info;
389230ea29718bcf1a92a89a1a518fb896bbbe00cfreed@google.com    if (!bm.asImageInfo(&info)) {
39889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        return NULL;
40889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    }
41889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
42889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkImage* image = NULL;
4397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    if (canSharePixelRef || bm.isImmutable()) {
44889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
45889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    } else {
46889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        bm.lockPixels();
4770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        if (bm.getPixels()) {
48b947625800a26194fcf63d7b57dadb1a63677f6amike@reedtribe.org            image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
49889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        }
50889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        bm.unlockPixels();
51889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    }
52889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    return image;
53889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
54889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
5570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgstatic bool needs_layer(const SkPaint& paint) {
5670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    return  0xFF != paint.getAlpha() ||
5770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    paint.getColorFilter() ||
5870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    paint.getImageFilter() ||
5970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
6070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
6170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
6270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
6370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org                            SkScalar x, SkScalar y, const SkPaint* paint) {
6470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    int saveCount = canvas->getSaveCount();
65fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
6670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    if (paint && needs_layer(*paint)) {
6770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        SkRect bounds;
6870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        bounds.set(x, y,
6970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org                   x + SkIntToScalar(picture->width()),
7070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org                   y + SkIntToScalar(picture->height()));
7170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        canvas->saveLayer(&bounds, paint);
729ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com        canvas->translate(x, y);
7370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    } else if (x || y) {
7470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        canvas->save();
759ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com        canvas->translate(x, y);
7670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    }
77fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
7870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    canvas->drawPicture(*picture);
7970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    canvas->restoreToCount(saveCount);
8070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
81dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org
82dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
837f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com                            const SkRect* src,  const SkRect& dst, const SkPaint* paint) {
847f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com    int saveCount = canvas->getSaveCount();
85dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org
86dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    SkMatrix matrix;
87dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    SkRect   tmpSrc;
88dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org
89dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    if (NULL != src) {
90dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org        tmpSrc = *src;
91dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    } else {
92dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org        tmpSrc.set(0, 0,
93dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org                   SkIntToScalar(picture->width()),
94dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org                   SkIntToScalar(picture->height()));
95dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    }
96dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org
97dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
98dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    if (paint && needs_layer(*paint)) {
99dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org        canvas->saveLayer(&dst, paint);
100dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    } else {
101dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org        canvas->save();
102dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    }
103dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    canvas->concat(matrix);
104dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    if (!paint || !needs_layer(*paint)) {
105dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org        canvas->clipRect(tmpSrc);
106dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    }
1077f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com
108dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    canvas->drawPicture(*picture);
109dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org    canvas->restoreToCount(saveCount);
110dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org}
111