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