| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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. | |
| 4 | |
| 5 #include "skia/ext/skia_utils_mac.h" | |
| 6 | |
| 7 #import <AppKit/AppKit.h> | |
| 8 | |
| 9 #include "base/mac/scoped_nsobject.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 #include "third_party/skia/include/core/SkCanvas.h" | |
| 12 | |
| 13 namespace { | |
| 14 | |
| 15 class SkiaUtilsMacTest : public testing::Test { | |
| 16 public: | |
| 17 // Creates a red or blue bitmap. | |
| 18 SkBitmap CreateSkBitmap(int width, int height, bool isred, bool tfbit); | |
| 19 | |
| 20 // Creates a red or blue image. | |
| 21 NSImage* CreateNSImage(int width, int height, bool isred); | |
| 22 | |
| 23 // Checks that the given bitmap rep is actually red or blue. | |
| 24 void TestImageRep(NSBitmapImageRep* imageRep, bool isred); | |
| 25 | |
| 26 // Checks that the given bitmap is actually red or blue. | |
| 27 void TestSkBitmap(const SkBitmap& bitmap, bool isred); | |
| 28 | |
| 29 enum BitLockerTest { | |
| 30 TestIdentity = 0, | |
| 31 TestTranslate = 1, | |
| 32 TestClip = 2, | |
| 33 TestXClip = TestTranslate | TestClip, | |
| 34 TestNoBits = 4, | |
| 35 TestTranslateNoBits = TestTranslate | TestNoBits, | |
| 36 TestClipNoBits = TestClip | TestNoBits, | |
| 37 TestXClipNoBits = TestXClip | TestNoBits, | |
| 38 }; | |
| 39 void RunBitLockerTest(BitLockerTest test); | |
| 40 | |
| 41 // If not red, is blue. | |
| 42 // If not tfbit (twenty-four-bit), is 444. | |
| 43 void ShapeHelper(int width, int height, bool isred, bool tfbit); | |
| 44 }; | |
| 45 | |
| 46 SkBitmap SkiaUtilsMacTest::CreateSkBitmap(int width, int height, | |
| 47 bool isred, bool tfbit) { | |
| 48 SkColorType ct = tfbit ? kN32_SkColorType : kARGB_4444_SkColorType; | |
| 49 SkImageInfo info = SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType); | |
| 50 | |
| 51 SkBitmap bitmap; | |
| 52 bitmap.allocPixels(info); | |
| 53 | |
| 54 if (isred) | |
| 55 bitmap.eraseARGB(0xff, 0xff, 0, 0); | |
| 56 else | |
| 57 bitmap.eraseARGB(0xff, 0, 0, 0xff); | |
| 58 | |
| 59 return bitmap; | |
| 60 } | |
| 61 | |
| 62 NSImage* SkiaUtilsMacTest::CreateNSImage(int width, int height, bool isred) { | |
| 63 base::scoped_nsobject<NSImage> image( | |
| 64 [[NSImage alloc] initWithSize:NSMakeSize(width, height)]); | |
| 65 [image lockFocus]; | |
| 66 if (isred) | |
| 67 [[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] set]; | |
| 68 else | |
| 69 [[NSColor colorWithDeviceRed:0.0 green:0.0 blue:1.0 alpha:1.0] set]; | |
| 70 NSRectFill(NSMakeRect(0, 0, width, height)); | |
| 71 [image unlockFocus]; | |
| 72 return [image.release() autorelease]; | |
| 73 } | |
| 74 | |
| 75 void SkiaUtilsMacTest::TestImageRep(NSBitmapImageRep* imageRep, bool isred) { | |
| 76 // Get the color of a pixel and make sure it looks fine | |
| 77 int x = [imageRep size].width > 17 ? 17 : 0; | |
| 78 int y = [imageRep size].height > 17 ? 17 : 0; | |
| 79 NSColor* color = [imageRep colorAtX:x y:y]; | |
| 80 CGFloat red = 0, green = 0, blue = 0, alpha = 0; | |
| 81 | |
| 82 // SkBitmapToNSImage returns a bitmap in the calibrated color space (sRGB), | |
| 83 // while NSReadPixel returns a color in the device color space. Convert back | |
| 84 // to the calibrated color space before testing. | |
| 85 color = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; | |
| 86 | |
| 87 [color getRed:&red green:&green blue:&blue alpha:&alpha]; | |
| 88 | |
| 89 // Be tolerant of floating point rounding and lossy color space conversions. | |
| 90 if (isred) { | |
| 91 EXPECT_GT(red, 0.95); | |
| 92 EXPECT_LT(blue, 0.05); | |
| 93 } else { | |
| 94 EXPECT_LT(red, 0.05); | |
| 95 EXPECT_GT(blue, 0.95); | |
| 96 } | |
| 97 EXPECT_LT(green, 0.05); | |
| 98 EXPECT_GT(alpha, 0.95); | |
| 99 } | |
| 100 | |
| 101 void SkiaUtilsMacTest::TestSkBitmap(const SkBitmap& bitmap, bool isred) { | |
| 102 int x = bitmap.width() > 17 ? 17 : 0; | |
| 103 int y = bitmap.height() > 17 ? 17 : 0; | |
| 104 SkColor color = bitmap.getColor(x, y); | |
| 105 | |
| 106 if (isred) { | |
| 107 EXPECT_EQ(255u, SkColorGetR(color)); | |
| 108 EXPECT_EQ(0u, SkColorGetB(color)); | |
| 109 } else { | |
| 110 EXPECT_EQ(0u, SkColorGetR(color)); | |
| 111 EXPECT_EQ(255u, SkColorGetB(color)); | |
| 112 } | |
| 113 EXPECT_EQ(0u, SkColorGetG(color)); | |
| 114 EXPECT_EQ(255u, SkColorGetA(color)); | |
| 115 } | |
| 116 | |
| 117 // setBitmapDevice has been deprecated/removed. Is this test still useful? | |
| 118 void SkiaUtilsMacTest::RunBitLockerTest(BitLockerTest test) { | |
| 119 const unsigned width = 2; | |
| 120 const unsigned height = 2; | |
| 121 const unsigned storageSize = width * height; | |
| 122 const unsigned original[] = {0xFF333333, 0xFF666666, 0xFF999999, 0xFFCCCCCC}; | |
| 123 EXPECT_EQ(storageSize, sizeof(original) / sizeof(original[0])); | |
| 124 unsigned bits[storageSize]; | |
| 125 memcpy(bits, original, sizeof(original)); | |
| 126 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); | |
| 127 SkBitmap bitmap; | |
| 128 bitmap.installPixels(info, bits, info.minRowBytes()); | |
| 129 | |
| 130 SkCanvas canvas(bitmap); | |
| 131 if (test & TestTranslate) | |
| 132 canvas.translate(width / 2, 0); | |
| 133 if (test & TestClip) { | |
| 134 SkRect clipRect = {0, height / 2, width, height}; | |
| 135 canvas.clipRect(clipRect); | |
| 136 } | |
| 137 { | |
| 138 gfx::SkiaBitLocker bitLocker(&canvas); | |
| 139 CGContextRef cgContext = bitLocker.cgContext(); | |
| 140 CGColorRef testColor = CGColorGetConstantColor(kCGColorWhite); | |
| 141 CGContextSetFillColorWithColor(cgContext, testColor); | |
| 142 CGRect cgRect = {{0, 0}, {width, height}}; | |
| 143 CGContextFillRect(cgContext, cgRect); | |
| 144 if (test & TestNoBits) { | |
| 145 if (test & TestClip) { | |
| 146 SkRect clipRect = {0, height / 2, width, height}; | |
| 147 canvas.clipRect(clipRect); | |
| 148 } | |
| 149 } | |
| 150 } | |
| 151 const unsigned results[][storageSize] = { | |
| 152 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, // identity | |
| 153 {0xFF333333, 0xFFFFFFFF, 0xFF999999, 0xFFFFFFFF}, // translate | |
| 154 {0xFF333333, 0xFF666666, 0xFFFFFFFF, 0xFFFFFFFF}, // clip | |
| 155 {0xFF333333, 0xFF666666, 0xFF999999, 0xFFFFFFFF} // translate | clip | |
| 156 }; | |
| 157 for (unsigned index = 0; index < storageSize; index++) | |
| 158 EXPECT_EQ(results[test & ~TestNoBits][index], bits[index]); | |
| 159 } | |
| 160 | |
| 161 void SkiaUtilsMacTest::ShapeHelper(int width, int height, | |
| 162 bool isred, bool tfbit) { | |
| 163 SkBitmap thing(CreateSkBitmap(width, height, isred, tfbit)); | |
| 164 | |
| 165 // Confirm size | |
| 166 NSImage* image = gfx::SkBitmapToNSImage(thing); | |
| 167 EXPECT_DOUBLE_EQ([image size].width, (double)width); | |
| 168 EXPECT_DOUBLE_EQ([image size].height, (double)height); | |
| 169 | |
| 170 EXPECT_TRUE([[image representations] count] == 1); | |
| 171 EXPECT_TRUE([[[image representations] lastObject] | |
| 172 isKindOfClass:[NSBitmapImageRep class]]); | |
| 173 TestImageRep([[image representations] lastObject], isred); | |
| 174 } | |
| 175 | |
| 176 TEST_F(SkiaUtilsMacTest, BitmapToNSImage_RedSquare64x64) { | |
| 177 ShapeHelper(64, 64, true, true); | |
| 178 } | |
| 179 | |
| 180 TEST_F(SkiaUtilsMacTest, BitmapToNSImage_BlueRectangle199x19) { | |
| 181 ShapeHelper(199, 19, false, true); | |
| 182 } | |
| 183 | |
| 184 TEST_F(SkiaUtilsMacTest, BitmapToNSImage_BlueRectangle444) { | |
| 185 ShapeHelper(200, 200, false, false); | |
| 186 } | |
| 187 | |
| 188 TEST_F(SkiaUtilsMacTest, BitmapToNSBitmapImageRep_BlueRectangle20x30) { | |
| 189 int width = 20; | |
| 190 int height = 30; | |
| 191 | |
| 192 SkBitmap bitmap(CreateSkBitmap(width, height, false, true)); | |
| 193 NSBitmapImageRep* imageRep = gfx::SkBitmapToNSBitmapImageRep(bitmap); | |
| 194 | |
| 195 EXPECT_DOUBLE_EQ(width, [imageRep size].width); | |
| 196 EXPECT_DOUBLE_EQ(height, [imageRep size].height); | |
| 197 TestImageRep(imageRep, false); | |
| 198 } | |
| 199 | |
| 200 TEST_F(SkiaUtilsMacTest, NSImageRepToSkBitmap) { | |
| 201 int width = 10; | |
| 202 int height = 15; | |
| 203 bool isred = true; | |
| 204 | |
| 205 NSImage* image = CreateNSImage(width, height, isred); | |
| 206 EXPECT_EQ(1u, [[image representations] count]); | |
| 207 NSBitmapImageRep* imageRep = [[image representations] lastObject]; | |
| 208 NSColorSpace* colorSpace = [NSColorSpace deviceRGBColorSpace]; | |
| 209 SkBitmap bitmap(gfx::NSImageRepToSkBitmapWithColorSpace( | |
| 210 imageRep, [image size], false, [colorSpace CGColorSpace])); | |
| 211 TestSkBitmap(bitmap, isred); | |
| 212 } | |
| 213 | |
| 214 TEST_F(SkiaUtilsMacTest, BitLocker_Identity) { | |
| 215 RunBitLockerTest(SkiaUtilsMacTest::TestIdentity); | |
| 216 } | |
| 217 | |
| 218 TEST_F(SkiaUtilsMacTest, BitLocker_Translate) { | |
| 219 RunBitLockerTest(SkiaUtilsMacTest::TestTranslate); | |
| 220 } | |
| 221 | |
| 222 TEST_F(SkiaUtilsMacTest, BitLocker_Clip) { | |
| 223 RunBitLockerTest(SkiaUtilsMacTest::TestClip); | |
| 224 } | |
| 225 | |
| 226 TEST_F(SkiaUtilsMacTest, BitLocker_XClip) { | |
| 227 RunBitLockerTest(SkiaUtilsMacTest::TestXClip); | |
| 228 } | |
| 229 | |
| 230 TEST_F(SkiaUtilsMacTest, BitLocker_NoBits) { | |
| 231 RunBitLockerTest(SkiaUtilsMacTest::TestNoBits); | |
| 232 } | |
| 233 | |
| 234 TEST_F(SkiaUtilsMacTest, BitLocker_TranslateNoBits) { | |
| 235 RunBitLockerTest(SkiaUtilsMacTest::TestTranslateNoBits); | |
| 236 } | |
| 237 | |
| 238 TEST_F(SkiaUtilsMacTest, BitLocker_ClipNoBits) { | |
| 239 RunBitLockerTest(SkiaUtilsMacTest::TestClipNoBits); | |
| 240 } | |
| 241 | |
| 242 TEST_F(SkiaUtilsMacTest, BitLocker_XClipNoBits) { | |
| 243 RunBitLockerTest(SkiaUtilsMacTest::TestXClipNoBits); | |
| 244 } | |
| 245 | |
| 246 } // namespace | |
| 247 | |
| OLD | NEW |