1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#include "platform/graphics/filters/FilterOperation.h"
29
30#include "platform/animation/AnimationUtilities.h"
31
32namespace blink {
33
34PassRefPtr<FilterOperation> FilterOperation::blend(const FilterOperation* from, const FilterOperation* to, double progress)
35{
36    ASSERT(from || to);
37    if (to)
38        return to->blend(from, progress);
39    return from->blend(0, 1 - progress);
40}
41
42PassRefPtr<FilterOperation> BasicColorMatrixFilterOperation::blend(const FilterOperation* from, double progress) const
43{
44    double fromAmount;
45    if (from) {
46        ASSERT_WITH_SECURITY_IMPLICATION(from->isSameType(*this));
47        fromAmount = toBasicColorMatrixFilterOperation(from)->amount();
48    } else {
49        switch (m_type) {
50        case GRAYSCALE:
51        case SEPIA:
52        case HUE_ROTATE:
53            fromAmount = 0;
54            break;
55        case SATURATE:
56            fromAmount = 1;
57            break;
58        default:
59            fromAmount = 0;
60            ASSERT_NOT_REACHED();
61        }
62    }
63
64    double result = blink::blend(fromAmount, m_amount, progress);
65    switch (m_type) {
66    case HUE_ROTATE:
67        break;
68    case GRAYSCALE:
69    case SEPIA:
70        result = clampTo<double>(result, 0, 1);
71        break;
72    case SATURATE:
73        result = clampTo<double>(result, 0);
74        break;
75    default:
76        ASSERT_NOT_REACHED();
77    }
78    return BasicColorMatrixFilterOperation::create(result, m_type);
79}
80
81PassRefPtr<FilterOperation> BasicComponentTransferFilterOperation::blend(const FilterOperation* from, double progress) const
82{
83    double fromAmount;
84    if (from) {
85        ASSERT_WITH_SECURITY_IMPLICATION(from->isSameType(*this));
86        fromAmount = toBasicComponentTransferFilterOperation(from)->amount();
87    } else {
88        switch (m_type) {
89        case OPACITY:
90        case CONTRAST:
91        case BRIGHTNESS:
92            fromAmount = 1;
93            break;
94        case INVERT:
95            fromAmount = 0;
96            break;
97        default:
98            fromAmount = 0;
99            ASSERT_NOT_REACHED();
100        }
101    }
102
103    double result = blink::blend(fromAmount, m_amount, progress);
104    switch (m_type) {
105    case BRIGHTNESS:
106    case CONTRAST:
107        result = clampTo<double>(result, 0);
108        break;
109    case INVERT:
110    case OPACITY:
111        result = clampTo<double>(result, 0, 1);
112        break;
113    default:
114        ASSERT_NOT_REACHED();
115    }
116    return BasicComponentTransferFilterOperation::create(result, m_type);
117}
118
119PassRefPtr<FilterOperation> BlurFilterOperation::blend(const FilterOperation* from, double progress) const
120{
121    LengthType lengthType = m_stdDeviation.type();
122    if (!from)
123        return BlurFilterOperation::create(m_stdDeviation.blend(Length(lengthType), progress, ValueRangeNonNegative));
124
125    const BlurFilterOperation* fromOp = toBlurFilterOperation(from);
126    return BlurFilterOperation::create(m_stdDeviation.blend(fromOp->m_stdDeviation, progress, ValueRangeNonNegative));
127}
128
129PassRefPtr<FilterOperation> DropShadowFilterOperation::blend(const FilterOperation* from, double progress) const
130{
131    if (!from) {
132        return DropShadowFilterOperation::create(
133            blink::blend(IntPoint(), m_location, progress),
134            blink::blend(0, m_stdDeviation, progress),
135            blink::blend(Color(Color::transparent), m_color, progress));
136    }
137
138    const DropShadowFilterOperation* fromOp = toDropShadowFilterOperation(from);
139    return DropShadowFilterOperation::create(
140        blink::blend(fromOp->location(), m_location, progress),
141        blink::blend(fromOp->stdDeviation(), m_stdDeviation, progress),
142        blink::blend(fromOp->color(), m_color, progress));
143}
144
145} // namespace blink
146
147