a14ac1c76b4217ef5534e1ad38d618ddfe85b757
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / RenderLayerReflectionInfo.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3  *
4  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5  *
6  * Other contributors:
7  *   Robert O'Callahan <roc+@cs.cmu.edu>
8  *   David Baron <dbaron@fas.harvard.edu>
9  *   Christian Biesinger <cbiesinger@web.de>
10  *   Randall Jesup <rjesup@wgate.com>
11  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
12  *   Josh Soref <timeless@mac.com>
13  *   Boris Zbarsky <bzbarsky@mit.edu>
14  *
15  * This library is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU Lesser General Public
17  * License as published by the Free Software Foundation; either
18  * version 2.1 of the License, or (at your option) any later version.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28  *
29  * Alternatively, the contents of this file may be used under the terms
30  * of either the Mozilla Public License Version 1.1, found at
31  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
32  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
33  * (the "GPL"), in which case the provisions of the MPL or the GPL are
34  * applicable instead of those above.  If you wish to allow use of your
35  * version of this file only under the terms of one of those two
36  * licenses (the MPL or the GPL) and not to allow others to use your
37  * version of this file under the LGPL, indicate your decision by
38  * deletingthe provisions above and replace them with the notice and
39  * other provisions required by the MPL or the GPL, as the case may be.
40  * If you do not delete the provisions above, a recipient may use your
41  * version of this file under any of the LGPL, the MPL or the GPL.
42  */
43
44 #include "config.h"
45 #include "core/rendering/RenderLayerReflectionInfo.h"
46
47 #include "core/frame/UseCounter.h"
48 #include "core/rendering/RenderLayer.h"
49 #include "core/rendering/RenderReplica.h"
50 #include "core/rendering/style/RenderStyle.h"
51 #include "platform/transforms/ScaleTransformOperation.h"
52 #include "platform/transforms/TranslateTransformOperation.h"
53
54 #include "wtf/RefPtr.h"
55
56 namespace blink {
57
58 RenderLayerReflectionInfo::RenderLayerReflectionInfo(RenderBox& renderer)
59     : m_box(renderer)
60     , m_isPaintingInsideReflection(false)
61 {
62     UseCounter::count(box().document(), UseCounter::Reflection);
63
64     m_reflection = RenderReplica::createAnonymous(&box().document());
65     m_reflection->setParent(m_box); // We create a 1-way connection.
66 }
67
68 void RenderLayerReflectionInfo::destroy()
69 {
70     if (!m_reflection->documentBeingDestroyed())
71         m_reflection->removeLayers(box().layer());
72
73     m_reflection->setParent(0);
74     m_reflection->destroy();
75     m_reflection = nullptr;
76 }
77
78 void RenderLayerReflectionInfo::trace(Visitor* visitor)
79 {
80     visitor->trace(m_box);
81     visitor->trace(m_reflection);
82 }
83
84 RenderLayer* RenderLayerReflectionInfo::reflectionLayer() const
85 {
86     return m_reflection->layer();
87 }
88
89 void RenderLayerReflectionInfo::updateAfterStyleChange(const RenderStyle* oldStyle)
90 {
91     RefPtr<RenderStyle> newStyle = RenderStyle::create();
92     newStyle->inheritFrom(box().style());
93
94     // Map in our transform.
95     TransformOperations transform;
96     switch (box().style()->boxReflect()->direction()) {
97     case ReflectionBelow:
98         transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
99             Length(100., Percent), TransformOperation::Translate));
100         transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
101             box().style()->boxReflect()->offset(), TransformOperation::Translate));
102         transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::Scale));
103         break;
104
105     case ReflectionAbove:
106         transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::Scale));
107         transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
108             Length(100., Percent), TransformOperation::Translate));
109         transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
110             box().style()->boxReflect()->offset(), TransformOperation::Translate));
111         break;
112
113     case ReflectionRight:
114         transform.operations().append(TranslateTransformOperation::create(Length(100., Percent),
115             Length(0, Fixed), TransformOperation::Translate));
116         transform.operations().append(TranslateTransformOperation::create(
117             box().style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
118         transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::Scale));
119         break;
120
121     case ReflectionLeft:
122         transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::Scale));
123         transform.operations().append(TranslateTransformOperation::create(Length(100., Percent),
124             Length(0, Fixed), TransformOperation::Translate));
125         transform.operations().append(TranslateTransformOperation::create(
126             box().style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
127         break;
128     }
129     newStyle->setTransform(transform);
130
131     // Map in our mask.
132     newStyle->setMaskBoxImage(box().style()->boxReflect()->mask());
133
134     m_reflection->setStyle(newStyle.release());
135 }
136
137 void RenderLayerReflectionInfo::paint(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags flags)
138 {
139     if (m_isPaintingInsideReflection)
140         return;
141
142     // Mark that we are now inside replica painting.
143     m_isPaintingInsideReflection = true;
144     reflectionLayer()->paintLayer(context, paintingInfo, flags);
145     m_isPaintingInsideReflection = false;
146 }
147
148 String RenderLayerReflectionInfo::debugName() const
149 {
150     return box().debugName() + " (reflection)";
151 }
152
153 } // namespace blink