- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / image / SkImagePriv.cpp
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
12 SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) {
13     switch (info.fColorType) {
14         case kAlpha_8_SkColorType:
15             return SkBitmap::kA8_Config;
16
17         case kRGB_565_SkColorType:
18             return SkBitmap::kRGB_565_Config;
19
20         case kPMColor_SkColorType:
21             return SkBitmap::kARGB_8888_Config;
22
23         default:
24             // break for unsupported colortypes
25             break;
26     }
27     return SkBitmap::kNo_Config;
28 }
29
30 int SkImageBytesPerPixel(SkColorType ct) {
31     static const uint8_t gColorTypeBytesPerPixel[] = {
32         1,  // kAlpha_8_SkColorType
33         2,  // kRGB_565_SkColorType
34         4,  // kRGBA_8888_SkColorType
35         4,  // kBGRA_8888_SkColorType
36         4,  // kPMColor_SkColorType
37     };
38
39     SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
40     return gColorTypeBytesPerPixel[ct];
41 }
42
43 bool SkBitmapToImageInfo(const SkBitmap& bm, SkImageInfo* info) {
44     switch (bm.config()) {
45         case SkBitmap::kA8_Config:
46             info->fColorType = kAlpha_8_SkColorType;
47             break;
48
49         case SkBitmap::kRGB_565_Config:
50             info->fColorType = kRGB_565_SkColorType;
51             break;
52
53         case SkBitmap::kARGB_8888_Config:
54             info->fColorType = kPMColor_SkColorType;
55             break;
56
57         default:
58             return false;
59     }
60
61     info->fWidth = bm.width();
62     info->fHeight = bm.height();
63     info->fAlphaType = bm.isOpaque() ? kOpaque_SkAlphaType :
64                                        kPremul_SkAlphaType;
65     return true;
66 }
67
68 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
69     SkImageInfo info;
70     if (!SkBitmapToImageInfo(bm, &info)) {
71         return NULL;
72     }
73
74     SkImage* image = NULL;
75     if (canSharePixelRef || bm.isImmutable()) {
76         image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
77     } else {
78         bm.lockPixels();
79         if (bm.getPixels()) {
80             image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
81         }
82         bm.unlockPixels();
83     }
84     return image;
85 }
86
87 static 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
94 void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
95                             SkScalar x, SkScalar y, const SkPaint* paint) {
96     int saveCount = canvas->getSaveCount();
97
98     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);
104         canvas->translate(x, y);
105     } else if (x || y) {
106         canvas->save();
107         canvas->translate(x, y);
108     }
109
110     canvas->drawPicture(*picture);
111     canvas->restoreToCount(saveCount);
112 }
113
114 void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
115                             const SkRect* src,  const SkRect& dst, const SkPaint* paint) {
116     int saveCount = canvas->getSaveCount();
117
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     }
139
140     canvas->drawPicture(*picture);
141     canvas->restoreToCount(saveCount);
142 }