15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 32a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 33a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h" 34a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageBuffer.h" 35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/win/TransparencyWin.h" 361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/transforms/AffineTransform.h" 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <windows.h> 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include <gtest/gtest.h> 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static FloatRect RECTToFloatRect(const RECT* rect) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return FloatRect(static_cast<float>(rect->left), 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static_cast<float>(rect->top), 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static_cast<float>(rect->right - rect->left), 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static_cast<float>(rect->bottom - rect->top)); 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Color getPixelAt(GraphicsContext* context, int x, int y) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) const SkBitmap& bitmap = context->layerBitmap(); 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Color(*reinterpret_cast<const RGBA32*>(bitmap.getAddr32(x, y))); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Resets the top layer's alpha channel to 0 for each pixel. This simulates 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Windows messing it up. 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void clearTopLayerAlphaChannel(GraphicsContext* context) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) SkBitmap& bitmap = const_cast<SkBitmap&>(context->layerBitmap()); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int y = 0; y < bitmap.height(); y++) { 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t* row = bitmap.getAddr32(0, y); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int x = 0; x < bitmap.width(); x++) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) row[x] &= 0x00FFFFFF; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Clears the alpha channel on the specified pixel. 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void clearTopLayerAlphaPixel(GraphicsContext* context, int x, int y) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) SkBitmap& bitmap = const_cast<SkBitmap&>(context->layerBitmap()); 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *bitmap.getAddr32(x, y) &= 0x00FFFFFF; 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static std::ostream& operator<<(std::ostream& out, const Color& c) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::ios_base::fmtflags oldFlags = out.flags(std::ios_base::hex | 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::ios_base::showbase); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) out << c.rgb(); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) out.flags(oldFlags); 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return out; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, NoLayer) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 87a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(17, 16))); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // KeepTransform 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::NoLayer, 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 12)); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() == helper.context()); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect()); 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Untransform is not allowed for NoLayer. 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ScaleTransform 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->scale(FloatSize(2.0, 0.5)); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::NoLayer, 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::ScaleTransform, 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(2, 2, 6, 6)); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The coordinate system should be based in the upper left of our box. 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // It should be post-transformed. 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() == helper.context()); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(4, 1, 12, 3) == helper.drawRect()); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, WhiteLayer) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 126a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // KeepTransform 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::WhiteLayer, 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 12)); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect()); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Untransform 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::WhiteLayer, 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::Untransform, 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 12)); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(0, 0, 14, 12) == helper.drawRect()); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ScaleTransform 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->scale(FloatSize(2.0, 0.5)); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::WhiteLayer, 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::ScaleTransform, 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(2, 2, 6, 6)); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The coordinate system should be based in the upper left of our box. 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // It should be post-transformed. 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(0, 0, 12, 3) == helper.drawRect()); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, TextComposite) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 178a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // KeepTransform is the only valid transform mode for TextComposite. 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::TextComposite, 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 12)); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect()); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, OpaqueCompositeLayer) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 197a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // KeepTransform 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 12)); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(1, 1, 14, 12) == helper.drawRect()); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // KeepTransform with scroll applied. 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->translate(0, -1); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 14)); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(14, 14) == helper.m_layerSize); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(1, 1, 14, 14) == helper.drawRect()); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Untransform 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::Untransform, 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 12)); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(14, 12) == helper.m_layerSize); 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(0, 0, 14, 12) == helper.drawRect()); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ScaleTransform 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->scale(FloatSize(2.0, 0.5)); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::ScaleTransform, 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(2, 2, 6, 6)); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The coordinate system should be based in the upper left of our box. 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // It should be post-transformed. 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(src->context() != helper.context()); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntSize(12, 3) == helper.m_layerSize); 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(IntRect(0, 0, 12, 3) == helper.drawRect()); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, OpaqueCompositeLayerPixel) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color red(0xFFFF0000), darkRed(0xFFBF0000); 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color green(0xFF00FF00); 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make a red bottom layer, followed by a half green next layer @ 50%. 270a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect fullRect(0, 0, 16, 16); 2735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(fullRect, red); 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->beginTransparencyLayer(0.5); 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect rightHalf(8, 0, 8, 16); 2765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(rightHalf, green); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make a transparency layer inset by one pixel, and fill it inset by 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // another pixel with 50% black. 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 14, 14)); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect inner(2, 2, 12, 12); 2885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(inner, Color(0x7f000000)); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // These coordinates are relative to the layer, whish is inset by 1x1 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // pixels from the top left. So we're actually clearing (2, 2) and 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (13,13), which are the extreme corners of the black area (and which 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // we check below). 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearTopLayerAlphaPixel(helper.context(), 1, 1); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearTopLayerAlphaPixel(helper.context(), 12, 12); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Finish the compositing. 299c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) src->context()->endLayer(); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check that we got the right values, it should be like the rectangle was 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // drawn with half opacity even though the alpha channel got messed up. 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(red, getPixelAt(src->context(), 0, 0)); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(red, getPixelAt(src->context(), 1, 1)); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(darkRed, getPixelAt(src->context(), 2, 2)); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The dark result is: 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (black @ 50% atop green) @ 50% atop red = 0xFF804000 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // which is 0xFFA02000 (Skia computes 0xFFA11F00 due to rounding). 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color darkGreenRed(0xFF803f00); 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(darkGreenRed, getPixelAt(src->context(), 13, 13)); 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 50% green on top of red = FF808000 (rounded to what Skia will produce). 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color greenRed(0xFF807F00); 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(greenRed, getPixelAt(src->context(), 14, 14)); 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(greenRed, getPixelAt(src->context(), 15, 15)); 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Tests that translations are properly handled when using KeepTransform. 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, TranslateOpaqueCompositeLayer) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Fill with white. 323a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color white(0xFFFFFFFF); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect fullRect(0, 0, 16, 16); 3265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(fullRect, white); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Scroll down by 8 (coordinate system goes up). 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->translate(0, -8); 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color red(0xFFFF0000); 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color green(0xFF00FF00); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make the transparency layer after translation will be @ (0, -8) with 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // size 16x16. 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(0, 0, 16, 16)); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Draw a red pixel at (15, 15). This should be the at (15, 7) after 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the transform. 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect bottomRight(15, 15, 1, 1); 3465267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(bottomRight, green); 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check the pixel we wrote. 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(green, getPixelAt(src->context(), 15, 7)); 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void testClippedLayerKeepTransform(TransparencyWin::LayerMode layerMode) 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Fill with white. 359a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color white(0xFFFFFFFF); 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect fullRect(0, 0, 16, 16); 3625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(fullRect, white); 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect clipRect(IntPoint(11, 5), IntSize(1, 1)); 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->clip(clipRect); 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Scroll down by 6 (coordinate system goes up). 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->translate(0, -6); 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color red(0xFFFF0000); 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color green(0xFF00FF00); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The transparency layer after translation will be @ (0, -6) with 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // a size that would be too large to handle unclipped. 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) layerMode, 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(0, 0, INT_MAX, INT_MAX)); 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Draw a green pixel at (11, 11). This should be within the clip rect 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and at (11, 5) after the transform. 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect greenRect(11, 11, 1, 1); 3855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(greenRect, green); 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Draw a red pixel at (9, 9). This should be outside the clip rect 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and not drawn. 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect redRect(9, 9, 1, 1); 3905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(redRect, red); 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify green pixel got drawn in clip rect and red pixel got clipped. 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(green, getPixelAt(src->context(), 11, 5)); 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 9, 3)); 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, ClippedKeepTransformNoLayer) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testClippedLayerKeepTransform(TransparencyWin::NoLayer); 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, ClippedKeepTransformOpaqueCompositeLayer) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testClippedLayerKeepTransform(TransparencyWin::OpaqueCompositeLayer); 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, ClippedKeepTransformWhiteLayer) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testClippedLayerKeepTransform(TransparencyWin::WhiteLayer); 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Same as OpaqueCompositeLayer, but the canvas has a rotation applied. This 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// tests that the propert transform is applied to the copied layer. 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, RotateOpaqueCompositeLayer) 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 420a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The background is white. 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color white(0xFFFFFFFF); 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect fullRect(0, 0, 16, 16); 4255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(fullRect, white); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Rotate the image by 90 degrees. This matrix is the same as 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // cw90.rotate(90); but avoids rounding errors. Rounding errors can cause 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Skia to think that !rectStaysRect() and it will fall through to path 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // drawing mode, which in turn gives us antialiasing. We want no 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // antialiasing or other rounding problems since we're testing exact pixel 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // values. 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform cw90(0, 1, -1, 0, 0, 0); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->concatCTM(cw90); 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make a transparency layer consisting of a horizontal line of 50% black. 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Since the rotation is applied, this will actually be a vertical line 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // down the middle of the image. 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->beginTransparencyLayer(0.5); 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect blackRect(0, -9, 16, 2); 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color black(0xFF000000); 4435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(blackRect, black); 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now draw 50% red square. 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Create a transparency helper inset one pixel in the buffer. The 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // coordinates are before transforming into this space, and maps to 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // IntRect(1, 1, 14, 14). 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::Untransform, 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, -15, 14, 14)); 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Fill with red. 4575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000)); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearTopLayerAlphaChannel(helper.context()); 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Finish the compositing. 463c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) src->context()->endLayer(); 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Top corner should be the original background. 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 0, 0)); 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check the stripe down the middle, first at the top... 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color gray(0xFF808080); 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 6, 0)); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(gray, getPixelAt(src->context(), 7, 0)); 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(gray, getPixelAt(src->context(), 8, 0)); 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 9, 0)); 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ...now at the bottom. 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 6, 15)); 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(gray, getPixelAt(src->context(), 7, 15)); 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(gray, getPixelAt(src->context(), 8, 15)); 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 9, 15)); 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Our red square should be 25% red over the top of those two. 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color redwhite(0xFFdfbfbf); 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color redgray(0xFF9f8080); 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 0, 1)); 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redwhite, getPixelAt(src->context(), 1, 1)); 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redwhite, getPixelAt(src->context(), 6, 1)); 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redgray, getPixelAt(src->context(), 7, 1)); 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redgray, getPixelAt(src->context(), 8, 1)); 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redwhite, getPixelAt(src->context(), 9, 1)); 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redwhite, getPixelAt(src->context(), 14, 1)); 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 15, 1)); 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Complete the 50% transparent layer. 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, DISABLED_TranslateScaleOpaqueCompositeLayer) 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 499a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The background is white on top with red on bottom. 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color white(0xFFFFFFFF); 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect topRect(0, 0, 16, 8); 5045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(topRect, white); 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color red(0xFFFF0000); 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect bottomRect(0, 8, 16, 8); 5075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(bottomRect, red); 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Translate left by one pixel. 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform left; 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left.translate(-1, 0); 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Scale by 2x. 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform scale; 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scale.scale(2.0); 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->concatCTM(scale); 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Then translate up by one pixel (which will actually be 2 due to scaling). 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform up; 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) up.translate(0, -1); 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->concatCTM(up); 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now draw 50% red square. 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Create a transparency helper inset one pixel in the buffer. The 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // coordinates are before transforming into this space, and maps to 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // IntRect(1, 1, 14, 14). 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, -15, 14, 14)); 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Fill with red. 5375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000)); 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearTopLayerAlphaChannel(helper.context()); 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Tests scale mode with no additional copy. 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, Scale) 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Create an opaque white buffer. 547a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect fullBuffer(0, 0, 16, 16); 5495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(fullBuffer, Color::white); 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Scale by 2x. 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform scale; 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scale.scale(2.0); 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->concatCTM(scale); 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Start drawing a rectangle from 1->4. This should get scaled to 2->8. 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::NoLayer, 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::ScaleTransform, 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 3, 3)); 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The context should now have the identity transform and the returned 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // rect should be scaled. 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(helper.context()->getCTM().isIdentity()); 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(2, helper.drawRect().x()); 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(2, helper.drawRect().y()); 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(8, helper.drawRect().maxX()); 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(8, helper.drawRect().maxY()); 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Set the pixel at (2, 2) to be transparent. This should be fixed when 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the helper goes out of scope. We don't want to call 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // clearTopLayerAlphaChannel because that will actually clear the whole 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // canvas (since we have no extra layer!). 57781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) SkBitmap& bitmap = const_cast<SkBitmap&>(helper.context()->layerBitmap()); 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *bitmap.getAddr32(2, 2) &= 0x00FFFFFF; 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check the pixel we previously made transparent, it should have gotten 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fixed back up to white. 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The current version doesn't fixup transparency when there is no layer. 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This seems not to be necessary, so we don't bother, but if it becomes 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // necessary, this line should be uncommented. 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // EXPECT_EQ(Color(Color::white), getPixelAt(src->context(), 2, 2)); 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Tests scale mode with an additional copy for transparency. This will happen 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// if we have a scaled textbox, for example. WebKit will create a new 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// transparency layer, draw the text field, then draw the text into it, then 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// composite this down with an opacity. 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, ScaleTransparency) 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Create an opaque white buffer. 600a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect fullBuffer(0, 0, 16, 16); 6025267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(fullBuffer, Color::white); 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make another layer (which duplicates how WebKit will make this). We fill 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the top half with red, and have the layer be 50% opaque. 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->beginTransparencyLayer(0.5); 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect topHalf(0, 0, 16, 8); 6085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) src->context()->fillRect(topHalf, Color(0xFFFF0000)); 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Scale by 2x. 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->save(); 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform scale; 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scale.scale(2.0); 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->concatCTM(scale); 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Make a layer inset two pixels (because of scaling, this is 2->14). And 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // will it with 50% black. 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::OpaqueCompositeLayer, 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::ScaleTransform, 6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(1, 1, 6, 6)); 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(helper.drawRect(), Color(0x7f000000)); 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearTopLayerAlphaChannel(helper.context()); 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Finish the layer. 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src->context()->restore(); 632c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) src->context()->endLayer(); 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color redBackground(0xFFFF8080); // 50% red composited on white. 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redBackground, getPixelAt(src->context(), 0, 0)); 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(redBackground, getPixelAt(src->context(), 1, 1)); 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Top half (minus two pixel border) should be 50% gray atop opaque 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // red = 0xFF804141. Then that's composited with 50% transparency on solid 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // white = 0xFFC0A1A1. 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color darkRed(0xFFBF8080); 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(darkRed, getPixelAt(src->context(), 2, 2)); 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(darkRed, getPixelAt(src->context(), 7, 7)); 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Bottom half (minus a two pixel border) should be a layer with 5% gray 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // with another 50% opacity composited atop white. 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color darkWhite(0xFFBFBFBF); 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(darkWhite, getPixelAt(src->context(), 8, 8)); 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(darkWhite, getPixelAt(src->context(), 13, 13)); 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color white(0xFFFFFFFF); // Background in the lower-right. 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 14, 14)); 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(white, getPixelAt(src->context(), 15, 15)); 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST(TransparencyWin, Text) 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 658a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16))); 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Our text should end up 50% transparent blue-green. 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color fullResult(0x80008080); 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin helper; 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.init(src->context(), 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::TextComposite, 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransparencyWin::KeepTransform, 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect(0, 0, 16, 16)); 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.setTextCompositeColor(fullResult); 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Write several different squares to simulate ClearType. These should 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // all reduce to 2/3 coverage. 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect pixel(0, 0, 1, 1); 6745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(pixel, 0xFFFF0000); 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pixel.move(1.0f, 0.0f); 6765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(pixel, 0xFF00FF00); 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pixel.move(1.0f, 0.0f); 6785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(pixel, 0xFF0000FF); 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pixel.move(1.0f, 0.0f); 6805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(pixel, 0xFF008080); 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pixel.move(1.0f, 0.0f); 6825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(pixel, 0xFF800080); 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pixel.move(1.0f, 0.0f); 6845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(pixel, 0xFF808000); 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Try one with 100% coverage (opaque black). 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pixel.move(1.0f, 0.0f); 6885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) helper.context()->fillRect(pixel, 0xFF000000); 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now mess with the alpha channel. 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearTopLayerAlphaChannel(helper.context()); 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) helper.composite(); 6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Color oneThirdResult(0x55005555); // = fullResult * 2 / 3 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 0, 0)); 6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 1, 0)); 6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 2, 0)); 6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 3, 0)); 7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 4, 0)); 7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(oneThirdResult, getPixelAt(src->context(), 5, 0)); 7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(fullResult, getPixelAt(src->context(), 6, 0)); 7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ(Color::transparent, getPixelAt(src->context(), 7, 0)); 7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 707