15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009, 2010, 2012 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 INC. AND ITS CONTRIBUTORS ``AS IS'' 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THE POSSIBILITY OF SUCH DAMAGE. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GradientGeneratedImage.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatRect.h" 30a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContextStateSaver.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 34e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void GradientGeneratedImage::draw(GraphicsContext* destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp, WebBlendMode blendMode) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GraphicsContextStateSaver stateSaver(*destContext); 37591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch destContext->setCompositeOperation(compositeOp, blendMode); 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destContext->clip(destRect); 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destContext->translate(destRect.x(), destRect.y()); 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (destRect.size() != srcRect.size()) 415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) destContext->scale(destRect.width() / srcRect.width(), destRect.height() / srcRect.height()); 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destContext->translate(-srcRect.x(), -srcRect.y()); 435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) destContext->setFillGradient(m_gradient); 445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) destContext->fillRect(FloatRect(FloatPoint(), m_size)); 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 47bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void GradientGeneratedImage::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const FloatSize& scale, 48e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect, WebBlendMode blendMode, const IntSize& repeatSpacing) 49e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 50bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) float stepX = srcRect.width() + repeatSpacing.width(); 51bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) float stepY = srcRect.height() + repeatSpacing.height(); 52e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch int firstColumn = static_cast<int>(floorf((((destRect.x() - phase.x()) / scale.width()) - srcRect.x()) / srcRect.width())); 53e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch int firstRow = static_cast<int>(floorf((((destRect.y() - phase.y()) / scale.height()) - srcRect.y()) / srcRect.height())); 54e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch for (int i = firstColumn; ; ++i) { 55bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) float dstX = (srcRect.x() + i * stepX) * scale.width() + phase.x(); 56e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // assert that first column encroaches left edge of dstRect. 57e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(i > firstColumn || dstX <= destRect.x()); 58e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(i == firstColumn || dstX > destRect.x()); 59e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 60e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstX >= destRect.maxX()) 61e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch break; 62e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch float dstMaxX = dstX + srcRect.width() * scale.width(); 63e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstX < destRect.x()) 64e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch dstX = destRect.x(); 65e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstMaxX > destRect.maxX()) 66e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch dstMaxX = destRect.maxX(); 67e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstX >= dstMaxX) 68e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch continue; 69e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 70e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch FloatRect visibleSrcRect; 71e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch FloatRect tileDstRect; 72e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch tileDstRect.setX(dstX); 73e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch tileDstRect.setWidth(dstMaxX - dstX); 74bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) visibleSrcRect.setX((tileDstRect.x() - phase.x()) / scale.width() - i * stepX); 75e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch visibleSrcRect.setWidth(tileDstRect.width() / scale.width()); 76e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 77e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch for (int j = firstRow; ; j++) { 78bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) float dstY = (srcRect.y() + j * stepY) * scale.height() + phase.y(); 79e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // assert that first row encroaches top edge of dstRect. 80e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(j > firstRow || dstY <= destRect.y()); 81e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ASSERT(j == firstRow || dstY > destRect.y()); 82e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 83e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstY >= destRect.maxY()) 84e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch break; 85e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch float dstMaxY = dstY + srcRect.height() * scale.height(); 86e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstY < destRect.y()) 87e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch dstY = destRect.y(); 88e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstMaxY > destRect.maxY()) 89e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch dstMaxY = destRect.maxY(); 90e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (dstY >= dstMaxY) 91e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch continue; 92e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 93e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch tileDstRect.setY(dstY); 94e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch tileDstRect.setHeight(dstMaxY - dstY); 95bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) visibleSrcRect.setY((tileDstRect.y() - phase.y()) / scale.height() - j * stepY); 96e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch visibleSrcRect.setHeight(tileDstRect.height() / scale.height()); 97e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch draw(destContext, tileDstRect, visibleSrcRect, compositeOp, blendMode); 98e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 99e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 100e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 101e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 102e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} // namespace blink 103