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 2302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * 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/filters/FilterOperations.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/LengthFunctions.h" 301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntSize.h" 31a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/filters/FEGaussianBlur.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline IntSize outsetSizeForBlur(float stdDeviation) 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch IntSize kernelSize = FEGaussianBlur::calculateUnscaledKernelSize(FloatPoint(stdDeviation, stdDeviation)); 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntSize outset; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We take the half kernel size and multiply it with three, because we run box blur three times. 4107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch outset.setWidth(3 * kernelSize.width() * 0.5f); 4207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch outset.setHeight(3 * kernelSize.height() * 0.5f); 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return outset; 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FilterOperations::FilterOperations() 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FilterOperations& FilterOperations::operator=(const FilterOperations& other) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_operations = other.m_operations; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return *this; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FilterOperations::operator==(const FilterOperations& o) const 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_operations.size() != o.m_operations.size()) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 6102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned s = m_operations.size(); 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < s; i++) { 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (*m_operations[i] != *o.m_operations[i]) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 71f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)bool FilterOperations::canInterpolateWith(const FilterOperations& other) const 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 73f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) for (size_t i = 0; i < operations().size(); ++i) { 7451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!FilterOperation::canInterpolate(operations()[i]->type())) 75f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) return false; 76f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 77f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 78f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) for (size_t i = 0; i < other.operations().size(); ++i) { 7951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!FilterOperation::canInterpolate(other.operations()[i]->type())) 80f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) return false; 81f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 8202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 83f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) size_t commonSize = std::min(operations().size(), other.operations().size()); 84f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) for (size_t i = 0; i < commonSize; ++i) { 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!operations()[i]->isSameType(*other.operations()[i])) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FilterOperations::hasReferenceFilter() const 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < m_operations.size(); ++i) { 9451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (m_operations.at(i)->type() == FilterOperation::REFERENCE) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FilterOperations::hasOutsets() const 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < m_operations.size(); ++i) { 10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) FilterOperation::OperationType operationType = m_operations.at(i)->type(); 104e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (operationType == FilterOperation::BLUR || operationType == FilterOperation::DROP_SHADOW || operationType == FilterOperation::REFERENCE) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)FilterOutsets FilterOperations::outsets() const 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FilterOutsets totalOutsets; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < m_operations.size(); ++i) { 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterOperation* filterOperation = m_operations.at(i).get(); 11551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) switch (filterOperation->type()) { 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FilterOperation::BLUR: { 11751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) BlurFilterOperation* blurOperation = toBlurFilterOperation(filterOperation); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0); 119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) IntSize outsetSize = outsetSizeForBlur(stdDeviation); 120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FilterOutsets outsets(outsetSize.height(), outsetSize.width(), outsetSize.height(), outsetSize.width()); 121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) totalOutsets += outsets; 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FilterOperation::DROP_SHADOW: { 12551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation); 126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) IntSize outsetSize = outsetSizeForBlur(dropShadowOperation->stdDeviation()); 127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FilterOutsets outsets( 128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) std::max(0, outsetSize.height() - dropShadowOperation->y()), 129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) std::max(0, outsetSize.width() + dropShadowOperation->x()), 130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) std::max(0, outsetSize.height() + dropShadowOperation->y()), 131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) std::max(0, outsetSize.width() - dropShadowOperation->x()) 132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ); 133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) totalOutsets += outsets; 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 136e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) case FilterOperation::REFERENCE: { 13751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation); 138e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (referenceOperation->filter() && referenceOperation->filter()->lastEffect()) { 139e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) FloatRect outsetRect(0, 0, 1, 1); 140e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch outsetRect = referenceOperation->filter()->lastEffect()->mapRectRecursive(outsetRect); 141e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) FilterOutsets outsets( 142e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) std::max(0.0f, -outsetRect.y()), 143e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) std::max(0.0f, outsetRect.x() + outsetRect.width() - 1), 144e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) std::max(0.0f, outsetRect.y() + outsetRect.height() - 1), 145e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) std::max(0.0f, -outsetRect.x()) 146e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) ); 147e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) totalOutsets += outsets; 148e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 149e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) break; 150e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return totalOutsets; 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FilterOperations::hasFilterThatAffectsOpacity() const 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < m_operations.size(); ++i) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_operations[i]->affectsOpacity()) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FilterOperations::hasFilterThatMovesPixels() const 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < m_operations.size(); ++i) 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_operations[i]->movesPixels()) 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 174c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 176