• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkImageInfoToBitmapConfig(const SkImage::Info & info,bool * isOpaque)12 SkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info,
13                                            bool* isOpaque) {
14     switch (info.fColorType) {
15         case SkImage::kAlpha_8_ColorType:
16             switch (info.fAlphaType) {
17                 case SkImage::kIgnore_AlphaType:
18                     // makes no sense
19                     return SkBitmap::kNo_Config;
20 
21                 case SkImage::kOpaque_AlphaType:
22                     *isOpaque = true;
23                     return SkBitmap::kA8_Config;
24 
25                 case SkImage::kPremul_AlphaType:
26                 case SkImage::kUnpremul_AlphaType:
27                     *isOpaque = false;
28                     return SkBitmap::kA8_Config;
29             }
30             break;
31 
32         case SkImage::kRGB_565_ColorType:
33             // we ignore fAlpahType, though some would not make sense
34             *isOpaque = true;
35             return SkBitmap::kRGB_565_Config;
36 
37         case SkImage::kRGBA_8888_ColorType:
38         case SkImage::kBGRA_8888_ColorType:
39             // not supported yet
40             return SkBitmap::kNo_Config;
41 
42         case SkImage::kPMColor_ColorType:
43             switch (info.fAlphaType) {
44                 case SkImage::kIgnore_AlphaType:
45                 case SkImage::kUnpremul_AlphaType:
46                     // not supported yet
47                     return SkBitmap::kNo_Config;
48                 case SkImage::kOpaque_AlphaType:
49                     *isOpaque = true;
50                     return SkBitmap::kARGB_8888_Config;
51                 case SkImage::kPremul_AlphaType:
52                     *isOpaque = false;
53                     return SkBitmap::kARGB_8888_Config;
54             }
55             break;
56     }
57     SkASSERT(!"how did we get here");
58     return SkBitmap::kNo_Config;
59 }
60 
SkImageBytesPerPixel(SkImage::ColorType ct)61 int SkImageBytesPerPixel(SkImage::ColorType ct) {
62     static const uint8_t gColorTypeBytesPerPixel[] = {
63         1,  // kAlpha_8_ColorType
64         2,  // kRGB_565_ColorType
65         4,  // kRGBA_8888_ColorType
66         4,  // kBGRA_8888_ColorType
67         4,  // kPMColor_ColorType
68     };
69 
70     SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
71     return gColorTypeBytesPerPixel[ct];
72 }
73 
SkBitmapToImageInfo(const SkBitmap & bm,SkImage::Info * info)74 bool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) {
75     switch (bm.config()) {
76         case SkBitmap::kA8_Config:
77             info->fColorType = SkImage::kAlpha_8_ColorType;
78             break;
79 
80         case SkBitmap::kRGB_565_Config:
81             info->fColorType = SkImage::kRGB_565_ColorType;
82             break;
83 
84         case SkBitmap::kARGB_8888_Config:
85             info->fColorType = SkImage::kPMColor_ColorType;
86             break;
87 
88         default:
89             return false;
90     }
91 
92     info->fWidth = bm.width();
93     info->fHeight = bm.height();
94     info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType :
95                                        SkImage::kPremul_AlphaType;
96     return true;
97 }
98 
SkNewImageFromBitmap(const SkBitmap & bm,bool canSharePixelRef)99 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
100     SkImage::Info info;
101     if (!SkBitmapToImageInfo(bm, &info)) {
102         return NULL;
103     }
104 
105     SkImage* image = NULL;
106     if (canSharePixelRef || bm.isImmutable()) {
107         image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
108     } else {
109         bm.lockPixels();
110         if (bm.getPixels()) {
111             image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
112         }
113         bm.unlockPixels();
114     }
115     return image;
116 }
117 
needs_layer(const SkPaint & paint)118 static bool needs_layer(const SkPaint& paint) {
119     return  0xFF != paint.getAlpha() ||
120     paint.getColorFilter() ||
121     paint.getImageFilter() ||
122     SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
123 }
124 
SkImagePrivDrawPicture(SkCanvas * canvas,SkPicture * picture,SkScalar x,SkScalar y,const SkPaint * paint)125 void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
126                             SkScalar x, SkScalar y, const SkPaint* paint) {
127     int saveCount = canvas->getSaveCount();
128 
129     if (paint && needs_layer(*paint)) {
130         SkRect bounds;
131         bounds.set(x, y,
132                    x + SkIntToScalar(picture->width()),
133                    y + SkIntToScalar(picture->height()));
134         canvas->saveLayer(&bounds, paint);
135         canvas->translate(x, y);
136     } else if (x || y) {
137         canvas->save();
138         canvas->translate(x, y);
139     }
140 
141     canvas->drawPicture(*picture);
142     canvas->restoreToCount(saveCount);
143 }
144