SkImagePriv.cpp revision 9230ea29718bcf1a92a89a1a518fb896bbbe00cf
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 SkImageInfoToBitmapConfig(const SkImageInfo& info) {
13    switch (info.fColorType) {
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
36SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
37    SkImageInfo info;
38    if (!bm.asImageInfo(&info)) {
39        return NULL;
40    }
41
42    SkImage* image = NULL;
43    if (canSharePixelRef || bm.isImmutable()) {
44        image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
45    } else {
46        bm.lockPixels();
47        if (bm.getPixels()) {
48            image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
49        }
50        bm.unlockPixels();
51    }
52    return image;
53}
54
55static bool needs_layer(const SkPaint& paint) {
56    return  0xFF != paint.getAlpha() ||
57    paint.getColorFilter() ||
58    paint.getImageFilter() ||
59    SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
60}
61
62void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
63                            SkScalar x, SkScalar y, const SkPaint* paint) {
64    int saveCount = canvas->getSaveCount();
65
66    if (paint && needs_layer(*paint)) {
67        SkRect bounds;
68        bounds.set(x, y,
69                   x + SkIntToScalar(picture->width()),
70                   y + SkIntToScalar(picture->height()));
71        canvas->saveLayer(&bounds, paint);
72        canvas->translate(x, y);
73    } else if (x || y) {
74        canvas->save();
75        canvas->translate(x, y);
76    }
77
78    canvas->drawPicture(*picture);
79    canvas->restoreToCount(saveCount);
80}
81
82void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
83                            const SkRect* src,  const SkRect& dst, const SkPaint* paint) {
84    int saveCount = canvas->getSaveCount();
85
86    SkMatrix matrix;
87    SkRect   tmpSrc;
88
89    if (NULL != src) {
90        tmpSrc = *src;
91    } else {
92        tmpSrc.set(0, 0,
93                   SkIntToScalar(picture->width()),
94                   SkIntToScalar(picture->height()));
95    }
96
97    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
98    if (paint && needs_layer(*paint)) {
99        canvas->saveLayer(&dst, paint);
100    } else {
101        canvas->save();
102    }
103    canvas->concat(matrix);
104    if (!paint || !needs_layer(*paint)) {
105        canvas->clipRect(tmpSrc);
106    }
107
108    canvas->drawPicture(*picture);
109    canvas->restoreToCount(saveCount);
110}
111