1 /*
2  * Copyright 2013 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 "gm.h"
9 #include "SkBitmap.h"
10 #include "SkCanvas.h"
11 #include "SkColorPriv.h"
12 
13 /**
14  * This GM checks that bitmap pixels are unpremultiplied before being exported
15  * to other formats. If unpremultiplication is implemented properly, this
16  * GM should come out completely white. If not, this GM looks like a row of two
17  * greyscale gradients above a row of grey lines.
18  * This tests both the ARGB4444 and ARGB8888 bitmap configurations.
19  */
20 
21 static const int SLIDE_SIZE = 256;
22 static const int PIXEL_SIZE_8888 = SLIDE_SIZE / 256;
23 static const int PIXEL_SIZE_4444 = SLIDE_SIZE / 16;
24 
init_bitmap(SkColorType ct,SkBitmap * bitmap)25 static void init_bitmap(SkColorType ct, SkBitmap* bitmap) {
26     bitmap->allocPixels(SkImageInfo::Make(SLIDE_SIZE, SLIDE_SIZE, ct,
27                                           kPremul_SkAlphaType));
28     bitmap->eraseColor(SK_ColorWHITE);
29 }
30 
make_argb8888_gradient()31 static SkBitmap make_argb8888_gradient() {
32     SkBitmap bitmap;
33     init_bitmap(kN32_SkColorType, &bitmap);
34     uint8_t rowColor = 0;
35     for (int y = 0; y < SLIDE_SIZE; y++) {
36         uint32_t* dst = bitmap.getAddr32(0, y);
37         for (int x = 0; x < SLIDE_SIZE; x++) {
38             dst[x] = SkPackARGB32(rowColor, rowColor,
39                                   rowColor, rowColor);
40         }
41         if (y % PIXEL_SIZE_8888 == PIXEL_SIZE_8888 - 1) {
42             rowColor++;
43         }
44     }
45     return bitmap;
46 }
47 
make_argb4444_gradient()48 static SkBitmap make_argb4444_gradient() {
49     SkBitmap bitmap;
50     init_bitmap(kARGB_4444_SkColorType, &bitmap);
51     uint8_t rowColor = 0;
52     for (int y = 0; y < SLIDE_SIZE; y++) {
53         uint16_t* dst = bitmap.getAddr16(0, y);
54         for (int x = 0; x < SLIDE_SIZE; x++) {
55             dst[x] = SkPackARGB4444(rowColor, rowColor,
56                                     rowColor, rowColor);
57         }
58         if (y % PIXEL_SIZE_4444 == PIXEL_SIZE_4444 - 1) {
59             rowColor++;
60         }
61     }
62     return bitmap;
63 }
64 
make_argb8888_stripes()65 static SkBitmap make_argb8888_stripes() {
66     SkBitmap bitmap;
67     init_bitmap(kN32_SkColorType, &bitmap);
68     uint8_t rowColor = 0;
69     for (int y = 0; y < SLIDE_SIZE; y++) {
70         uint32_t* dst = bitmap.getAddr32(0, y);
71         for (int x = 0; x < SLIDE_SIZE; x++) {
72             dst[x] = SkPackARGB32(rowColor, rowColor,
73                                   rowColor, rowColor);
74         }
75         if (rowColor == 0) {
76             rowColor = 255;
77         } else {
78             rowColor = 0;
79         }
80     }
81     return bitmap;
82 }
83 
make_argb4444_stripes()84 static SkBitmap make_argb4444_stripes() {
85     SkBitmap bitmap;
86     init_bitmap(kARGB_4444_SkColorType, &bitmap);
87     uint8_t rowColor = 0;
88     for (int y = 0; y < SLIDE_SIZE; y++) {
89         uint16_t* dst = bitmap.getAddr16(0, y);
90         for (int x = 0; x < SLIDE_SIZE; x++) {
91             dst[x] = SkPackARGB4444(rowColor, rowColor,
92                                     rowColor, rowColor);
93         }
94         if (rowColor == 0) {
95             rowColor = 15;
96         } else {
97             rowColor = 0;
98         }
99     }
100     return bitmap;
101 }
102 
103 namespace skiagm {
104 
105 class BitmapPremulGM : public GM {
106 public:
BitmapPremulGM()107     BitmapPremulGM() {
108         this->setBGColor(SK_ColorWHITE);
109     }
110 
111 protected:
onShortName()112     SkString onShortName() override {
113         return SkString("bitmap_premul");
114     }
115 
onISize()116     SkISize onISize() override {
117         return SkISize::Make(SLIDE_SIZE * 2, SLIDE_SIZE * 2);
118     }
119 
onDraw(SkCanvas * canvas)120     void onDraw(SkCanvas* canvas) override {
121         SkScalar slideSize = SkIntToScalar(SLIDE_SIZE);
122         canvas->drawBitmap(make_argb8888_gradient(), 0, 0);
123         canvas->drawBitmap(make_argb4444_gradient(), slideSize, 0);
124         canvas->drawBitmap(make_argb8888_stripes(), 0, slideSize);
125         canvas->drawBitmap(make_argb4444_stripes(), slideSize, slideSize);
126     }
127 
128 private:
129     typedef GM INHERITED;
130 };
131 
132 DEF_GM( return new BitmapPremulGM; )
133 }
134