18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderBox.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedImage.h"
29d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Chrome.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ChromeClient.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
34db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "HitTestResult.h"
358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "htmlediting.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLElement.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ImageBuffer.h"
39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "FloatQuad.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h"
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "PaintInfo.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderArena.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderFlexibleBox.h"
45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderInline.h"
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderLayer.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTableCell.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h"
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h"
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h"
53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "ScrollbarTheme.h"
548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "TransformState.h"
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <algorithm>
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h>
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(WML)
59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WMLNames.h"
60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
62e7913fbdd6f145fe1644c90c22aa73cb733c9e17Ben Murdoch#if PLATFORM(ANDROID)
63e7913fbdd6f145fe1644c90c22aa73cb733c9e17Ben Murdoch#include "PlatformBridge.h"
64e7913fbdd6f145fe1644c90c22aa73cb733c9e17Ben Murdoch#endif
65e7913fbdd6f145fe1644c90c22aa73cb733c9e17Ben Murdoch
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Used by flexible boxes when flexing this element.
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef WTF::HashMap<const RenderBox*, int> OverrideSizeMap;
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic OverrideSizeMap* gOverrideSizeMap = 0;
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBox::s_hadOverflowClip = false;
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBox::RenderBox(Node* node)
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    : RenderBoxModelObject(node)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_marginLeft(0)
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_marginRight(0)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_marginTop(0)
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_marginBottom(0)
84bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_minPreferredLogicalWidth(-1)
85bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_maxPreferredLogicalWidth(-1)
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_inlineBoxWrapper(0)
87ef1adcdfc805d4d13103f6f15cc5b4d96828a60fPatrick Scott#ifdef ANDROID_LAYOUT
88ef1adcdfc805d4d13103f6f15cc5b4d96828a60fPatrick Scott    , m_visibleWidth(0)
89ef1adcdfc805d4d13103f6f15cc5b4d96828a60fPatrick Scott    , m_isVisibleWidthChangedBeforeLayout(false)
90ef1adcdfc805d4d13103f6f15cc5b4d96828a60fPatrick Scott#endif
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setIsBox();
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderBox::~RenderBox()
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
99bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::marginBefore() const
100bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
103bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginTop;
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
105bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginBottom;
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginLeft;
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
109bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginRight;
110bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
111bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT_NOT_REACHED();
112bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return m_marginTop;
113bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
114bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
115bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::marginAfter() const
116bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
119bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginBottom;
120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
121bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginTop;
122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
123bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginRight;
124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
125bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return m_marginLeft;
126bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
127bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT_NOT_REACHED();
128bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return m_marginBottom;
129bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
130bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
131bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::marginStart() const
132bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1332bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? m_marginLeft : m_marginRight;
135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? m_marginTop : m_marginBottom;
136bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
137bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
138bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::marginEnd() const
139bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1402bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return style()->isLeftToRightDirection() ? m_marginRight : m_marginLeft;
142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return style()->isLeftToRightDirection() ? m_marginBottom : m_marginTop;
143bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
144bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
145bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::setMarginStart(int margin)
146bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1472bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
148a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
149bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginLeft = margin;
150bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else
151bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginRight = margin;
152bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    } else {
153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
154bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginTop = margin;
155bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else
156bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginBottom = margin;
157bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
158bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
159bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBox::setMarginEnd(int margin)
161bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1622bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode()) {
163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
164bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginRight = margin;
165bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else
166bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginLeft = margin;
167bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    } else {
168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (style()->isLeftToRightDirection())
169bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginBottom = margin;
170bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else
171bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_marginTop = margin;
172bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
173bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
174bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
175bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::setMarginBefore(int margin)
176bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
177a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
179bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginTop = margin;
180bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
182bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginBottom = margin;
183bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
185bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginLeft = margin;
186bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
188bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginRight = margin;
189bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
190bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
191bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
192bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
193a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid RenderBox::setMarginAfter(int margin)
194bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
195a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (style()->writingMode()) {
196a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case TopToBottomWritingMode:
197bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginBottom = margin;
198bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case BottomToTopWritingMode:
200bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginTop = margin;
201bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case LeftToRightWritingMode:
203bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginRight = margin;
204bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
205a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    case RightToLeftWritingMode:
206bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_marginLeft = margin;
207bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        break;
208bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
209bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
210bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::destroy()
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // A lot of the code in this function is just pasted into
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // RenderWidget::destroy. If anything in this function changes,
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // be sure to fix RenderWidget::destroy() as well.
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasOverrideSize())
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gOverrideSizeMap->remove(this);
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2192bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (style() && (style()->logicalHeight().isPercent() || style()->logicalMinHeight().isPercent() || style()->logicalMaxHeight().isPercent()))
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock::removePercentHeightDescendant(this);
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBoxModelObject::destroy();
2238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::removeFloatingOrPositionedChildFromBlockLists()
2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(isFloatingOrPositioned());
2288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (documentBeingDestroyed())
2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
2318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isFloating()) {
23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RenderBlock* parentBlock = 0;
23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (curr->isRenderBlock()) {
23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                RenderBlock* currBlock = toRenderBlock(curr);
23754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block                if (!parentBlock || currBlock->containsFloat(this))
23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                    parentBlock = currBlock;
23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            }
2408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
2418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (parentBlock) {
24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            RenderObject* parent = parentBlock->parent();
244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (parent && parent->isFlexibleBox())
24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                parentBlock = toRenderBlock(parent);
246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            parentBlock->markAllDescendantsWithFloatsForLayout(this, false);
248a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
2498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isPositioned()) {
25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (RenderObject* curr = parent(); curr; curr = curr->parent()) {
25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (curr->isRenderBlock())
25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                toRenderBlock(curr)->removePositionedObject(this);
2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s_hadOverflowClip = hasOverflowClip();
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (style()) {
264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // The background of the root element or the body element could propagate up to
265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // the canvas.  Just dirty the entire canvas when our style changes substantially.
2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (diff >= StyleDifferenceRepaint && node() &&
2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                (node()->hasTagName(htmlTag) || node()->hasTagName(bodyTag)))
268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            view()->repaint();
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // When a layout hint happens and an object's position style changes, we have to do a layout
2715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // to dirty the render tree using the old position value now.
2725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (diff == StyleDifferenceLayout && parent() && style()->position() != newStyle->position()) {
2735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            markContainingBlocksForLayout();
2745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (style()->position() == StaticPosition)
2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                repaint();
276cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            else if (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition)
277cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                parent()->setChildNeedsLayout(true);
2785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
2795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                removeFloatingOrPositionedChildFromBlockLists();
280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
281967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    } else if (newStyle && isBody())
282967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        view()->repaint();
283967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (FrameView *frameView = view()->frameView()) {
285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition;
286dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        bool oldStyleIsFixed = style() && style()->position() == FixedPosition;
287dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (newStyleIsFixed != oldStyleIsFixed) {
288dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (newStyleIsFixed)
289dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                frameView->addFixedObject();
290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            else
291dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                frameView->removeFixedObject();
292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBoxModelObject::styleWillChange(diff, newStyle);
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBoxModelObject::styleDidChange(diff, oldStyle);
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3022bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (needsLayout() && oldStyle) {
3032bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (oldStyle && (oldStyle->logicalHeight().isPercent() || oldStyle->logicalMinHeight().isPercent() || oldStyle->logicalMaxHeight().isPercent()))
3042bde8e466a4451c7319e3a072d118917957d6554Steve Block            RenderBlock::removePercentHeightDescendant(this);
3052bde8e466a4451c7319e3a072d118917957d6554Steve Block
3062bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Normally we can do optimized positioning layout for absolute/fixed positioned objects. There is one special case, however, which is
3072bde8e466a4451c7319e3a072d118917957d6554Steve Block        // when the positioned object's margin-before is changed. In this case the parent has to get a layout in order to run margin collapsing
3082bde8e466a4451c7319e3a072d118917957d6554Steve Block        // to determine the new static position.
3092bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isPositioned() && style()->hasStaticBlockPosition(isHorizontalWritingMode()) && oldStyle->marginBefore() != style()->marginBefore()
3102bde8e466a4451c7319e3a072d118917957d6554Steve Block            && parent() && !parent()->normalChildNeedsLayout())
3112bde8e466a4451c7319e3a072d118917957d6554Steve Block            parent()->setChildNeedsLayout(true);
3122bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
3158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // new zoomed coordinate space.
3168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) {
3176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (int left = layer()->scrollXOffset()) {
3188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom();
3196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            layer()->scrollToXOffset(left);
3208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
3216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (int top = layer()->scrollYOffset()) {
3228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom();
3236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            layer()->scrollToYOffset(top);
3248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
3258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
327e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool isBodyRenderer = isBody();
328e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool isRootRenderer = isRoot();
329e14391e94c850b8bd03680c23b38978db68687a8John Reck
3308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Set the text color if we're the body.
331e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (isBodyRenderer)
332e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        document()->setTextColor(style()->visitedDependentColor(CSSPropertyColor));
3334a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
3344a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (isRootRenderer || isBodyRenderer) {
335e14391e94c850b8bd03680c23b38978db68687a8John Reck        // Propagate the new writing mode and direction up to the RenderView.
336bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        RenderView* viewRenderer = view();
337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        RenderStyle* viewStyle = viewRenderer->style();
3384a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        if (viewStyle->direction() != style()->direction() && (isRootRenderer || !document()->directionSetOnDocumentElement())) {
339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            viewStyle->setDirection(style()->direction());
340e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (isBodyRenderer)
341e14391e94c850b8bd03680c23b38978db68687a8John Reck                document()->documentElement()->renderer()->style()->setDirection(style()->direction());
3424a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            setNeedsLayoutAndPrefWidthsRecalc();
343a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
3444a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
3454a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        if (viewStyle->writingMode() != style()->writingMode() && (isRootRenderer || !document()->writingModeSetOnDocumentElement())) {
346e14391e94c850b8bd03680c23b38978db68687a8John Reck            viewStyle->setWritingMode(style()->writingMode());
3472bde8e466a4451c7319e3a072d118917957d6554Steve Block            viewRenderer->setHorizontalWritingMode(style()->isHorizontalWritingMode());
3482bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (isBodyRenderer) {
349e14391e94c850b8bd03680c23b38978db68687a8John Reck                document()->documentElement()->renderer()->style()->setWritingMode(style()->writingMode());
3502bde8e466a4451c7319e3a072d118917957d6554Steve Block                document()->documentElement()->renderer()->setHorizontalWritingMode(style()->isHorizontalWritingMode());
3512bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
3524a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch            setNeedsLayoutAndPrefWidthsRecalc();
353e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
354bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
3558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
3568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::updateBoxModelInfoFromStyle()
3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBoxModelObject::updateBoxModelInfoFromStyle();
3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    bool isRootObject = isRoot();
362635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    bool isViewObject = isRenderView();
363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The root and the RenderView always paint their backgrounds/borders.
365635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (isRootObject || isViewObject)
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setHasBoxDecorations(true);
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setPositioned(style()->position() == AbsolutePosition || style()->position() == FixedPosition);
3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setFloating(!isPositioned() && style()->isFloating());
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We also handle <body> and <html>, whose overflow applies to the viewport.
372635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (style()->overflowX() != OVISIBLE && !isRootObject && (isRenderBlock() || isTableRow() || isTableSection())) {
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool boxHasOverflowClip = true;
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isBody()) {
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Overflow on the body can propagate to the viewport under the following conditions.
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (1) The root element is <html>.
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (2) We are the primary <body> (can be checked by looking at document.body).
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // (3) The root element has visible overflow.
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (document()->documentElement()->hasTagName(htmlTag) &&
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                document()->body() == node() &&
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                document()->documentElement()->renderer()->style()->overflowX() == OVISIBLE)
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                boxHasOverflowClip = false;
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check for overflow clip.
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // It's sufficient to just check one direction, since it's illegal to have visible on only one overflow value.
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (boxHasOverflowClip) {
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!s_hadOverflowClip)
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Erase the overflow
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                repaint();
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setHasOverflowClip();
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setHasTransform(style()->hasTransformRelatedProperty());
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setHasReflection(style()->boxReflect());
397635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::layout()
400635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(needsLayout());
402635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* child = firstChild();
4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!child) {
4058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setNeedsLayout(false);
4068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
407635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
408635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (child) {
4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        child->layoutIfNeeded();
4128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(!child->needsLayout());
4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        child = child->nextSibling();
414635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
4158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    statePusher.pop();
4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setNeedsLayout(false);
417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
418635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// More IE extensions.  clientWidth and clientHeight represent the interior of an object
420635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// excluding border and scrollbar.
421635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::clientWidth() const
422635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
423635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return width() - borderLeft() - borderRight() - verticalScrollbarWidth();
424635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
425635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
426635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::clientHeight() const
427635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
428635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return height() - borderTop() - borderBottom() - horizontalScrollbarHeight();
429635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
430635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
431635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::scrollWidth() const
432635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
433635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasOverflowClip())
4348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return layer()->scrollWidth();
4350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // For objects with visible overflow, this matches IE.
436f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: Need to work right with writing modes.
437a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (style()->isLeftToRightDirection())
4382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return max(clientWidth(), maxXLayoutOverflow() - borderLeft());
4392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return clientWidth() - min(0, minXLayoutOverflow() - borderLeft());
440635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
441635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
442635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::scrollHeight() const
443635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
444635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasOverflowClip())
4458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return layer()->scrollHeight();
4460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // For objects with visible overflow, this matches IE.
447f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: Need to work right with writing modes.
4482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return max(clientHeight(), maxYLayoutOverflow() - borderTop());
449635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
451635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::scrollLeft() const
452635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return hasOverflowClip() ? layer()->scrollXOffset() : 0;
454635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
455635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
456635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::scrollTop() const
457635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return hasOverflowClip() ? layer()->scrollYOffset() : 0;
459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
460635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
461635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBox::setScrollLeft(int newLeft)
462635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasOverflowClip())
4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        layer()->scrollToXOffset(newLeft);
465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
466635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
467635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBox::setScrollTop(int newTop)
468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
469635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasOverflowClip())
4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        layer()->scrollToYOffset(newTop);
471635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
472635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    rects.append(IntRect(tx, ty, width(), height()));
476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
477635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderBox::absoluteQuads(Vector<FloatQuad>& quads)
479635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
4808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
482635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
483f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderBox::updateLayerTransform()
484a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
485f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Transform-origin depends on box size, so we need to update the layer transform after layout.
486f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasLayer())
487d06194330da2bb8da887d2e1adeacb3a5c1504b2Steve Block        layer()->updateTransform();
488a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
489a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
490635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect RenderBox::absoluteContentBox() const
491635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
492635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect rect = contentBoxRect();
493635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    FloatPoint absPos = localToAbsolute(FloatPoint());
494635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    rect.move(absPos.x(), absPos.y());
495635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return rect;
496635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
497635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
498635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectFloatQuad RenderBox::absoluteContentQuad() const
499635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
500635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect rect = contentBoxRect();
501635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return localToAbsoluteQuad(FloatRect(rect));
502635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
503635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
504dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockIntRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer, IntPoint* cachedOffsetToRepaintContainer) const
505635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
506635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect box = borderBoundingBox();
507635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    adjustRectForOutlineAndShadow(box);
508635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
509dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    FloatQuad containerRelativeQuad = FloatRect(box);
510dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (cachedOffsetToRepaintContainer)
511dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        containerRelativeQuad.move(cachedOffsetToRepaintContainer->x(), cachedOffsetToRepaintContainer->y());
512dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else
513dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        containerRelativeQuad = localToContainerQuad(containerRelativeQuad, repaintContainer);
514dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
5155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    box = containerRelativeQuad.enclosingBoundingBox();
516635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
517635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: layoutDelta needs to be applied in parts before/after transforms and
518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    box.move(view()->layoutDelta());
520635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
521635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return box;
522635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
523635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
524d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderBox::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
525635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
526d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (width() && height())
527d0825bca7fe65beaee391d30da42e937db621564Steve Block        rects.append(IntRect(tx, ty, width(), height()));
528635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
529635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
530635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect RenderBox::reflectionBox() const
531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
532635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect result;
533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!style()->boxReflect())
534635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return result;
535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect box = borderBoxRect();
536635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    result = box;
537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    switch (style()->boxReflect()->direction()) {
538635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionBelow:
539635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            result.move(0, box.height() + reflectionOffset());
540635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionAbove:
542635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            result.move(0, -box.height() - reflectionOffset());
543635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
544635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionLeft:
545635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            result.move(-box.width() - reflectionOffset(), 0);
546635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
547635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionRight:
548635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            result.move(box.width() + reflectionOffset(), 0);
549635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
550635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
551635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return result;
552635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
553635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
554635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::reflectionOffset() const
555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
556635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!style()->boxReflect())
557635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return 0;
558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (style()->boxReflect()->direction() == ReflectionLeft || style()->boxReflect()->direction() == ReflectionRight)
559635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return style()->boxReflect()->offset().calcValue(borderBoxRect().width());
560635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return style()->boxReflect()->offset().calcValue(borderBoxRect().height());
561635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
562635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
563635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect RenderBox::reflectedRect(const IntRect& r) const
564635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
565635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!style()->boxReflect())
566635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return IntRect();
567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
568635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect box = borderBoxRect();
569635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect result = r;
570635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    switch (style()->boxReflect()->direction()) {
571635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionBelow:
5722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            result.setY(box.maxY() + reflectionOffset() + (box.maxY() - r.maxY()));
573635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
574635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionAbove:
5752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            result.setY(box.y() - reflectionOffset() - box.height() + (box.maxY() - r.maxY()));
576635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
577635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionLeft:
5782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            result.setX(box.x() - reflectionOffset() - box.width() + (box.maxX() - r.maxX()));
579635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
580635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case ReflectionRight:
5812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            result.setX(box.maxX() + reflectionOffset() + (box.maxX() - r.maxX()));
582635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
583635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
584635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return result;
585635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
586635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
587ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochbool RenderBox::includeVerticalScrollbarSize() const
588ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
58981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return hasOverflowClip() && !layer()->hasOverlayScrollbars()
59081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO);
591ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
592ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
593ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochbool RenderBox::includeHorizontalScrollbarSize() const
594ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
59581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return hasOverflowClip() && !layer()->hasOverlayScrollbars()
59681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO);
597ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
598ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
599635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::verticalScrollbarWidth() const
600635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
601635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return includeVerticalScrollbarSize() ? layer()->verticalScrollbarWidth() : 0;
602635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
603635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
604635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderBox::horizontalScrollbarHeight() const
605635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
606635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return includeHorizontalScrollbarSize() ? layer()->horizontalScrollbarHeight() : 0;
607635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
608635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
609231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode)
610635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
611635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderLayer* l = layer();
612231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (l && l->scroll(direction, granularity, multiplier)) {
613231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (stopNode)
614231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            *stopNode = node();
615635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return true;
616231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
617231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
618231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (stopNode && *stopNode && *stopNode == node())
619231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return true;
620231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
621635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderBlock* b = containingBlock();
622635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (b && !b->isRenderView())
623231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return b->scroll(direction, granularity, multiplier, stopNode);
624635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return false;
625635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
626231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
627f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool RenderBox::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, float multiplier, Node** stopNode)
628f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
629f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool scrolled = false;
630f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
631f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderLayer* l = layer();
632f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (l) {
633f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if PLATFORM(MAC)
634f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // On Mac only we reset the inline direction position when doing a document scroll (e.g., hitting Home/End).
635f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (granularity == ScrollByDocument)
6362bde8e466a4451c7319e3a072d118917957d6554Steve Block            scrolled = l->scroll(logicalToPhysical(ScrollInlineDirectionBackward, isHorizontalWritingMode(), style()->isFlippedBlocksWritingMode()), ScrollByDocument, multiplier);
637f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
6382bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (l->scroll(logicalToPhysical(direction, isHorizontalWritingMode(), style()->isFlippedBlocksWritingMode()), granularity, multiplier))
639f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            scrolled = true;
640f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
641f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (scrolled) {
642f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (stopNode)
643f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                *stopNode = node();
644f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return true;
645f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
646f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
647f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
648f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (stopNode && *stopNode && *stopNode == node())
649f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return true;
650f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
651f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    RenderBlock* b = containingBlock();
652f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (b && !b->isRenderView())
653f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return b->logicalScroll(direction, granularity, multiplier, stopNode);
654f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return false;
655f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
656f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
657231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool RenderBox::canBeScrolledAndHasScrollableArea() const
658231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
659dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return canBeProgramaticallyScrolled(false) && (scrollHeight() != clientHeight() || scrollWidth() != clientWidth());
660231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
661635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
662635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBox::canBeProgramaticallyScrolled(bool) const
663635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
6642bde8e466a4451c7319e3a072d118917957d6554Steve Block    return (hasOverflowClip() && (scrollsOverflow() || (node() && node()->rendererIsEditable()))) || (node() && node()->isDocumentNode());
665635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
666635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
667635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBox::autoscroll()
668635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
669635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (layer())
670635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        layer()->autoscroll();
671635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
672635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
673635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBox::panScroll(const IntPoint& source)
674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
675635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (layer())
676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        layer()->panScrollFromPoint(source);
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
679bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::minPreferredLogicalWidth() const
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
681bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (preferredLogicalWidthsDirty())
682bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        const_cast<RenderBox*>(this)->computePreferredLogicalWidths();
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
684bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return m_minPreferredLogicalWidth;
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
687bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::maxPreferredLogicalWidth() const
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
689bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (preferredLogicalWidthsDirty())
690bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        const_cast<RenderBox*>(this)->computePreferredLogicalWidths();
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
692bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return m_maxPreferredLogicalWidth;
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBox::overrideSize() const
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasOverrideSize())
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return gOverrideSizeMap->get(this);
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::setOverrideSize(int s)
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (s == -1) {
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasOverrideSize()) {
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setHasOverrideSize(false);
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gOverrideSizeMap->remove(this);
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!gOverrideSizeMap)
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            gOverrideSizeMap = new OverrideSizeMap();
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setHasOverrideSize(true);
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gOverrideSizeMap->set(this, s);
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBox::overrideWidth() const
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
719635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return hasOverrideSize() ? overrideSize() : width();
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderBox::overrideHeight() const
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
724635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return hasOverrideSize() ? overrideSize() : height();
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
727bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::computeBorderBoxLogicalWidth(int width) const
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
729bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int bordersPlusPadding = borderAndPaddingLogicalWidth();
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->boxSizing() == CONTENT_BOX)
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return width + bordersPlusPadding;
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return max(width, bordersPlusPadding);
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
735bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::computeBorderBoxLogicalHeight(int height) const
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
737bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int bordersPlusPadding = borderAndPaddingLogicalHeight();
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->boxSizing() == CONTENT_BOX)
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return height + bordersPlusPadding;
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return max(height, bordersPlusPadding);
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
743bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::computeContentBoxLogicalWidth(int width) const
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->boxSizing() == BORDER_BOX)
746bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        width -= borderAndPaddingLogicalWidth();
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return max(0, width);
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
750bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::computeContentBoxLogicalHeight(int height) const
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->boxSizing() == BORDER_BOX)
753bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        height -= borderAndPaddingLogicalHeight();
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return max(0, height);
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Hit Testing
758635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action)
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
760635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    tx += x();
761635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ty += y();
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check kids first.
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
7658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!child->hasLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
766635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
77108c1068d9fd18289b9812c3d1fbcfccb8dfa3e60Steve Block    // Check our bounds next. For this purpose always assume that we can only be hit in the
77208c1068d9fd18289b9812c3d1fbcfccb8dfa3e60Steve Block    // foreground phase (which is true for replaced elements like images).
773db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    IntRect boundsRect = IntRect(tx, ty, width(), height());
774a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (visibleToHitTesting() && action == HitTestForeground && boundsRect.intersects(result.rectForPoint(xPos, yPos))) {
775db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
776db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        if (!result.addNodeToRectBasedTestResult(node(), xPos, yPos, boundsRect))
777db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block            return true;
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// --------------------- painting stuff -------------------------------
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::paint(PaintInfo& paintInfo, int tx, int ty)
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
787635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    tx += x();
788635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ty += y();
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // default implementation. Just pass paint through to the children
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PaintInfo childInfo(paintInfo);
792ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    childInfo.updatePaintingRootForChildren(this);
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RenderObject* child = firstChild(); child; child = child->nextSibling())
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->paint(childInfo, tx, ty);
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7972bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RenderBox::paintRootBoxFillLayers(const PaintInfo& paintInfo)
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const FillLayer* bgLayer = style()->backgroundLayers();
800e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    Color bgColor = style()->visitedDependentColor(CSSPropertyBackgroundColor);
801d0825bca7fe65beaee391d30da42e937db621564Steve Block    RenderObject* bodyObject = 0;
802e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (!hasBackground() && node() && node()->hasTagName(HTMLNames::htmlTag)) {
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Locate the <body> element using the DOM.  This is easier than trying
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // to crawl around a render tree with potential :before/:after content and
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // anonymous blocks created by inline <body> tags etc.  We can locate the <body>
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // render object very easily via the DOM.
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLElement* body = document()->body();
808d0825bca7fe65beaee391d30da42e937db621564Steve Block        bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (bodyObject) {
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bgLayer = bodyObject->style()->backgroundLayers();
811e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            bgColor = bodyObject->style()->visitedDependentColor(CSSPropertyBackgroundColor);
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
815f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // The background of the box generated by the root element covers the entire canvas, so just use
816f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // the RenderView's docTop/Left/Width/Height accessors.
817f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), CompositeSourceOver, bodyObject);
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
822ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (!paintInfo.shouldPaintWithinRoot(this))
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
82421939df44de1705786c545cd1bf519d47250322dBen Murdoch    return paintBoxDecorationsWithSize(paintInfo, tx, ty, width(), height());
82521939df44de1705786c545cd1bf519d47250322dBen Murdoch}
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
82721939df44de1705786c545cd1bf519d47250322dBen Murdochvoid RenderBox::paintBoxDecorationsWithSize(PaintInfo& paintInfo, int tx, int ty, int width, int height)
82821939df44de1705786c545cd1bf519d47250322dBen Murdoch{
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // border-fit can adjust where we paint our border and background.  If set, we snugly fit our line box descendants.  (The iChat
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // balloon layout is an example of this).
83121939df44de1705786c545cd1bf519d47250322dBen Murdoch    borderFitAdjust(tx, width);
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Should eventually give the theme control over whether the box shadow should paint, since controls could have
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // custom shadows of their own.
83521939df44de1705786c545cd1bf519d47250322dBen Murdoch    paintBoxShadow(paintInfo.context, tx, ty, width, height, style(), Normal);
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we have a native theme appearance, paint that before painting our background.
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The theme will tell us whether or not we should also paint the CSS background.
83921939df44de1705786c545cd1bf519d47250322dBen Murdoch    bool themePainted = style()->hasAppearance() && !theme()->paint(this, paintInfo, IntRect(tx, ty, width, height));
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!themePainted) {
8412bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isRoot())
8422bde8e466a4451c7319e3a072d118917957d6554Steve Block            paintRootBoxFillLayers(paintInfo);
8432bde8e466a4451c7319e3a072d118917957d6554Steve Block        else if (!isBody() || document()->documentElement()->renderer()->hasBackground()) {
8442bde8e466a4451c7319e3a072d118917957d6554Steve Block            // The <body> only paints its background if the root element has defined a background
8452bde8e466a4451c7319e3a072d118917957d6554Steve Block            // independent of the body.
846a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard#if PLATFORM(ANDROID)
847a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard            // If we only want to draw the decorations, don't draw
848a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard            // the background
849a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard            if (paintInfo.phase != PaintPhaseBlockBackgroundDecorations)
850a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard#endif
851e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), tx, ty, width, height);
8522bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->hasAppearance())
85421939df44de1705786c545cd1bf519d47250322dBen Murdoch            theme()->paintDecorations(this, paintInfo, IntRect(tx, ty, width, height));
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
85621939df44de1705786c545cd1bf519d47250322dBen Murdoch    paintBoxShadow(paintInfo.context, tx, ty, width, height, style(), Inset);
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The theme will tell us whether or not we should also paint the CSS border.
85921939df44de1705786c545cd1bf519d47250322dBen Murdoch    if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, IntRect(tx, ty, width, height)))) && style()->hasBorder())
86021939df44de1705786c545cd1bf519d47250322dBen Murdoch        paintBorder(paintInfo.context, tx, ty, width, height, style());
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::paintMask(PaintInfo& paintInfo, int tx, int ty)
8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
865a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!paintInfo.shouldPaintWithinRoot(this) || style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask || paintInfo.context->paintingDisabled())
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int w = width();
869635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int h = height();
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // border-fit can adjust where we paint our border and background.  If set, we snugly fit our line box descendants.  (The iChat
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // balloon layout is an example of this).
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    borderFitAdjust(tx, w);
8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    paintMaskImages(paintInfo, tx, ty, w, h);
8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int w, int h)
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Figure out if we need to push a transparency layer to render our mask.
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool pushTransparencyLayer = false;
882231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool compositedMask = hasLayer() && layer()->hasCompositedMask();
883231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    CompositeOperator compositeOp = CompositeSourceOver;
884231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
885d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool allMaskImagesLoaded = true;
886d0825bca7fe65beaee391d30da42e937db621564Steve Block
887231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!compositedMask) {
888a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // If the context has a rotation, scale or skew, then use a transparency layer to avoid
889a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // pixel cruft around the edge of the mask.
890a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        const AffineTransform& currentCTM = paintInfo.context->getCTM();
891a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        pushTransparencyLayer = !currentCTM.isIdentityOrTranslationOrFlipped();
892a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
893231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        StyleImage* maskBoxImage = style()->maskBoxImage().image();
894d0825bca7fe65beaee391d30da42e937db621564Steve Block        const FillLayer* maskLayers = style()->maskLayers();
895d0825bca7fe65beaee391d30da42e937db621564Steve Block
896d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Don't render a masked element until all the mask images have loaded, to prevent a flash of unmasked content.
897d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (maskBoxImage)
898d0825bca7fe65beaee391d30da42e937db621564Steve Block            allMaskImagesLoaded &= maskBoxImage->isLoaded();
899d0825bca7fe65beaee391d30da42e937db621564Steve Block
900d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (maskLayers)
901d0825bca7fe65beaee391d30da42e937db621564Steve Block            allMaskImagesLoaded &= maskLayers->imagesAreLoaded();
902d0825bca7fe65beaee391d30da42e937db621564Steve Block
903d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Before all images have loaded, just use an empty transparency layer as the mask.
904d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!allMaskImagesLoaded)
905d0825bca7fe65beaee391d30da42e937db621564Steve Block            pushTransparencyLayer = true;
906d0825bca7fe65beaee391d30da42e937db621564Steve Block
907d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (maskBoxImage && maskLayers->hasImage()) {
908d0825bca7fe65beaee391d30da42e937db621564Steve Block            // We have a mask-box-image and mask-image, so need to composite them together before using the result as a mask.
909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            pushTransparencyLayer = true;
910231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else {
911231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // We have to use an extra image buffer to hold the mask. Multiple mask images need
912231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // to composite together using source-over so that they can then combine into a single unified mask that
913231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // can be composited with the content using destination-in.  SVG images need to be able to set compositing modes
914231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // as they draw images contained inside their sub-document, so we paint all our images into a separate buffer
915231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // and composite that buffer as the mask.
916231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // We have to check that the mask images to be rendered contain at least one image that can be actually used in rendering
917231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // before pushing the transparency layer.
918d0825bca7fe65beaee391d30da42e937db621564Steve Block            for (const FillLayer* fillLayer = maskLayers->next(); fillLayer; fillLayer = fillLayer->next()) {
919231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (fillLayer->hasImage() && fillLayer->image()->canRender(style()->effectiveZoom())) {
920231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    pushTransparencyLayer = true;
921231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    // We found one image that can be used in rendering, exit the loop
922231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
923231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                }
9245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
9255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
926231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
927231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        compositeOp = CompositeDestinationIn;
928231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (pushTransparencyLayer) {
929231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            paintInfo.context->setCompositeOperation(CompositeDestinationIn);
930231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            paintInfo.context->beginTransparencyLayer(1.0f);
931231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            compositeOp = CompositeSourceOver;
932231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
935d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (allMaskImagesLoaded) {
936d0825bca7fe65beaee391d30da42e937db621564Steve Block        paintFillLayers(paintInfo, Color(), style()->maskLayers(), tx, ty, w, h, compositeOp);
937d0825bca7fe65beaee391d30da42e937db621564Steve Block        paintNinePieceImage(paintInfo.context, tx, ty, w, h, style(), style()->maskBoxImage(), compositeOp);
938d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (pushTransparencyLayer)
9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintInfo.context->endTransparencyLayer();
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntRect RenderBox::maskClipRect()
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
946635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect bbox = borderBoxRect();
9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->maskBoxImage().image())
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return bbox;
9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect result;
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (const FillLayer* maskLayer = style()->maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (maskLayer->image()) {
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect maskRect;
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntPoint phase;
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntSize tileSize;
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            calculateBackgroundImageGeometry(maskLayer, bbox.x(), bbox.y(), bbox.width(), bbox.height(), maskRect, phase, tileSize);
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result.unite(maskRect);
9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
963d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject)
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!fillLayer)
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968d0825bca7fe65beaee391d30da42e937db621564Steve Block    paintFillLayers(paintInfo, c, fillLayer->next(), tx, ty, width, height, op, backgroundObject);
969d0825bca7fe65beaee391d30da42e937db621564Steve Block    paintFillLayer(paintInfo, c, fillLayer, tx, ty, width, height, op, backgroundObject);
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
972d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject)
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, width, height, 0, 0, 0, op, backgroundObject);
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
977f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if USE(ACCELERATED_COMPOSITING)
978f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic bool layersUseImage(WrappedImagePtr image, const FillLayer* layers)
979f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
980f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next()) {
981f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (curLayer->image() && image == curLayer->image()->data())
982f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return true;
983f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
984f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
985f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return false;
986f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
987f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
988f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
989635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderBox::imageChanged(WrappedImagePtr image, const IntRect*)
9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
991635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!parent())
992635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
993635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
9948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((style()->borderImage().image() && style()->borderImage().image()->data() == image) ||
9958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        (style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image)) {
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaint();
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool didFullRepaint = repaintLayerRectsForImage(image, style()->backgroundLayers(), true);
10018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!didFullRepaint)
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintLayerRectsForImage(image, style()->maskLayers(), false);
1003f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1004f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1005f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if USE(ACCELERATED_COMPOSITING)
1006f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasLayer() && layer()->hasCompositedMask() && layersUseImage(image, style()->maskLayers()))
1007f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        layer()->contentChanged(RenderLayer::MaskImageChanged);
1008f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground)
10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1013635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect rendererRect;
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBox* layerRenderer = 0;
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next()) {
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (curLayer->image() && image == curLayer->image()->data() && curLayer->image()->canRender(style()->effectiveZoom())) {
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Now that we know this image is being used, compute the renderer and the rect
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // if we haven't already
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!layerRenderer) {
1021e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                bool drawingRootBackground = drawingBackground && (isRoot() || (isBody() && !document()->documentElement()->renderer()->hasBackground()));
10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (drawingRootBackground) {
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    layerRenderer = view();
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int rw;
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int rh;
10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (FrameView* frameView = toRenderView(layerRenderer)->frameView()) {
10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        rw = frameView->contentsWidth();
10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        rh = frameView->contentsHeight();
10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else {
10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        rw = layerRenderer->width();
10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        rh = layerRenderer->height();
10348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
1035635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    rendererRect = IntRect(-layerRenderer->marginLeft(),
10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        -layerRenderer->marginTop(),
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        max(layerRenderer->width() + layerRenderer->marginLeft() + layerRenderer->marginRight() + layerRenderer->borderLeft() + layerRenderer->borderRight(), rw),
10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        max(layerRenderer->height() + layerRenderer->marginTop() + layerRenderer->marginBottom() + layerRenderer->borderTop() + layerRenderer->borderBottom(), rh));
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    layerRenderer = this;
1041635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    rendererRect = borderBoxRect();
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect repaintRect;
10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntPoint phase;
10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntSize tileSize;
1048635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            layerRenderer->calculateBackgroundImageGeometry(curLayer, rendererRect.x(), rendererRect.y(), rendererRect.width(), rendererRect.height(), repaintRect, phase, tileSize);
1049635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            layerRenderer->repaintRectangle(repaintRect);
1050635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (repaintRect == rendererRect)
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(MAC)
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText)
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1061545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    Frame* frame = this->frame();
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Page* page = frame->page();
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!page)
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineBox* boxWrap = inlineBoxWrapper();
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* r = boxWrap ? boxWrap->root() : 0;
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (r) {
1071bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        FloatRect rootRect(tx + r->x(), ty + r->selectionTop(), r->logicalWidth(), r->selectionHeight());
1072635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        FloatRect imageRect(tx + x(), rootRect.y(), width(), rootRect.height());
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        page->chrome()->client()->paintCustomHighlight(node(), type, imageRect, rootRect, behindText, false);
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1075635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        FloatRect imageRect(tx + x(), ty + y(), width(), height());
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        page->chrome()->client()->paintCustomHighlight(node(), type, imageRect, imageRect, behindText, false);
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool RenderBox::pushContentsClip(PaintInfo& paintInfo, int tx, int ty)
10838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
10848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseSelfOutline || paintInfo.phase == PaintPhaseMask)
10858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return false;
10868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool isControlClip = hasControlClip();
10888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool isOverflowClip = hasOverflowClip() && !layer()->isSelfPaintingLayer();
10898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!isControlClip && !isOverflowClip)
10918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return false;
10928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (paintInfo.phase == PaintPhaseOutline)
10948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.phase = PaintPhaseChildOutlines;
10958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    else if (paintInfo.phase == PaintPhaseChildBlockBackground) {
10968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.phase = PaintPhaseBlockBackground;
10978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintObject(paintInfo, tx, ty);
10988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.phase = PaintPhaseChildBlockBackgrounds;
10998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
11008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    IntRect clipRect(isControlClip ? controlClipRect(tx, ty) : overflowClipRect(tx, ty));
11018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    paintInfo.context->save();
1102ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if (style()->hasBorderRadius())
1103ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        paintInfo.context->addRoundedRectClip(style()->getRoundedBorderFor(IntRect(tx, ty, width(), height())));
11045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    paintInfo.context->clip(clipRect);
11058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return true;
11068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
11078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
11088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::popContentsClip(PaintInfo& paintInfo, PaintPhase originalPhase, int tx, int ty)
11098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
11108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(hasControlClip() || (hasOverflowClip() && !layer()->isSelfPaintingLayer()));
11118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
11128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    paintInfo.context->restore();
11138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (originalPhase == PaintPhaseOutline) {
11148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.phase = PaintPhaseSelfOutline;
11158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintObject(paintInfo, tx, ty);
11168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.phase = originalPhase;
11178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else if (originalPhase == PaintPhaseChildBlockBackground)
11188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.phase = originalPhase;
11198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
11208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
11212bde8e466a4451c7319e3a072d118917957d6554Steve BlockIntRect RenderBox::overflowClipRect(int tx, int ty, OverlayScrollbarSizeRelevancy relevancy)
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: When overflow-clip (CSS3) is implemented, we'll obtain the property
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // here.
11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bLeft = borderLeft();
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int bTop = borderTop();
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int clipX = tx + bLeft;
11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int clipY = ty + bTop;
1131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int clipWidth = width() - bLeft - borderRight();
1132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int clipHeight = height() - bTop - borderBottom();
11338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Subtract out scrollbars if we have them.
11358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (layer()) {
11362bde8e466a4451c7319e3a072d118917957d6554Steve Block        clipWidth -= layer()->verticalScrollbarWidth(relevancy);
11372bde8e466a4451c7319e3a072d118917957d6554Steve Block        clipHeight -= layer()->horizontalScrollbarHeight(relevancy);
11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return IntRect(clipX, clipY, clipWidth, clipHeight);
11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBox::clipRect(int tx, int ty)
11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int clipX = tx;
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int clipY = ty;
1147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int clipWidth = width();
1148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int clipHeight = height();
11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!style()->clipLeft().isAuto()) {
1151635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int c = style()->clipLeft().calcValue(width());
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        clipX += c;
11538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        clipWidth -= c;
11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!style()->clipRight().isAuto())
1157635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        clipWidth -= width() - style()->clipRight().calcValue(width());
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!style()->clipTop().isAuto()) {
1160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int c = style()->clipTop().calcValue(height());
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        clipY += c;
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        clipHeight -= c;
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!style()->clipBottom().isAuto())
1166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        clipHeight -= height() - style()->clipBottom().calcValue(height());
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return IntRect(clipX, clipY, clipWidth, clipHeight);
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1171bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::containingBlockLogicalWidthForContent() const
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock* cb = containingBlock();
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (shrinkToAvoidFloats())
1175bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return cb->availableLogicalWidthForLine(y(), false);
1176bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return cb->availableLogicalWidth();
1177bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
1178bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1179bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::perpendicularContainingBlockLogicalHeight() const
1180bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1181bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    RenderBlock* cb = containingBlock();
1182bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    RenderStyle* containingBlockStyle = cb->style();
1183bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    Length logicalHeightLength = containingBlockStyle->logicalHeight();
1184bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1185bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: For now just support fixed heights.  Eventually should support percentage heights as well.
1186bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!logicalHeightLength.isFixed()) {
1187bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // Rather than making the child be completely unconstrained, WinIE uses the viewport width and height
1188bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // as a constraint.  We do that for now as well even though it's likely being unconstrained is what the spec
1189bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // will decide.
1190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return containingBlockStyle->isHorizontalWritingMode() ? view()->frameView()->visibleHeight() : view()->frameView()->visibleWidth();
1191bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
1192bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1193bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Use the content box logical height as specified by the style.
1194bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return cb->computeContentBoxLogicalHeight(logicalHeightLength.value());
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (repaintContainer == this)
12008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (RenderView* v = view()) {
12035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (v->layoutStateEnabled() && !repaintContainer) {
1204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            LayoutState* layoutState = v->layoutState();
120568513a70bcd92384395513322f1b801e7bf9c729Steve Block            IntSize offset = layoutState->m_paintOffset;
1206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            offset.expand(x(), y());
12078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (style()->position() == RelativePosition && layer())
12088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                offset += layer()->relativePositionOffset();
12098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            transformState.move(offset);
12108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return;
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool containerSkipped;
1215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RenderObject* o = container(repaintContainer, &containerSkipped);
12168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!o)
12178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1219d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool isFixedPos = style()->position() == FixedPosition;
12208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool hasTransform = hasLayer() && layer()->transform();
1221d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (hasTransform) {
1222d0825bca7fe65beaee391d30da42e937db621564Steve Block        // If this box has a transform, it acts as a fixed position container for fixed descendants,
1223d0825bca7fe65beaee391d30da42e937db621564Steve Block        // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
1224d0825bca7fe65beaee391d30da42e937db621564Steve Block        fixed &= isFixedPos;
1225d0825bca7fe65beaee391d30da42e937db621564Steve Block    } else
1226d0825bca7fe65beaee391d30da42e937db621564Steve Block        fixed |= isFixedPos;
1227d0825bca7fe65beaee391d30da42e937db621564Steve Block
1228692e5dbf12901edacf14812a6fae25462920af42Steve Block    IntSize containerOffset = offsetFromContainer(o, roundedIntPoint(transformState.mappedPoint()));
12296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
12315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (useTransforms && shouldUseTransformFromContainer(o)) {
12325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        TransformationMatrix t;
12335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        getTransformFromContainer(o, containerOffset, t);
12345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
12355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else
12365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
12378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1238231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (containerSkipped) {
1239231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // There can't be a transform between repaintContainer and o, because transforms create containers, so it should be safe
1240231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // to just subtract the delta between the repaintContainer and o.
1241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        IntSize containerOffset = repaintContainer->offsetFromAncestorContainer(o);
1242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
1243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
1244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1245231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
12468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
1247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
1248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
12498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
1250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
1251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // We don't expect absoluteToLocal() to be called during layout (yet)
1252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(!view() || !view()->layoutStateEnabled());
1253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1254d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool isFixedPos = style()->position() == FixedPosition;
12558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool hasTransform = hasLayer() && layer()->transform();
1256d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (hasTransform) {
1257d0825bca7fe65beaee391d30da42e937db621564Steve Block        // If this box has a transform, it acts as a fixed position container for fixed descendants,
1258d0825bca7fe65beaee391d30da42e937db621564Steve Block        // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
1259d0825bca7fe65beaee391d30da42e937db621564Steve Block        fixed &= isFixedPos;
1260d0825bca7fe65beaee391d30da42e937db621564Steve Block    } else
1261d0825bca7fe65beaee391d30da42e937db621564Steve Block        fixed |= isFixedPos;
1262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* o = container();
12648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!o)
12658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
1266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
12678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
1268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1269692e5dbf12901edacf14812a6fae25462920af42Steve Block    IntSize containerOffset = offsetFromContainer(o, IntPoint());
1270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
12718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
12725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (useTransforms && shouldUseTransformFromContainer(o)) {
12735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        TransformationMatrix t;
12745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        getTransformFromContainer(o, containerOffset, t);
12755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
12765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else
12775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
1278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
12798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1280692e5dbf12901edacf14812a6fae25462920af42Steve BlockIntSize RenderBox::offsetFromContainer(RenderObject* o, const IntPoint& point) const
1281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
1282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(o == container());
1283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntSize offset;
1285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (isRelPositioned())
1286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        offset += relativePositionOffset();
1287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!isInline() || isReplaced()) {
12896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
12902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (o->hasColumns()) {
12912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                IntRect columnRect(frameRect());
12922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                toRenderBlock(o)->flipForWritingModeIncludingColumns(columnRect);
12932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset += IntSize(columnRect.location().x(), columnRect.location().y());
12942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                columnRect.move(point.x(), point.y());
12952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                o->adjustForColumns(offset, columnRect.location());
12962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            } else
12972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset += locationOffsetIncludingFlipping();
12986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        } else
129981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            offset += locationOffsetIncludingFlipping();
13008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (o->hasOverflowClip())
1303635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        offset -= toRenderBox(o)->layer()->scrolledContentOffset();
1304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
13058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
13068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        offset += toRenderInline(o)->relativePositionedInlineOffset(this);
1307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return offset;
13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianInlineBox* RenderBox::createInlineBox()
13128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
13138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return new (renderArena()) InlineBox(this);
13148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
13158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::dirtyLineBoxes(bool fullLayout)
13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_inlineBoxWrapper) {
13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (fullLayout) {
13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_inlineBoxWrapper->destroy(renderArena());
13218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_inlineBoxWrapper = 0;
13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_inlineBoxWrapper->dirtyLineBoxes();
13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::positionLineBox(InlineBox* box)
13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isPositioned()) {
13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Cache the x position only if we were an INLINE type originally.
13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool wasInline = style()->isOriginalDisplayInlineType();
13322bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (wasInline) {
13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The value is cached in the xPos of the box.  We only need this value if
13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // our object was inline originally, since otherwise it would have ended up underneath
13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the inlines.
133681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            layer()->setStaticInlinePosition(lroundf(box->logicalLeft()));
13372bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (style()->hasStaticInlinePosition(box->isHorizontal()))
13382bde8e466a4451c7319e3a072d118917957d6554Steve Block                setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
13392bde8e466a4451c7319e3a072d118917957d6554Steve Block        } else {
13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Our object was a block originally, so we make our normal flow position be
13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // just below the line box (as though all the inlines that came before us got
13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // wrapped in an anonymous block, which is what would have happened had we been
13438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // in flow).  This value was cached in the y() of the box.
134481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            layer()->setStaticBlockPosition(box->logicalTop());
13452bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (style()->hasStaticBlockPosition(box->isHorizontal()))
13462bde8e466a4451c7319e3a072d118917957d6554Steve Block                setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
13478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Nuke the box.
13508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        box->remove();
13518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        box->destroy(renderArena());
13528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (isReplaced()) {
135381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        setLocation(lroundf(box->x()), lroundf(box->y()));
13548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_inlineBoxWrapper = box;
13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::deleteLineBoxWrapper()
13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_inlineBoxWrapper) {
13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!documentBeingDestroyed())
13628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_inlineBoxWrapper->remove();
13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_inlineBoxWrapper->destroy(renderArena());
13648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_inlineBoxWrapper = 0;
13658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianIntRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
13698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
13718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return IntRect();
13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1373f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect r = visualOverflowRect();
13748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1375635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderView* v = view();
1376635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (v) {
1377635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // FIXME: layoutDelta needs to be applied in parts before/after transforms and
1378635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
13798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        r.move(v->layoutDelta());
1380635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
1381635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
13828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()) {
13838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->hasAppearance())
13848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The theme may wish to inflate the rect used when repainting.
13858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            theme()->adjustRepaintRect(this, r);
13868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1387635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // We have to use maximalOutlineSize() because a child might have an outline
1388635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // that projects outside of our overflowRect.
1389635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (v) {
1390635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            ASSERT(style()->outlineSize() <= v->maximalOutlineSize());
1391635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            r.inflate(v->maximalOutlineSize());
1392635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
13958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    computeRectForRepaint(repaintContainer, r);
13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return r;
13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // The rect we compute at each step is shifted by our x/y offset in the parent container's coordinate space.
14026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Only when we cross a writing mode boundary will we have to possibly flipForWritingMode (to convert into a more appropriate
14036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // offset corner for the enclosing container).  This allows for a fully RL or BT document to repaint
14046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // properly even during layout, since the rect remains flipped all the way until the end.
14056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    //
14066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // RenderView::computeRectForRepaint then converts the rect to physical coordinates.  We also convert to
14076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // physical when we hit a repaintContainer boundary.  Therefore the final rect returned is always in the
14086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // physical coordinate space of the repaintContainer.
14098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (RenderView* v = view()) {
1410635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // LayoutState is only valid for root-relative repainting
1411635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (v->layoutStateEnabled() && !repaintContainer) {
1412635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            LayoutState* layoutState = v->layoutState();
14135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
14145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (layer() && layer()->transform())
14155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                rect = layer()->transform()->mapRect(rect);
14165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
14178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (style()->position() == RelativePosition && layer())
14188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                rect.move(layer()->relativePositionOffset());
1419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1420635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            rect.move(x(), y());
142168513a70bcd92384395513322f1b801e7bf9c729Steve Block            rect.move(layoutState->m_paintOffset);
14228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (layoutState->m_clipped)
14238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rect.intersect(layoutState->m_clipRect);
14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
14258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1428635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (hasReflection())
1429635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        rect.unite(reflectedRect(rect));
1430635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
14316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (repaintContainer == this) {
14326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (repaintContainer->style()->isFlippedBlocksWritingMode())
14336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            flipForWritingMode(rect);
1434635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
14356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
14368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1437231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool containerSkipped;
1438231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RenderObject* o = container(repaintContainer, &containerSkipped);
1439635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!o)
1440635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
14418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (isWritingModeRoot() && !isPositioned())
14436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        flipForWritingMode(rect);
1444635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntPoint topLeft = rect.location();
1445635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    topLeft.move(x(), y());
14468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1447dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    EPosition position = style()->position();
14488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1449635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // We are now in our parent container's coordinate space.  Apply our transform to obtain a bounding box
1450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // in the parent's coordinate space that encloses us.
14518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (layer() && layer()->transform()) {
1452dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        fixed = position == FixedPosition;
14538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        rect = layer()->transform()->mapRect(rect);
1454635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        topLeft = rect.location();
1455635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        topLeft.move(x(), y());
1456dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else if (position == FixedPosition)
1457dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        fixed = true;
1458635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1459dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (position == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
14608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        topLeft += toRenderInline(o)->relativePositionedInlineOffset(this);
1461dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if (position == RelativePosition && layer()) {
1462635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Apply the relative position offset when invalidating a rectangle.  The layer
1463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // is translated, but the render box isn't, so we need to do this to get the
1464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // right dirty rect.  Since this is called from RenderObject::setStyle, the relative position
1465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // flag on the RenderObject has been cleared, so use the one on the style().
14668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        topLeft += layer()->relativePositionOffset();
14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1469e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (o->isBlockFlow() && position != AbsolutePosition && position != FixedPosition) {
1470e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        RenderBlock* cb = toRenderBlock(o);
1471e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (cb->hasColumns()) {
1472e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            IntRect repaintRect(topLeft, rect.size());
1473e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            cb->adjustRectForColumns(repaintRect);
1474e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            topLeft = repaintRect.location();
1475e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            rect = repaintRect;
1476e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        }
1477e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    }
1478e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
1479635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,
1480635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer.
1481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (o->hasOverflowClip()) {
1482635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* containerBox = toRenderBox(o);
1483635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1484635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the
1485635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint
1486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // anyway if its size does change.
1487635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        topLeft -= containerBox->layer()->scrolledContentOffset(); // For overflow:auto/scroll/hidden.
1488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1489635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        IntRect repaintRect(topLeft, rect.size());
1490635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        IntRect boxRect(0, 0, containerBox->layer()->width(), containerBox->layer()->height());
1491635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        rect = intersection(repaintRect, boxRect);
1492635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (rect.isEmpty())
1493635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return;
1494635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    } else
1495635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        rect.setLocation(topLeft);
1496231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1497231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (containerSkipped) {
1498231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // If the repaintContainer is below o, then we need to map the rect into repaintContainer's coordinates.
1499231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        IntSize containerOffset = repaintContainer->offsetFromAncestorContainer(o);
1500231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        rect.move(-containerOffset);
1501231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
1502231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
15036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
15048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    o->computeRectForRepaint(repaintContainer, rect, fixed);
15058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderBox::repaintDuringLayoutIfMoved(const IntRect& rect)
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1509635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int newX = x();
1510635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int newY = y();
1511635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int newWidth = width();
1512635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int newHeight = height();
15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (rect.x() != newX || rect.y() != newY) {
15148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The child moved.  Invalidate the object's old and new positions.  We have to do this
15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // since the object may not have gotten a layout.
1516635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_frameRect = rect;
15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaint();
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintOverhangingFloats(true);
1519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_frameRect = IntRect(newX, newY, newWidth, newHeight);
15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaint();
15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repaintOverhangingFloats(true);
15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
152523e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang#ifdef ANDROID_LAYOUT
152623e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wangvoid RenderBox::setVisibleWidth(int newWidth) {
152723e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    const Settings* settings = document()->settings();
152823e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    ASSERT(settings);
152923e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    if (settings->layoutAlgorithm() != Settings::kLayoutFitColumnToScreen
153023e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang        || m_visibleWidth == newWidth)
153123e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang        return;
153223e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    m_isVisibleWidthChangedBeforeLayout = true;
153323e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    m_visibleWidth = newWidth;
153423e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang}
153523e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang
153623e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wangbool RenderBox::checkAndSetRelayoutChildren(bool* relayoutChildren) {
153723e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    if (m_isVisibleWidthChangedBeforeLayout) {
153823e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang        m_isVisibleWidthChangedBeforeLayout = false;
153923e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang        *relayoutChildren = true;
154023e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang        return true;
154123e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    }
154223e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    return false;
154323e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang}
154423e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang#endif
154523e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang
1546bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computeLogicalWidth()
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
154923e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang    if (view()->frameView())
155023e9dd818a876304304944c844be7625f63383c4Shimeng (Simon) Wang        setVisibleWidth(view()->frameView()->textWrapWidth());
15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1552bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block
15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isPositioned()) {
1554bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This calculation is not patched for block-flow yet.
1555bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46500
1556bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        computePositionedLogicalWidth();
15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1560bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // If layout is limited to a subtree, the subtree root's logical width does not change.
15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node() && view()->frameView() && view()->frameView()->layoutRoot(true) == this)
15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The parent box is flexing us, so it has increased or decreased our
15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // width.  Use the width from the style context.
1566bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: Account for block-flow in flexible boxes.
1567bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // https://bugs.webkit.org/show_bug.cgi?id=46418
15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasOverrideSize() &&  parent()->style()->boxOrient() == HORIZONTAL
15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            && parent()->isFlexibleBox() && parent()->isFlexingChildren()) {
1570965fc3e3a2ae0316a67f7e1c82a04bc533a383d4Teng-Hui Zhu#if PLATFORM(ANDROID)
1571965fc3e3a2ae0316a67f7e1c82a04bc533a383d4Teng-Hui Zhu        // Strangely, the slider is get overrided as width 0 on youtube.com
1572965fc3e3a2ae0316a67f7e1c82a04bc533a383d4Teng-Hui Zhu        // The wrong width will cause the touch hit test for the slider failed.
1573965fc3e3a2ae0316a67f7e1c82a04bc533a383d4Teng-Hui Zhu        // This WAR should be safe since it is only targeted to slider.
1574965fc3e3a2ae0316a67f7e1c82a04bc533a383d4Teng-Hui Zhu        // TODO: root cause this and see if any webkit update fix this.
1575965fc3e3a2ae0316a67f7e1c82a04bc533a383d4Teng-Hui Zhu        if (!(isSlider() &&  overrideSize() == 0))
1576965fc3e3a2ae0316a67f7e1c82a04bc533a383d4Teng-Hui Zhu#endif
1577bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalWidth(overrideSize());
15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1581bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: Account for block-flow in flexible boxes.
1582bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // https://bugs.webkit.org/show_bug.cgi?id=46418
15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool inVerticalBox = parent()->isFlexibleBox() && (parent()->style()->boxOrient() == VERTICAL);
15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool stretching = (parent()->style()->boxAlign() == BSTRETCH);
1585bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool treatAsReplaced = shouldComputeSizeAsReplaced() && (!inVerticalBox || !stretching);
15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1587a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Length logicalWidthLength = (treatAsReplaced) ? Length(computeReplacedLogicalWidth(), Fixed) : style()->logicalWidth();
15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock* cb = containingBlock();
1590bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int containerLogicalWidth = max(0, containingBlockLogicalWidthForContent());
15912bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasPerpendicularContainingBlock = cb->isHorizontalWritingMode() != isHorizontalWritingMode();
1592bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int containerWidthInInlineDirection = containerLogicalWidth;
1593bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (hasPerpendicularContainingBlock)
1594bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        containerWidthInInlineDirection = perpendicularContainingBlockLogicalHeight();
1595bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
15968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isInline() && !isInlineBlockOrInlineTable()) {
15978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // just calculate margins
1598e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen        setMarginStart(style()->marginStart().calcMinValue(containerLogicalWidth));
1599e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen        setMarginEnd(style()->marginEnd().calcMinValue(containerLogicalWidth));
1600635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifdef ANDROID_LAYOUT
1601635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (treatAsReplaced) {
1602635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else
16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (treatAsReplaced)
1604635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
1605e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen            setLogicalWidth(max(logicalWidthLength.value() + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth()));
1606bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block
16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
1608635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // in SSR mode with replaced box, if the box width is wider than the container width,
1609635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // it will be shrinked to fit to the container.
161015196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen            if (containerLogicalWidth && (width() + m_marginLeft + m_marginRight) > containerLogicalWidth &&
1611635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    document()->frame()->settings()->layoutAlgorithm() == Settings::kLayoutSSR) {
1612635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                m_marginLeft = m_marginRight = 0;
161315196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen                setWidth(containerLogicalWidth);
161415196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen                m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = containerLogicalWidth;
1615635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
16168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1617635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
16188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
16198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Width calculations
16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (treatAsReplaced)
1623bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalWidth(logicalWidthLength.value() + borderAndPaddingLogicalWidth());
16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
1625bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // Calculate LogicalWidth
1626bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalWidth(computeLogicalWidthUsing(LogicalWidth, containerWidthInInlineDirection));
1627bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1628bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // Calculate MaxLogicalWidth
1629bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!style()->logicalMaxWidth().isUndefined()) {
1630bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int maxLogicalWidth = computeLogicalWidthUsing(MaxLogicalWidth, containerWidthInInlineDirection);
1631bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            if (logicalWidth() > maxLogicalWidth) {
1632bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                setLogicalWidth(maxLogicalWidth);
1633bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                logicalWidthLength = style()->logicalMaxWidth();
16348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
16358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1637bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // Calculate MinLogicalWidth
1638bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int minLogicalWidth = computeLogicalWidthUsing(MinLogicalWidth, containerWidthInInlineDirection);
1639bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (logicalWidth() < minLogicalWidth) {
1640bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalWidth(minLogicalWidth);
1641bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            logicalWidthLength = style()->logicalMinWidth();
16428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1645bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Fieldsets are currently the only objects that stretch to their minimum width.
1646bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (stretchesToMinIntrinsicLogicalWidth()) {
1647bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalWidth(max(logicalWidth(), minPreferredLogicalWidth()));
1648bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        logicalWidthLength = Length(logicalWidth(), Fixed);
16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1651e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen    // Margin calculations.
1652e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen    if (logicalWidthLength.isAuto() || hasPerpendicularContainingBlock || isFloating() || isInline()) {
1653e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen        setMarginStart(style()->marginStart().calcMinValue(containerLogicalWidth));
1654e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen        setMarginEnd(style()->marginEnd().calcMinValue(containerLogicalWidth));
1655e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen    } else
1656e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen        computeInlineDirectionMargins(cb, containerLogicalWidth, logicalWidth());
1657e1a0cd8247467a70fed9f6099fc9c65ec35ae23eKristian Monsen
16588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
16598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // in SSR mode with non-replaced box, we use ANDROID_SSR_MARGIN_PADDING for left/right margin.
1660bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block    // If the box width is wider than the container width, it will be shrinked to fit to the container.
166115196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen    if (containerLogicalWidth && !treatAsReplaced &&
16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            document()->settings()->layoutAlgorithm() == Settings::kLayoutSSR) {
1663635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        setWidth(width() + m_marginLeft + m_marginRight);
16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_marginLeft = m_marginLeft > ANDROID_SSR_MARGIN_PADDING ? ANDROID_SSR_MARGIN_PADDING : m_marginLeft;
16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_marginRight = m_marginRight > ANDROID_SSR_MARGIN_PADDING ? ANDROID_SSR_MARGIN_PADDING : m_marginRight;
166615196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen        if (width() > containerLogicalWidth) {
166715196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = containerLogicalWidth-(m_marginLeft + m_marginRight);
166815196e7281a07cd210bad6e50ad31dabab648e6cKristian Monsen            setWidth(m_minPreferredLogicalWidth);
1669635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else
1670635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            setWidth(width() -(m_marginLeft + m_marginRight));
16718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
16738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1674bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (!hasPerpendicularContainingBlock && containerLogicalWidth && containerLogicalWidth != (logicalWidth() + marginStart() + marginEnd())
1675bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            && !isFloating() && !isInline() && !cb->isFlexibleBox())
1676a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cb->setMarginEndForChild(this, containerLogicalWidth - logicalWidth() - cb->marginStartForChild(this));
16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1679bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::computeLogicalWidthUsing(LogicalWidthType widthType, int availableLogicalWidth)
16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1681bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int logicalWidthResult = logicalWidth();
1682bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    Length logicalWidth;
1683bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (widthType == LogicalWidth)
1684bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        logicalWidth = style()->logicalWidth();
1685bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    else if (widthType == MinLogicalWidth)
1686bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        logicalWidth = style()->logicalMinWidth();
16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1688bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        logicalWidth = style()->logicalMaxWidth();
16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1690bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (logicalWidth.isIntrinsicOrAuto()) {
1691bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int marginStart = style()->marginStart().calcMinValue(availableLogicalWidth);
1692bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int marginEnd = style()->marginEnd().calcMinValue(availableLogicalWidth);
1693bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (availableLogicalWidth)
1694bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            logicalWidthResult = availableLogicalWidth - marginStart - marginEnd;
16958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1696bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (sizesToIntrinsicLogicalWidth(widthType)) {
1697bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            logicalWidthResult = max(logicalWidthResult, minPreferredLogicalWidth());
1698bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            logicalWidthResult = min(logicalWidthResult, maxPreferredLogicalWidth());
16998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1700bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    } else // FIXME: If the containing block flow is perpendicular to our direction we need to use the available logical height instead.
1701bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        logicalWidthResult = computeBorderBoxLogicalWidth(logicalWidth.calcValue(availableLogicalWidth));
17028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1703bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return logicalWidthResult;
17048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1706bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenbool RenderBox::sizesToIntrinsicLogicalWidth(LogicalWidthType widthType) const
17078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Marquees in WinIE are like a mixture of blocks and inline-blocks.  They size as though they're blocks,
17098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // but they allow text to sit on the same line as the marquee.
1710635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (isFloating() || (isInlineBlockOrInlineTable() && !isHTMLMarquee()))
17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
17128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This code may look a bit strange.  Basically width:intrinsic should clamp the size when testing both
17148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // min-width and width.  max-width is only clamped if it is also intrinsic.
1715bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    Length logicalWidth = (widthType == MaxLogicalWidth) ? style()->logicalMaxWidth() : style()->logicalWidth();
1716bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (logicalWidth.type() == Intrinsic)
17178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
17188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Children of a horizontal marquee do not fill the container by default.
17208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Need to deal with MAUTO value properly.  It could be vertical.
1721bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: Think about block-flow here.  Need to find out how marquee direction relates to
1722bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // block-flow (as well as how marquee overflow should relate to block flow).
1723bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // https://bugs.webkit.org/show_bug.cgi?id=46472
17248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (parent()->style()->overflowX() == OMARQUEE) {
17258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        EMarqueeDirection dir = parent()->style()->marqueeDirection();
17268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (dir == MAUTO || dir == MFORWARD || dir == MBACKWARD || dir == MLEFT || dir == MRIGHT)
17278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
17288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Flexible horizontal boxes lay out children at their intrinsic widths.  Also vertical boxes
17318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // that don't stretch their kids lay out their children at their intrinsic widths.
1732bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: Think about block-flow here.
1733bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // https://bugs.webkit.org/show_bug.cgi?id=46473
17348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (parent()->isFlexibleBox()
17358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            && (parent()->style()->boxOrient() == HORIZONTAL || parent()->style()->boxAlign() != BSTRETCH))
17368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
17378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1738f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Button, input, select, textarea, legend and datagrid treat
1739f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // width value of 'auto' as 'intrinsic' unless it's in a
1740f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // stretching vertical flexbox.
1741bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: Think about block-flow here.
1742bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // https://bugs.webkit.org/show_bug.cgi?id=46473
1743bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (logicalWidth.type() == Auto && !(parent()->isFlexibleBox() && parent()->style()->boxOrient() == VERTICAL && parent()->style()->boxAlign() == BSTRETCH) && node() && (node()->hasTagName(inputTag) || node()->hasTagName(selectTag) || node()->hasTagName(buttonTag) || node()->hasTagName(textareaTag) || node()->hasTagName(legendTag) || node()->hasTagName(datagridTag)))
1744f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return true;
1745f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
17468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
17478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1749bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, int containerWidth, int childWidth)
17508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1751bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    const RenderStyle* containingBlockStyle = containingBlock->style();
1752bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    Length marginStartLength = style()->marginStartUsing(containingBlockStyle);
1753bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    Length marginEndLength = style()->marginEndUsing(containingBlockStyle);
1754bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1755bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Case One: The object is being centered in the containing block's available logical width.
1756bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if ((marginStartLength.isAuto() && marginEndLength.isAuto() && childWidth < containerWidth)
1757bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        || (!marginStartLength.isAuto() && !marginEndLength.isAuto() && containingBlock->style()->textAlign() == WEBKIT_CENTER)) {
1758a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        containingBlock->setMarginStartForChild(this, max(0, (containerWidth - childWidth) / 2));
1759a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        containingBlock->setMarginEndForChild(this, containerWidth - childWidth - containingBlock->marginStartForChild(this));
17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1761bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
1762bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1763bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Case Two: The object is being pushed to the start of the containing block's available logical width.
1764bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (marginEndLength.isAuto() && childWidth < containerWidth) {
1765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        containingBlock->setMarginStartForChild(this, marginStartLength.calcValue(containerWidth));
1766a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        containingBlock->setMarginEndForChild(this, containerWidth - childWidth - containingBlock->marginStartForChild(this));
1767bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return;
1768bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
1769bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1770bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Case Three: The object is being pushed to the end of the containing block's available logical width.
1771a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool pushToEndFromTextAlign = !marginEndLength.isAuto() && ((!containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_LEFT)
1772a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        || (containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_RIGHT));
1773bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if ((marginStartLength.isAuto() && childWidth < containerWidth) || pushToEndFromTextAlign) {
1774a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        containingBlock->setMarginEndForChild(this, marginEndLength.calcValue(containerWidth));
1775a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        containingBlock->setMarginStartForChild(this, containerWidth - childWidth - containingBlock->marginEndForChild(this));
1776bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return;
1777bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
1778bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1779bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Case Four: Either no auto margins, or our width is >= the container width (css2.1, 10.3.3).  In that case
1780bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // auto margins will just turn into 0.
1781a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    containingBlock->setMarginStartForChild(this, marginStartLength.calcMinValue(containerWidth));
1782a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    containingBlock->setMarginEndForChild(this, marginEndLength.calcMinValue(containerWidth));
17838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1785bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computeLogicalHeight()
17868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Cell height is managed by the table and inline non-replaced elements do not support a height property.
17888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isTableCell() || (isInline() && !isReplaced()))
17898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
17908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Length h;
1792bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (isPositioned()) {
1793bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: This calculation is not patched for block-flow yet.
1794bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46500
1795bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        computePositionedLogicalHeight();
1796bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    } else {
1797bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        RenderBlock* cb = containingBlock();
17982bde8e466a4451c7319e3a072d118917957d6554Steve Block        bool hasPerpendicularContainingBlock = cb->isHorizontalWritingMode() != isHorizontalWritingMode();
1799bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1800bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!hasPerpendicularContainingBlock)
1801bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeBlockDirectionMargins(cb);
18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For tables, calculate margins only.
1804bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (isTable()) {
1805bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            if (hasPerpendicularContainingBlock)
1806bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), logicalHeight());
18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
1808bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
18098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1810bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: Account for block-flow in flexible boxes.
1811bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46418
18128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool inHorizontalBox = parent()->isFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL;
18138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool stretching = parent()->style()->boxAlign() == BSTRETCH;
1814bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        bool treatAsReplaced = shouldComputeSizeAsReplaced() && (!inHorizontalBox || !stretching);
18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool checkMinMaxHeight = false;
18168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The parent box is flexing us, so it has increased or decreased our height.  We have to
18188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // grab our cached flexible height.
1819bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: Account for block-flow in flexible boxes.
1820bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46418
18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasOverrideSize() && parent()->isFlexibleBox() && parent()->style()->boxOrient() == VERTICAL
18228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                && parent()->isFlexingChildren())
1823bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            h = Length(overrideSize() - borderAndPaddingLogicalHeight(), Fixed);
18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (treatAsReplaced)
1825a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            h = Length(computeReplacedLogicalHeight(), Fixed);
18268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
1827bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            h = style()->logicalHeight();
18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            checkMinMaxHeight = true;
18298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
18308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Block children of horizontal flexible boxes fill the height of the box.
1832bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: Account for block-flow in flexible boxes.
1833bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46418
18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (h.isAuto() && parent()->isFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL
18358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                && parent()->isStretchingChildren()) {
1836bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            h = Length(parentBox()->contentLogicalHeight() - marginBefore() - marginAfter() - borderAndPaddingLogicalHeight(), Fixed);
18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            checkMinMaxHeight = false;
18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1840635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        int heightResult;
18418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (checkMinMaxHeight) {
18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_LAYOUT
18438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // in SSR mode, ignore CSS height as layout is so different
18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (document()->settings()->layoutAlgorithm() == Settings::kLayoutSSR)
1845635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                heightResult = -1;
18468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1848bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            heightResult = computeLogicalHeightUsing(style()->logicalHeight());
1849635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (heightResult == -1)
1850bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                heightResult = logicalHeight();
1851bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int minH = computeLogicalHeightUsing(style()->logicalMinHeight()); // Leave as -1 if unset.
1852bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int maxH = style()->logicalMaxHeight().isUndefined() ? heightResult : computeLogicalHeightUsing(style()->logicalMaxHeight());
18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (maxH == -1)
1854635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                maxH = heightResult;
1855635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            heightResult = min(maxH, heightResult);
1856635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            heightResult = max(minH, heightResult);
18575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else {
18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The only times we don't check min/max height are when a fixed length has
18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // been given as an override.  Just use that.  The value has already been adjusted
18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // for box-sizing.
1861bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            heightResult = h.value() + borderAndPaddingLogicalHeight();
1862635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
18638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1864bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setLogicalHeight(heightResult);
1865bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1866bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (hasPerpendicularContainingBlock)
1867bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), heightResult);
18685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
18695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
18708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // WinIE quirk: The <html> block always fills the entire canvas in quirks mode.  The <body> always fills the
18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <html> block in quirks mode.  Only apply this quirk if the block is normal flow and no height
18725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // is specified. When we're printing, we also need this quirk if the body or root has a percentage
18735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // height since we don't set a height in RenderView when we're printing. So without this quirk, the
18745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // height has nothing to be a percentage of, and it ends up being 0. That is bad.
187568513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool paginatedContentNeedsBaseHeight = document()->printing() && h.isPercent()
1876bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        && (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->logicalHeight().isPercent()));
1877a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (stretchesToViewport() || paginatedContentNeedsBaseHeight) {
1878bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: Finish accounting for block flow here.
1879bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // https://bugs.webkit.org/show_bug.cgi?id=46603
1880bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int margins = collapsedMarginBefore() + collapsedMarginAfter();
1881bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int visHeight;
1882bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (document()->printing())
1883f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            visHeight = static_cast<int>(view()->pageLogicalHeight());
1884bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        else  {
18852bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (isHorizontalWritingMode())
1886bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                visHeight = view()->viewHeight();
1887bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            else
1888bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                visHeight = view()->viewWidth();
1889bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
18908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isRoot())
1891bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(max(logicalHeight(), visHeight - margins));
18928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
1893bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int marginsBordersPadding = margins + parentBox()->marginBefore() + parentBox()->marginAfter() + parentBox()->borderAndPaddingLogicalHeight();
1894bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            setLogicalHeight(max(logicalHeight(), visHeight - marginsBordersPadding));
18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1899bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::computeLogicalHeightUsing(const Length& h)
19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1901bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int logicalHeight = -1;
19028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!h.isAuto()) {
19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (h.isFixed())
1904bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            logicalHeight = h.value();
19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (h.isPercent())
1906bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            logicalHeight = computePercentageLogicalHeight(h);
1907bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (logicalHeight != -1) {
1908bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            logicalHeight = computeBorderBoxLogicalHeight(logicalHeight);
1909bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            return logicalHeight;
19108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1912bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return logicalHeight;
19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1915bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::computePercentageLogicalHeight(const Length& height)
19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int result = -1;
19182bde8e466a4451c7319e3a072d118917957d6554Steve Block
19192bde8e466a4451c7319e3a072d118917957d6554Steve Block    // In quirks mode, blocks with auto height are skipped, and we keep looking for an enclosing
19202bde8e466a4451c7319e3a072d118917957d6554Steve Block    // block that may have a specified height and then use it. In strict mode, this violates the
19212bde8e466a4451c7319e3a072d118917957d6554Steve Block    // specification, which states that percentage heights just revert to auto if the containing
19222bde8e466a4451c7319e3a072d118917957d6554Steve Block    // block has an auto height. We still skip anonymous containing blocks in both modes, though, and look
19232bde8e466a4451c7319e3a072d118917957d6554Steve Block    // only at explicit containers.
1924231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool skippedAutoHeightContainingBlock = false;
19258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock* cb = containingBlock();
19262bde8e466a4451c7319e3a072d118917957d6554Steve Block    while (!cb->isRenderView() && !cb->isBody() && !cb->isTableCell() && !cb->isPositioned() && cb->style()->logicalHeight().isAuto()) {
19272bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!document()->inQuirksMode() && !cb->isAnonymousBlock())
19282bde8e466a4451c7319e3a072d118917957d6554Steve Block            break;
19292bde8e466a4451c7319e3a072d118917957d6554Steve Block        skippedAutoHeightContainingBlock = true;
19302bde8e466a4451c7319e3a072d118917957d6554Steve Block        cb = cb->containingBlock();
19312bde8e466a4451c7319e3a072d118917957d6554Steve Block        cb->addPercentHeightDescendant(this);
19328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // A positioned element that specified both top/bottom or that specifies height should be treated as though it has a height
19358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // explicitly specified that can be used for any percentage computations.
1936bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: We can't just check top/bottom here.
1937bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // https://bugs.webkit.org/show_bug.cgi?id=46500
1938bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool isPositionedWithSpecifiedHeight = cb->isPositioned() && (!cb->style()->logicalHeight().isAuto() || (!cb->style()->top().isAuto() && !cb->style()->bottom().isAuto()));
19398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1940231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool includeBorderPadding = isTable();
1941231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Table cells violate what the CSS spec says to do with heights.  Basically we
19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // don't care if the cell specified a height or not.  We just always make ourselves
19448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // be a percentage of the cell's current content height.
19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (cb->isTableCell()) {
1946231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!skippedAutoHeightContainingBlock) {
1947231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            result = cb->overrideSize();
1948231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (result == -1) {
1949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // Normally we would let the cell size intrinsically, but scrolling overflow has to be
1950231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // treated differently, since WinIE lets scrolled overflow regions shrink as needed.
1951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // While we can't get all cases right, we can at least detect when the cell has a specified
1952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // height or when the table has a specified height.  In these cases we want to initially have
1953231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // no size and allow the flexing of the table or the cell to its specified height to cause us
1954231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // to grow to fill the space.  This could end up being wrong in some cases, but it is
1955231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // preferable to the alternative (sizing intrinsically and making the row end up too big).
1956231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                RenderTableCell* cell = toRenderTableCell(cb);
1957bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                if (scrollsOverflowY() && (!cell->style()->logicalHeight().isAuto() || !cell->table()->style()->logicalHeight().isAuto()))
1958231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    return 0;
1959231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                return -1;
1960231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
1961231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            includeBorderPadding = true;
19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Otherwise we only use our percentage height if our containing block had a specified
19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height.
1966bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    else if (cb->style()->logicalHeight().isFixed())
1967bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        result = cb->computeContentBoxLogicalHeight(cb->style()->logicalHeight().value());
1968bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    else if (cb->style()->logicalHeight().isPercent() && !isPositionedWithSpecifiedHeight) {
19698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We need to recur and compute the percentage height for our containing block.
1970bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        result = cb->computePercentageLogicalHeight(cb->style()->logicalHeight());
19718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result != -1)
1972bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            result = cb->computeContentBoxLogicalHeight(result);
19735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    } else if (cb->isRenderView() || (cb->isBody() && document()->inQuirksMode()) || isPositionedWithSpecifiedHeight) {
1974635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Don't allow this to affect the block' height() member variable, since this
19758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // can get called while the block is still laying out its kids.
1976bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int oldHeight = cb->logicalHeight();
1977bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        cb->computeLogicalHeight();
1978bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        result = cb->contentLogicalHeight();
1979bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        cb->setLogicalHeight(oldHeight);
19808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (cb->isRoot() && isPositioned())
19818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Match the positioned objects behavior, which is that positioned objects will fill their viewport
1982bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // always.  Note we could only hit this case by recurring into computePercentageLogicalHeight on a positioned containing block.
1983bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        result = cb->computeContentBoxLogicalHeight(cb->availableLogicalHeight());
19848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result != -1) {
19868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = height.calcValue(result);
19878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (includeBorderPadding) {
19888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // It is necessary to use the border-box to match WinIE's broken
19898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // box model.  This is essential for sizing inside
19908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // table cells using percentage heights.
1991bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            result -= borderAndPaddingLogicalHeight();
19928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = max(0, result);
19938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
19968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
19978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1998a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBox::computeReplacedLogicalWidth(bool includeMaxWidth) const
19998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2000a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalWidth = computeReplacedLogicalWidthUsing(style()->logicalWidth());
2001a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int minLogicalWidth = computeReplacedLogicalWidthUsing(style()->logicalMinWidth());
2002a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int maxLogicalWidth = !includeMaxWidth || style()->logicalMaxWidth().isUndefined() ? logicalWidth : computeReplacedLogicalWidthUsing(style()->logicalMaxWidth());
20038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2004a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return max(minLogicalWidth, min(logicalWidth, maxLogicalWidth));
20058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2007a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBox::computeReplacedLogicalWidthUsing(Length logicalWidth) const
20088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2009a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (logicalWidth.type()) {
20108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Fixed:
2011a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return computeContentBoxLogicalWidth(logicalWidth.value());
20128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Percent: {
2013bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // FIXME: containingBlockLogicalWidthForContent() is wrong if the replaced element's block-flow is perpendicular to the
2014bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // containing block's block-flow.
2015bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // https://bugs.webkit.org/show_bug.cgi?id=46496
201681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            const int cw = isPositioned() ? containingBlockLogicalWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockLogicalWidthForContent();
20178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (cw > 0)
2018a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                return computeContentBoxLogicalWidth(logicalWidth.calcMinValue(cw));
20198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
20208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // fall through
20218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
2022a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return intrinsicLogicalWidth();
20238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     }
20240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
20258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2026a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBox::computeReplacedLogicalHeight() const
20278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2028a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int logicalHeight = computeReplacedLogicalHeightUsing(style()->logicalHeight());
2029a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int minLogicalHeight = computeReplacedLogicalHeightUsing(style()->logicalMinHeight());
2030a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int maxLogicalHeight = style()->logicalMaxHeight().isUndefined() ? logicalHeight : computeReplacedLogicalHeightUsing(style()->logicalMaxHeight());
20318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2032a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return max(minLogicalHeight, min(logicalHeight, maxLogicalHeight));
20338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2035a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) const
20368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2037a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    switch (logicalHeight.type()) {
20388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Fixed:
2039a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return computeContentBoxLogicalHeight(logicalHeight.value());
20408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Percent:
20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
20428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* cb = isPositioned() ? container() : containingBlock();
20438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (cb->isAnonymous()) {
20448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cb = cb->containingBlock();
20458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                toRenderBlock(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));
20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
20478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2048a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // FIXME: This calculation is not patched for block-flow yet.
2049a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // https://bugs.webkit.org/show_bug.cgi?id=46500
20508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (cb->isPositioned() && cb->style()->height().isAuto() && !(cb->style()->top().isAuto() || cb->style()->bottom().isAuto())) {
20518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(cb->isRenderBlock());
20528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                RenderBlock* block = toRenderBlock(cb);
20538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int oldHeight = block->height();
2054bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                block->computeLogicalHeight();
2055bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                int newHeight = block->computeContentBoxLogicalHeight(block->contentHeight());
20568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                block->setHeight(oldHeight);
2057a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                return computeContentBoxLogicalHeight(logicalHeight.calcValue(newHeight));
20588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
20598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2060a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // FIXME: availableLogicalHeight() is wrong if the replaced element's block-flow is perpendicular to the
2061a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // containing block's block-flow.
2062a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // https://bugs.webkit.org/show_bug.cgi?id=46496
206381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int availableHeight = isPositioned() ? containingBlockLogicalHeightForPositioned(toRenderBoxModelObject(cb)) : toRenderBox(cb)->availableLogicalHeight();
20648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // It is necessary to use the border-box to match WinIE's broken
20668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // box model.  This is essential for sizing inside
20678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // table cells using percentage heights.
2068a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // FIXME: This needs to be made block-flow-aware.  If the cell and image are perpendicular block-flows, this isn't right.
2069a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // https://bugs.webkit.org/show_bug.cgi?id=46997
2070a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (cb->isTableCell() && (cb->style()->logicalHeight().isAuto() || cb->style()->logicalHeight().isPercent())) {
20718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Don't let table cells squeeze percent-height replaced elements
20728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // <http://bugs.webkit.org/show_bug.cgi?id=15359>
2073a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                availableHeight = max(availableHeight, intrinsicLogicalHeight());
2074a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                return logicalHeight.calcValue(availableHeight - borderAndPaddingLogicalHeight());
20758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
20768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2077a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return computeContentBoxLogicalHeight(logicalHeight.calcValue(availableHeight));
20788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
20798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
2080a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return intrinsicLogicalHeight();
20818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
20828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2084bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::availableLogicalHeight() const
20858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2086bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return availableLogicalHeightUsing(style()->logicalHeight());
20878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2089bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenint RenderBox::availableLogicalHeightUsing(const Length& h) const
20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (h.isFixed())
2092bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return computeContentBoxLogicalHeight(h.value());
20938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRenderView())
20952bde8e466a4451c7319e3a072d118917957d6554Steve Block        return isHorizontalWritingMode() ? toRenderView(this)->frameView()->visibleHeight() : toRenderView(this)->frameView()->visibleWidth();
20968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to stop here, since we don't want to increase the height of the table
20988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // artificially.  We're going to rely on this cell getting expanded to some new
20998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // height, and then when we lay out again we'll use the calculation below.
21008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isTableCell() && (h.isAuto() || h.isPercent()))
2101bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return overrideSize() - borderAndPaddingLogicalWidth();
21028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (h.isPercent())
2104bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen       return computeContentBoxLogicalHeight(h.calcValue(containingBlock()->availableLogicalHeight()));
21058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2106bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // FIXME: We can't just check top/bottom here.
2107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // https://bugs.webkit.org/show_bug.cgi?id=46500
21088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isRenderBlock() && isPositioned() && style()->height().isAuto() && !(style()->top().isAuto() || style()->bottom().isAuto())) {
21098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* block = const_cast<RenderBlock*>(toRenderBlock(this));
2110bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int oldHeight = block->logicalHeight();
2111bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        block->computeLogicalHeight();
2112bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        int newHeight = block->computeContentBoxLogicalHeight(block->contentLogicalHeight());
2113bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        block->setLogicalHeight(oldHeight);
2114bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return computeContentBoxLogicalHeight(newHeight);
21158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2117bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return containingBlock()->availableLogicalHeight();
211868513a70bcd92384395513322f1b801e7bf9c729Steve Block}
211968513a70bcd92384395513322f1b801e7bf9c729Steve Block
2120bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computeBlockDirectionMargins(RenderBlock* containingBlock)
21218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isTableCell()) {
2123bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // FIXME: Not right if we allow cells to have different directionality than the table.  If we do allow this, though,
2124bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // we may just do it with an extra anonymous block inside the cell.
2125bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginBefore(0);
2126bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        setMarginAfter(0);
21278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2130bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Margins are calculated with respect to the logical width of
21318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the containing block (8.3)
2132bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    int cw = containingBlockLogicalWidthForContent();
21338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2134bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    RenderStyle* containingBlockStyle = containingBlock->style();
2135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    containingBlock->setMarginBeforeForChild(this, style()->marginBeforeUsing(containingBlockStyle).calcMinValue(cw));
2136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    containingBlock->setMarginAfterForChild(this, style()->marginAfterUsing(containingBlockStyle).calcMinValue(cw));
21378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
213981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochint RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode) const
21408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21418b7cce7f189cb149ee3f31faac189d3a6451a2acTeng-Hui Zhu#if PLATFORM(ANDROID)
21420026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    // Fixed element's position should be decided by the visible screen size.
21430026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    // That is in the doc coordindate.
21440026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    if (style()->position() == FixedPosition && containingBlock->isRenderView()) {
21450026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu        const RenderView* view = toRenderView(containingBlock);
21463a7568b5aa8ee4ef6ba961eae690b498f5ba8e9eTeng-Hui Zhu        return PlatformBridge::screenWidthInDocCoord(view->frameView());
21470026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    }
21488b7cce7f189cb149ee3f31faac189d3a6451a2acTeng-Hui Zhu#endif
21499921f05212aa840e1ce32e9f04fa60ca4b3bcbb7Ben Murdoch
21502bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (checkForPerpendicularWritingMode && containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode())
215181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return containingBlockLogicalHeightForPositioned(containingBlock, false);
215281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
215381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (containingBlock->isBox())
215481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return toRenderBox(containingBlock)->clientLogicalWidth();
215581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
21568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned());
21578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const RenderInline* flow = toRenderInline(containingBlock);
21598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    InlineFlowBox* first = flow->firstLineBox();
21608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    InlineFlowBox* last = flow->lastLineBox();
21618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If the containing block is empty, return a width of 0.
21638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!first || !last)
21648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 0;
21658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int fromLeft;
21678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int fromRight;
2168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (containingBlock->style()->isLeftToRightDirection()) {
2169bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        fromLeft = first->logicalLeft() + first->borderLogicalLeft();
2170bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        fromRight = last->logicalLeft() + last->logicalWidth() - last->borderLogicalRight();
21718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else {
2172bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        fromRight = first->logicalLeft() + first->logicalWidth() - first->borderLogicalRight();
2173bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        fromLeft = last->logicalLeft() + last->borderLogicalLeft();
21748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return max(0, (fromRight - fromLeft));
21778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21799921f05212aa840e1ce32e9f04fa60ca4b3bcbb7Ben Murdochint RenderBox::containingBlockLogicalHeightForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode) const
21808b7cce7f189cb149ee3f31faac189d3a6451a2acTeng-Hui Zhu{
21818b7cce7f189cb149ee3f31faac189d3a6451a2acTeng-Hui Zhu#if PLATFORM(ANDROID)
21820026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    // Fixed element's position should be decided by the visible screen size.
21830026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    // That is in the doc coordindate.
21840026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    if (style()->position() == FixedPosition && containingBlock->isRenderView()) {
21850026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu        const RenderView* view = toRenderView(containingBlock);
21863a7568b5aa8ee4ef6ba961eae690b498f5ba8e9eTeng-Hui Zhu        return PlatformBridge::screenHeightInDocCoord(view->frameView());
21870026842c0dc9cc472966e6ef44b707683ca5317bTeng-Hui Zhu    }
21888b7cce7f189cb149ee3f31faac189d3a6451a2acTeng-Hui Zhu#endif
21899921f05212aa840e1ce32e9f04fa60ca4b3bcbb7Ben Murdoch
21902bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (checkForPerpendicularWritingMode && containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode())
219181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return containingBlockLogicalWidthForPositioned(containingBlock, false);
219281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
21938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (containingBlock->isBox())
219481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return toRenderBox(containingBlock)->clientLogicalHeight();
219581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
219681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned());
219781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
219881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const RenderInline* flow = toRenderInline(containingBlock);
219981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    InlineFlowBox* first = flow->firstLineBox();
220081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    InlineFlowBox* last = flow->lastLineBox();
220181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
220281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // If the containing block is empty, return a height of 0.
220381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!first || !last)
220481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return 0;
220581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
220681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int heightResult;
220781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    IntRect boundingBox = flow->linesBoundingBox();
22082bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (containingBlock->isHorizontalWritingMode())
220981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        heightResult = boundingBox.height();
221081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
221181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        heightResult = boundingBox.width();
221281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    heightResult -= (containingBlock->borderBefore() + containingBlock->borderAfter());
221381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return heightResult;
221481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
221581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
221681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRight, const RenderBox* child, const RenderBoxModelObject* containerBlock, int containerLogicalWidth,
221781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                        TextDirection containerDirection)
221881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
221981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!logicalLeft.isAuto() || !logicalRight.isAuto())
222081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
222181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
222281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: The static distance computation has not been patched for mixed writing modes yet.
222381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (containerDirection == LTR) {
222481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int staticPosition = child->layer()->staticInlinePosition() - containerBlock->borderLogicalLeft();
22252bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (RenderObject* curr = child->parent(); curr && curr != containerBlock; curr = curr->container()) {
222681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (curr->isBox())
222781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                staticPosition += toRenderBox(curr)->logicalLeft();
222881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
222981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeft.setValue(Fixed, staticPosition);
223081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else {
223181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        RenderBox* enclosingBox = child->parent()->enclosingBox();
223281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int staticPosition = child->layer()->staticInlinePosition() + containerLogicalWidth + containerBlock->borderLogicalRight();
223381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        staticPosition -= enclosingBox->logicalWidth();
22342bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (RenderObject* curr = enclosingBox; curr && curr != containerBlock; curr = curr->container()) {
223581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (curr->isBox())
223681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                staticPosition -= toRenderBox(curr)->logicalLeft();
223781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
223881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalRight.setValue(Fixed, staticPosition);
22398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
22408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2242bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computePositionedLogicalWidth()
22438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isReplaced()) {
2245bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        computePositionedLogicalWidthReplaced();
22468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
22478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // QUESTIONS
22508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME 1: Which RenderObject's 'direction' property should used: the
22518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // containing block (cb) as the spec seems to imply, the parent (parent()) as
22528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // was previously done in calculating the static distances, or ourself, which
22538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // was also previously done for deciding what to override when you had
22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // over-constrained margins?  Also note that the container block is used
2255bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // in similar situations in other parts of the RenderBox class (see computeLogicalWidth()
2256bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // and computeMarginsInContainingBlockInlineDirection()). For now we are using the parent for quirks
22578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // mode and the containing block for strict mode.
22588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME 2: Should we still deal with these the cases of 'left' or 'right' having
22608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the type 'static' in determining whether to calculate the static distance?
22618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOTE: 'static' is not a legal value for 'left' or 'right' as of CSS 2.1.
22628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME 3: Can perhaps optimize out cases when max-width/min-width are greater
2264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // than or less than the computed width().  Be careful of box-sizing and
22658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // percentage issues.
22668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The following is based off of the W3C Working Draft from April 11, 2006 of
22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // CSS 2.1: Section 10.3.7 "Absolutely positioned, non-replaced elements"
22698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width>
2270bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // (block-style-comments in this function and in computePositionedLogicalWidthUsing()
22718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // correspond to text from the spec)
22728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't use containingBlock(), since we may be positioned by an enclosing
22758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // relative positioned inline.
22768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
2277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
227881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int containerLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock);
22798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // To match WinIE, in quirks mode use the parent's 'direction' property
22818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // instead of the the container block's.
22825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    TextDirection containerDirection = (document()->inQuirksMode()) ? parent()->style()->direction() : containerBlock->style()->direction();
22838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22842bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
228581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int bordersPlusPadding = borderAndPaddingLogicalWidth();
228681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const Length marginLogicalLeft = isHorizontal ? style()->marginLeft() : style()->marginTop();
228781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const Length marginLogicalRight = isHorizontal ? style()->marginRight() : style()->marginBottom();
228881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginLogicalLeftAlias = isHorizontal ? m_marginLeft : m_marginTop;
228981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginLogicalRightAlias = isHorizontal ? m_marginRight : m_marginBottom;
229081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
229181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalLeft = style()->logicalLeft();
229281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalRight = style()->logicalRight();
22938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*---------------------------------------------------------------------------*\
22958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * For the purposes of this section and the next, the term "static position"
22968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * (of an element) refers, roughly, to the position an element would have had
22978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * in the normal flow. More precisely:
22988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *
22998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * * The static position for 'left' is the distance from the left edge of the
23008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *   containing block to the left margin edge of a hypothetical box that would
23018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *   have been the first box of the element if its 'position' property had
23028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *   been 'static' and 'float' had been 'none'. The value is negative if the
23038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *   hypothetical box is to the left of the containing block.
23048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * * The static position for 'right' is the distance from the right edge of the
23058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *   containing block to the right margin edge of the same hypothetical box as
23068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *   above. The value is positive if the hypothetical box is to the left of the
23078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *   containing block's edge.
23088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *
23098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * But rather than actually calculating the dimensions of that hypothetical box,
23108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * user agents are free to make a guess at its probable position.
23118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *
23128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * For the purposes of calculating the static position, the containing block of
23138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * fixed positioned elements is the initial containing block instead of the
23148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * viewport, and all scrollable boxes should be assumed to be scrolled to their
23158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * origin.
23168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*---------------------------------------------------------------------------*/
23178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // see FIXME 2
23198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate the static distance if needed.
232081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock, containerLogicalWidth, containerDirection);
232181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
23228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate constraint equation values for 'width' case.
232381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalWidthResult;
232481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalLeftResult;
232581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computePositionedLogicalWidthUsing(style()->logicalWidth(), containerBlock, containerDirection,
232681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                       containerLogicalWidth, bordersPlusPadding,
232781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                       logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
232881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                       logicalWidthResult, marginLogicalLeftAlias, marginLogicalRightAlias, logicalLeftResult);
232981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalWidth(logicalWidthResult);
233081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalLeft(logicalLeftResult);
23318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate constraint equation values for 'max-width' case.
233381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!style()->logicalMaxWidth().isUndefined()) {
233481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxLogicalWidth;
233581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxMarginLogicalLeft;
233681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxMarginLogicalRight;
233781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxLogicalLeftPos;
233881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
233981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        computePositionedLogicalWidthUsing(style()->logicalMaxWidth(), containerBlock, containerDirection,
234081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           containerLogicalWidth, bordersPlusPadding,
234181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
234281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           maxLogicalWidth, maxMarginLogicalLeft, maxMarginLogicalRight, maxLogicalLeftPos);
234381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
234481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (logicalWidth() > maxLogicalWidth) {
234581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setLogicalWidth(maxLogicalWidth);
234681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalLeftAlias = maxMarginLogicalLeft;
234781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalRightAlias = maxMarginLogicalRight;
234881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setLogicalLeft(maxLogicalLeftPos);
23498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
23508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate constraint equation values for 'min-width' case.
235381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!style()->logicalMinWidth().isZero()) {
235481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minLogicalWidth;
235581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minMarginLogicalLeft;
235681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minMarginLogicalRight;
235781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minLogicalLeftPos;
235881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
235981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        computePositionedLogicalWidthUsing(style()->logicalMinWidth(), containerBlock, containerDirection,
236081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           containerLogicalWidth, bordersPlusPadding,
236181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
236281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           minLogicalWidth, minMarginLogicalLeft, minMarginLogicalRight, minLogicalLeftPos);
236381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
236481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (logicalWidth() < minLogicalWidth) {
236581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setLogicalWidth(minLogicalWidth);
236681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalLeftAlias = minMarginLogicalLeft;
236781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalRightAlias = minMarginLogicalRight;
236881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setLogicalLeft(minLogicalLeftPos);
23698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
237281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (stretchesToMinIntrinsicLogicalWidth() && logicalWidth() < minPreferredLogicalWidth() - bordersPlusPadding) {
2373bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        computePositionedLogicalWidthUsing(Length(minPreferredLogicalWidth() - bordersPlusPadding, Fixed), containerBlock, containerDirection,
237481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           containerLogicalWidth, bordersPlusPadding,
237581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           logicalLeft, logicalRight, marginLogicalLeft, marginLogicalRight,
237681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                           logicalWidthResult, marginLogicalLeftAlias, marginLogicalRightAlias, logicalLeftResult);
237781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        setLogicalWidth(logicalWidthResult);
237881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        setLogicalLeft(logicalLeftResult);
2379635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
23808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Put logicalWidth() into correct form.
238281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalWidth(logicalWidth() + bordersPlusPadding);
23838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void computeLogicalLeftPositionedOffset(int& logicalLeftPos, const RenderBox* child, int logicalWidthValue, const RenderBoxModelObject* containerBlock, int containerLogicalWidth)
238681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
238781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Deal with differing writing modes here.  Our offset needs to be in the containing block's coordinate space. If the containing block is flipped
238881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // along this axis, then we need to flip the coordinate.  This can only happen if the containing block is both a flipped mode and perpendicular to us.
23892bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (containerBlock->isHorizontalWritingMode() != child->isHorizontalWritingMode() && containerBlock->style()->isFlippedBlocksWritingMode()) {
239081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeftPos;
23912bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->borderRight() : containerBlock->borderBottom());
239281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else
23932bde8e466a4451c7319e3a072d118917957d6554Steve Block        logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->borderLeft() : containerBlock->borderTop());
239481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
239581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
239681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
239781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                                   int containerLogicalWidth, int bordersPlusPadding,
239881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                                   Length logicalLeft, Length logicalRight, Length marginLogicalLeft, Length marginLogicalRight,
239981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                                   int& logicalWidthValue, int& marginLogicalLeftValue, int& marginLogicalRightValue, int& logicalLeftPos)
24008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 'left' and 'right' cannot both be 'auto' because one would of been
2402d0825bca7fe65beaee391d30da42e937db621564Steve Block    // converted to the static position already
240381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto()));
24048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
240581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalLeftValue = 0;
24068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
240781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool logicalWidthIsAuto = logicalWidth.isIntrinsicOrAuto();
240881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool logicalLeftIsAuto = logicalLeft.isAuto();
240981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool logicalRightIsAuto = logicalRight.isAuto();
24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
241181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
24128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        /*-----------------------------------------------------------------------*\
24138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * If none of the three is 'auto': If both 'margin-left' and 'margin-
24148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * right' are 'auto', solve the equation under the extra constraint that
24158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * the two margins get equal values, unless this would make them negative,
24168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * in which case when direction of the containing block is 'ltr' ('rtl'),
24178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * set 'margin-left' ('margin-right') to zero and solve for 'margin-right'
24188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto',
24198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * solve the equation for that value. If the values are over-constrained,
24208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * ignore the value for 'left' (in case the 'direction' property of the
24218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * containing block is 'rtl') or 'right' (in case 'direction' is 'ltr')
24228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * and solve for that value.
24238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        \*-----------------------------------------------------------------------*/
24248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NOTE:  It is not necessary to solve for 'right' in the over constrained
24258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // case because the value is not used for any further calculations.
24268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
242781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
242881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
24298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
243081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        const int availableSpace = containerLogicalWidth - (logicalLeftValue + logicalWidthValue + logicalRight.calcValue(containerLogicalWidth) + bordersPlusPadding);
24318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Margins are now the only unknown
243381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
24348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Both margins auto, solve for equality
24358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (availableSpace >= 0) {
243681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                marginLogicalLeftValue = availableSpace / 2; // split the difference
243781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                marginLogicalRightValue = availableSpace - marginLogicalLeftValue; // account for odd valued differences
24388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
24398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // see FIXME 1
24408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (containerDirection == LTR) {
244181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    marginLogicalLeftValue = 0;
244281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    marginLogicalRightValue = availableSpace; // will be negative
24438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
244481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    marginLogicalLeftValue = availableSpace; // will be negative
244581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    marginLogicalRightValue = 0;
24468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
24478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
244881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (marginLogicalLeft.isAuto()) {
24498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Solve for left margin
245081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalRightValue = marginLogicalRight.calcValue(containerLogicalWidth);
245181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalLeftValue = availableSpace - marginLogicalRightValue;
245281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (marginLogicalRight.isAuto()) {
24538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Solve for right margin
245481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalLeftValue = marginLogicalLeft.calcValue(containerLogicalWidth);
245581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalRightValue = availableSpace - marginLogicalLeftValue;
24568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
24578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Over-constrained, solve for left if direction is RTL
245881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalLeftValue = marginLogicalLeft.calcValue(containerLogicalWidth);
245981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalRightValue = marginLogicalRight.calcValue(containerLogicalWidth);
24608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // see FIXME 1 -- used to be "this->style()->direction()"
24628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (containerDirection == RTL)
246381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                logicalLeftValue = (availableSpace + logicalLeftValue) - marginLogicalLeftValue - marginLogicalRightValue;
24648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
24668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        /*--------------------------------------------------------------------*\
24678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * Otherwise, set 'auto' values for 'margin-left' and 'margin-right'
24688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * to 0, and pick the one of the following six rules that applies.
24698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
24708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the
24718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    width is shrink-to-fit. Then solve for 'left'
24728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
24738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *              OMIT RULE 2 AS IT SHOULD NEVER BE HIT
24748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * ------------------------------------------------------------------
24758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if
24768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    the 'direction' property of the containing block is 'ltr' set
24778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    'left' to the static position, otherwise set 'right' to the
24788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    static position. Then solve for 'left' (if 'direction is 'rtl')
24798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    or 'right' (if 'direction' is 'ltr').
24808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * ------------------------------------------------------------------
24818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
24828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the
24838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    width is shrink-to-fit . Then solve for 'right'
24848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve
24858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    for 'left'
24868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve
24878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    for 'width'
24888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve
24898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    for 'right'
24908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
24918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * Calculation of the shrink-to-fit width is similar to calculating the
24928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * width of a table cell using the automatic table layout algorithm.
24938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * Roughly: calculate the preferred width by formatting the content
24948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * without breaking lines other than where explicit line breaks occur,
24958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * and also calculate the preferred minimum width, e.g., by trying all
24968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * possible line breaks. CSS 2.1 does not define the exact algorithm.
24978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * Thirdly, calculate the available width: this is found by solving
24988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * for 'width' after setting 'left' (in case 1) or 'right' (in case 3)
24998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * to 0.
25008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
25018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * Then the shrink-to-fit width is:
25028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * min(max(preferred minimum width, available width), preferred width).
25038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        \*--------------------------------------------------------------------*/
25048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NOTE: For rules 3 and 6 it is not necessary to solve for 'right'
25058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // because the value is not used for any further calculations.
25068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Calculate margins, 'auto' margins are ignored.
250881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalLeftValue = marginLogicalLeft.calcMinValue(containerLogicalWidth);
250981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalRightValue = marginLogicalRight.calcMinValue(containerLogicalWidth);
25108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
251181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        const int availableSpace = containerLogicalWidth - (marginLogicalLeftValue + marginLogicalRightValue + bordersPlusPadding);
25128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Is there a faster way to find the correct case?
25148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Use rule/case that applies.
251581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
25168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 1: (use shrink-to-fit for width, and solve of left)
251781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
25188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // FIXME: would it be better to have shrink-to-fit in one step?
2520bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
2521bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int preferredMinWidth = minPreferredLogicalWidth() - bordersPlusPadding;
252281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int availableWidth = availableSpace - logicalRightValue;
252381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalWidthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
252481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalLeftValue = availableSpace - (logicalWidthValue + logicalRightValue);
252581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (!logicalLeftIsAuto && logicalWidthIsAuto && logicalRightIsAuto) {
25268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 3: (use shrink-to-fit for width, and no need solve of right)
252781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
25288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // FIXME: would it be better to have shrink-to-fit in one step?
2530bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
2531bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            int preferredMinWidth = minPreferredLogicalWidth() - bordersPlusPadding;
253281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            int availableWidth = availableSpace - logicalLeftValue;
253381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalWidthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
253481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
25358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 4: (solve for left)
253681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
253781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalLeftValue = availableSpace - (logicalWidthValue + logicalRight.calcValue(containerLogicalWidth));
253881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (!logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
25398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 5: (solve for width)
254081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
254181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalWidthValue = availableSpace - (logicalLeftValue + logicalRight.calcValue(containerLogicalWidth));
254281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (!logicalLeftIsAuto && !logicalWidthIsAuto && logicalRightIsAuto) {
25438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 6: (no need solve for right)
254481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
254581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
25468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
25478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Use computed values to calculate the horizontal position.
25508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
255181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: This hack is needed to calculate the  logical left position for a 'rtl' relatively
255281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // positioned, inline because right now, it is using the logical left position
25538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // of the first line box when really it should use the last line box.  When
25548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // this is fixed elsewhere, this block should be removed.
2555a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (containerBlock->isRenderInline() && !containerBlock->style()->isLeftToRightDirection()) {
25568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        const RenderInline* flow = toRenderInline(containerBlock);
25578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineFlowBox* firstLine = flow->firstLineBox();
25588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineFlowBox* lastLine = flow->lastLineBox();
25598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLine && lastLine && firstLine != lastLine) {
256081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalLeftPos = logicalLeftValue + marginLogicalLeftValue + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft());
25618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
25628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
25638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
256581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    logicalLeftPos = logicalLeftValue + marginLogicalLeftValue;
256681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeLogicalLeftPositionedOffset(logicalLeftPos, this, logicalWidthValue, containerBlock, containerLogicalWidth);
256781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
256881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
256981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void computeBlockStaticDistance(Length& logicalTop, Length& logicalBottom, const RenderBox* child, const RenderBoxModelObject* containerBlock)
257081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
257181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!logicalTop.isAuto() || !logicalBottom.isAuto())
257281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
257381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
257481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: The static distance computation has not been patched for mixed writing modes.
257581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int staticLogicalTop = child->layer()->staticBlockPosition() - containerBlock->borderBefore();
25762bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (RenderObject* curr = child->parent(); curr && curr != containerBlock; curr = curr->container()) {
257781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (curr->isBox() && !curr->isTableRow())
257881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            staticLogicalTop += toRenderBox(curr)->logicalTop();
257981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
258081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    logicalTop.setValue(Fixed, staticLogicalTop);
25818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2583bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computePositionedLogicalHeight()
25848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isReplaced()) {
2586bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        computePositionedLogicalHeightReplaced();
25878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The following is based off of the W3C Working Draft from April 11, 2006 of
25918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements"
25928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replaced-height>
2593bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // (block-style-comments in this function and in computePositionedLogicalHeightUsing()
25948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // correspond to text from the spec)
25958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
25988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
25998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
260081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int containerLogicalHeight = containingBlockLogicalHeightForPositioned(containerBlock);
26018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26022bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
260381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool isFlipped = style()->isFlippedBlocksWritingMode();
260481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int bordersPlusPadding = borderAndPaddingLogicalHeight();
260581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const Length marginBefore = style()->marginBefore();
260681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const Length marginAfter = style()->marginAfter();
260781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginBeforeAlias = isHorizontal ? (isFlipped ? m_marginBottom : m_marginTop) : (isFlipped ? m_marginRight: m_marginLeft);
260881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginAfterAlias = isHorizontal ? (isFlipped ? m_marginTop : m_marginBottom) : (isFlipped ? m_marginLeft: m_marginRight);
26098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
261081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalTop = style()->logicalTop();
261181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalBottom = style()->logicalBottom();
261281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
26138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*---------------------------------------------------------------------------*\
26148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * For the purposes of this section and the next, the term "static position"
26158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * (of an element) refers, roughly, to the position an element would have had
26168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * in the normal flow. More precisely, the static position for 'top' is the
26178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * distance from the top edge of the containing block to the top margin edge
26188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * of a hypothetical box that would have been the first box of the element if
26198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * its 'position' property had been 'static' and 'float' had been 'none'. The
26208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * value is negative if the hypothetical box is above the containing block.
26218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *
26228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * But rather than actually calculating the dimensions of that hypothetical
26238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * box, user agents are free to make a guess at its probable position.
26248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *
26258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * For the purposes of calculating the static position, the containing block
26268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * of fixed positioned elements is the initial containing block instead of
26278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * the viewport.
26288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*---------------------------------------------------------------------------*/
26298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // see FIXME 2
26318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate the static distance if needed.
263281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeBlockStaticDistance(logicalTop, logicalBottom, this, containerBlock);
26338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
263481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalHeightResult; // Needed to compute overflow.
263581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalTopPos;
26368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate constraint equation values for 'height' case.
263881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computePositionedLogicalHeightUsing(style()->logicalHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
263981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                        logicalTop, logicalBottom, marginBefore, marginAfter,
264081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                        logicalHeightResult, marginBeforeAlias, marginAfterAlias, logicalTopPos);
264181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalTop(logicalTopPos);
26428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Avoid doing any work in the common case (where the values of min-height and max-height are their defaults).
26448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // see FIXME 3
26458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate constraint equation values for 'max-height' case.
264781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!style()->logicalMaxHeight().isUndefined()) {
264881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxLogicalHeight;
264981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxMarginBefore;
265081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxMarginAfter;
265181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int maxLogicalTopPos;
265281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
265381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        computePositionedLogicalHeightUsing(style()->logicalMaxHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
265481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                            logicalTop, logicalBottom, marginBefore, marginAfter,
265581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                            maxLogicalHeight, maxMarginBefore, maxMarginAfter, maxLogicalTopPos);
265681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
265781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (logicalHeightResult > maxLogicalHeight) {
265881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalHeightResult = maxLogicalHeight;
265981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginBeforeAlias = maxMarginBefore;
266081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginAfterAlias = maxMarginAfter;
266181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setLogicalTop(maxLogicalTopPos);
26628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calculate constraint equation values for 'min-height' case.
266681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!style()->logicalMinHeight().isZero()) {
266781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minLogicalHeight;
266881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minMarginBefore;
266981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minMarginAfter;
267081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int minLogicalTopPos;
267181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
267281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        computePositionedLogicalHeightUsing(style()->logicalMinHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
267381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                            logicalTop, logicalBottom, marginBefore, marginAfter,
267481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                            minLogicalHeight, minMarginBefore, minMarginAfter, minLogicalTopPos);
267581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
267681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (logicalHeightResult < minLogicalHeight) {
267781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalHeightResult = minLogicalHeight;
267881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginBeforeAlias = minMarginBefore;
267981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginAfterAlias = minMarginAfter;
268081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setLogicalTop(minLogicalTopPos);
26818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Set final height value.
268581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalHeight(logicalHeightResult + bordersPlusPadding);
26868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void computeLogicalTopPositionedOffset(int& logicalTopPos, const RenderBox* child, int logicalHeightValue, const RenderBoxModelObject* containerBlock, int containerLogicalHeight)
268981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
269081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Deal with differing writing modes here.  Our offset needs to be in the containing block's coordinate space. If the containing block is flipped
269181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // along this axis, then we need to flip the coordinate.  This can only happen if the containing block is both a flipped mode and perpendicular to us.
26922bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ((child->style()->isFlippedBlocksWritingMode() && child->isHorizontalWritingMode() != containerBlock->isHorizontalWritingMode())
26932bde8e466a4451c7319e3a072d118917957d6554Steve Block        || (child->style()->isFlippedBlocksWritingMode() != containerBlock->style()->isFlippedBlocksWritingMode() && child->isHorizontalWritingMode() == containerBlock->isHorizontalWritingMode()))
269481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopPos = containerLogicalHeight - logicalHeightValue - logicalTopPos;
269581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
269681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Our offset is from the logical bottom edge in a flipped environment, e.g., right for vertical-rl and bottom for horizontal-bt.
26972bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (containerBlock->style()->isFlippedBlocksWritingMode() && child->isHorizontalWritingMode() == containerBlock->isHorizontalWritingMode()) {
26982bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (child->isHorizontalWritingMode())
269981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopPos += containerBlock->borderBottom();
270081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else
270181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopPos += containerBlock->borderRight();
270281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else {
27032bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (child->isHorizontalWritingMode())
270481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopPos += containerBlock->borderTop();
270581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else
270681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopPos += containerBlock->borderLeft();
270781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
270881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
270981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
271081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength, const RenderBoxModelObject* containerBlock,
271181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                                    int containerLogicalHeight, int bordersPlusPadding,
271281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                                    Length logicalTop, Length logicalBottom, Length marginBefore, Length marginAfter,
271381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                                                    int& logicalHeightValue, int& marginBeforeValue, int& marginAfterValue, int& logicalTopPos)
27148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
27158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 'top' and 'bottom' cannot both be 'auto' because 'top would of been
2716bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // converted to the static position in computePositionedLogicalHeight()
271781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!(logicalTop.isAuto() && logicalBottom.isAuto()));
27188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
271981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int contentLogicalHeight = logicalHeight() - bordersPlusPadding;
27208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
272181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalTopValue = 0;
27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
272381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool logicalHeightIsAuto = logicalHeightLength.isAuto();
272481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool logicalTopIsAuto = logicalTop.isAuto();
272581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool logicalBottomIsAuto = logicalBottom.isAuto();
27268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Height is never unsolved for tables.
27288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isTable()) {
272981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalHeightLength.setValue(Fixed, contentLogicalHeight);
273081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalHeightIsAuto = false;
27318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
27328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
273381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
27348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        /*-----------------------------------------------------------------------*\
27358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * If none of the three are 'auto': If both 'margin-top' and 'margin-
27368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * bottom' are 'auto', solve the equation under the extra constraint that
27378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * the two margins get equal values. If one of 'margin-top' or 'margin-
27388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * bottom' is 'auto', solve the equation for that value. If the values
27398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * are over-constrained, ignore the value for 'bottom' and solve for that
27408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * value.
27418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        \*-----------------------------------------------------------------------*/
27428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NOTE:  It is not necessary to solve for 'bottom' in the over constrained
27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // case because the value is not used for any further calculations.
27448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
274581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
274681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
27478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
274881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        const int availableSpace = containerLogicalHeight - (logicalTopValue + logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight) + bordersPlusPadding);
27498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Margins are now the only unknown
275181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (marginBefore.isAuto() && marginAfter.isAuto()) {
27528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Both margins auto, solve for equality
27538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // NOTE: This may result in negative values.
275481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginBeforeValue = availableSpace / 2; // split the difference
275581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginAfterValue = availableSpace - marginBeforeValue; // account for odd valued differences
275681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (marginBefore.isAuto()) {
27578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Solve for top margin
275881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginAfterValue = marginAfter.calcValue(containerLogicalHeight);
275981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginBeforeValue = availableSpace - marginAfterValue;
276081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (marginAfter.isAuto()) {
27618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Solve for bottom margin
276281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginBeforeValue = marginBefore.calcValue(containerLogicalHeight);
276381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginAfterValue = availableSpace - marginBeforeValue;
27648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
27658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Over-constrained, (no need solve for bottom)
276681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginBeforeValue = marginBefore.calcValue(containerLogicalHeight);
276781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginAfterValue = marginAfter.calcValue(containerLogicalHeight);
27688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
27698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
27708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        /*--------------------------------------------------------------------*\
27718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * Otherwise, set 'auto' values for 'margin-top' and 'margin-bottom'
27728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * to 0, and pick the one of the following six rules that applies.
27738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
27748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then
27758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    the height is based on the content, and solve for 'top'.
27768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
27778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *              OMIT RULE 2 AS IT SHOULD NEVER BE HIT
27788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * ------------------------------------------------------------------
27798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then
27808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    set 'top' to the static position, and solve for 'bottom'.
27818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * ------------------------------------------------------------------
27828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *
27838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then
27848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    the height is based on the content, and solve for 'bottom'.
27858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', and
27868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    solve for 'top'.
27878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', and
27888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    solve for 'height'.
27898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         * 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', and
27908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         *    solve for 'bottom'.
27918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        \*--------------------------------------------------------------------*/
27928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NOTE: For rules 3 and 6 it is not necessary to solve for 'bottom'
27938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // because the value is not used for any further calculations.
27948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Calculate margins, 'auto' margins are ignored.
279681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginBeforeValue = marginBefore.calcMinValue(containerLogicalHeight);
279781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginAfterValue = marginAfter.calcMinValue(containerLogicalHeight);
27988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
279981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        const int availableSpace = containerLogicalHeight - (marginBeforeValue + marginAfterValue + bordersPlusPadding);
28008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Use rule/case that applies.
280281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
28038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 1: (height is content based, solve of top)
280481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalHeightValue = contentLogicalHeight;
280581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopValue = availableSpace - (logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight));
280681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (!logicalTopIsAuto && logicalHeightIsAuto && logicalBottomIsAuto) {
28078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 3: (height is content based, no need solve of bottom)
280881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
280981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalHeightValue = contentLogicalHeight;
281081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
28118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 4: (solve of top)
281281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
281381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopValue = availableSpace - (logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight));
281481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (!logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
28158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 5: (solve of height)
281681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
281781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalHeightValue = max(0, availableSpace - (logicalTopValue + logicalBottom.calcValue(containerLogicalHeight)));
281881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else if (!logicalTopIsAuto && !logicalHeightIsAuto && logicalBottomIsAuto) {
28198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // RULE 6: (no need solve of bottom)
282081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
282181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
28228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
28238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Use computed values to calculate the vertical position.
282681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    logicalTopPos = logicalTopValue + marginBeforeValue;
282781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeLogicalTopPositionedOffset(logicalTopPos, this, logicalHeightValue, containerBlock, containerLogicalHeight);
28288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2830bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computePositionedLogicalWidthReplaced()
28318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The following is based off of the W3C Working Draft from April 11, 2006 of
2833d0825bca7fe65beaee391d30da42e937db621564Steve Block    // CSS 2.1: Section 10.3.8 "Absolutely positioned, replaced elements"
28348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-width>
28358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (block-style-comments in this function correspond to text from the spec and
28368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the numbers correspond to numbers in spec)
28378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't use containingBlock(), since we may be positioned by an enclosing
28398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // relative positioned inline.
28408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
28418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
284281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int containerLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock);
28438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // To match WinIE, in quirks mode use the parent's 'direction' property
28458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // instead of the the container block's.
28465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    TextDirection containerDirection = (document()->inQuirksMode()) ? parent()->style()->direction() : containerBlock->style()->direction();
28478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Variables to solve.
28492bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
285081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalLeft = style()->logicalLeft();
285181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalRight = style()->logicalRight();
285281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length marginLogicalLeft = isHorizontal ? style()->marginLeft() : style()->marginTop();
285381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length marginLogicalRight = isHorizontal ? style()->marginRight() : style()->marginBottom();
285481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginLogicalLeftAlias = isHorizontal ? m_marginLeft : m_marginTop;
285581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginLogicalRightAlias = isHorizontal ? m_marginRight : m_marginBottom;
28568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
28588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 1. The used value of 'width' is determined as for inline replaced
28598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    elements.
28608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
28618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOTE: This value of width is FINAL in that the min/max width calculations
2862bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // are dealt with in computeReplacedWidth().  This means that the steps to produce
28638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // correct max/min in the non-replaced version, are not necessary.
286481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalWidth(computeReplacedLogicalWidth() + borderAndPaddingLogicalWidth());
286581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int availableSpace = containerLogicalWidth - logicalWidth();
28668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
28688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 2. If both 'left' and 'right' have the value 'auto', then if 'direction'
28698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    of the containing block is 'ltr', set 'left' to the static position;
28708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    else if 'direction' is 'rtl', set 'right' to the static position.
28718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
28728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // see FIXME 2
287381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock, containerLogicalWidth, containerDirection);
28748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
28768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left'
28778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    or 'margin-right' with '0'.
28788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
287981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (logicalLeft.isAuto() || logicalRight.isAuto()) {
288081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (marginLogicalLeft.isAuto())
288181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalLeft.setValue(Fixed, 0);
288281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (marginLogicalRight.isAuto())
288381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalRight.setValue(Fixed, 0);
28848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
28878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 4. If at this point both 'margin-left' and 'margin-right' are still
28888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    'auto', solve the equation under the extra constraint that the two
28898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    margins must get equal values, unless this would make them negative,
28908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    in which case when the direction of the containing block is 'ltr'
28918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    ('rtl'), set 'margin-left' ('margin-right') to zero and solve for
28928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    'margin-right' ('margin-left').
28938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
289481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalLeftValue = 0;
289581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalRightValue = 0;
28968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
289781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
28988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // 'left' and 'right' cannot be 'auto' due to step 3
289981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto()));
29008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
290181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
290281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
29038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
290481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int difference = availableSpace - (logicalLeftValue + logicalRightValue);
29058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (difference > 0) {
290681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalLeftAlias = difference / 2; // split the difference
290781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginLogicalRightAlias = difference - marginLogicalLeftAlias; // account for odd valued differences
29088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
29098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // see FIXME 1
29108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (containerDirection == LTR) {
291181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                marginLogicalLeftAlias = 0;
291281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                marginLogicalRightAlias = difference; // will be negative
29138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
291481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                marginLogicalLeftAlias = difference; // will be negative
291581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                marginLogicalRightAlias = 0;
29168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
29178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
29188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
29208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 5. If at this point there is an 'auto' left, solve the equation for
29218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    that value.
29228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
292381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (logicalLeft.isAuto()) {
292481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
292581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
292681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
29278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'left'
292981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = availableSpace - (logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias);
293081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (logicalRight.isAuto()) {
293181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
293281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
293381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
29348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'right'
293681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalRightValue = availableSpace - (logicalLeftValue + marginLogicalLeftAlias + marginLogicalRightAlias);
293781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (marginLogicalLeft.isAuto()) {
293881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
293981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
294081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
29418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'margin-left'
294381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalLeftAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalRightAlias);
294481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (marginLogicalRight.isAuto()) {
294581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
294681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
294781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
29488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'margin-right'
295081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalRightAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalLeftAlias);
29518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
29528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Nothing is 'auto', just calculate the values.
295381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
295481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
295581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
295681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
29578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
29608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 6. If at this point the values are over-constrained, ignore the value
29618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    for either 'left' (in case the 'direction' property of the
29628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    containing block is 'rtl') or 'right' (in case 'direction' is
29638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    'ltr') and solve for that value.
29648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
29658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOTE:  It is not necessary to solve for 'right' when the direction is
29668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // LTR because the value is not used.
296781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int totalLogicalWidth = logicalWidth() + logicalLeftValue + logicalRightValue +  marginLogicalLeftAlias + marginLogicalRightAlias;
296881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (totalLogicalWidth > containerLogicalWidth && (containerDirection == RTL))
296981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalLeftValue = containerLogicalWidth - (totalLogicalWidth - logicalLeftValue);
29708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
297181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: Deal with differing writing modes here.  Our offset needs to be in the containing block's coordinate space, so that
297281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // can make the result here rather complicated to compute.
297381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
29748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Use computed values to calculate the horizontal position.
29758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
297681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: This hack is needed to calculate the logical left position for a 'rtl' relatively
297781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // positioned, inline containing block because right now, it is using the logical left position
29788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // of the first line box when really it should use the last line box.  When
29798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // this is fixed elsewhere, this block should be removed.
2980a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (containerBlock->isRenderInline() && !containerBlock->style()->isLeftToRightDirection()) {
29818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        const RenderInline* flow = toRenderInline(containerBlock);
29828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineFlowBox* firstLine = flow->firstLineBox();
29838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineFlowBox* lastLine = flow->lastLineBox();
29848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (firstLine && lastLine && firstLine != lastLine) {
298581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setLogicalLeft(logicalLeftValue + marginLogicalLeftAlias + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft()));
29868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
29878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
29888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
299081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalLeftPos = logicalLeftValue + marginLogicalLeftAlias;
299181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeLogicalLeftPositionedOffset(logicalLeftPos, this, logicalWidth(), containerBlock, containerLogicalWidth);
299281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalLeft(logicalLeftPos);
29938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2995bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderBox::computePositionedLogicalHeightReplaced()
29968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The following is based off of the W3C Working Draft from April 11, 2006 of
2998d0825bca7fe65beaee391d30da42e937db621564Steve Block    // CSS 2.1: Section 10.6.5 "Absolutely positioned, replaced elements"
29998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-height>
30008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (block-style-comments in this function correspond to text from the spec and
30018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the numbers correspond to numbers in spec)
30028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
30048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
30058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
300681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int containerLogicalHeight = containingBlockLogicalHeightForPositioned(containerBlock);
30078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Variables to solve.
30092bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isHorizontal = isHorizontalWritingMode();
301081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool isFlipped = style()->isFlippedBlocksWritingMode();
301181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length marginBefore = style()->marginBefore();
301281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length marginAfter = style()->marginAfter();
301381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginBeforeAlias = isHorizontal ? (isFlipped ? m_marginBottom : m_marginTop) : (isFlipped ? m_marginRight: m_marginLeft);
301481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int& marginAfterAlias = isHorizontal ? (isFlipped ? m_marginTop : m_marginBottom) : (isFlipped ? m_marginLeft: m_marginRight);
30158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
301681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalTop = style()->logicalTop();
301781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Length logicalBottom = style()->logicalBottom();
30188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
30208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 1. The used value of 'height' is determined as for inline replaced
30218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    elements.
30228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
30238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOTE: This value of height is FINAL in that the min/max height calculations
3024bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // are dealt with in computeReplacedHeight().  This means that the steps to produce
30258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // correct max/min in the non-replaced version, are not necessary.
302681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalHeight(computeReplacedLogicalHeight() + borderAndPaddingLogicalHeight());
302781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const int availableSpace = containerLogicalHeight - logicalHeight();
30288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
30308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 2. If both 'top' and 'bottom' have the value 'auto', replace 'top'
30318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    with the element's static position.
30328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
30338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // see FIXME 2
303481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeBlockStaticDistance(logicalTop, logicalBottom, this, containerBlock);
30358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
30378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 3. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or
30388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    'margin-bottom' with '0'.
30398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
30408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: The spec. says that this step should only be taken when bottom is
30418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // auto, but if only top is auto, this makes step 4 impossible.
304281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (logicalTop.isAuto() || logicalBottom.isAuto()) {
304381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (marginBefore.isAuto())
304481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginBefore.setValue(Fixed, 0);
304581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (marginAfter.isAuto())
304681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            marginAfter.setValue(Fixed, 0);
30478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
30488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
30508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 4. If at this point both 'margin-top' and 'margin-bottom' are still
30518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    'auto', solve the equation under the extra constraint that the two
30528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    margins must get equal values.
30538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
305481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalTopValue = 0;
305581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalBottomValue = 0;
30568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
305781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (marginBefore.isAuto() && marginAfter.isAuto()) {
3058d0825bca7fe65beaee391d30da42e937db621564Steve Block        // 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combined.
305981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(!(logicalTop.isAuto() || logicalBottom.isAuto()));
30608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
306181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
306281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
30638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
306481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        int difference = availableSpace - (logicalTopValue + logicalBottomValue);
30658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NOTE: This may result in negative values.
306681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginBeforeAlias =  difference / 2; // split the difference
306781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginAfterAlias = difference - marginBeforeAlias; // account for odd valued differences
30688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
30708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 5. If at this point there is only one 'auto' left, solve the equation
30718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    for that value.
30728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
307381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (logicalTop.isAuto()) {
307481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
307581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
307681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
30778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'top'
307981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopValue = availableSpace - (logicalBottomValue + marginBeforeAlias + marginAfterAlias);
308081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (logicalBottom.isAuto()) {
308181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
308281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
308381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
30848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'bottom'
30868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NOTE: It is not necessary to solve for 'bottom' because we don't ever
30878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // use the value.
308881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (marginBefore.isAuto()) {
308981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
309081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
309181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
30928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'margin-top'
309481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginBeforeAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginAfterAlias);
309581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else if (marginAfter.isAuto()) {
309681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
309781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
309881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
30998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Solve for 'margin-bottom'
310181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginAfterAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginBeforeAlias);
31028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
31038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Nothing is 'auto', just calculate the values.
310481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
310581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
310681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
31078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // NOTE: It is not necessary to solve for 'bottom' because we don't ever
31088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // use the value.
31098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     }
31108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*-----------------------------------------------------------------------*\
31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * 6. If at this point the values are over-constrained, ignore the value
31138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *    for 'bottom' and solve for that value.
31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    \*-----------------------------------------------------------------------*/
31158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOTE: It is not necessary to do this step because we don't end up using
31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the value of 'bottom' regardless of whether the values are over-constrained
31178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // or not.
31188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Use computed values to calculate the vertical position.
312081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int logicalTopPos = logicalTopValue + marginBeforeAlias;
312181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    computeLogicalTopPositionedOffset(logicalTopPos, this, logicalHeight(), containerBlock, containerLogicalHeight);
312281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setLogicalTop(logicalTopPos);
31238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWidthToEndOfLine)
31268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // VisiblePositions at offsets inside containers either a) refer to the positions before/after
31288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // those containers (tables and select elements) or b) refer to the position inside an empty block.
31298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // They never refer to children.
31308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Paint the carets inside empty blocks differently than the carets before/after elements.
31318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: What about border and padding?
3133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    IntRect rect(x(), y(), caretWidth, height());
3134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool ltr = box ? box->isLeftToRightDirection() : style()->isLeftToRightDirection();
31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if ((!caretOffset) ^ ltr)
3137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        rect.move(IntSize(width() - caretWidth, 0));
31388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (box) {
31408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RootInlineBox* rootBox = box->root();
3141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        int top = rootBox->lineTop();
31428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        rect.setY(top);
3143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        rect.setHeight(rootBox->lineBottom() - top);
31448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If height of box is smaller than font height, use the latter one,
31478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // otherwise the caret might become invisible.
31488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
31498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Also, if the box is not a replaced element, always use the font height.
31508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This prevents the "big caret" bug described in:
31518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <rdar://problem/3777804> Deleting all content in a document can result in giant tall-as-window insertion point
31528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
31538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: ignoring :first-line, missing good reason to take care of
31542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int fontHeight = style()->fontMetrics().height();
31558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (fontHeight > rect.height() || (!isReplaced() && !isTable()))
31568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        rect.setHeight(fontHeight);
31578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (extraWidthToEndOfLine)
31592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        *extraWidthToEndOfLine = x() + width() - rect.maxX();
31608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Move to local coords
3162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    rect.move(-x(), -y());
31638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return rect;
31648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianVisiblePosition RenderBox::positionForPoint(const IntPoint& point)
31678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
31688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // no children...return this render object's element, if there is one, and offset 0
31698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!firstChild())
31702bde8e466a4451c7319e3a072d118917957d6554Steve Block        return createVisiblePosition(node() ? firstPositionInOrBeforeNode(node()) : Position(0, 0));
31718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
31728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int xPos = point.x();
31738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int yPos = point.y();
31748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
31758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isTable() && node()) {
317621939df44de1705786c545cd1bf519d47250322dBen Murdoch        int right = contentWidth() + borderAndPaddingWidth();
317721939df44de1705786c545cd1bf519d47250322dBen Murdoch        int bottom = contentHeight() + borderAndPaddingHeight();
31788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
31798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (xPos < 0 || xPos > right || yPos < 0 || yPos > bottom) {
31808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (xPos <= right / 2)
31812bde8e466a4451c7319e3a072d118917957d6554Steve Block                return createVisiblePosition(firstPositionInOrBeforeNode(node()));
31822bde8e466a4451c7319e3a072d118917957d6554Steve Block            return createVisiblePosition(lastPositionInOrAfterNode(node()));
31838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
31848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
31858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
31868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Pass off to the closest child.
31878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int minDist = INT_MAX;
31888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderBox* closestRenderer = 0;
31898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int newX = xPos;
31908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int newY = yPos;
31918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isTableRow()) {
31928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newX += x();
31938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newY += y();
31948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
31958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (RenderObject* renderObject = firstChild(); renderObject; renderObject = renderObject->nextSibling()) {
31968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if ((!renderObject->firstChild() && !renderObject->isInline() && !renderObject->isBlockFlow() )
31978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            || renderObject->style()->visibility() != VISIBLE)
31988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            continue;
31998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!renderObject->isBox())
32018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            continue;
32028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBox* renderer = toRenderBox(renderObject);
32048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int top = renderer->borderTop() + renderer->paddingTop() + (isTableRow() ? 0 : renderer->y());
32068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int bottom = top + renderer->contentHeight();
32078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRow() ? 0 : renderer->x());
32088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int right = left + renderer->contentWidth();
32098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (xPos <= right && xPos >= left && yPos <= top && yPos >= bottom) {
32118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (renderer->isTableRow())
32128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return renderer->positionForCoordinates(xPos + newX - renderer->x(), yPos + newY - renderer->y());
32138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return renderer->positionForCoordinates(xPos - renderer->x(), yPos - renderer->y());
32148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
32158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Find the distance from (x, y) to the box.  Split the space around the box into 8 pieces
32178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // and use a different compare depending on which piece (x, y) is in.
32188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        IntPoint cmp;
32198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (xPos > right) {
32208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (yPos < top)
32218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(right, top);
32228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else if (yPos > bottom)
32238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(right, bottom);
32248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else
32258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(right, yPos);
32268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (xPos < left) {
32278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (yPos < top)
32288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(left, top);
32298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else if (yPos > bottom)
32308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(left, bottom);
32318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else
32328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(left, yPos);
32338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
32348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (yPos < top)
32358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(xPos, top);
32368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else
32378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                cmp = IntPoint(xPos, bottom);
32388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
32398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int x1minusx2 = cmp.x() - xPos;
32418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int y1minusy2 = cmp.y() - yPos;
32428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        int dist = x1minusx2 * x1minusx2 + y1minusy2 * y1minusy2;
32448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (dist < minDist) {
32458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            closestRenderer = renderer;
32468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            minDist = dist;
32478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
32488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
32498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (closestRenderer)
32518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return closestRenderer->positionForCoordinates(newX - closestRenderer->x(), newY - closestRenderer->y());
32528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32532bde8e466a4451c7319e3a072d118917957d6554Steve Block    return createVisiblePosition(firstPositionInOrBeforeNode(node()));
32548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
32558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool RenderBox::shrinkToAvoidFloats() const
32578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
3258ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    // Floating objects don't shrink.  Objects that don't avoid floats don't shrink.  Marquees don't shrink.
3259ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if ((isInline() && !isHTMLMarquee()) || !avoidsFloats() || isFloating())
32608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return false;
32618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // All auto-width objects that avoid floats should always use lineWidth.
3263ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    return style()->width().isAuto();
32648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
32658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
32668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool RenderBox::avoidsFloats() const
32678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
326836df29d71f5315df6fe4375954add26fe3849273Steve Block    return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isDeprecatedFlexItem();
32698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
32708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3271231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBox::addShadowOverflow()
3272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
3273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int shadowLeft;
3274231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int shadowRight;
3275231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int shadowTop;
3276231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int shadowBottom;
3277231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    style()->getBoxShadowExtent(shadowTop, shadowRight, shadowBottom, shadowLeft);
3278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntRect borderBox = borderBoxRect();
3279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int overflowLeft = borderBox.x() + shadowLeft;
32802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int overflowRight = borderBox.maxX() + shadowRight;
3281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    int overflowTop = borderBox.y() + shadowTop;
32822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int overflowBottom = borderBox.maxY() + shadowBottom;
3283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    addVisualOverflow(IntRect(overflowLeft, overflowTop, overflowRight - overflowLeft, overflowBottom - overflowTop));
3284231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
3285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBox::addOverflowFromChild(RenderBox* child, const IntSize& delta)
3287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
3288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Only propagate layout overflow from the child if the child isn't clipping its overflow.  If it is, then
3289f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // its overflow is internal to it, and we don't care about it.  layoutOverflowRectForPropagation takes care of this
3290f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // and just propagates the border box rect instead.
3291f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect childLayoutOverflowRect = child->layoutOverflowRectForPropagation(style());
3292231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    childLayoutOverflowRect.move(delta);
3293231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    addLayoutOverflow(childLayoutOverflowRect);
3294231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3295231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Add in visual overflow from the child.  Even if the child clips its overflow, it may still
3296231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // have visual overflow of its own set from box shadows or reflections.  It is unnecessary to propagate this
3297231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // overflow if we are clipping our own overflow.
3298f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (child->hasSelfPaintingLayer() || hasOverflowClip())
3299231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
3300f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect childVisualOverflowRect = child->visualOverflowRectForPropagation(style());
3301231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    childVisualOverflowRect.move(delta);
3302231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    addVisualOverflow(childVisualOverflowRect);
3303231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
3304231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3305231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBox::addLayoutOverflow(const IntRect& rect)
3306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
3307f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect clientBox = clientBoxRect();
3308f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (clientBox.contains(rect) || rect.isEmpty())
3309231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
3310f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3311f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // For overflow clip objects, we don't want to propagate overflow into unreachable areas.
3312f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect overflowRect(rect);
3313f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (hasOverflowClip() || isRenderView()) {
3314f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Overflow is in the block's coordinate space and thus is flipped for horizontal-bt and vertical-rl
3315f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // writing modes.  At this stage that is actually a simplification, since we can treat horizontal-tb/bt as the same
3316f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // and vertical-lr/rl as the same.
33172bde8e466a4451c7319e3a072d118917957d6554Steve Block        bool hasTopOverflow = !style()->isLeftToRightDirection() && !isHorizontalWritingMode();
33182bde8e466a4451c7319e3a072d118917957d6554Steve Block        bool hasLeftOverflow = !style()->isLeftToRightDirection() && isHorizontalWritingMode();
3319f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3320f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!hasTopOverflow)
33212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            overflowRect.shiftYEdgeTo(max(overflowRect.y(), clientBox.y()));
3322f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
33232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            overflowRect.shiftMaxYEdgeTo(min(overflowRect.maxY(), clientBox.maxY()));
3324f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!hasLeftOverflow)
33252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            overflowRect.shiftXEdgeTo(max(overflowRect.x(), clientBox.x()));
3326f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        else
33272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            overflowRect.shiftMaxXEdgeTo(min(overflowRect.maxX(), clientBox.maxX()));
3328231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3329f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Now re-test with the adjusted rectangle and see if it has become unreachable or fully
3330f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // contained.
3331f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (clientBox.contains(overflowRect) || overflowRect.isEmpty())
3332f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return;
3333f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
3334f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_overflow)
3336f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_overflow.set(new RenderOverflow(clientBox, borderBoxRect()));
3337231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3338f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_overflow->addLayoutOverflow(overflowRect);
3339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
3340231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3341231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBox::addVisualOverflow(const IntRect& rect)
3342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
3343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntRect borderBox = borderBoxRect();
3344f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (borderBox.contains(rect) || rect.isEmpty())
3345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
3346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_overflow)
3348f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_overflow.set(new RenderOverflow(clientBoxRect(), borderBox));
3349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_overflow->addVisualOverflow(rect);
3351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
3352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderBox::clearLayoutOverflow()
3354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
3355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_overflow)
3356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
3357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3358231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (visualOverflowRect() == borderBoxRect()) {
3359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_overflow.clear();
3360231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
3361231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
3362231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3363231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_overflow->resetLayoutOverflow(borderBoxRect());
3364231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
3365231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3366a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochint RenderBox::lineHeight(bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
336768513a70bcd92384395513322f1b801e7bf9c729Steve Block{
3368a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (isReplaced())
3369a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
3370a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return 0;
3371a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
337268513a70bcd92384395513322f1b801e7bf9c729Steve Block
33736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderBox::baselinePosition(FontBaseline baselineType, bool /*firstLine*/, LineDirectionMode direction, LinePositionMode /*linePositionMode*/) const
3374a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
33756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (isReplaced()) {
33766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        int result = direction == HorizontalLine ? m_marginTop + height() + m_marginBottom : m_marginRight + width() + m_marginLeft;
33776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (baselineType == AlphabeticBaseline)
33786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return result;
33796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return result - result / 2;
33806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
3381a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return 0;
338268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
338368513a70bcd92384395513322f1b801e7bf9c729Steve Block
3384f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3385f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochRenderLayer* RenderBox::enclosingFloatPaintingLayer() const
3386e14391e94c850b8bd03680c23b38978db68687a8John Reck{
3387f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    const RenderObject* curr = this;
3388f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    while (curr) {
3389f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        RenderLayer* layer = curr->hasLayer() && curr->isBox() ? toRenderBoxModelObject(curr)->layer() : 0;
3390f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (layer && layer->isSelfPaintingLayer())
3391f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            return layer;
3392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        curr = curr->parent();
3393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
3394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return 0;
3395f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
3396f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3397f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochIntRect RenderBox::logicalVisualOverflowRectForPropagation(RenderStyle* parentStyle) const
3398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
3399f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect rect = visualOverflowRectForPropagation(parentStyle);
3400f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!parentStyle->isHorizontalWritingMode())
3401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return rect.transposedRect();
3402f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return rect;
3403f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
3404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3405f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochIntRect RenderBox::visualOverflowRectForPropagation(RenderStyle* parentStyle) const
3406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
3407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // If the writing modes of the child and parent match, then we don't have to
3408f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // do anything fancy. Just return the result.
3409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect rect = visualOverflowRect();
3410f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (parentStyle->writingMode() == style()->writingMode())
3411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return rect;
3412f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // We are putting ourselves into our parent's coordinate space.  If there is a flipped block mismatch
3414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // in a particular axis, then we have to flip the rect along that axis.
3415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (style()->writingMode() == RightToLeftWritingMode || parentStyle->writingMode() == RightToLeftWritingMode)
34162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setX(width() - rect.maxX());
3417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    else if (style()->writingMode() == BottomToTopWritingMode || parentStyle->writingMode() == BottomToTopWritingMode)
34182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setY(height() - rect.maxY());
3419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return rect;
3421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
3422f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3423f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochIntRect RenderBox::logicalLayoutOverflowRectForPropagation(RenderStyle* parentStyle) const
3424f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
3425f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect rect = layoutOverflowRectForPropagation(parentStyle);
3426f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!parentStyle->isHorizontalWritingMode())
3427f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return rect.transposedRect();
3428f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return rect;
3429f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
3430f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3431f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochIntRect RenderBox::layoutOverflowRectForPropagation(RenderStyle* parentStyle) const
3432f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
3433f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Only propagate interior layout overflow if we don't clip it.
3434f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    IntRect rect = borderBoxRect();
3435f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!hasOverflowClip())
3436f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        rect.unite(layoutOverflowRect());
3437f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
34382bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasTransform = hasLayer() && layer()->transform();
34392bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isRelPositioned() || hasTransform) {
3440f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // If we are relatively positioned or if we have a transform, then we have to convert
3441f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // this rectangle into physical coordinates, apply relative positioning and transforms
3442f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // to it, and then convert it back.
3443f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        flipForWritingMode(rect);
3444f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
34452bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (hasTransform)
3446f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rect = layer()->currentTransform().mapRect(rect);
3447f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3448f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (isRelPositioned())
3449f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            rect.move(relativePositionOffsetX(), relativePositionOffsetY());
3450f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3451f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Now we need to flip back.
3452f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        flipForWritingMode(rect);
3453f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
3454f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3455f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // If the writing modes of the child and parent match, then we don't have to
3456f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // do anything fancy. Just return the result.
3457f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (parentStyle->writingMode() == style()->writingMode())
3458f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return rect;
3459f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3460f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // We are putting ourselves into our parent's coordinate space.  If there is a flipped block mismatch
3461f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // in a particular axis, then we have to flip the rect along that axis.
3462f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (style()->writingMode() == RightToLeftWritingMode || parentStyle->writingMode() == RightToLeftWritingMode)
34632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setX(width() - rect.maxX());
3464f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    else if (style()->writingMode() == BottomToTopWritingMode || parentStyle->writingMode() == BottomToTopWritingMode)
34652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setY(height() - rect.maxY());
3466f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
3467f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return rect;
3468e14391e94c850b8bd03680c23b38978db68687a8John Reck}
3469e14391e94c850b8bd03680c23b38978db68687a8John Reck
34706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerIntPoint RenderBox::flipForWritingMode(const RenderBox* child, const IntPoint& point, FlippingAdjustment adjustment) const
3471e14391e94c850b8bd03680c23b38978db68687a8John Reck{
3472e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!style()->isFlippedBlocksWritingMode())
347328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return point;
3474e14391e94c850b8bd03680c23b38978db68687a8John Reck
3475e14391e94c850b8bd03680c23b38978db68687a8John Reck    // The child is going to add in its x() and y(), so we have to make sure it ends up in
3476e14391e94c850b8bd03680c23b38978db68687a8John Reck    // the right place.
34772bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
347828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return IntPoint(point.x(), point.y() + height() - child->height() - child->y() - (adjustment == ParentToChildFlippingAdjustment ? child->y() : 0));
347928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return IntPoint(point.x() + width() - child->width() - child->x() - (adjustment == ParentToChildFlippingAdjustment ? child->x() : 0), point.y());
348028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
348128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
34826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid RenderBox::flipForWritingMode(IntRect& rect) const
348328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
348428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!style()->isFlippedBlocksWritingMode())
348528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return;
348628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
34872bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
34882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setY(height() - rect.maxY());
3489e14391e94c850b8bd03680c23b38978db68687a8John Reck    else
34902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rect.setX(width() - rect.maxX());
349128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
349228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
34936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderBox::flipForWritingMode(int position) const
349428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
349528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!style()->isFlippedBlocksWritingMode())
349628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return position;
349728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return logicalHeight() - position;
349828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
349928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
35006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerIntPoint RenderBox::flipForWritingMode(const IntPoint& position) const
350128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
350228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!style()->isFlippedBlocksWritingMode())
350328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return position;
35042bde8e466a4451c7319e3a072d118917957d6554Steve Block    return isHorizontalWritingMode() ? IntPoint(position.x(), height() - position.y()) : IntPoint(width() - position.x(), position.y());
3505e14391e94c850b8bd03680c23b38978db68687a8John Reck}
3506e14391e94c850b8bd03680c23b38978db68687a8John Reck
35072fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIntPoint RenderBox::flipForWritingModeIncludingColumns(const IntPoint& point) const
35082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
35092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
35102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return flipForWritingMode(point);
35112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return toRenderBlock(this)->flipForWritingModeIncludingColumns(point);
35122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
35132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
35146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerIntSize RenderBox::flipForWritingMode(const IntSize& offset) const
3515e14391e94c850b8bd03680c23b38978db68687a8John Reck{
3516e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!style()->isFlippedBlocksWritingMode())
351728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return offset;
35182bde8e466a4451c7319e3a072d118917957d6554Steve Block    return isHorizontalWritingMode() ? IntSize(offset.width(), height() - offset.height()) : IntSize(width() - offset.width(), offset.height());
3519e14391e94c850b8bd03680c23b38978db68687a8John Reck}
3520e14391e94c850b8bd03680c23b38978db68687a8John Reck
352181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochFloatPoint RenderBox::flipForWritingMode(const FloatPoint& position) const
352281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
352381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!style()->isFlippedBlocksWritingMode())
352481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return position;
35252bde8e466a4451c7319e3a072d118917957d6554Steve Block    return isHorizontalWritingMode() ? FloatPoint(position.x(), height() - position.y()) : FloatPoint(width() - position.x(), position.y());
352681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
352781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
352881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid RenderBox::flipForWritingMode(FloatRect& rect) const
352981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
353081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!style()->isFlippedBlocksWritingMode())
353181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
353281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
35332bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isHorizontalWritingMode())
353481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        rect.setY(height() - rect.maxY());
353581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
353681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        rect.setX(width() - rect.maxX());
353781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
353881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
35396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerIntSize RenderBox::locationOffsetIncludingFlipping() const
3540e14391e94c850b8bd03680c23b38978db68687a8John Reck{
354181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RenderBlock* containerBlock = containingBlock();
354281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!containerBlock || containerBlock == this)
3543e14391e94c850b8bd03680c23b38978db68687a8John Reck        return locationOffset();
3544e14391e94c850b8bd03680c23b38978db68687a8John Reck
35456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    IntRect rect(frameRect());
354681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    containerBlock->flipForWritingMode(rect); // FIXME: This is wrong if we are an absolutely positioned object enclosed by a relative-positioned inline.
35476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    return IntSize(rect.x(), rect.y());
3548e14391e94c850b8bd03680c23b38978db68687a8John Reck}
3549e14391e94c850b8bd03680c23b38978db68687a8John Reck
35508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
3551