15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Apple 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 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/CrossfadeGeneratedImage.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatRect.h" 30a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContextStateSaver.h" 31a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageBuffer.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std; 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CrossfadeGeneratedImage::CrossfadeGeneratedImage(Image* fromImage, Image* toImage, float percentage, IntSize crossfadeSize, const IntSize& size) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_fromImage(fromImage) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_toImage(toImage) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_percentage(percentage) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_crossfadeSize(crossfadeSize) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_size = size; 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void CrossfadeGeneratedImage::drawCrossfade(GraphicsContext* context) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float inversePercentage = 1 - m_percentage; 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntSize fromImageSize = m_fromImage->size(); 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntSize toImageSize = m_toImage->size(); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Draw nothing if either of the images hasn't loaded yet. 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_fromImage == Image::nullImage() || m_toImage == Image::nullImage()) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GraphicsContextStateSaver stateSaver(*context); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->clip(IntRect(IntPoint(), m_crossfadeSize)); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->beginTransparencyLayer(1); 615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Draw the image we're fading away from. 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->save(); 64a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_crossfadeSize != fromImageSize) { 65a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) context->scale(FloatSize( 66a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) static_cast<float>(m_crossfadeSize.width()) / fromImageSize.width(), 67a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) static_cast<float>(m_crossfadeSize.height()) / fromImageSize.height())); 68a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->setAlpha(inversePercentage); 705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) context->drawImage(m_fromImage, IntPoint()); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->restore(); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Draw the image we're fading towards. 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->save(); 75a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_crossfadeSize != toImageSize) { 76a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) context->scale(FloatSize( 77a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) static_cast<float>(m_crossfadeSize.width()) / toImageSize.width(), 78a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) static_cast<float>(m_crossfadeSize.height()) / toImageSize.height())); 79a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->setAlpha(m_percentage); 815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) context->drawImage(m_toImage, IntPoint(), CompositePlusLighter); 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->restore(); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 84c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) context->endLayer(); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 87a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void CrossfadeGeneratedImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, blink::WebBlendMode blendMode) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GraphicsContextStateSaver stateSaver(*context); 903c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch context->setCompositeOperation(compositeOp, blendMode); 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->clip(dstRect); 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->translate(dstRect.x(), dstRect.y()); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (dstRect.size() != srcRect.size()) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height())); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->translate(-srcRect.x(), -srcRect.y()); 965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) drawCrossfade(context); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 100a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void CrossfadeGeneratedImage::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const FloatSize& scale, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& dstRect, blink::WebBlendMode blendMode, const IntSize& repeatSpacing) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 102a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> imageBuffer = context->createCompatibleBuffer(m_size); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!imageBuffer) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Fill with the cross-faded image. 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GraphicsContext* graphicsContext = imageBuffer->context(); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) drawCrossfade(graphicsContext); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Tile the image buffer into the context. 1111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) imageBuffer->drawPattern(context, srcRect, scale, phase, compositeOp, dstRect, blendMode, repeatSpacing); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 115