193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)/*
293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) *
493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * modification, are permitted provided that the following conditions are
693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * met:
793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) *
893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
1093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
1193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
1293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * in the documentation and/or other materials provided with the
1393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * distribution.
1493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
1593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
1693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * this software without specific prior written permission.
1793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) *
1893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) */
3093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
3193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "config.h"
32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/graphics/DrawLooperBuilder.h"
3393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatSize.h"
35f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/graphics/Color.h"
3693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
3793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "third_party/skia/include/core/SkColorFilter.h"
38fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch#include "third_party/skia/include/core/SkDrawLooper.h"
3993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h"
4093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "third_party/skia/include/core/SkXfermode.h"
4193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "third_party/skia/include/effects/SkBlurMaskFilter.h"
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/RefPtr.h"
4393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
44c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
4593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)DrawLooperBuilder::DrawLooperBuilder() { }
47fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)DrawLooperBuilder::~DrawLooperBuilder() { }
49fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassOwnPtr<DrawLooperBuilder> DrawLooperBuilder::create()
51fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch{
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return adoptPtr(new DrawLooperBuilder);
53fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch}
5493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtr<SkDrawLooper> DrawLooperBuilder::detachDrawLooper()
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return adoptRef(m_skDrawLooperBuilder.detachLooper());
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void DrawLooperBuilder::addUnmodifiedContent()
6193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
6293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SkLayerDrawLooper::LayerInfo info;
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_skDrawLooperBuilder.addLayerOnTop(info);
6493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
6593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
66323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)// This replicates the old skia behavior when it used to take radius for blur. Now it takes sigma.
67323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)static SkScalar RadiusToSigma(SkScalar radius)
68323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){
69323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    SkASSERT(radius > 0);
70323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return 0.57735f * radius + 0.5f;
71323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)}
72323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void DrawLooperBuilder::addShadow(const FloatSize& offset, float blur, const Color& color,
7493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ShadowTransformMode shadowTransformMode, ShadowAlphaMode shadowAlphaMode)
7593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
7693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Detect when there's no effective shadow.
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!color.alpha())
7893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
7993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    SkColor skColor = color.rgb();
8193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
8293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SkLayerDrawLooper::LayerInfo info;
8393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
8493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    switch (shadowAlphaMode) {
8593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case ShadowRespectsAlpha:
8693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        info.fColorMode = SkXfermode::kDst_Mode;
8793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
8893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case ShadowIgnoresAlpha:
8993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        info.fColorMode = SkXfermode::kSrc_Mode;
9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
9193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    default:
9293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT_NOT_REACHED();
9393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
9493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (blur)
9693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; // our blur
9793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit;
9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    info.fOffset.set(offset.width(), offset.height());
9993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    info.fPostTranslate = (shadowTransformMode == ShadowIgnoresTransforms);
10093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint* paint = m_skDrawLooperBuilder.addLayerOnTop(info);
10293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
10393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (blur) {
104323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        const SkScalar sigma = RadiusToSigma(blur / 2);
10593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint32_t mfFlags = SkBlurMaskFilter::kHighQuality_BlurFlag;
10693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (shadowTransformMode == ShadowIgnoresTransforms)
10793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            mfFlags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
108323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        RefPtr<SkMaskFilter> mf = adoptRef(SkBlurMaskFilter::Create(kNormal_SkBlurStyle, sigma, mfFlags));
109fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch        paint->setMaskFilter(mf.get());
11093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
11193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
112fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    RefPtr<SkColorFilter> cf = adoptRef(SkColorFilter::CreateModeFilter(skColor, SkXfermode::kSrcIn_Mode));
113fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    paint->setColorFilter(cf.get());
11493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
11593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
117