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)
56f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)namespace WebCore {
57f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
58f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuRenderLayerReflectionInfo::RenderLayerReflectionInfo(RenderBox& renderer)
59f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    : m_box(renderer)
60f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_isPaintingInsideReflection(false)
61f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
62f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    UseCounter::count(m_box.document(), UseCounter::Reflection);
63f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
64f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    m_reflection = RenderReplica::createAnonymous(&(m_box.document()));
65f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    m_reflection->setParent(&m_box); // We create a 1-way connection.
66f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
67f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
68f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)RenderLayerReflectionInfo::~RenderLayerReflectionInfo()
69f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
70f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (!m_reflection->documentBeingDestroyed())
71f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        m_reflection->removeLayers(m_box.layer());
72f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
73f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_reflection->setParent(0);
74f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_reflection->destroy();
75f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_reflection = 0;
76f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
77f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
78f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
79f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)RenderLayer* RenderLayerReflectionInfo::reflectionLayer() const
80f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
81f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    return m_reflection->layer();
82f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
83f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
84f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderLayerReflectionInfo::updateAfterStyleChange(const RenderStyle* oldStyle)
85f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
86f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    RefPtr<RenderStyle> newStyle = RenderStyle::create();
87f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    newStyle->inheritFrom(m_box.style());
88f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
89f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // Map in our transform.
90f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    TransformOperations transform;
91f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    switch (m_box.style()->boxReflect()->direction()) {
92f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    case ReflectionBelow:
93f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
94f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            Length(100., Percent), TransformOperation::Translate));
95f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
96f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            m_box.style()->boxReflect()->offset(), TransformOperation::Translate));
97f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::Scale));
98f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        break;
99f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
100f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    case ReflectionAbove:
101f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::Scale));
102f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
103f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            Length(100., Percent), TransformOperation::Translate));
104f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
105f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            m_box.style()->boxReflect()->offset(), TransformOperation::Translate));
106f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        break;
107f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
108f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    case ReflectionRight:
109f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(Length(100., Percent),
110f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            Length(0, Fixed), TransformOperation::Translate));
111f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(
112f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            m_box.style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
113f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::Scale));
114f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        break;
115f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
116f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    case ReflectionLeft:
117f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::Scale));
118f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(Length(100., Percent),
119f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            Length(0, Fixed), TransformOperation::Translate));
120f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        transform.operations().append(TranslateTransformOperation::create(
121f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            m_box.style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
122f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        break;
123f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    }
124f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    newStyle->setTransform(transform);
125f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
126f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // Map in our mask.
127f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    newStyle->setMaskBoxImage(m_box.style()->boxReflect()->mask());
128f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
129f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_reflection->setStyle(newStyle.release());
130f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
131f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
132f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderLayerReflectionInfo::paint(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags flags)
133f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
134f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (m_isPaintingInsideReflection)
135f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        return;
136f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
137f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // Mark that we are now inside replica painting.
138f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_isPaintingInsideReflection = true;
139f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    reflectionLayer()->paintLayer(context, paintingInfo, flags);
140f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_isPaintingInsideReflection = false;
141f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
142f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
143f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)String RenderLayerReflectionInfo::debugName() const
144f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
145f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    return m_box.debugName() + " (reflection)";
146f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
147f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
148f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} // namespace WebCore
149