• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.mm"
6
7#include "base/mac/mac_util.h"
8#include "base/mac/scoped_nsobject.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace {
12
13class SkiaUtilsMacTest : public testing::Test {
14 public:
15  // Creates a red or blue bitmap.
16  SkBitmap CreateSkBitmap(int width, int height, bool isred, bool tfbit);
17
18  // Creates a red or blue image.
19  NSImage* CreateNSImage(int width, int height, bool isred);
20
21  // Checks that the given bitmap rep is actually red or blue.
22  void TestImageRep(NSBitmapImageRep* imageRep, bool isred);
23
24  // Checks that the given bitmap is actually red or blue.
25  void TestSkBitmap(const SkBitmap& bitmap, bool isred);
26
27  enum BitLockerTest {
28    TestIdentity = 0,
29    TestTranslate = 1,
30    TestClip = 2,
31    TestXClip = TestTranslate | TestClip,
32    TestNoBits = 4,
33    TestTranslateNoBits = TestTranslate | TestNoBits,
34    TestClipNoBits = TestClip | TestNoBits,
35    TestXClipNoBits = TestXClip | TestNoBits,
36  };
37  void RunBitLockerTest(BitLockerTest test);
38
39  // If not red, is blue.
40  // If not tfbit (twenty-four-bit), is 444.
41  void ShapeHelper(int width, int height, bool isred, bool tfbit);
42};
43
44SkBitmap SkiaUtilsMacTest::CreateSkBitmap(int width, int height,
45                                          bool isred, bool tfbit) {
46  SkBitmap bitmap;
47
48  if (tfbit)
49    bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
50  else
51    bitmap.setConfig(SkBitmap::kARGB_4444_Config, width, height);
52  bitmap.allocPixels();
53
54  if (isred)
55    bitmap.eraseRGB(0xff, 0, 0);
56  else
57    bitmap.eraseRGB(0, 0, 0xff);
58
59  return bitmap;
60}
61
62NSImage* 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
75void 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
101void 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?
118void 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  SkBitmap bitmap;
127  bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
128  bitmap.setPixels(bits);
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
161void 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
176TEST_F(SkiaUtilsMacTest, BitmapToNSImage_RedSquare64x64) {
177  ShapeHelper(64, 64, true, true);
178}
179
180TEST_F(SkiaUtilsMacTest, BitmapToNSImage_BlueRectangle199x19) {
181  ShapeHelper(199, 19, false, true);
182}
183
184TEST_F(SkiaUtilsMacTest, BitmapToNSImage_BlueRectangle444) {
185  ShapeHelper(200, 200, false, false);
186}
187
188TEST_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
200TEST_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
214TEST_F(SkiaUtilsMacTest, BitLocker_Identity) {
215  RunBitLockerTest(SkiaUtilsMacTest::TestIdentity);
216}
217
218TEST_F(SkiaUtilsMacTest, BitLocker_Translate) {
219  RunBitLockerTest(SkiaUtilsMacTest::TestTranslate);
220}
221
222TEST_F(SkiaUtilsMacTest, BitLocker_Clip) {
223  RunBitLockerTest(SkiaUtilsMacTest::TestClip);
224}
225
226TEST_F(SkiaUtilsMacTest, BitLocker_XClip) {
227  RunBitLockerTest(SkiaUtilsMacTest::TestXClip);
228}
229
230TEST_F(SkiaUtilsMacTest, BitLocker_NoBits) {
231  RunBitLockerTest(SkiaUtilsMacTest::TestNoBits);
232}
233
234TEST_F(SkiaUtilsMacTest, BitLocker_TranslateNoBits) {
235  RunBitLockerTest(SkiaUtilsMacTest::TestTranslateNoBits);
236}
237
238TEST_F(SkiaUtilsMacTest, BitLocker_ClipNoBits) {
239  RunBitLockerTest(SkiaUtilsMacTest::TestClipNoBits);
240}
241
242TEST_F(SkiaUtilsMacTest, BitLocker_XClipNoBits) {
243  RunBitLockerTest(SkiaUtilsMacTest::TestXClipNoBits);
244}
245
246}  // namespace
247
248