SkImagePriv.cpp revision 61e96cd44624c9faceb625519c1b29775b161f45
1/*
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
8#include "SkImagePriv.h"
9#include "SkCanvas.h"
10#include "SkPicture.h"
11
12SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType colorType) {
13    switch (colorType) {
14        case kAlpha_8_SkColorType:
15            return SkBitmap::kA8_Config;
16
17        case kARGB_4444_SkColorType:
18            return SkBitmap::kARGB_4444_Config;
19
20        case kRGB_565_SkColorType:
21            return SkBitmap::kRGB_565_Config;
22
23        case kPMColor_SkColorType:
24            return SkBitmap::kARGB_8888_Config;
25
26        case kIndex_8_SkColorType:
27            return SkBitmap::kIndex8_Config;
28
29        default:
30            // break for unsupported colortypes
31            break;
32    }
33    return SkBitmap::kNo_Config;
34}
35
36SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) {
37    return SkColorTypeToBitmapConfig(info.fColorType);
38}
39
40SkColorType SkBitmapConfigToColorType(SkBitmap::Config config) {
41    static const SkColorType gCT[] = {
42        kUnknown_SkColorType,   // kNo_Config
43        kAlpha_8_SkColorType,   // kA8_Config
44        kIndex_8_SkColorType,   // kIndex8_Config
45        kRGB_565_SkColorType,   // kRGB_565_Config
46        kARGB_4444_SkColorType, // kARGB_4444_Config
47        kPMColor_SkColorType,   // kARGB_8888_Config
48    };
49    SkASSERT((unsigned)config < SK_ARRAY_COUNT(gCT));
50    return gCT[config];
51}
52
53SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
54    SkImageInfo info;
55    if (!bm.asImageInfo(&info)) {
56        return NULL;
57    }
58
59    SkImage* image = NULL;
60    if (canSharePixelRef || bm.isImmutable()) {
61        image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
62    } else {
63        bm.lockPixels();
64        if (bm.getPixels()) {
65            image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
66        }
67        bm.unlockPixels();
68    }
69    return image;
70}
71
72static bool needs_layer(const SkPaint& paint) {
73    return  0xFF != paint.getAlpha() ||
74    paint.getColorFilter() ||
75    paint.getImageFilter() ||
76    SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
77}
78
79void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
80                            SkScalar x, SkScalar y, const SkPaint* paint) {
81    int saveCount = canvas->getSaveCount();
82
83    if (paint && needs_layer(*paint)) {
84        SkRect bounds;
85        bounds.set(x, y,
86                   x + SkIntToScalar(picture->width()),
87                   y + SkIntToScalar(picture->height()));
88        canvas->saveLayer(&bounds, paint);
89        canvas->translate(x, y);
90    } else if (x || y) {
91        canvas->save();
92        canvas->translate(x, y);
93    }
94
95    canvas->drawPicture(*picture);
96    canvas->restoreToCount(saveCount);
97}
98
99void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
100                            const SkRect* src,  const SkRect& dst, const SkPaint* paint) {
101    int saveCount = canvas->getSaveCount();
102
103    SkMatrix matrix;
104    SkRect   tmpSrc;
105
106    if (NULL != src) {
107        tmpSrc = *src;
108    } else {
109        tmpSrc.set(0, 0,
110                   SkIntToScalar(picture->width()),
111                   SkIntToScalar(picture->height()));
112    }
113
114    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
115    if (paint && needs_layer(*paint)) {
116        canvas->saveLayer(&dst, paint);
117    } else {
118        canvas->save();
119    }
120    canvas->concat(matrix);
121    if (!paint || !needs_layer(*paint)) {
122        canvas->clipRect(tmpSrc);
123    }
124
125    canvas->drawPicture(*picture);
126    canvas->restoreToCount(saveCount);
127}
128