1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "skia/ext/skia_utils_mac.mm"
6 #include "testing/gtest/include/gtest/gtest.h"
10 class SkiaUtilsMacTest : public testing::Test {
12 // Creates a red or blue bitmap.
13 SkBitmap CreateSkBitmap(int width, int height, bool isred, bool tfbit);
15 // Creates a red or blue image.
16 NSImage* CreateNSImage(int width, int height, bool isred);
18 // Checks that the given bitmap rep is actually red or blue.
19 void TestImageRep(NSBitmapImageRep* imageRep, bool isred);
21 // Checks that the given bitmap is actually red or blue.
22 void TestSkBitmap(const SkBitmap& bitmap, bool isred);
28 TestXClip = TestTranslate | TestClip
30 void RunBitLockerTest(BitLockerTest test);
32 // If not red, is blue.
33 // If not tfbit (twenty-four-bit), is 444.
34 void ShapeHelper(int width, int height, bool isred, bool tfbit);
37 SkBitmap SkiaUtilsMacTest::CreateSkBitmap(int width, int height,
38 bool isred, bool tfbit) {
42 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
44 bitmap.setConfig(SkBitmap::kARGB_4444_Config, width, height);
48 bitmap.eraseRGB(0xff, 0, 0);
50 bitmap.eraseRGB(0, 0, 0xff);
55 NSImage* SkiaUtilsMacTest::CreateNSImage(int width, int height, bool isred) {
56 scoped_nsobject<NSImage> image(
57 [[NSImage alloc] initWithSize:NSMakeSize(width, height)]);
60 [[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] set];
62 [[NSColor colorWithDeviceRed:0.0 green:0.0 blue:1.0 alpha:1.0] set];
63 NSRectFill(NSMakeRect(0, 0, width, height));
65 return [image.release() autorelease];
68 void SkiaUtilsMacTest::TestImageRep(NSBitmapImageRep* imageRep, bool isred) {
69 // Get the color of a pixel and make sure it looks fine
70 int x = [imageRep size].width > 17 ? 17 : 0;
71 int y = [imageRep size].height > 17 ? 17 : 0;
72 NSColor* color = [imageRep colorAtX:x y:y];
73 CGFloat red = 0, green = 0, blue = 0, alpha = 0;
75 // SkBitmapToNSImage returns a bitmap in the calibrated color space (sRGB),
76 // while NSReadPixel returns a color in the device color space. Convert back
77 // to the calibrated color space before testing.
78 color = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
80 [color getRed:&red green:&green blue:&blue alpha:&alpha];
82 // Be tolerant of floating point rounding and lossy color space conversions.
85 EXPECT_LT(blue, 0.05);
88 EXPECT_GT(blue, 0.95);
90 EXPECT_LT(green, 0.05);
91 EXPECT_GT(alpha, 0.95);
94 void SkiaUtilsMacTest::TestSkBitmap(const SkBitmap& bitmap, bool isred) {
95 int x = bitmap.width() > 17 ? 17 : 0;
96 int y = bitmap.height() > 17 ? 17 : 0;
97 SkColor color = bitmap.getColor(x, y);
99 // Be tolerant of lossy color space conversions.
100 // TODO(sail): Fix color space conversion issues, http://crbug.com/79946
102 EXPECT_GT(SkColorGetR(color), 245u);
103 EXPECT_LT(SkColorGetB(color), 10u);
105 EXPECT_LT(SkColorGetR(color), 10u);
106 EXPECT_GT(SkColorGetB(color), 245u);
108 EXPECT_LT(SkColorGetG(color), 10u);
109 EXPECT_GT(SkColorGetA(color), 245u);
112 void SkiaUtilsMacTest::RunBitLockerTest(BitLockerTest test) {
113 const unsigned width = 2;
114 const unsigned height = 2;
115 const unsigned storageSize = width * height;
116 const unsigned original[] = {0xFF333333, 0xFF666666, 0xFF999999, 0xFFCCCCCC};
117 EXPECT_EQ(storageSize, sizeof(original) / sizeof(original[0]));
118 unsigned bits[storageSize];
119 memcpy(bits, original, sizeof(original));
121 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
122 bitmap.setPixels(bits);
124 canvas.setBitmapDevice(bitmap);
125 if (test & TestTranslate)
126 canvas.translate(width / 2, 0);
127 if (test & TestClip) {
128 SkRect clipRect = {0, height / 2, width, height};
129 canvas.clipRect(clipRect);
131 gfx::SkiaBitLocker bitLocker(&canvas);
132 CGContextRef cgContext = bitLocker.cgContext();
133 CGColorRef testColor = CGColorGetConstantColor(kCGColorWhite);
134 CGContextSetFillColorWithColor(cgContext, testColor);
135 CGRect cgRect = {{0, 0}, {width, height}};
136 CGContextFillRect(cgContext, cgRect);
137 const unsigned results[][storageSize] = {
138 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, // identity
139 {0xFF333333, 0xFFFFFFFF, 0xFF999999, 0xFFFFFFFF}, // translate
140 {0xFF333333, 0xFF666666, 0xFFFFFFFF, 0xFFFFFFFF}, // clip
141 {0xFF333333, 0xFF666666, 0xFF999999, 0xFFFFFFFF} // translate | clip
143 for (unsigned index = 0; index < storageSize; index++)
144 EXPECT_EQ(results[test][index], bits[index]);
147 void SkiaUtilsMacTest::ShapeHelper(int width, int height,
148 bool isred, bool tfbit) {
149 SkBitmap thing(CreateSkBitmap(width, height, isred, tfbit));
152 NSImage* image = gfx::SkBitmapToNSImage(thing);
153 EXPECT_DOUBLE_EQ([image size].width, (double)width);
154 EXPECT_DOUBLE_EQ([image size].height, (double)height);
156 EXPECT_TRUE([[image representations] count] == 1);
157 EXPECT_TRUE([[[image representations] lastObject]
158 isKindOfClass:[NSBitmapImageRep class]]);
159 TestImageRep([[image representations] lastObject], isred);
162 TEST_F(SkiaUtilsMacTest, FAILS_BitmapToNSImage_RedSquare64x64) {
163 ShapeHelper(64, 64, true, true);
166 TEST_F(SkiaUtilsMacTest, BitmapToNSImage_BlueRectangle199x19) {
167 ShapeHelper(199, 19, false, true);
170 TEST_F(SkiaUtilsMacTest, FAILS_BitmapToNSImage_BlueRectangle444) {
171 ShapeHelper(200, 200, false, false);
174 TEST_F(SkiaUtilsMacTest, FAILS_MultipleBitmapsToNSImage) {
180 SkBitmap redBitmap(CreateSkBitmap(redWidth, redHeight, true, true));
181 SkBitmap blueBitmap(CreateSkBitmap(blueWidth, blueHeight, false, true));
182 std::vector<const SkBitmap*> bitmaps;
183 bitmaps.push_back(&redBitmap);
184 bitmaps.push_back(&blueBitmap);
186 NSImage* image = gfx::SkBitmapsToNSImage(bitmaps);
188 // Image size should be the same as the smallest bitmap.
189 EXPECT_DOUBLE_EQ(redWidth, [image size].width);
190 EXPECT_DOUBLE_EQ(redHeight, [image size].height);
192 EXPECT_EQ(2u, [[image representations] count]);
194 for (NSBitmapImageRep* imageRep in [image representations]) {
195 bool isred = [imageRep size].width == redWidth;
197 EXPECT_DOUBLE_EQ(redHeight, [imageRep size].height);
199 EXPECT_DOUBLE_EQ(blueWidth, [imageRep size].width);
200 EXPECT_DOUBLE_EQ(blueHeight, [imageRep size].height);
202 TestImageRep(imageRep, isred);
206 TEST_F(SkiaUtilsMacTest, NSImageRepToSkBitmap) {
211 NSImage* image = CreateNSImage(width, height, isred);
212 EXPECT_EQ(1u, [[image representations] count]);
213 NSBitmapImageRep* imageRep = [[image representations] lastObject];
214 SkBitmap bitmap(gfx::NSImageRepToSkBitmap(imageRep, [image size], false));
215 TestSkBitmap(bitmap, isred);
218 TEST_F(SkiaUtilsMacTest, BitLocker_Identity) {
219 RunBitLockerTest(SkiaUtilsMacTest::TestIdentity);
222 TEST_F(SkiaUtilsMacTest, BitLocker_Translate) {
223 RunBitLockerTest(SkiaUtilsMacTest::TestTranslate);
226 TEST_F(SkiaUtilsMacTest, BitLocker_Clip) {
227 RunBitLockerTest(SkiaUtilsMacTest::TestClip);
230 TEST_F(SkiaUtilsMacTest, BitLocker_XClip) {
231 RunBitLockerTest(SkiaUtilsMacTest::TestXClip);