1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/ext/skia_utils_mac.h"
#import <AppKit/AppKit.h>
#include "base/apple/foundation_util.h"
#include "base/mac/mac_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
namespace {
class SkiaUtilsMacTest : public testing::Test {
public:
enum class TestColor {
kRed,
kBlue,
};
enum class ColorType {
k24Bit, // kN32_SkColorType
k16Bit, // kARGB_4444_SkColorType
};
// Creates a test bitmap of the specified color and color type.
SkBitmap CreateSkBitmap(int width,
int height,
TestColor test_color,
ColorType color_type);
// Creates a red image.
NSImage* CreateNSImage(int width, int height);
// Checks that the given bitmap rep is actually the correct color.
void TestImageRep(NSBitmapImageRep* image_rep, TestColor test_color);
// Checks that the given bitmap is red.
void TestSkBitmap(const SkBitmap& bitmap);
// Tests `SkBitmapToNSImage` for a specific combination of color and color
// type. Creates a bitmap with `CreateSkBitmap`, converts it into an
// `NSImage`, then tests it with `TestImageRep`.
void ShapeHelper(int width,
int height,
TestColor test_color,
ColorType color_type);
};
SkBitmap SkiaUtilsMacTest::CreateSkBitmap(int width,
int height,
TestColor test_color,
ColorType color_type) {
SkColorType sk_color_type = color_type == ColorType::k24Bit
? kN32_SkColorType
: kARGB_4444_SkColorType;
SkImageInfo info =
SkImageInfo::Make(width, height, sk_color_type, kPremul_SkAlphaType,
SkColorSpace::MakeSRGB());
SkBitmap bitmap;
bitmap.allocPixels(info);
if (test_color == TestColor::kRed)
bitmap.eraseARGB(0xff, 0xff, 0, 0);
else
bitmap.eraseARGB(0xff, 0, 0, 0xff);
return bitmap;
}
NSImage* SkiaUtilsMacTest::CreateNSImage(int width, int height) {
// An `NSBitmapImageRep` can only be created with a handful of named color
// spaces, and sRGB isn't one. Do a retagging after creation to switch it.
NSBitmapImageRep* initial_bitmap = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:nil
pixelsWide:width
pixelsHigh:height
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:0
bytesPerRow:4 * width
bitsPerPixel:32];
NSBitmapImageRep* bitmap = [initial_bitmap
bitmapImageRepByRetaggingWithColorSpace:NSColorSpace.sRGBColorSpace];
{
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
NSGraphicsContext.currentContext =
[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap];
CGFloat comps[] = {1.0, 0.0, 0.0, 1.0};
NSColor* color = [NSColor colorWithColorSpace:NSColorSpace.sRGBColorSpace
components:comps
count:4];
[color set];
NSRectFill(NSMakeRect(0, 0, width, height));
}
NSImage* image = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
[image addRepresentation:bitmap];
return image;
}
void SkiaUtilsMacTest::TestImageRep(NSBitmapImageRep* image_rep,
TestColor test_color) {
// Get the color of a pixel and make sure it looks fine.
int x = image_rep.size.width > 17 ? 17 : 0;
int y = image_rep.size.height > 17 ? 17 : 0;
NSColor* color = [image_rep colorAtX:x y:y];
ASSERT_EQ(4, color.numberOfComponents);
CGFloat color_components[4];
[color getComponents:color_components];
const CGFloat& red = color_components[0];
const CGFloat& green = color_components[1];
const CGFloat& blue = color_components[2];
const CGFloat& alpha = color_components[3];
// Be a little tolerant of floating point rounding, maybe, but everything is
// done in SRGB so there should be no color space conversion affecting things.
if (test_color == TestColor::kRed) {
EXPECT_GT(red, 0.9995);
EXPECT_LT(blue, 0.0005);
} else {
EXPECT_LT(red, 0.0005);
EXPECT_GT(blue, 0.9995);
}
EXPECT_LT(green, 0.0005);
EXPECT_GT(alpha, 0.9995);
}
void SkiaUtilsMacTest::TestSkBitmap(const SkBitmap& bitmap) {
int x = bitmap.width() > 17 ? 17 : 0;
int y = bitmap.height() > 17 ? 17 : 0;
SkColor color = bitmap.getColor(x, y);
EXPECT_EQ(255u, SkColorGetR(color));
EXPECT_EQ(0u, SkColorGetB(color));
EXPECT_EQ(0u, SkColorGetG(color));
EXPECT_EQ(255u, SkColorGetA(color));
}
void SkiaUtilsMacTest::ShapeHelper(int width,
int height,
TestColor test_color,
ColorType color_type) {
SkBitmap bitmap(CreateSkBitmap(width, height, test_color, color_type));
// Confirm size
NSImage* image = skia::SkBitmapToNSImage(bitmap);
EXPECT_DOUBLE_EQ(image.size.width, (CGFloat)width);
EXPECT_DOUBLE_EQ(image.size.height, (CGFloat)height);
EXPECT_TRUE(image.representations.count == 1);
EXPECT_TRUE([image.representations.lastObject
isKindOfClass:[NSBitmapImageRep class]]);
TestImageRep(base::apple::ObjCCastStrict<NSBitmapImageRep>(
image.representations.lastObject),
test_color);
}
TEST_F(SkiaUtilsMacTest, BitmapToNSImage_RedSquare64x64) {
ShapeHelper(64, 64, TestColor::kRed, ColorType::k24Bit);
}
TEST_F(SkiaUtilsMacTest, BitmapToNSImage_BlueRectangle199x19) {
ShapeHelper(199, 19, TestColor::kBlue, ColorType::k24Bit);
}
TEST_F(SkiaUtilsMacTest, BitmapToNSImage_BlueRectangle444) {
ShapeHelper(200, 200, TestColor::kBlue, ColorType::k16Bit);
}
TEST_F(SkiaUtilsMacTest, BitmapToNSBitmapImageRep_BlueRectangle20x30) {
int width = 20;
int height = 30;
SkBitmap bitmap(
CreateSkBitmap(width, height, TestColor::kBlue, ColorType::k24Bit));
NSBitmapImageRep* imageRep = skia::SkBitmapToNSBitmapImageRep(bitmap);
EXPECT_DOUBLE_EQ(width, imageRep.size.width);
EXPECT_DOUBLE_EQ(height, imageRep.size.height);
TestImageRep(imageRep, TestColor::kBlue);
}
TEST_F(SkiaUtilsMacTest, NSImageRepToSkBitmap) {
int width = 10;
int height = 15;
NSImage* image = CreateNSImage(width, height);
EXPECT_EQ(1u, image.representations.count);
NSBitmapImageRep* imageRep = base::apple::ObjCCastStrict<NSBitmapImageRep>(
image.representations.lastObject);
SkBitmap bitmap(skia::NSImageRepToSkBitmap(imageRep, image.size, false));
TestSkBitmap(bitmap);
}
} // namespace
|