1/*
2 Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB.  If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "GraphicsLayerTransform.h"
22
23namespace WebCore {
24
25GraphicsLayerTransform::GraphicsLayerTransform()
26    : m_anchorPoint(0.5, 0.5, 0)
27    , m_flattening(true)
28    , m_dirty(false) // false by default since all default values would be combined as the identity matrix
29    , m_childrenDirty(false)
30{
31}
32
33void GraphicsLayerTransform::setPosition(const FloatPoint& position)
34{
35    if (m_position == position)
36        return;
37    m_position = position;
38    m_dirty = true;
39}
40
41void GraphicsLayerTransform::setSize(const FloatSize& size)
42{
43    if (m_size == size)
44        return;
45    m_size = size;
46    m_dirty = true;
47}
48
49void GraphicsLayerTransform::setAnchorPoint(const FloatPoint3D& anchorPoint)
50{
51    if (m_anchorPoint == anchorPoint)
52        return;
53    m_anchorPoint = anchorPoint;
54    m_dirty = true;
55}
56
57void GraphicsLayerTransform::setFlattening(bool flattening)
58{
59    if (m_flattening == flattening)
60        return;
61    m_flattening = flattening;
62    m_dirty = true;
63}
64
65void GraphicsLayerTransform::setLocalTransform(const TransformationMatrix& transform)
66{
67    if (m_local == transform)
68        return;
69    m_local = transform;
70    m_dirty = true;
71}
72
73void GraphicsLayerTransform::setChildrenTransform(const TransformationMatrix& transform)
74{
75    if (m_children == transform)
76        return;
77    m_children = transform;
78    m_dirty = true;
79}
80
81TransformationMatrix GraphicsLayerTransform::combined()
82{
83    ASSERT(!m_dirty);
84    return m_combined;
85}
86
87TransformationMatrix GraphicsLayerTransform::combinedForChildren()
88{
89    ASSERT(!m_dirty);
90    if (m_childrenDirty)
91        combineTransformsForChildren();
92    return m_combinedForChildren;
93}
94
95void GraphicsLayerTransform::combineTransforms(const TransformationMatrix& parentTransform)
96{
97    float originX = m_anchorPoint.x() * m_size.width();
98    float originY = m_anchorPoint.y() * m_size.height();
99    m_combined =
100        TransformationMatrix(parentTransform)
101            .translate3d(originX + m_position.x(), originY + m_position.y(), m_anchorPoint.z() )
102            .multiply(m_local);
103
104    // The children transform will take it from here, if it gets used.
105    m_combinedForChildren = m_combined;
106    m_combined.translate3d(-originX, -originY, -m_anchorPoint.z());
107
108    m_dirty = false;
109    m_childrenDirty = true;
110}
111
112void GraphicsLayerTransform::combineTransformsForChildren()
113{
114    ASSERT(!m_dirty);
115    ASSERT(m_childrenDirty);
116
117    float originX = m_anchorPoint.x() * m_size.width();
118    float originY = m_anchorPoint.y() * m_size.height();
119
120    // In case a parent had preserves3D and this layer has not, flatten our children.
121    if (m_flattening)
122        m_combinedForChildren = m_combinedForChildren.to2dTransform();
123    m_combinedForChildren.multiply(m_children);
124    m_combinedForChildren.translate3d(-originX, -originY, -m_anchorPoint.z());
125
126    m_childrenDirty = false;
127}
128
129}
130