TransparencyWinTest.cpp [plain text]
#include "config.h"
#include "TransparencyWin.h"
#include "AffineTransform.h"
#include "ImageBuffer.h"
#include <gtest/gtest.h>
#include <windows.h>
namespace WebCore {
static FloatRect RECTToFloatRect(const RECT* rect)
{
return FloatRect(static_cast<float>(rect->left),
static_cast<float>(rect->top),
static_cast<float>(rect->right - rect->left),
static_cast<float>(rect->bottom - rect->top));
}
static void drawNativeRect(GraphicsContext* context,
int x, int y, int w, int h)
{
SkCanvas* canvas = context->platformContext()->canvas();
HDC dc = skia::BeginPlatformPaint(canvas);
RECT innerRc;
innerRc.left = x;
innerRc.top = y;
innerRc.right = x + w;
innerRc.bottom = y + h;
FillRect(dc, &innerRc,
reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
skia::EndPlatformPaint(canvas);
}
static Color getPixelAt(GraphicsContext* context, int x, int y)
{
const SkBitmap& bitmap = context->platformContext()->canvas()->getTopDevice()->accessBitmap(false);
return Color(*reinterpret_cast<const RGBA32*>(bitmap.getAddr32(x, y)));
}
static void clearTopLayerAlphaChannel(GraphicsContext* context)
{
SkBitmap& bitmap = const_cast<SkBitmap&>(context->platformContext()->canvas()->getTopDevice()->accessBitmap(false));
for (int y = 0; y < bitmap.height(); y++) {
uint32_t* row = bitmap.getAddr32(0, y);
for (int x = 0; x < bitmap.width(); x++)
row[x] &= 0x00FFFFFF;
}
}
static void clearTopLayerAlphaPixel(GraphicsContext* context, int x, int y)
{
SkBitmap& bitmap = const_cast<SkBitmap&>(context->platformContext()->canvas()->getTopDevice()->accessBitmap(false));
*bitmap.getAddr32(x, y) &= 0x00FFFFFF;
}
static std::ostream& operator<<(std::ostream& out, const Color& c)
{
std::ios_base::fmtflags oldFlags = out.flags(std::ios_base::hex |
std::ios_base::showbase);
out << c.rgb();
out.flags(oldFlags);
return out;
}
TEST(TransparencyWin, NoLayer)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(17, 16), ColorSpaceDeviceRGB));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::NoLayer,
TransparencyWin::KeepTransform,
IntRect(1, 1, 14, 12));
EXPECT_TRUE(src->context() == helper.context());
EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
}
src->context()->save();
src->context()->scale(FloatSize(2.0, 0.5));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::NoLayer,
TransparencyWin::ScaleTransform,
IntRect(2, 2, 6, 6));
helper.composite();
EXPECT_TRUE(src->context() == helper.context());
EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize);
EXPECT_TRUE(IntRect(4, 1, 12, 3) == helper.drawRect());
}
src->context()->restore();
}
TEST(TransparencyWin, WhiteLayer)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::WhiteLayer,
TransparencyWin::KeepTransform,
IntRect(1, 1, 14, 12));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
}
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::WhiteLayer,
TransparencyWin::Untransform,
IntRect(1, 1, 14, 12));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
EXPECT_TRUE(IntRect(0, 0, 14, 12) == helper.drawRect());
}
src->context()->save();
src->context()->scale(FloatSize(2.0, 0.5));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::WhiteLayer,
TransparencyWin::ScaleTransform,
IntRect(2, 2, 6, 6));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize);
EXPECT_TRUE(IntRect(0, 0, 12, 3) == helper.drawRect());
}
src->context()->restore();
}
TEST(TransparencyWin, TextComposite)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::TextComposite,
TransparencyWin::KeepTransform,
IntRect(1, 1, 14, 12));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
}
}
TEST(TransparencyWin, OpaqueCompositeLayer)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::KeepTransform,
IntRect(1, 1, 14, 12));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect());
}
src->context()->save();
src->context()->translate(0, -1);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::KeepTransform,
IntRect(1, 1, 14, 14));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(14, 14) == helper.m_layerSize);
EXPECT_TRUE(IntRect(1, 1, 14, 14) == helper.drawRect());
}
src->context()->restore();
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::Untransform,
IntRect(1, 1, 14, 12));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize);
EXPECT_TRUE(IntRect(0, 0, 14, 12) == helper.drawRect());
}
src->context()->save();
src->context()->scale(FloatSize(2.0, 0.5));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::ScaleTransform,
IntRect(2, 2, 6, 6));
helper.composite();
EXPECT_TRUE(src->context() != helper.context());
EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize);
EXPECT_TRUE(IntRect(0, 0, 12, 3) == helper.drawRect());
}
src->context()->restore();
}
TEST(TransparencyWin, WhiteLayerPixelTest)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::WhiteLayer,
TransparencyWin::KeepTransform,
IntRect(1, 1, 14, 14));
drawNativeRect(helper.context(), 3, 3, 1, 1);
clearTopLayerAlphaChannel(helper.context());
helper.composite();
}
EXPECT_EQ(Color(Color::transparent), getPixelAt(src->context(), 0, 0));
EXPECT_EQ(Color(Color::white), getPixelAt(src->context(), 2, 2));
EXPECT_EQ(Color(Color::black), getPixelAt(src->context(), 3, 3));
EXPECT_EQ(Color(Color::white), getPixelAt(src->context(), 4, 4));
}
TEST(TransparencyWin, OpaqueCompositeLayerPixel)
{
Color red(0xFFFF0000), darkRed(0xFFBF0000);
Color green(0xFF00FF00);
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
FloatRect fullRect(0, 0, 16, 16);
src->context()->fillRect(fullRect, red, ColorSpaceDeviceRGB);
src->context()->beginTransparencyLayer(0.5);
FloatRect rightHalf(8, 0, 8, 16);
src->context()->fillRect(rightHalf, green, ColorSpaceDeviceRGB);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::KeepTransform,
IntRect(1, 1, 14, 14));
FloatRect inner(2, 2, 12, 12);
helper.context()->fillRect(inner, Color(0x7f000000), ColorSpaceDeviceRGB);
clearTopLayerAlphaPixel(helper.context(), 1, 1);
clearTopLayerAlphaPixel(helper.context(), 12, 12);
helper.composite();
}
src->context()->endTransparencyLayer();
EXPECT_EQ(red, getPixelAt(src->context(), 0, 0));
EXPECT_EQ(red, getPixelAt(src->context(), 1, 1));
EXPECT_EQ(darkRed, getPixelAt(src->context(), 2, 2));
Color darkGreenRed(0xFF803f00);
EXPECT_EQ(darkGreenRed, getPixelAt(src->context(), 13, 13));
Color greenRed(0xFF807F00);
EXPECT_EQ(greenRed, getPixelAt(src->context(), 14, 14));
EXPECT_EQ(greenRed, getPixelAt(src->context(), 15, 15));
}
TEST(TransparencyWin, TranslateOpaqueCompositeLayer)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
Color white(0xFFFFFFFF);
FloatRect fullRect(0, 0, 16, 16);
src->context()->fillRect(fullRect, white, ColorSpaceDeviceRGB);
src->context()->save();
src->context()->translate(0, -8);
Color red(0xFFFF0000);
Color green(0xFF00FF00);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::KeepTransform,
IntRect(0, 0, 16, 16));
FloatRect bottomRight(15, 15, 1, 1);
helper.context()->fillRect(bottomRight, green, ColorSpaceDeviceRGB);
helper.composite();
}
src->context()->restore();
EXPECT_EQ(green, getPixelAt(src->context(), 15, 7));
}
TEST(TransparencyWin, RotateOpaqueCompositeLayer)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
Color white(0xFFFFFFFF);
FloatRect fullRect(0, 0, 16, 16);
src->context()->fillRect(fullRect, white, ColorSpaceDeviceRGB);
src->context()->save();
AffineTransform cw90(0, 1, -1, 0, 0, 0);
src->context()->concatCTM(cw90);
src->context()->beginTransparencyLayer(0.5);
FloatRect blackRect(0, -9, 16, 2);
Color black(0xFF000000);
src->context()->fillRect(blackRect, black, ColorSpaceDeviceRGB);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::Untransform,
IntRect(1, -15, 14, 14));
helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000), ColorSpaceDeviceRGB);
clearTopLayerAlphaChannel(helper.context());
helper.composite();
}
src->context()->endTransparencyLayer();
EXPECT_EQ(white, getPixelAt(src->context(), 0, 0));
Color gray(0xFF808080);
EXPECT_EQ(white, getPixelAt(src->context(), 6, 0));
EXPECT_EQ(gray, getPixelAt(src->context(), 7, 0));
EXPECT_EQ(gray, getPixelAt(src->context(), 8, 0));
EXPECT_EQ(white, getPixelAt(src->context(), 9, 0));
EXPECT_EQ(white, getPixelAt(src->context(), 6, 15));
EXPECT_EQ(gray, getPixelAt(src->context(), 7, 15));
EXPECT_EQ(gray, getPixelAt(src->context(), 8, 15));
EXPECT_EQ(white, getPixelAt(src->context(), 9, 15));
Color redwhite(0xFFdfbfbf);
Color redgray(0xFF9f8080);
EXPECT_EQ(white, getPixelAt(src->context(), 0, 1));
EXPECT_EQ(redwhite, getPixelAt(src->context(), 1, 1));
EXPECT_EQ(redwhite, getPixelAt(src->context(), 6, 1));
EXPECT_EQ(redgray, getPixelAt(src->context(), 7, 1));
EXPECT_EQ(redgray, getPixelAt(src->context(), 8, 1));
EXPECT_EQ(redwhite, getPixelAt(src->context(), 9, 1));
EXPECT_EQ(redwhite, getPixelAt(src->context(), 14, 1));
EXPECT_EQ(white, getPixelAt(src->context(), 15, 1));
src->context()->restore();
}
TEST(TransparencyWin, DISABLED_TranslateScaleOpaqueCompositeLayer)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
Color white(0xFFFFFFFF);
FloatRect topRect(0, 0, 16, 8);
src->context()->fillRect(topRect, white, ColorSpaceDeviceRGB);
Color red(0xFFFF0000);
FloatRect bottomRect(0, 8, 16, 8);
src->context()->fillRect(bottomRect, red, ColorSpaceDeviceRGB);
src->context()->save();
AffineTransform left;
left.translate(-1, 0);
AffineTransform scale;
scale.scale(2.0);
src->context()->concatCTM(scale);
AffineTransform up;
up.translate(0, -1);
src->context()->concatCTM(up);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::KeepTransform,
IntRect(1, -15, 14, 14));
helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000), ColorSpaceDeviceRGB);
clearTopLayerAlphaChannel(helper.context());
helper.composite();
}
}
TEST(TransparencyWin, Scale)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
FloatRect fullBuffer(0, 0, 16, 16);
src->context()->fillRect(fullBuffer, Color::white, ColorSpaceDeviceRGB);
src->context()->save();
AffineTransform scale;
scale.scale(2.0);
src->context()->concatCTM(scale);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::NoLayer,
TransparencyWin::ScaleTransform,
IntRect(1, 1, 3, 3));
EXPECT_TRUE(helper.context()->getCTM().isIdentity());
EXPECT_EQ(2, helper.drawRect().x());
EXPECT_EQ(2, helper.drawRect().y());
EXPECT_EQ(8, helper.drawRect().maxX());
EXPECT_EQ(8, helper.drawRect().maxY());
SkBitmap& bitmap = const_cast<SkBitmap&>(helper.context()->platformContext()->canvas()->getTopDevice()->accessBitmap(false));
*bitmap.getAddr32(2, 2) &= 0x00FFFFFF;
helper.composite();
}
src->context()->restore();
}
TEST(TransparencyWin, ScaleTransparency)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
FloatRect fullBuffer(0, 0, 16, 16);
src->context()->fillRect(fullBuffer, Color::white, ColorSpaceDeviceRGB);
src->context()->beginTransparencyLayer(0.5);
FloatRect topHalf(0, 0, 16, 8);
src->context()->fillRect(topHalf, Color(0xFFFF0000), ColorSpaceDeviceRGB);
src->context()->save();
AffineTransform scale;
scale.scale(2.0);
src->context()->concatCTM(scale);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::ScaleTransform,
IntRect(1, 1, 6, 6));
helper.context()->fillRect(helper.drawRect(), Color(0x7f000000), ColorSpaceDeviceRGB);
clearTopLayerAlphaChannel(helper.context());
helper.composite();
}
src->context()->restore();
src->context()->endTransparencyLayer();
Color redBackground(0xFFFF8080); EXPECT_EQ(redBackground, getPixelAt(src->context(), 0, 0));
EXPECT_EQ(redBackground, getPixelAt(src->context(), 1, 1));
Color darkRed(0xFFBF8080);
EXPECT_EQ(darkRed, getPixelAt(src->context(), 2, 2));
EXPECT_EQ(darkRed, getPixelAt(src->context(), 7, 7));
Color darkWhite(0xFFBFBFBF);
EXPECT_EQ(darkWhite, getPixelAt(src->context(), 8, 8));
EXPECT_EQ(darkWhite, getPixelAt(src->context(), 13, 13));
Color white(0xFFFFFFFF); EXPECT_EQ(white, getPixelAt(src->context(), 14, 14));
EXPECT_EQ(white, getPixelAt(src->context(), 15, 15));
}
TEST(TransparencyWin, Text)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), ColorSpaceDeviceRGB));
Color fullResult(0x80008080);
{
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::TextComposite,
TransparencyWin::KeepTransform,
IntRect(0, 0, 16, 16));
helper.setTextCompositeColor(fullResult);
FloatRect pixel(0, 0, 1, 1);
helper.context()->fillRect(pixel, 0xFFFF0000, ColorSpaceDeviceRGB);
pixel.move(1.0f, 0.0f);
helper.context()->fillRect(pixel, 0xFF00FF00, ColorSpaceDeviceRGB);
pixel.move(1.0f, 0.0f);
helper.context()->fillRect(pixel, 0xFF0000FF, ColorSpaceDeviceRGB);
pixel.move(1.0f, 0.0f);
helper.context()->fillRect(pixel, 0xFF008080, ColorSpaceDeviceRGB);
pixel.move(1.0f, 0.0f);
helper.context()->fillRect(pixel, 0xFF800080, ColorSpaceDeviceRGB);
pixel.move(1.0f, 0.0f);
helper.context()->fillRect(pixel, 0xFF808000, ColorSpaceDeviceRGB);
pixel.move(1.0f, 0.0f);
helper.context()->fillRect(pixel, 0xFF000000, ColorSpaceDeviceRGB);
clearTopLayerAlphaChannel(helper.context());
helper.composite();
}
Color oneThirdResult(0x55005555); EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 0, 0));
EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 1, 0));
EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 2, 0));
EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 3, 0));
EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 4, 0));
EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 5, 0));
EXPECT_EQ(fullResult, getPixelAt(src->context(), 6, 0));
EXPECT_EQ(Color::transparent, getPixelAt(src->context(), 7, 0));
}
}