Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / LayoutState.cpp
1 /*
2  * Copyright (C) 2007 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 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 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 #include "core/rendering/LayoutState.h"
28
29 #include "core/rendering/RenderInline.h"
30 #include "core/rendering/RenderLayer.h"
31 #include "core/rendering/RenderView.h"
32 #include "platform/Partitions.h"
33
34 namespace WebCore {
35
36 LayoutState::LayoutState(LayoutState* prev, RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo)
37     : m_columnInfo(columnInfo)
38     , m_next(prev)
39 #ifndef NDEBUG
40     , m_renderer(&renderer)
41 #endif
42 {
43     ASSERT(m_next);
44
45     bool fixed = renderer.isOutOfFlowPositioned() && renderer.style()->position() == FixedPosition;
46     if (fixed) {
47         // FIXME: This doesn't work correctly with transforms.
48         FloatPoint fixedOffset = renderer.view()->localToAbsolute(FloatPoint(), IsFixed);
49         m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset;
50     } else
51         m_paintOffset = prev->m_paintOffset + offset;
52
53     if (renderer.isOutOfFlowPositioned() && !fixed) {
54         if (RenderObject* container = renderer.container()) {
55             if (container->isInFlowPositioned() && container->isRenderInline())
56                 m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(renderer);
57         }
58     }
59
60     m_layoutOffset = m_paintOffset;
61
62     if (renderer.isInFlowPositioned() && renderer.hasLayer())
63         m_paintOffset += renderer.layer()->offsetForInFlowPosition();
64
65     m_clipped = !fixed && prev->m_clipped;
66     if (m_clipped)
67         m_clipRect = prev->m_clipRect;
68
69     if (renderer.hasOverflowClip()) {
70         LayoutSize deltaSize = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : renderer.view()->layoutDelta();
71
72         LayoutRect clipRect(toPoint(m_paintOffset) + deltaSize, renderer.cachedSizeForOverflowClip());
73         if (m_clipped)
74             m_clipRect.intersect(clipRect);
75         else {
76             m_clipRect = clipRect;
77             m_clipped = true;
78         }
79
80         m_paintOffset -= renderer.scrolledContentOffset();
81     }
82
83     // If we establish a new page height, then cache the offset to the top of the first page.
84     // We can compare this later on to figure out what part of the page we're actually on,
85     if (pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread()) {
86         m_pageLogicalHeight = pageLogicalHeight;
87         bool isFlipped = renderer.style()->isFlippedBlocksWritingMode();
88         m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.paddingRight()),
89             m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + renderer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom()));
90         m_pageLogicalHeightChanged = pageLogicalHeightChanged;
91         m_isPaginated = true;
92     } else {
93         // If we don't establish a new page height, then propagate the old page height and offset down.
94         m_pageLogicalHeight = m_next->m_pageLogicalHeight;
95         m_pageLogicalHeightChanged = m_next->m_pageLogicalHeightChanged;
96         m_pageOffset = m_next->m_pageOffset;
97
98         // Disable pagination for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
99         // writing mode roots.
100         if (renderer.isUnsplittableForPagination()) {
101             m_pageLogicalHeight = 0;
102             m_isPaginated = false;
103         } else {
104             m_isPaginated = m_pageLogicalHeight || m_next->m_columnInfo || renderer.flowThreadContainingBlock();
105         }
106     }
107
108     if (!m_columnInfo)
109         m_columnInfo = m_next->m_columnInfo;
110
111     if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
112         m_layoutDelta = m_next->m_layoutDelta;
113 #if !ASSERT_DISABLED
114         m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated;
115         m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated;
116 #endif
117     }
118
119     // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
120 }
121
122 LayoutState::LayoutState(RenderObject& root)
123     : m_clipped(false)
124     , m_isPaginated(false)
125     , m_pageLogicalHeightChanged(false)
126 #if !ASSERT_DISABLED
127     , m_layoutDeltaXSaturated(false)
128     , m_layoutDeltaYSaturated(false)
129 #endif
130     , m_columnInfo(0)
131     , m_next(0)
132     , m_pageLogicalHeight(0)
133 #ifndef NDEBUG
134     , m_renderer(&root)
135 #endif
136 {
137     RenderObject* container = root.container();
138     FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTransforms);
139     m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y());
140
141     if (container->hasOverflowClip()) {
142         m_clipped = true;
143         RenderBox* containerBox = toRenderBox(container);
144         m_clipRect = LayoutRect(toPoint(m_paintOffset), containerBox->cachedSizeForOverflowClip());
145         m_paintOffset -= containerBox->scrolledContentOffset();
146     }
147 }
148
149 void* LayoutState::operator new(size_t sz)
150 {
151     return partitionAlloc(Partitions::getRenderingPartition(), sz);
152 }
153
154 void LayoutState::operator delete(void* ptr)
155 {
156     partitionFree(ptr);
157 }
158
159 void LayoutState::clearPaginationInformation()
160 {
161     m_pageLogicalHeight = m_next->m_pageLogicalHeight;
162     m_pageOffset = m_next->m_pageOffset;
163     m_columnInfo = m_next->m_columnInfo;
164 }
165
166 LayoutUnit LayoutState::pageLogicalOffset(const RenderBox& child, const LayoutUnit& childLogicalOffset) const
167 {
168     if (child.isHorizontalWritingMode())
169         return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.height();
170     return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width();
171 }
172
173 void LayoutState::addForcedColumnBreak(const RenderBox& child, const LayoutUnit& childLogicalOffset)
174 {
175     if (!m_columnInfo || m_columnInfo->columnHeight())
176         return;
177     m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset));
178 }
179
180 } // namespace WebCore