15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderInline.h"
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
269e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/dom/Fullscreen.h"
27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/StyleEngine.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Chrome.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Page.h"
307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/BoxPainter.h"
317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/InlinePainter.h"
327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/ObjectPainter.h"
3319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "core/rendering/GraphicsContextAnnotator.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestResult.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/InlineTextBox.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderBlock.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderFlowThread.h"
3893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/rendering/RenderFullScreen.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderGeometryMap.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTheme.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/style/StyleInheritedData.h"
441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatQuad.h"
45bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/geometry/TransformState.h"
46a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h"
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct SameSizeAsRenderInline : public RenderBoxModelObject {
51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual ~SameSizeAsRenderInline() { }
52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RenderObjectChildList m_children;
53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RenderLineBoxList m_lineBoxes;
54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)COMPILE_ASSERT(sizeof(RenderInline) == sizeof(SameSizeAsRenderInline), RenderInline_should_stay_small);
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderInline::RenderInline(Element* element)
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : RenderBoxModelObject(element)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setChildrenInline(true);
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderInline::trace(Visitor* visitor)
65e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
66e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    visitor->trace(m_children);
67e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RenderBoxModelObject::trace(visitor);
68e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
69e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderInline* RenderInline::createAnonymous(Document* document)
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
72f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    RenderInline* renderer = new RenderInline(0);
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    renderer->setDocumentForAnonymous(document);
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return renderer;
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::willBeDestroyed()
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Make sure we do not retain "this" in the continuation outline table map of our containing blocks.
817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (parent() && style()->visibility() == VISIBLE && style()->hasOutline()) {
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool containingBlockPaintsContinuationOutline = continuation() || isInlineElementContinuation();
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (containingBlockPaintsContinuationOutline) {
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (RenderBlock* cb = containingBlock()) {
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (RenderBlock* cbCb = cb->containingBlock())
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ASSERT(!cbCb->paintsContinuationOutline(this));
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // properly dirty line boxes that they are removed from.  Effects that do :before/:after only on hover could crash otherwise.
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    children()->destroyLeftoverChildren();
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Destroy our continuation before anything other than anonymous children.
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The reason we don't destroy it before anonymous children is that they may
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // have continuations of their own that are anonymous children of our continuation.
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* continuation = this->continuation();
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (continuation) {
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        continuation->destroy();
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setContinuation(0);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!documentBeingDestroyed()) {
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (firstLineBox()) {
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We can't wait for RenderBoxModelObject::destroy to clear the selection,
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // because by then we will have nuked the line boxes.
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: The FrameSelection should be responsible for this when it
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // is notified of DOM mutations.
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isSelectionBorder())
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                view()->clearSelection();
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If line boxes are contained inside a root, that means we're an inline.
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // In that case, we need to remove all the line boxes so that the parent
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // lines aren't pointing to deleted children. If the first line box does
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // not have a parent that means they are either already disconnected or
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // root lines that can just be destroyed without disconnecting.
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (firstLineBox()->parent()) {
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox())
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    box->remove();
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
12302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        } else if (parent())
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            parent()->dirtyLinesFromChangedChild(this);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
127f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    m_lineBoxes.deleteLineBoxes();
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject::willBeDestroyed();
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderInline* RenderInline::inlineElementContinuation() const
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* continuation = this->continuation();
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!continuation || continuation->isInline())
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return toRenderInline(continuation);
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toRenderBlock(continuation)->inlineElementContinuation();
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::updateFromStyle()
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject::updateFromStyle();
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    // FIXME: Is this still needed. Was needed for run-ins, since run-in is considered a block display type.
14519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    setInline(true);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Support transforms and reflections on inline flows someday.
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setHasTransform(false);
14902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    setHasReflection(false);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static RenderObject* inFlowPositionedInlineAncestor(RenderObject* p)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (p && p->isRenderInline()) {
155197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (p->isRelPositioned())
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return p;
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        p = p->parent();
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void updateStyleOfAnonymousBlockContinuations(RenderObject* block, const RenderStyle* newStyle, const RenderStyle* oldStyle)
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (;block && block->isAnonymousBlock(); block = block->nextSibling()) {
165e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (!toRenderBlock(block)->isAnonymousBlockContinuation())
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
167e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
1687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        RefPtr<RenderStyle> newBlockStyle;
169e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
170e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (!block->style()->isOutlineEquivalent(newStyle)) {
1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            newBlockStyle = RenderStyle::clone(block->style());
1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            newBlockStyle->setOutlineFromStyle(*newStyle);
173e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        }
174e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
175e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (block->style()->position() != newStyle->position()) {
176e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            // If we are no longer in-flow positioned but our descendant block(s) still have an in-flow positioned ancestor then
177e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            // their containing anonymous block should keep its in-flow positioning.
1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (oldStyle->hasInFlowPosition()
1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                && inFlowPositionedInlineAncestor(toRenderBlock(block)->inlineElementContinuation()))
180e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                continue;
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (!newBlockStyle)
1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                newBlockStyle = RenderStyle::clone(block->style());
1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            newBlockStyle->setPosition(newStyle->position());
184e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        }
1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (newBlockStyle)
1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            block->setStyle(newBlockStyle);
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject::styleDidChange(diff, oldStyle);
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Ensure that all of the split inlines pick up the new style. We
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // only do this if we're an inline, since we don't want to propagate
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // a block's style to the other inlines.
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // e.g., <font>foo <h4>goo</h4> moo</font>.  The <font> inlines before
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and after the block share the same style, but the block doesn't
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // need to pass its style on to anyone else.
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderStyle* newStyle = style();
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderInline* continuation = inlineElementContinuation();
203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (RenderInline* currCont = continuation; currCont; currCont = currCont->inlineElementContinuation()) {
204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        RenderBoxModelObject* nextCont = currCont->continuation();
205926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        currCont->setContinuation(0);
206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        currCont->setStyle(newStyle);
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        currCont->setContinuation(nextCont);
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // If an inline's outline or in-flow positioning has changed then any descendant blocks will need to change their styles accordingly.
2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Do this by updating the styles of the descendant blocks' containing anonymous blocks - there may be more than one.
212e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (continuation && oldStyle
213e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        && (!newStyle->isOutlineEquivalent(oldStyle)
214e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            || (newStyle->position() != oldStyle->position() && (newStyle->hasInFlowPosition() || oldStyle->hasInFlowPosition())))) {
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If any descendant blocks exist then they will be in the next anonymous block and its siblings.
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* block = containingBlock()->nextSibling();
217e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (block && block->isAnonymousBlock())
218e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            updateStyleOfAnonymousBlockContinuations(block, newStyle, oldStyle);
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
221c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!alwaysCreateLineBoxes()) {
2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        bool alwaysCreateLineBoxesNew = hasSelfPaintingLayer() || hasBoxDecorationBackground() || newStyle->hasPadding() || newStyle->hasMargin() || newStyle->hasOutline();
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (oldStyle && alwaysCreateLineBoxesNew) {
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            dirtyLineBoxes(false);
2255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            setNeedsLayoutAndFullPaintInvalidation();
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
227c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        setAlwaysCreateLineBoxes(alwaysCreateLineBoxesNew);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::updateAlwaysCreateLineBoxes(bool fullLayout)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Once we have been tainted once, just assume it will happen again. This way effects like hover highlighting that change the
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // background color will only cause a layout on the first rollover.
235c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (alwaysCreateLineBoxes())
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderStyle* parentStyle = parent()->style();
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderInline* parentRenderInline = parent()->isRenderInline() ? toRenderInline(parent()) : 0;
2408abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    bool checkFonts = document().inNoQuirksMode();
241c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool alwaysCreateLineBoxesNew = (parentRenderInline && parentRenderInline->alwaysCreateLineBoxes())
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || (parentRenderInline && parentStyle->verticalAlign() != BASELINE)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || style()->verticalAlign() != BASELINE
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || style()->textEmphasisMark() != TextEmphasisMarkNone
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || (checkFonts && (!parentStyle->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(style()->font().fontMetrics())
24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || parentStyle->lineHeight() != style()->lineHeight()));
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
248c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!alwaysCreateLineBoxesNew && checkFonts && document().styleEngine()->usesFirstLineRules()) {
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Have to check the first line style as well.
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        parentStyle = parent()->style(true);
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderStyle* childStyle = style(true);
252c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        alwaysCreateLineBoxesNew = !parentStyle->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle->font().fontMetrics())
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || childStyle->verticalAlign() != BASELINE
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || parentStyle->lineHeight() != childStyle->lineHeight();
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (alwaysCreateLineBoxesNew) {
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!fullLayout)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            dirtyLineBoxes(false);
260c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        setAlwaysCreateLineBoxes();
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderInline::localCaretRect(InlineBox* inlineBox, int, LayoutUnit* extraWidthToEndOfLine)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstChild()) {
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This condition is possible if the RenderInline is at an editing boundary,
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // i.e. the VisiblePosition is:
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        //   <RenderInline editingBoundary=true>|<RenderText> </RenderText></RenderInline>
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: need to figure out how to make this return a valid rect, note that
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // there are no line boxes created in the above case.
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutRect();
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_UNUSED(inlineBox, !inlineBox);
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (extraWidthToEndOfLine)
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *extraWidthToEndOfLine = 0;
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect caretRect = localCaretRectForEmptyElement(borderAndPaddingWidth(), 0);
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (InlineBox* firstBox = firstLineBox())
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        caretRect.moveBy(roundedLayoutPoint(firstBox->topLeft()));
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return caretRect;
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (continuation())
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return addChildToContinuation(newChild, beforeChild);
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return addChildIgnoringContinuation(newChild, beforeChild);
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderer->isInline() && !renderer->isReplaced())
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return toRenderInline(renderer)->continuation();
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toRenderBlock(renderer)->inlineElementContinuation();
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild)
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild && beforeChild->parent() == this)
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return this;
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* curr = nextContinuation(this);
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* nextToLast = this;
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* last = this;
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (curr) {
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (beforeChild && beforeChild->parent() == curr) {
312d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (curr->slowFirstChild() == beforeChild)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return last;
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return curr;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextToLast = last;
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        last = curr;
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = nextContinuation(curr);
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
322d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!beforeChild && !last->slowFirstChild())
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return nextToLast;
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return last;
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Make sure we don't append things after :after-generated content if we have it.
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!beforeChild && isAfterContent(lastChild()))
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChild = lastChild();
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We are placing a block inside an inline. We have to perform a split of this
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // inline into continuations.  This involves creating an anonymous block box to hold
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // |newChild|.  We then make that block box a continuation of this inline.  We take all of
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the children after |beforeChild| and put them in a clone of this object.
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
33902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If inside an inline affected by in-flow positioning the block needs to be affected by it too.
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Giving the block a layer like this allows it to collect the x/y offsets from inline parents later.
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (RenderObject* positionedAncestor = inFlowPositionedInlineAncestor(this))
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newStyle->setPosition(positionedAncestor->style()->position());
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Push outline style to the block continuation.
3467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!newStyle->isOutlineEquivalent(style()))
3477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            newStyle->setOutlineFromStyle(*style());
3487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
349a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        RenderBlockFlow* newBox = RenderBlockFlow::createAnonymous(&document());
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newBox->setStyle(newStyle.release());
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBoxModelObject* oldContinuation = continuation();
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setContinuation(newBox);
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        splitFlow(beforeChild, newBox, newChild, oldContinuation);
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject::addChild(newChild, beforeChild);
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    newChild->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderInline* RenderInline::clone() const
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
365f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    RenderInline* cloneInline = new RenderInline(node());
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    cloneInline->setStyle(style());
367926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    cloneInline->setFlowThreadState(flowThreadState());
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return cloneInline;
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                RenderBlock* middleBlock,
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                RenderObject* beforeChild, RenderBoxModelObject* oldCont)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Create a clone of this inline.
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderInline* cloneInline = clone();
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    cloneInline->setContinuation(oldCont);
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // If we're splitting the inline containing the fullscreened element,
38093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // |beforeChild| may be the renderer for the fullscreened element. However,
38193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // that renderer is wrapped in a RenderFullScreen, so |this| is not its
38293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // parent. Since the splitting logic expects |this| to be the parent, set
38393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // |beforeChild| to be the RenderFullScreen.
3849e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (Fullscreen* fullscreen = Fullscreen::fromIfExists(document())) {
385521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        const Element* fullScreenElement = fullscreen->webkitCurrentFullScreenElement();
386521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if (fullScreenElement && beforeChild && beforeChild->node() == fullScreenElement)
387521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            beforeChild = fullscreen->fullScreenRenderer();
388521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
38993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now take all of the children from beforeChild to the end and remove
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // them from |this| and place them in the clone.
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* o = beforeChild;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (o) {
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* tmp = o;
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        o = tmp->nextSibling();
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneInline->addChildIgnoringContinuation(children()->removeChildNode(this, tmp), 0);
3975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        tmp->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Hook |clone| up as the continuation of the middle block.
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    middleBlock->setContinuation(cloneInline);
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We have been reparented and are now under the fromBlock.  We need
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // to walk up our inline parent chain until we hit the containing block.
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Once we hit the containing block we're done.
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* currChild = this;
40802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone.
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // There will eventually be a better approach to this problem that will let us nest to a much
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // greater depth (see bugzilla bug 13430) but for now we have a limit.  This *will* result in
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // incorrect rendering, but the alternative is to hang forever.
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned splitDepth = 1;
41402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    const unsigned cMaxSplitDepth = 200;
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (curr && curr != fromBlock) {
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(curr->isRenderInline());
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (splitDepth < cMaxSplitDepth) {
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Create a new clone.
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderInline* cloneChild = cloneInline;
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            cloneInline = toRenderInline(curr)->clone();
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Insert our child clone as the first child.
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            cloneInline->addChildIgnoringContinuation(cloneChild, 0);
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Hook the clone up as a continuation of |curr|.
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderInline* inlineCurr = toRenderInline(curr);
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            oldCont = inlineCurr->continuation();
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            inlineCurr->setContinuation(cloneInline);
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            cloneInline->setContinuation(oldCont);
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Now we need to take all of the children starting from the first child
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // *after* currChild and append them all to the clone.
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            o = currChild->nextSibling();
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (o) {
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                RenderObject* tmp = o;
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                o = tmp->nextSibling();
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                cloneInline->addChildIgnoringContinuation(inlineCurr->children()->removeChildNode(curr, tmp), 0);
4385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                tmp->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
44102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Keep walking up the chain.
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        currChild = curr;
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = toRenderBoxModelObject(curr->parent());
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        splitDepth++;
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now we are at the block level. We need to put the clone into the toBlock.
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    toBlock->children()->appendChildNode(toBlock, cloneInline);
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now take all the children after currChild and remove them from the fromBlock
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and put them in the toBlock.
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    o = currChild->nextSibling();
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (o) {
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* tmp = o;
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        o = tmp->nextSibling();
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        toBlock->children()->appendChildNode(toBlock, fromBlock->children()->removeChildNode(fromBlock, tmp));
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                             RenderObject* newChild, RenderBoxModelObject* oldCont)
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* pre = 0;
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* block = containingBlock();
46602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Delete our line boxes before we do the inline split into continuations.
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->deleteLineBoxTree();
46902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool madeNewBeforeBlock = false;
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We can reuse this block and make it the preBlock of the next continuation.
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre = block;
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre->removePositionedObjects(0);
475f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (pre->isRenderBlockFlow())
476f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            toRenderBlockFlow(pre)->removeFloatingObjects();
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block = block->containingBlock();
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // No anonymous block available for use.  Make one.
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre = block->createAnonymousBlock();
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        madeNewBeforeBlock = true;
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* post = toRenderBlock(pre->createAnonymousBoxWithSameTypeAs(block));
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (madeNewBeforeBlock)
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block->children()->insertChildNode(block, pre, boxFirst);
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->children()->insertChildNode(block, newBlockBox, boxFirst);
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->children()->insertChildNode(block, post, boxFirst);
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->setChildrenInline(false);
49202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (madeNewBeforeBlock) {
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* o = boxFirst;
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (o) {
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* no = o;
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            o = no->nextSibling();
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            pre->children()->appendChildNode(pre, block->children()->removeChildNode(block, no));
4995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            no->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    splitInlines(pre, post, newBlockBox, beforeChild, oldCont);
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // time in makeChildrenNonInline by just setting this explicitly up front.
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newBlockBox->setChildrenInline(false);
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newBlockBox->addChild(newChild);
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // make new line boxes instead of leaving the old line boxes around.
5145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
5155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
5165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* flow = continuationBefore(beforeChild);
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() || beforeChild->parent()->isRenderInline());
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* beforeChildParent = 0;
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild)
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBoxModelObject* cont = nextContinuation(flow);
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (cont)
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            beforeChildParent = cont;
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            beforeChildParent = flow;
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newChild->isFloatingOrOutOfFlowPositioned())
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // A continuation always consists of two potential candidates: an inline or an anonymous
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // block box holding block children.
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool childInline = newChild->isInline();
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool bcpInline = beforeChildParent->isInline();
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool flowInline = flow->isInline();
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (flow == beforeChildParent)
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return flow->addChildIgnoringContinuation(newChild, beforeChild);
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The goal here is to match up if we can, so that we can coalesce and create the
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // minimal # of continuations needed for the inline.
54851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (childInline == bcpInline || (beforeChild && beforeChild->isInline()))
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
55051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (flowInline == childInline)
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
55251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    InlinePainter(*this).paint(paintInfo, paintOffset);
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename GeneratorContext>
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::generateLineBoxRects(GeneratorContext& yield) const
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!alwaysCreateLineBoxes())
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        generateCulledLineBoxRects(yield, this);
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (InlineFlowBox* curr = firstLineBox()) {
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (; curr; curr = curr->nextLineBox())
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            yield(FloatRect(curr->topLeft(), curr->size()));
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        yield(FloatRect());
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename GeneratorContext>
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!culledInlineFirstLineBox()) {
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        yield(FloatRect());
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isHorizontal = style()->isHorizontalWritingMode();
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isFloatingOrOutOfFlowPositioned())
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
58602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // direction (aligned to the root box's baseline).
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isBox()) {
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBox* currBox = toRenderBox(curr);
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (currBox->inlineBoxWrapper()) {
592d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root();
593d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
594d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (isHorizontal)
596d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    yield(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, (currBox->width() + currBox->marginWidth()).toFloat(), logicalHeight));
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else
598d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    yield(FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, (currBox->height() + currBox->marginHeight()).toFloat()));
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (curr->isRenderInline()) {
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If the child doesn't need line boxes either, then we can recur.
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderInline* currInline = toRenderInline(curr);
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!currInline->alwaysCreateLineBoxes())
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                currInline->generateCulledLineBoxRects(yield, container);
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else {
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) {
607d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    RootInlineBox& rootBox = childLine->root();
608d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
609d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (isHorizontal)
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        yield(FloatRect(childLine->x() - childLine->marginLogicalLeft(),
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            logicalTop,
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight(),
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            logicalHeight));
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    else
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        yield(FloatRect(logicalTop,
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            childLine->y() - childLine->marginLogicalLeft(),
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            logicalHeight,
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight()));
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (curr->isText()) {
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderText* currText = toRenderText(curr);
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox()) {
625d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                RootInlineBox& rootBox = childText->root();
626d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
627d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (isHorizontal)
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    yield(FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight));
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    yield(FloatRect(logicalTop, childText->y(), logicalHeight, childText->logicalWidth()));
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class AbsoluteRectsGeneratorContext {
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AbsoluteRectsGeneratorContext(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset)
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_rects(rects)
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_accumulatedOffset(accumulatedOffset) { }
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void operator()(const FloatRect& rect)
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IntRect intRect = enclosingIntRect(rect);
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        intRect.move(m_accumulatedOffset.x(), m_accumulatedOffset.y());
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_rects.append(intRect);
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<IntRect>& m_rects;
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const LayoutPoint& m_accumulatedOffset;
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // unnamed namespace
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AbsoluteRectsGeneratorContext context(rects, accumulatedOffset);
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    generateLineBoxRects(context);
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (continuation()) {
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (continuation()->isBox()) {
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBox* box = toRenderBox(continuation());
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continuation()->absoluteRects(rects, toLayoutPoint(accumulatedOffset - containingBlock()->location() + box->locationOffset()));
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continuation()->absoluteRects(rects, toLayoutPoint(accumulatedOffset - containingBlock()->location()));
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class AbsoluteQuadsGeneratorContext {
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AbsoluteQuadsGeneratorContext(const RenderInline* renderer, Vector<FloatQuad>& quads)
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_quads(quads)
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_geometryMap()
6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_geometryMap.pushMappingsToAncestor(renderer, 0);
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void operator()(const FloatRect& rect)
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_quads.append(m_geometryMap.absoluteRect(rect));
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<FloatQuad>& m_quads;
6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderGeometryMap m_geometryMap;
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // unnamed namespace
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AbsoluteQuadsGeneratorContext context(this, quads);
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    generateLineBoxRects(context);
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (continuation())
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        continuation()->absoluteQuads(quads, wasFixed);
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::offsetLeft() const
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutPoint topLeft;
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (InlineBox* firstBox = firstLineBoxIncludingCulling())
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        topLeft = flooredLayoutPoint(firstBox->topLeft());
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return adjustedPositionRelativeToOffsetParent(topLeft).x();
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::offsetTop() const
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutPoint topLeft;
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (InlineBox* firstBox = firstLineBoxIncludingCulling())
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        topLeft = flooredLayoutPoint(firstBox->topLeft());
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return adjustedPositionRelativeToOffsetParent(topLeft).y();
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static LayoutUnit computeMargin(const RenderInline* renderer, const Length& margin)
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (margin.isAuto())
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (margin.isFixed())
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return margin.value();
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (margin.isPercent())
727197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return minimumValueForLength(margin, std::max<LayoutUnit>(0, renderer->containingBlock()->availableLogicalWidth()));
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginLeft() const
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginLeft());
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginRight() const
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginRight());
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginTop() const
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginTop());
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginBottom() const
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginBottom());
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginStart(const RenderStyle* otherStyle) const
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginStartUsing(otherStyle ? otherStyle : style()));
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginEnd(const RenderStyle* otherStyle) const
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginEndUsing(otherStyle ? otherStyle : style()));
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginBefore(const RenderStyle* otherStyle) const
7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginBeforeUsing(otherStyle ? otherStyle : style()));
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::marginAfter(const RenderStyle* otherStyle) const
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return computeMargin(this, style()->marginAfterUsing(otherStyle ? otherStyle : style()));
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char* RenderInline::renderName() const
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isRelPositioned())
7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "RenderInline (relative positioned)";
7757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // FIXME: Cleanup isPseudoElement duplication with other renderName methods.
7767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // crbug.com/415653
7777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (isPseudoElement()) {
7787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (style()->styleType() == BEFORE)
7797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return "RenderInline (pseudo:before)";
7807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (style()->styleType() == AFTER)
7817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return "RenderInline (pseudo:after)";
7827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (style()->styleType() == BACKDROP)
7837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return "RenderInline (pseudo:backdrop)";
7847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT_NOT_REACHED();
7857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isAnonymous())
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "RenderInline (generated)";
7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return "RenderInline";
7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderInline::nodeAtPoint(const HitTestRequest& request, HitTestResult& result,
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
797926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace {
798926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
799926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class HitTestCulledInlinesGeneratorContext {
800926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
801926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    HitTestCulledInlinesGeneratorContext(Region& region, const HitTestLocation& location) : m_intersected(false), m_region(region), m_location(location) { }
802926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void operator()(const FloatRect& rect)
803926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
804926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_intersected = m_intersected || m_location.intersects(rect);
805926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_region.unite(enclosingIntRect(rect));
806926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
807926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool intersected() const { return m_intersected; }
808926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)private:
809926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool m_intersected;
810926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Region& m_region;
811926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const HitTestLocation& m_location;
812926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
813926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
814926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} // unnamed namespace
815926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
816926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool RenderInline::hitTestCulledInline(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset)
817926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
818926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(result.isRectBasedTest() && !alwaysCreateLineBoxes());
81953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!visibleToHitTestRequest(request))
820926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
821926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
822926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    HitTestLocation tmpLocation(locationInContainer, -toLayoutSize(accumulatedOffset));
823926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
824926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Region regionResult;
825926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    HitTestCulledInlinesGeneratorContext context(regionResult, tmpLocation);
826926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    generateCulledLineBoxRects(context, this);
827926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
828926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (context.intersected()) {
829926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        updateHitTestResult(result, tmpLocation.point());
830926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // We can not use addNodeToRectBasedTestResult to determine if we fully enclose the hit-test area
831926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // because it can only handle rectangular targets.
832926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        result.addNodeToRectBasedTestResult(node(), request, locationInContainer);
833521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return regionResult.contains(tmpLocation.boundingBox());
834926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
835926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return false;
836926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
837926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
838f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)PositionWithAffinity RenderInline::positionForPoint(const LayoutPoint& point)
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
840197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // FIXME: Does not deal with relative positioned inlines (should it?)
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* cb = containingBlock();
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstLineBox()) {
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This inline actually has a line box.  We must have clicked in the border/padding of one of these boxes.  We
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // should try to find a result by asking our containing block.
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return cb->positionForPoint(point);
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Translate the coords from the pre-anonymous block to the post-anonymous block.
84902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    LayoutPoint parentBlockPoint = cb->location() + point;
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* c = continuation();
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (c) {
8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBox* contBlock = c->isInline() ? c->containingBlock() : toRenderBlock(c);
853d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        if (c->isInline() || c->slowFirstChild())
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return c->positionForPoint(parentBlockPoint - contBlock->locationOffset());
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        c = toRenderBlock(c)->inlineElementContinuation();
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
85702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return RenderBoxModelObject::positionForPoint(point);
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class LinesBoundingBoxGeneratorContext {
8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LinesBoundingBoxGeneratorContext(FloatRect& rect) : m_rect(rect) { }
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void operator()(const FloatRect& rect)
8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_rect.uniteIfNonZero(rect);
8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatRect& m_rect;
8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // unnamed namespace
8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect RenderInline::linesBoundingBox() const
8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!alwaysCreateLineBoxes()) {
8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!firstLineBox());
8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        FloatRect floatResult;
8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LinesBoundingBoxGeneratorContext context(floatResult);
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        generateCulledLineBoxRects(context, this);
8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return enclosingIntRect(floatResult);
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntRect result;
88702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See <rdar://problem/5289721>, for an unknown reason the linked list here is sometimes inconsistent, first is non-zero and last is zero.  We have been
8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // unable to reproduce this at all (and consequently unable to figure ot why this is happening).  The assert will hopefully catch the problem in debug
8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // builds and help us someday figure out why.  We also put in a redundant check of lastLineBox() to avoid the crash for now.
8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!firstLineBox() == !lastLineBox());  // Either both are null or both exist.
8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstLineBox() && lastLineBox()) {
8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Return the width of the minimal left side and the maximal right side.
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        float logicalLeftSide = 0;
8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        float logicalRightSide = 0;
8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide)
8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                logicalLeftSide = curr->logicalLeft();
8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (curr == firstLineBox() || curr->logicalRight() > logicalRightSide)
9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                logicalRightSide = curr->logicalRight();
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
90202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool isHorizontal = style()->isHorizontalWritingMode();
90402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        float x = isHorizontal ? logicalLeftSide : firstLineBox()->x();
9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        float y = isHorizontal ? firstLineBox()->y() : logicalLeftSide;
9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->logicalBottom() - x;
9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        float height = isHorizontal ? lastLineBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = enclosingIntRect(FloatRect(x, y, width, height));
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineBox* RenderInline::culledInlineFirstLineBox() const
9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
9185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isFloatingOrOutOfFlowPositioned())
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
92002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // direction (aligned to the root box's baseline).
9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isBox())
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return toRenderBox(curr)->inlineBoxWrapper();
9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isRenderInline()) {
9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderInline* currInline = toRenderInline(curr);
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            InlineBox* result = currInline->firstLineBoxIncludingCulling();
9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (result)
9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return result;
9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (curr->isText()) {
9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderText* currText = toRenderText(curr);
9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (currText->firstTextBox())
9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return currText->firstTextBox();
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineBox* RenderInline::culledInlineLastLineBox() const
9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject* curr = lastChild(); curr; curr = curr->previousSibling()) {
9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isFloatingOrOutOfFlowPositioned())
9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
94402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // direction (aligned to the root box's baseline).
9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isBox())
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return toRenderBox(curr)->inlineBoxWrapper();
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isRenderInline()) {
9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderInline* currInline = toRenderInline(curr);
9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            InlineBox* result = currInline->lastLineBoxIncludingCulling();
9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (result)
9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return result;
9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (curr->isText()) {
9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderText* currText = toRenderText(curr);
9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (currText->lastTextBox())
9575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return currText->lastTextBox();
9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
9615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderInline::culledInlineVisualOverflowBoundingBox() const
9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatRect floatResult;
9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LinesBoundingBoxGeneratorContext context(floatResult);
9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    generateCulledLineBoxRects(context, this);
9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect result(enclosingLayoutRect(floatResult));
9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isHorizontal = style()->isHorizontalWritingMode();
9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isFloatingOrOutOfFlowPositioned())
9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
97302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // For overflow we just have to propagate by hand and recompute it all.
9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isBox()) {
9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBox* currBox = toRenderBox(curr);
9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!currBox->hasSelfPaintingLayer() && currBox->inlineBoxWrapper()) {
9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                LayoutRect logicalRect = currBox->logicalVisualOverflowRectForPropagation(style());
9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (isHorizontal) {
9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    logicalRect.moveBy(currBox->location());
9815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    result.uniteIfNonZero(logicalRect);
9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    logicalRect.moveBy(currBox->location());
9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    result.uniteIfNonZero(logicalRect.transposedRect());
9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (curr->isRenderInline()) {
9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If the child doesn't need line boxes either, then we can recur.
9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderInline* currInline = toRenderInline(curr);
9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!currInline->alwaysCreateLineBoxes())
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result.uniteIfNonZero(currInline->culledInlineVisualOverflowBoundingBox());
9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else if (!currInline->hasSelfPaintingLayer())
9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result.uniteIfNonZero(currInline->linesVisualOverflowBoundingBox());
9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (curr->isText()) {
9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME; Overflow from text boxes is lost. We will need to cache this information in
9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // InlineTextBoxes.
9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderText* currText = toRenderText(curr);
9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.uniteIfNonZero(currText->linesVisualOverflowBoundingBox());
9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderInline::linesVisualOverflowBoundingBox() const
10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!alwaysCreateLineBoxes())
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return culledInlineVisualOverflowBoundingBox();
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!firstLineBox() || !lastLineBox())
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutRect();
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Return the width of the minimal left side and the maximal right side.
10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit logicalLeftSide = LayoutUnit::max();
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit logicalRightSide = LayoutUnit::min();
10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
1016197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        logicalLeftSide = std::min(logicalLeftSide, curr->logicalLeftVisualOverflow());
1017197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        logicalRightSide = std::max(logicalRightSide, curr->logicalRightVisualOverflow());
10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1020d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RootInlineBox& firstRootBox = firstLineBox()->root();
1021d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RootInlineBox& lastRootBox = lastLineBox()->root();
102202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1023d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LayoutUnit logicalTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox.lineTop());
10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide;
1025d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LayoutUnit logicalHeight = lastLineBox()->logicalBottomVisualOverflow(lastRootBox.lineBottom()) - logicalTop;
102602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight);
10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style()->isHorizontalWritingMode())
10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        rect = rect.transposedRect();
10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return rect;
10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1033197021e6b966cfb06891637935ef33fff06433d1Ben MurdochLayoutRect RenderInline::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const
10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1035c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if ((!firstLineBoxIncludingCulling() && !continuation()) || style()->visibility() != VISIBLE)
10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutRect();
10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10389e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    LayoutRect paintInvalidationRect(linesVisualOverflowBoundingBox());
10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit outlineSize = style()->outlineSize();
10419e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    paintInvalidationRect.inflate(outlineSize);
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    mapRectToPaintInvalidationBacking(paintInvalidationContainer, paintInvalidationRect, paintInvalidationState);
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (outlineSize) {
10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!curr->isText())
10489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                paintInvalidationRect.unite(curr->rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineSize));
10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (continuation() && !continuation()->isInline() && continuation()->parent())
10529e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            paintInvalidationRect.unite(continuation()->rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineSize));
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10559e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return paintInvalidationRect;
10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1058197021e6b966cfb06891637935ef33fff06433d1Ben MurdochLayoutRect RenderInline::rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth, const PaintInvalidationState* paintInvalidationState) const
10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1060197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutRect r(RenderBoxModelObject::rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineWidth, paintInvalidationState));
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!curr->isText())
1063197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            r.unite(curr->rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineWidth, paintInvalidationState));
10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return r;
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RenderInline::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState) const
10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1070197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (paintInvalidationState && paintInvalidationState->canMapToContainer(paintInvalidationContainer)) {
1071197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (style()->hasInFlowPosition() && layer())
1072197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            rect.move(layer()->offsetForInFlowPosition());
1073197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        rect.move(paintInvalidationState->paintOffset());
1074197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (paintInvalidationState->isClipped())
1075197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            rect.intersect(paintInvalidationState->clipRect());
1076197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return;
10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (paintInvalidationContainer == this)
10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool containerSkipped;
10835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RenderObject* o = container(paintInvalidationContainer, &containerSkipped);
10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!o)
10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutPoint topLeft = rect.location();
10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (o->isRenderBlockFlow() && !style()->hasOutOfFlowPosition()) {
10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBlock* cb = toRenderBlock(o);
10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (cb->hasColumns()) {
10929e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            LayoutRect paintInvalidationRect(topLeft, rect.size());
10939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            cb->adjustRectForColumns(paintInvalidationRect);
10949e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            topLeft = paintInvalidationRect.location();
10959e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            rect = paintInvalidationRect;
10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style()->hasInFlowPosition() && layer()) {
11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Apply the in-flow position offset when invalidating a rectangle. The layer
11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // is translated, but the render box isn't, so we need to do this to get the
1102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // right dirty rect. Since this is called from RenderObject::setStyle, the relative position
11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // flag on the RenderObject has been cleared, so use the one on the style().
1104e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        topLeft += layer()->offsetForInFlowPosition();
11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
110602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,
11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer.
11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    rect.setLocation(topLeft);
11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (o->hasOverflowClip()) {
11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBox* containerBox = toRenderBox(o);
11129e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        containerBox->applyCachedClipAndScrollOffsetForPaintInvalidation(rect);
11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (rect.isEmpty())
11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (containerSkipped) {
11185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        // If the paintInvalidationContainer is below o, then we need to map the rect into paintInvalidationContainer's coordinates.
11195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        LayoutSize containerOffset = paintInvalidationContainer->offsetFromAncestorContainer(o);
11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        rect.move(-containerOffset);
11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
112302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    o->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState);
11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1127d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)LayoutSize RenderInline::offsetFromContainer(const RenderObject* container, const LayoutPoint& point, bool* offsetDependsOnPoint) const
11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(container == this->container());
113002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
113102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    LayoutSize offset;
1132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (isRelPositioned())
11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        offset += offsetForInFlowPosition();
11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1135f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    offset += container->columnOffset(point);
11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (container->hasOverflowClip())
11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        offset -= toRenderBox(container)->scrolledContentOffset();
11395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1140521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (offsetDependsOnPoint) {
1141521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        *offsetDependsOnPoint = container->hasColumns()
1142521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            || (container->isBox() && container->style()->isFlippedBlocksWritingMode())
1143521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            || container->isRenderFlowThread();
1144521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return offset;
11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void RenderInline::mapLocalToContainer(const RenderLayerModelObject* paintInvalidationContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) const
11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11519e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (paintInvalidationContainer == this)
11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11549e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (paintInvalidationState && paintInvalidationState->canMapToContainer(paintInvalidationContainer)) {
1155197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        LayoutSize offset = paintInvalidationState->paintOffset();
1156197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (style()->hasInFlowPosition() && layer())
1157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            offset += layer()->offsetForInFlowPosition();
1158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        transformState.move(offset);
1159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return;
11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool containerSkipped;
11639e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    RenderObject* o = container(paintInvalidationContainer, &containerSkipped);
11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!o)
11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (mode & ApplyContainerFlip && o->isBox()) {
11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (o->style()->isFlippedBlocksWritingMode()) {
11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(centerPoint) - centerPoint);
11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mode &= ~ApplyContainerFlip;
11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutSize containerOffset = offsetFromContainer(o, roundedLayoutPoint(transformState.mappedPoint()));
11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool preserve3D = mode & UseTransforms && (o->style()->preserves3D() || style()->preserves3D());
11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (mode & UseTransforms && shouldUseTransformFromContainer(o)) {
11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TransformationMatrix t;
11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        getTransformFromContainer(o, containerOffset, t);
11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (containerSkipped) {
11869e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // There can't be a transform between paintInvalidationContainer and o, because transforms create containers, so it should be safe
11879e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // to just subtract the delta between the paintInvalidationContainer and o.
11889e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        LayoutSize containerOffset = paintInvalidationContainer->offsetFromAncestorContainer(o);
11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    o->mapLocalToContainer(paintInvalidationContainer, transformState, mode, wasFixed, paintInvalidationState);
11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::updateDragState(bool dragOn)
11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject::updateDragState(dragOn);
11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (continuation())
12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        continuation()->updateDragState(dragOn);
12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::childBecameNonInline(RenderObject* child)
12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We have to split the parent flow.
12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* newBox = containingBlock()->createAnonymousBlock();
12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* oldContinuation = continuation();
12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setContinuation(newBox);
12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* beforeChild = child->nextSibling();
12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    children()->removeChildNode(this, child);
12115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    splitFlow(beforeChild, newBox, child, oldContinuation);
12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (result.innerNode())
12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* n = node();
12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutPoint localPoint(point);
12215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (n) {
12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isInlineElementContinuation()) {
12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We're in the continuation of a split inline.  Adjust our local point to be in the coordinate space
12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // of the principal renderer's containing block.  This will end up being the innerNonSharedNode.
12255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBlock* firstBlock = n->renderer()->containingBlock();
122602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Get our containing block.
12285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBox* block = containingBlock();
12295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            localPoint.moveBy(block->location() - firstBlock->locationOffset());
12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.setInnerNode(n);
12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!result.innerNonSharedNode())
12345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result.setInnerNonSharedNode(n);
12355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.setLocalPoint(localPoint);
12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::dirtyLineBoxes(bool fullLayout)
12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (fullLayout) {
1242f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        m_lineBoxes.deleteLineBoxes();
12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!alwaysCreateLineBoxes()) {
12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We have to grovel into our children in order to dirty the appropriate lines.
12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
12495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (curr->isFloatingOrOutOfFlowPositioned())
12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (curr->isBox() && !curr->needsLayout()) {
12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                RenderBox* currBox = toRenderBox(curr);
12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (currBox->inlineBoxWrapper())
1254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    currBox->inlineBoxWrapper()->root().markDirty();
12555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else if (!curr->selfNeedsLayout()) {
12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (curr->isRenderInline()) {
12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    RenderInline* currInline = toRenderInline(curr);
12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox())
1259d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        childLine->root().markDirty();
12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else if (curr->isText()) {
12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    RenderText* currText = toRenderText(curr);
12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox())
1263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        childText->root().markDirty();
12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lineBoxes.dirtyLineBoxes();
12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::deleteLineBoxTree()
12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1273f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    m_lineBoxes.deleteLineBoxTree();
12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
127602772c6a72f1ee0b226341a4f4439970c29fc861Ben MurdochInlineFlowBox* RenderInline::createInlineFlowBox()
12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1278d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return new InlineFlowBox(*this);
12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InlineFlowBox* RenderInline::createAndAppendInlineFlowBox()
12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setAlwaysCreateLineBoxes();
12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineFlowBox* flowBox = createInlineFlowBox();
12855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lineBoxes.appendLineBox(flowBox);
12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return flowBox;
12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, LinePositionMode /*linePositionMode*/) const
12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12919bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (firstLine && document().styleEngine()->usesFirstLineRules()) {
12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderStyle* s = style(firstLine);
12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (s != style())
129409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return s->computedLineHeight();
12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
129709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return style()->computedLineHeight();
12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
130253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(linePositionMode == PositionOnContainingLine);
13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)LayoutSize RenderInline::offsetForInFlowPositionedInline(const RenderBox& child) const
13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: This function isn't right with mixed writing modes.
13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1311197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(isRelPositioned());
1312197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!isRelPositioned())
13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutSize();
13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // box from the rest of the content, but only in the cases where we know we're positioned
13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // relative to the inline itself.
13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutSize logicalOffset;
13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit inlinePosition;
13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit blockPosition;
13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstLineBox()) {
132393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        inlinePosition = LayoutUnit::fromFloatRound(firstLineBox()->logicalLeft());
13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        blockPosition = firstLineBox()->logicalTop();
13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        inlinePosition = layer()->staticInlinePosition();
13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        blockPosition = layer()->staticBlockPosition();
13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13309e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    // Per http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width an absolute positioned box
13319e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    // with a static position should locate itself as though it is a normal flow box in relation to
13329e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    // its containing block. If this relative-positioned inline has a negative offset we need to
13339e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    // compensate for it so that we align the positioned object with the edge of its containing block.
13349e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (child.style()->hasStaticInlinePosition(style()->isHorizontalWritingMode()))
13359e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        logicalOffset.setWidth(std::max(LayoutUnit(), -offsetForInFlowPosition().width()));
13369e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    else
13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        logicalOffset.setWidth(inlinePosition);
13385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!child.style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        logicalOffset.setHeight(blockPosition);
13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return style()->isHorizontalWritingMode() ? logicalOffset : logicalOffset.transposedSize();
13435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!parent())
13485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
134902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: We can do better.
13519e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    setShouldDoFullPaintInvalidation(true);
13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochnamespace {
13557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
13567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochclass AbsoluteLayoutRectsGeneratorContext {
13577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochpublic:
13587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    AbsoluteLayoutRectsGeneratorContext(Vector<LayoutRect>& rects, const LayoutPoint& accumulatedOffset)
13597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        : m_rects(rects)
13607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        , m_accumulatedOffset(accumulatedOffset) { }
13617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
13627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    void operator()(const FloatRect& rect)
13637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    {
13647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        LayoutRect layoutRect(rect);
13657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        layoutRect.move(m_accumulatedOffset.x(), m_accumulatedOffset.y());
13667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        m_rects.append(layoutRect);
13677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    }
13687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochprivate:
13697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Vector<LayoutRect>& m_rects;
13707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    const LayoutPoint& m_accumulatedOffset;
13717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch};
13727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
13737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass AbsoluteLayoutRectsIgnoringEmptyRectsGeneratorContext : public AbsoluteLayoutRectsGeneratorContext {
13747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic:
13757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    AbsoluteLayoutRectsIgnoringEmptyRectsGeneratorContext(Vector<LayoutRect>& rects, const LayoutPoint& accumulatedOffset)
13767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        : AbsoluteLayoutRectsGeneratorContext(rects, accumulatedOffset) { }
137702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
13787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void operator()(const FloatRect& rect)
13797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
13807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!rect.isEmpty())
13817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            AbsoluteLayoutRectsGeneratorContext::operator()(rect);
13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // unnamed namespace
13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RenderInline::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer) const
13887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
13897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    AbsoluteLayoutRectsIgnoringEmptyRectsGeneratorContext context(rects, additionalOffset);
13907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    generateLineBoxRects(context);
13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    addChildFocusRingRects(rects, additionalOffset, paintContainer);
1393e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
13947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (continuation()) {
13957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // If the continuation doesn't paint into the same container, let its paint invalidation container handle it.
13967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (paintContainer != continuation()->containerForPaintInvalidation())
13977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return;
13987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (continuation()->isInline())
13997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            continuation()->addFocusRingRects(rects, additionalOffset + (continuation()->containingBlock()->location() - containingBlock()->location()), paintContainer);
14007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        else
14017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            continuation()->addFocusRingRects(rects, additionalOffset + (toRenderBox(continuation())->location() - containingBlock()->location()), paintContainer);
14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RenderInline::computeSelfHitTestRects(Vector<LayoutRect>& rects, const LayoutPoint& layerOffset) const
14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    AbsoluteLayoutRectsGeneratorContext context(rects, layerOffset);
14087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    generateLineBoxRects(context);
14095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderInline::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Convert the style regions to absolute coordinates.
14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style()->visibility() != VISIBLE)
14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style()->getDraggableRegionMode() == DraggableRegionNone)
14185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AnnotatedRegionValue region;
14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    region.draggable = style()->getDraggableRegionMode() == DraggableRegionDrag;
14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    region.bounds = linesBoundingBox();
14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* container = containingBlock();
14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!container)
14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        container = this;
14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatPoint absPos = container->localToAbsolute();
14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    region.bounds.setX(absPos.x() + region.bounds.x());
14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    region.bounds.setY(absPos.y() + region.bounds.y());
143102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    regions.append(region);
14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1435c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
1436