1f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)/* 2f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved. 3f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * 4f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 5f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * modification, are permitted provided that the following conditions are 6f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * met: 7f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * 8f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 9f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 10f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 11f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 12f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * in the documentation and/or other materials provided with the 13f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * distribution. 14f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 15f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 16f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * this software without specific prior written permission. 17f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * 18f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) */ 30f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 31f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "config.h" 32f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "core/rendering/style/ShadowList.h" 33f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 34f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/geometry/FloatRect.h" 35f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/geometry/LayoutRect.h" 36f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 37f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)namespace WebCore { 38f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 39f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static inline void calculateShadowExtent(const ShadowList* shadowList, int additionalOutlineSize, int& shadowLeft, int& shadowRight, int& shadowTop, int& shadowBottom) 40f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 41f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) ASSERT(shadowList); 42f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) size_t shadowCount = shadowList->shadows().size(); 43f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) for (size_t i = 0; i < shadowCount; ++i) { 44f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) const ShadowData& shadow = shadowList->shadows()[i]; 45f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (shadow.style() == Inset) 46f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) continue; 47f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int blurAndSpread = shadow.blur() + shadow.spread() + additionalOutlineSize; 48f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) shadowLeft = std::min(shadow.x() - blurAndSpread, shadowLeft); 49f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) shadowRight = std::max(shadow.x() + blurAndSpread, shadowRight); 50f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) shadowTop = std::min(shadow.y() - blurAndSpread, shadowTop); 51f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) shadowBottom = std::max(shadow.y() + blurAndSpread, shadowBottom); 52f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 53f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 54f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 55f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void ShadowList::adjustRectForShadow(LayoutRect& rect, int additionalOutlineSize) const 56f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 57f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowLeft = 0; 58f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowRight = 0; 59f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowTop = 0; 60f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowBottom = 0; 61f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom); 62f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 63f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) rect.move(shadowLeft, shadowTop); 64f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) rect.setWidth(rect.width() - shadowLeft + shadowRight); 65f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) rect.setHeight(rect.height() - shadowTop + shadowBottom); 66f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 67f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 68f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void ShadowList::adjustRectForShadow(FloatRect& rect, int additionalOutlineSize) const 69f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 70f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowLeft = 0; 71f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowRight = 0; 72f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowTop = 0; 73f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) int shadowBottom = 0; 74f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom); 75f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 76f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) rect.move(shadowLeft, shadowTop); 77f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) rect.setWidth(rect.width() - shadowLeft + shadowRight); 78f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) rect.setHeight(rect.height() - shadowTop + shadowBottom); 79f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 80f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 81f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)PassRefPtr<ShadowList> ShadowList::blend(const ShadowList* from, const ShadowList* to, double progress) 82f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 83f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) size_t fromLength = from ? from->shadows().size() : 0; 84f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) size_t toLength = to ? to->shadows().size() : 0; 85f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (!fromLength && !toLength) 86f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) return 0; 87f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 88f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) ShadowDataVector shadows; 89f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 90f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) DEFINE_STATIC_LOCAL(ShadowData, defaultShadowData, (IntPoint(), 0, 0, Normal, Color::transparent)); 91f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) DEFINE_STATIC_LOCAL(ShadowData, defaultInsetShadowData, (IntPoint(), 0, 0, Inset, Color::transparent)); 92f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 93f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) size_t maxLength = std::max(fromLength, toLength); 94f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) for (size_t i = 0; i < maxLength; ++i) { 95f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) const ShadowData* fromShadow = i < fromLength ? &from->shadows()[i] : 0; 96f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) const ShadowData* toShadow = i < toLength ? &to->shadows()[i] : 0; 97f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (!fromShadow) 98f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) fromShadow = toShadow->style() == Inset ? &defaultInsetShadowData : &defaultShadowData; 99f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) else if (!toShadow) 100f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) toShadow = fromShadow->style() == Inset ? &defaultInsetShadowData : &defaultShadowData; 101f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) shadows.append(toShadow->blend(*fromShadow, progress)); 102f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 103f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 104f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) return ShadowList::adopt(shadows); 105f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 106f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 107f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} // namespace WebCore 108